|
|
1.1 root 1: /****************************************************************************
2: Microsoft RPC Version 1.0
3: Copyright Microsoft Corp. 1992
4: xmit Example
5:
6: FILE: xmitc.c
7: USAGE: xmitc -n network_address
8: -p protocol_sequence
9: -e endpoint
10: -o options
11: -c count of elements in linked list
12: -v value of first element in linked list
13: -d delta between values in linked list
14:
15: PURPOSE: Client side of RPC distributed application.
16: This sample demonstrates the transmit_as example.
17: A doubly-linked list is transmitted over the network
18: as a sized array.
19:
20: RELATED: xmits.c - server main
21: xmitp.c - remote procedures
1.1.1.2 ! root 22: xmitu.c - utility procedures
1.1 root 23:
24: FUNCTIONS: main() - bind to server and call remote procedure
25:
26: COMMENTS: This sample program generates a linked list to
1.1.1.2 ! root 27: demonstrate how a list with aliasing can be transmitted
! 28: using the transmit_as attribute as a sized array.
1.1 root 29: The pointers are rebuilt on the server side.
30:
31: The [transmit_as] attribute (used in the typedef of
1.1.1.2 ! root 32: DOUBLE_LINK_TYPE in the file XMIT.IDL) requires the
1.1 root 33: four user-supplied functions whose names start with
1.1.1.2 ! root 34: the name of the presented type, DOUBLE_LINK_TYPE.
1.1 root 35:
36: The [in, out] attributes applied to remote procedure
37: parameters require the two user-supplied functions
38: MIDL_user_allocate and MIDL_user_free.
39:
40: The other functions are utilities that are used to
41: build or display the data structures.
42:
43:
44: ****************************************************************************/
45: #include <stdio.h>
46: #include <string.h>
47: #include <stdlib.h>
48: #include <rpc.h> // RPC API functions, types
49: #include "xmit.h" // header file generated by MIDL compiler
1.1.1.2 ! root 50: #include "xmitu.h" // utility function prototypes
! 51:
! 52: DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious);
! 53:
! 54: void ArrayWalkProc(DOUBLE_XMIT_TYPE * pArray);
! 55: void ListWalkProc(DOUBLE_LINK_TYPE * pList);
! 56: void * MIDL_user_allocate(size_t len);
! 57: void MIDL_user_free(void * ptr);
! 58:
! 59: void DOUBLE_LINK_TYPE_free_inst (DOUBLE_LINK_TYPE * pList);
! 60: void DOUBLE_LINK_TYPE_free_xmit (DOUBLE_XMIT_TYPE * pSizedArray);
! 61: void DOUBLE_LINK_TYPE_to_xmit (DOUBLE_LINK_TYPE * pList,
! 62: DOUBLE_XMIT_TYPE ** ppArray);
! 63: void DOUBLE_LINK_TYPE_from_xmit (DOUBLE_XMIT_TYPE * pArray,
! 64: DOUBLE_LINK_TYPE * pDblLinkedList);
1.1 root 65:
66: #define PURPOSE \
67: "This Microsoft RPC Version 1.0 sample program demonstrates\n\
68: the use of the [transmit_as] attribute. For more information\n\
69: about the attributes and the RPC API functions, see the\n\
70: RPC programming guide and reference.\n\n"
71:
72: #define MAX_ELEMENTS 50
73:
74: void Usage(char * pszProgramName)
75: {
76: fprintf(stderr, "%s", PURPOSE);
77: fprintf(stderr, "Usage: %s\n", pszProgramName);
78: fprintf(stderr, " -p protocol_sequence\n");
79: fprintf(stderr, " -n network_address\n");
80: fprintf(stderr, " -e endpoint\n");
81: fprintf(stderr, " -o options\n");
82: fprintf(stderr, " -c count_of_elements\n");
83: fprintf(stderr, " -v value\n");
84: fprintf(stderr, " -d delta\n");
85:
86: exit(1);
87: }
88:
89: /* main: establish the binding to the server, call the remote procedure */
1.1.1.2 ! root 90: void _CRTAPI1 main(int argc, char **argv)
1.1 root 91: {
1.1.1.2 ! root 92: RPC_STATUS status; // returned by RPC API function
! 93: unsigned char * pszUuid = NULL;
1.1 root 94: unsigned char * pszProtocolSequence = "ncacn_np";
95: unsigned char * pszNetworkAddress = NULL;
96: unsigned char * pszEndpoint = "\\pipe\\xmit";
97: unsigned char * pszOptions = NULL;
98: unsigned char * pszStringBinding = NULL;
99: int i;
100: int cElements = 10;
101: short sValue = 100;
102: short sDelta = 10;
103:
1.1.1.2 ! root 104: PDOUBLE_LINK_TYPE pFirst, pCurrent;
1.1 root 105:
106: // allow the user to override settings with command line switches
107: for (i = 1; i < argc; i++) {
108: if ((*argv[i] == '-') || (*argv[i] == '/')) {
109: switch (tolower(*(argv[i]+1))) {
110: case 'p': // protocol sequence
111: pszProtocolSequence = argv[++i];
112: break;
113: case 'n': // network address
114: pszNetworkAddress = argv[++i];
115: break;
116: case 'e':
117: pszEndpoint = argv[++i];
118: break;
119: case 'o':
120: pszOptions = argv[++i];
121: break;
122: case 'c':
123: cElements = atoi(argv[++i]);
124: if (cElements > MAX_ELEMENTS)
125: cElements = MAX_ELEMENTS;
126: break;
127: case 'v':
128: sValue = (short)atoi(argv[++i]);
129: break;
130: case 'd':
131: sDelta = (short)atoi(argv[++i]);
132: break;
133:
134: case 'h':
135: case '?':
136: default:
137: Usage(argv[0]);
138: }
139: }
140: else
141: Usage(argv[0]);
142: }
143: /* initialize a list with a number of elements */
144: pFirst = InsertNewNode(sValue, NULL);
145: pCurrent = pFirst; /* assign some values to the list nodes */
146: sValue += sDelta; /* make them different values */
147:
148: for (i = 1; i < cElements; i++) {
1.1.1.2 ! root 149: pCurrent = InsertNewNode(sValue, pCurrent);
1.1 root 150: sValue += sDelta;
151: }
152: ListWalkProc(pFirst);
153:
154: /* Use a convenience function to concatenate the elements of the string */
155: /* binding into the syntax needed by RpcBindingFromStringBinding. */
156:
157: status = RpcStringBindingCompose(pszUuid,
158: pszProtocolSequence,
159: pszNetworkAddress,
160: pszEndpoint,
161: pszOptions,
162: &pszStringBinding);
163: printf("RpcStringBindingCompose returned 0x%x\n", status);
164: printf("pszStringBinding = %s\n", pszStringBinding);
165: if (status)
1.1.1.2 ! root 166: exit(status);
1.1 root 167:
168: /* Set the binding handle that will be used to bind to the server. */
169:
170: status = RpcBindingFromStringBinding(pszStringBinding,
171: &hXmit);
172: printf("RpcBindingFromStringBinding returned 0x%x\n", status);
173: if (status)
1.1.1.2 ! root 174: exit(status);
1.1 root 175:
176: printf("Calling the remote procedure 'ModifyListProc'\n");
177:
178: ModifyListProc(pFirst); // call the remote procedure
179:
180: printf("Calling the remote procedure 'Shutdown'\n");
181: Shutdown(); // shut down the server side
182:
183: printf("After ModifyListProc, the list appears as follows:\n");
184: ListWalkProc(pFirst); // call the utility that displays the list
185:
186: /* The calls to the remote procedures are complete. */
187: /* Free the string and the binding handle using RPC API calls. */
188:
189: status = RpcStringFree(&pszStringBinding); // remote calls done; unbind
190: printf("RpcStringFree returned 0x%x\n", status);
191: if (status)
1.1.1.2 ! root 192: exit(status);
1.1 root 193:
194: status = RpcBindingFree(&hXmit); // remote calls done; unbind
195: printf("RpcBindingFree returned 0x%x\n", status);
196: if (status)
1.1.1.2 ! root 197: exit(status);
1.1 root 198:
199: exit(0); /* successful completion */
200: }
1.1.1.2 ! root 201: /* end xmitc.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.