--- mstools/samples/rpc/data/xmit/xmitc.c 2018/08/09 18:20:59 1.1 +++ mstools/samples/rpc/data/xmit/xmitc.c 2018/08/09 18:24:25 1.1.1.3 @@ -1,62 +1,54 @@ /**************************************************************************** - Microsoft RPC Version 1.0 - Copyright Microsoft Corp. 1992 - xmit Example - - FILE: xmitc.c - USAGE: xmitc -n network_address - -p protocol_sequence - -e endpoint - -o options - -u uuid - -c count of elements in linked list - -v value of first element in linked list - -d delta between values in linked list - - PURPOSE: Client side of RPC distributed application. - This sample demonstrates the transmit_as example. - A doubly-linked list is transmitted over the network - as a sized array. - - RELATED: xmits.c - server main - xmitp.c - remote procedures - - FUNCTIONS: main() - bind to server and call remote procedure - PDOUBLE_LINK_TYPE_to_xmit - convert list to array - PDOUBLE_LINK_TYPE_from_xmit - convert array to list - PDOUBLE_LINK_TYPE_free_inst - free linked list memory - PDOUBLE_LINK_TYPE_free_xmit - free array memory - MIDL_user_allocate - user-supplied memory allocator - MIDL_user_free - user-supplied routine to free memory - - ArrayWalkProc - utility to display the array - ListWalkProc - utility to display the linked list - InsertNewNode - utility to add a node to the list - - COMMENTS: This sample program generates a linked list to - demonstrate how the list can be transmitted over - the network more efficiently as a sized array. - The pointers are rebuilt on the server side. - - The [transmit_as] attribute (used in the typedef of - PDOUBLE_LINK_TYPE in the file XMIT.IDL) requires the - four user-supplied functions whose names start with - the name of the presented type, PDOUBLE_LINK_TYPE. - - The [in, out] attributes applied to remote procedure - parameters require the two user-supplied functions - MIDL_user_allocate and MIDL_user_free. + Microsoft RPC Version 1.0 + Copyright Microsoft Corp. 1992 + xmit Example + + FILE: xmitc.c + + USAGE: xmitc -n network_address + -p protocol_sequence + -e endpoint + -o options + -c count of elements in linked list + -v value of first element in linked list + -d delta between values in linked list + + PURPOSE: Client side of RPC distributed application. + This sample demonstrates the transmit_as example. + A doubly-linked list is transmitted over the network + as a sized array. + + RELATED: xmits.c - server main + xmitp.c - remote procedures + xmitu.c - utility procedures + + FUNCTIONS: main() - bind to server and call remote procedure + + COMMENTS: This sample program generates a linked list to + demonstrate how a list with aliasing can be transmitted + using the transmit_as attribute as a sized array. + The pointers are rebuilt on the server side. + + The [transmit_as] attribute (used in the typedef of + DOUBLE_LINK_TYPE in the file XMIT.IDL) requires the + four user-supplied functions whose names start with + the name of the presented type, DOUBLE_LINK_TYPE. + + The [in, out] attributes applied to remote procedure + parameters require the two user-supplied functions + midl_user_allocate and midl_user_free. - The other functions are utilities that are used to - build or display the data structures. + The other functions are utilities that are used to + build or display the data structures. ****************************************************************************/ -#include -#include + #include -#include // RPC API functions, types +#include +#include #include "xmit.h" // header file generated by MIDL compiler +#include "xmitu.h" // utility function prototypes #define PURPOSE \ "This Microsoft RPC Version 1.0 sample program demonstrates\n\ @@ -74,199 +66,78 @@ void Usage(char * pszProgramName) fprintf(stderr, " -n network_address\n"); fprintf(stderr, " -e endpoint\n"); fprintf(stderr, " -o options\n"); - fprintf(stderr, " -u uuid\n"); fprintf(stderr, " -c count_of_elements\n"); fprintf(stderr, " -v value\n"); fprintf(stderr, " -d delta\n"); - exit(1); } -DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious) +void _CRTAPI1 main(int argc, char **argv) { -DOUBLE_LINK_TYPE * pNew; - - pNew = (DOUBLE_LINK_TYPE *) malloc(sizeof(DOUBLE_LINK_TYPE)); - if (pNew != NULL) { - pNew->sNumber = sValue; /* insert b between a and c */ - pNew->pPrevious = pPrevious; /* prev(b) = a */ - if (pPrevious != NULL) { - pNew->pNext = pPrevious->pNext; /* next(b) = c */ - pPrevious->pNext = pNew; /* next(a) = b */ - if (pNew->pNext != NULL) - (pNew->pNext)->pPrevious = pNew; /* prev(c) = b */ - } - else - pNew->pNext = NULL; - } - return(pNew); -} - -void ArrayWalkProc(DOUBLE_XMIT_TYPE * pArray) -{ - int i; - printf("Display contents of transmitted array:\n"); - - for (i = 0; i < pArray->sSize; i++) - printf("pArray->asNumber[%d] = %d\n", i, pArray->asNumber[i]); -} - -void ListWalkProc(DOUBLE_LINK_TYPE * pList) -{ - printf("Display contents of doubly linked list:\n"); - while (pList != NULL) { - printf("pList @0x%x = %d, Next = 0x%x\n", pList, pList->sNumber, pList->pNext); - pList = pList->pNext; - } -} - -void * MIDL_user_allocate(size_t len) -{ - return(malloc(len)); -} - -void MIDL_user_free(void * ptr) -{ - free(ptr); -} - -/* free the doubly linked list */ -void DOUBLE_LINK_TYPE_free_inst (DOUBLE_LINK_TYPE * pList) -{ - while (pList->pNext != NULL) /* go to end of list */ - pList = pList->pNext; - for (pList = pList->pPrevious; pList != NULL; pList = pList->pPrevious) - free(pList->pNext); -} - -/* free the array structure */ -void DOUBLE_LINK_TYPE_free_xmit (DOUBLE_XMIT_TYPE * pSizedArray) -{ - free(pSizedArray); -} - - -/* convert from linked list to array */ -void DOUBLE_LINK_TYPE_to_xmit (DOUBLE_LINK_TYPE * pList, - DOUBLE_XMIT_TYPE ** ppArray) -{ - short cCount = 0; - DOUBLE_LINK_TYPE * pHead = pList; /* save pointer to start */ - DOUBLE_XMIT_TYPE * pArray; - - /* count the number of elements to allocate memory */ - for (; pList != NULL; pList = pList->pNext) - cCount++; - - /* allocate the memory for the array */ - pArray = (DOUBLE_XMIT_TYPE *) malloc(sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short))); - pArray->sSize = cCount; - - /* copy the linked list contents into the array */ - cCount = 0; - for (pList = pHead; pList != NULL; pList = pList->pNext) - pArray->asNumber[cCount++] = pList->sNumber; - - /* return the address of the pointer to the array */ - *ppArray = pArray; -} - -/* convert from array to linked list */ -void DOUBLE_LINK_TYPE_from_xmit (DOUBLE_XMIT_TYPE * pArray, - DOUBLE_LINK_TYPE * pDblLinkedList) -{ - PDOUBLE_LINK_TYPE pCurrent, pNew; - - int i; - - pCurrent = pDblLinkedList; - pCurrent->sNumber = pArray->asNumber[0]; - - DOUBLE_LINK_TYPE_free_inst(pCurrent); - pCurrent->pNext = NULL; /* wipe out pointer to old list */ - - for (i = 1; i < pArray->sSize; i++) { - pNew = InsertNewNode(pArray->asNumber[i], pCurrent); - pCurrent = pNew; - } - return; -} - - -/* main: establish the binding to the server, call the remote procedure */ -void main(int argc, char **argv) -{ - RPC_STATUS status; // returned by RPC API function - unsigned char * pszUuid = "12345678-1234-1234-1234-123456789ABC"; + RPC_STATUS status; + unsigned char * pszUuid = NULL; unsigned char * pszProtocolSequence = "ncacn_np"; unsigned char * pszNetworkAddress = NULL; - unsigned char * pszEndpoint = "\\pipe\\xmit"; + unsigned char * pszEndpoint = "\\pipe\\xmit"; unsigned char * pszOptions = NULL; - unsigned char * pszStringBinding = NULL; + unsigned char * pszStringBinding = NULL; int i; int cElements = 10; short sValue = 100; short sDelta = 10; - DOUBLE_LINK_TYPE * pFirst; - DOUBLE_LINK_TYPE * pCurrent, * pNew; + DOUBLE_LINK_TYPE *pFirst, *pCurrent; - // allow the user to override settings with command line switches + /* allow the user to override settings with command line switches */ for (i = 1; i < argc; i++) { - if ((*argv[i] == '-') || (*argv[i] == '/')) { - switch (tolower(*(argv[i]+1))) { - case 'p': // protocol sequence - pszProtocolSequence = argv[++i]; - break; - case 'n': // network address - pszNetworkAddress = argv[++i]; - break; - case 'e': - pszEndpoint = argv[++i]; - break; - case 'o': - pszOptions = argv[++i]; - break; - case 'u': - pszUuid = argv[++i]; - break; - case 'c': - cElements = atoi(argv[++i]); - if (cElements > MAX_ELEMENTS) - cElements = MAX_ELEMENTS; - break; - case 'v': - sValue = (short)atoi(argv[++i]); - break; - case 'd': - sDelta = (short)atoi(argv[++i]); - break; - - case 'h': - case '?': - default: - Usage(argv[0]); - } - } - else - Usage(argv[0]); + if ((*argv[i] == '-') || (*argv[i] == '/')) { + switch (tolower(*(argv[i]+1))) { + case 'p': // protocol sequence + pszProtocolSequence = argv[++i]; + break; + case 'n': // network address + pszNetworkAddress = argv[++i]; + break; + case 'e': + pszEndpoint = argv[++i]; + break; + case 'o': + pszOptions = argv[++i]; + break; + case 'c': + cElements = atoi(argv[++i]); + if (cElements > MAX_ELEMENTS) + cElements = MAX_ELEMENTS; + break; + case 'v': + sValue = (short)atoi(argv[++i]); + break; + case 'd': + sDelta = (short)atoi(argv[++i]); + break; + case 'h': + case '?': + default: + Usage(argv[0]); + } + } + else + Usage(argv[0]); } -/* initialize a list with a number of elements */ + + /* initialize a list with a number of elements */ pFirst = InsertNewNode(sValue, NULL); - pCurrent = pFirst; /* assign some values to the list nodes */ - sValue += sDelta; /* make them different values */ + pCurrent = pFirst; // assign some values to the list nodes + sValue += sDelta; // make them different values for (i = 1; i < cElements; i++) { - pNew = InsertNewNode(sValue, pCurrent); - pCurrent = pNew; - sValue += sDelta; + pCurrent = InsertNewNode(sValue, pCurrent); + sValue += sDelta; } - printf("Client main: "); ListWalkProc(pFirst); -/* Use a convenience function to concatenate the elements of the string */ -/* binding into the syntax needed by RpcBindingFromStringBinding. */ - + /* Use a convenience function to concatenate the elements of the string */ + /* binding into the syntax needed by RpcBindingFromStringBinding. */ status = RpcStringBindingCompose(pszUuid, pszProtocolSequence, pszNetworkAddress, @@ -275,40 +146,43 @@ void main(int argc, char **argv) &pszStringBinding); printf("RpcStringBindingCompose returned 0x%x\n", status); printf("pszStringBinding = %s\n", pszStringBinding); - if (status) - exit(2); - -/* Set the binding handle that will be used to bind to the server. */ + if (status) { + exit(status); + } + /* Set the binding handle that will be used to bind to the server. */ status = RpcBindingFromStringBinding(pszStringBinding, - &hXmit); + &hXmit); printf("RpcBindingFromStringBinding returned 0x%x\n", status); - if (status) - exit(2); + if (status) { + exit(status); + } printf("Calling the remote procedure 'ModifyListProc'\n"); - - ModifyListProc(pFirst); // call the remote procedure + ModifyListProc(pFirst); // call the remote procedure printf("Calling the remote procedure 'Shutdown'\n"); - Shutdown(); // shut down the server side + Shutdown(); // shut down the server side printf("After ModifyListProc, the list appears as follows:\n"); ListWalkProc(pFirst); // call the utility that displays the list -/* The calls to the remote procedures are complete. */ -/* Free the string and the binding handle using RPC API calls. */ - - status = RpcStringFree(&pszStringBinding); // remote calls done; unbind + /* The calls to the remote procedures are complete. */ + /* Free the string and the binding handle using RPC API calls. */ + status = RpcStringFree(&pszStringBinding); printf("RpcStringFree returned 0x%x\n", status); - if (status) - exit(2); + if (status) { + exit(status); + } - status = RpcBindingFree(&hXmit); // remote calls done; unbind + status = RpcBindingFree(&hXmit); printf("RpcBindingFree returned 0x%x\n", status); - if (status) - exit(2); + if (status) { + exit(status); + } - exit(0); /* successful completion */ -} -/* end \xmitc.c */ + exit(0); + +} // end main() + +/* end file xmitc.c */