--- mstools/samples/rpc/data/xmit/xmitu.c 2018/08/09 18:22:10 1.1 +++ mstools/samples/rpc/data/xmit/xmitu.c 2018/08/09 18:24:25 1.1.1.2 @@ -1,161 +1,183 @@ /**************************************************************************** - Microsoft RPC Version 1.0 - Copyright Microsoft Corp. 1992 - xmit Example - - FILE: xmitu.c - - PURPOSE: Utility functions used by both client and server - sides of the 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 - xmitc.c - client main - - FUNCTIONS: DOUBLE_LINK_TYPE_to_xmit - convert list to array - DOUBLE_LINK_TYPE_from_xmit - convert array to list - DOUBLE_LINK_TYPE_free_inst - free linked list memory - DOUBLE_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 a list with aliasing can be transmitted - using the transmit_as attribute as a sized array. - The pointers are rebuilt on the server side. + Microsoft RPC Version 1.0 + Copyright Microsoft Corp. 1992 + xmit Example + + FILE: xmitu.c + + PURPOSE: Utility functions used by both client and server + sides of the 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 + xmitc.c - client main + + FUNCTIONS: DOUBLE_LINK_TYPE_to_xmit - convert list to array + DOUBLE_LINK_TYPE_from_xmit - convert array to list + DOUBLE_LINK_TYPE_free_inst - free linked list memory + DOUBLE_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 a list with aliasing can be transmitted + using the transmit_as attribute as a sized array. + The pointers are rebuilt on the server side. ****************************************************************************/ -#include -#include + #include -#include // RPC API functions, types -#include "xmit.h" // header file generated by MIDL compiler +#include +#include "xmit.h" // header file generated by MIDL compiler +#include "xmitu.h" + + +/***************************************************************************/ 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]); + 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; + printf("pList @0x%lx = %d, Next = 0x%lx\n", + pList, pList->sNumber, pList->pNext); + pList = pList->pNext; } } DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious) { -DOUBLE_LINK_TYPE * pNew; + DOUBLE_LINK_TYPE * pNew; - do - pNew = (DOUBLE_LINK_TYPE *) MIDL_user_allocate(sizeof(DOUBLE_LINK_TYPE)); - while (pNew == pPrevious); - - pNew->pNext = NULL; /* initialize */ - pNew->pPrevious = NULL; /* initialize */ - 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 */ + do { + pNew = (DOUBLE_LINK_TYPE *)midl_user_allocate(sizeof(DOUBLE_LINK_TYPE)); + } while (pNew == pPrevious); + + pNew->pNext = NULL; // initialize + pNew->pPrevious = NULL; // initialize + pNew->sNumber = sValue; // insert b between a and c + + pNew->pPrevious = pPrevious; // prev(b) = a + if (pPrevious == NULL) + pNew->pNext = NULL; + else { + 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 * MIDL_user_allocate(size_t len) -{ - void * ptr; - ptr = malloc(len); - if (ptr == NULL) - exit(2); /* exit program */ - return(ptr); -} -void MIDL_user_free(void * ptr) -{ - if (ptr != NULL) - free(ptr); -} +/***************************************************************************/ -/* free the doubly linked list */ -/* move forward through list, freeing the previous entry */ -void DOUBLE_LINK_TYPE_free_inst (DOUBLE_LINK_TYPE * pList) +void __RPC_FAR * __RPC_API midl_user_allocate(size_t len) { - if (pList == NULL) - return; - - for (; pList->pNext != NULL; pList = pList->pNext) - MIDL_user_free(pList->pPrevious); - MIDL_user_free(pList); /* free the last entry */ + return(malloc(len)); } -/* free the array structure */ -void DOUBLE_LINK_TYPE_free_xmit (DOUBLE_XMIT_TYPE * pSizedArray) +void __RPC_API midl_user_free(void __RPC_FAR * ptr) { - MIDL_user_free(pSizedArray); + free(ptr); } + +/***************************************************************************/ + /* convert from linked list to array */ -void DOUBLE_LINK_TYPE_to_xmit (DOUBLE_LINK_TYPE * pList, - DOUBLE_XMIT_TYPE ** ppArray) +void __RPC_API +DOUBLE_LINK_TYPE_to_xmit( + DOUBLE_LINK_TYPE __RPC_FAR * pList, + DOUBLE_XMIT_TYPE __RPC_FAR * __RPC_FAR * ppArray) { - short cCount, i; - DOUBLE_LINK_TYPE * pHead = pList; /* save pointer to start */ + 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 (cCount = 0; pList != NULL; pList = pList->pNext) - cCount++; + for (; pList != NULL; pList = pList->pNext) + cCount++; /* allocate the memory for the array */ - pArray = (DOUBLE_XMIT_TYPE *) MIDL_user_allocate(sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short))); + pArray = (DOUBLE_XMIT_TYPE *) midl_user_allocate + (sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short))); pArray->sSize = cCount; /* copy the linked list contents into the array */ - for (i = 0, pList = pHead; pList != NULL; pList = pList->pNext) - pArray->asNumber[i++] = pList->sNumber; + for (cCount = 0, 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 */ -/* in C, the value for pDblLinkedList cannot change during the call */ - -void DOUBLE_LINK_TYPE_from_xmit (DOUBLE_XMIT_TYPE * pArray, - DOUBLE_LINK_TYPE * pDblLinkedList) +void __RPC_API +DOUBLE_LINK_TYPE_from_xmit( + DOUBLE_XMIT_TYPE __RPC_FAR * pArray, + DOUBLE_LINK_TYPE __RPC_FAR * pList) { - DOUBLE_LINK_TYPE * pCurrent; + DOUBLE_LINK_TYPE *pCurrent; int i; - pCurrent = pDblLinkedList; /* overwrite first element, delete others */ - pCurrent->sNumber = pArray->asNumber[0]; /* overwrite first element */ - DOUBLE_LINK_TYPE_free_inst(pCurrent->pNext); /* delete other elements */ - pCurrent->pNext = NULL; /* initialize */ - pCurrent->pPrevious = NULL; + if (pArray->sSize <= 0) { // error checking + pList = NULL; + return; + } + + if (pList == NULL) + pList = InsertNewNode(pArray->asNumber[0], NULL); + else { + DOUBLE_LINK_TYPE_free_inst(pList); // free all other nodes + pList->sNumber = pArray->asNumber[0]; + pList->pNext = NULL; + } + + pCurrent = pList; + for (i = 1; i < pArray->sSize; i++) // write new values + pCurrent = InsertNewNode(pArray->asNumber[i], pCurrent); +} + - for (i = 1; i < pArray->sSize; i++) { /* write new values */ - pCurrent = InsertNewNode(pArray->asNumber[i], pCurrent); +/* free the doubly linked list */ +/* move forward through list, freeing the previous entry */ +void __RPC_API +DOUBLE_LINK_TYPE_free_inst( + DOUBLE_LINK_TYPE __RPC_FAR * pList) +{ + while (pList->pNext != NULL) // go to end of list + pList = pList->pNext; + + pList = pList->pPrevious; + while (pList != NULL) { // back through list + midl_user_free(pList->pNext); + pList = pList->pPrevious; } - return; } -/* end xmitu.c */ +/* free the array structure */ +void __RPC_API +DOUBLE_LINK_TYPE_free_xmit( + DOUBLE_XMIT_TYPE __RPC_FAR * pArray) +{ + midl_user_free(pArray); +} + +/* end file xmitu.c */