Annotation of mstools/samples/rpc/data/xmit/xmitc.c, revision 1.1

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:                         -u uuid
        !            12:                         -c count of elements in linked list
        !            13:                         -v value of first element in linked list
        !            14:                         -d delta between values in linked list
        !            15: 
        !            16:     PURPOSE:   Client side of RPC distributed application.
        !            17:                This sample demonstrates the transmit_as example.
        !            18:                A doubly-linked list is transmitted over the network
        !            19:                as a sized array.
        !            20: 
        !            21:     RELATED:   xmits.c - server main
        !            22:                xmitp.c - remote procedures
        !            23: 
        !            24:     FUNCTIONS: main() - bind to server and call remote procedure
        !            25:                PDOUBLE_LINK_TYPE_to_xmit - convert list to array
        !            26:                PDOUBLE_LINK_TYPE_from_xmit - convert array to list
        !            27:                PDOUBLE_LINK_TYPE_free_inst - free linked list memory
        !            28:                PDOUBLE_LINK_TYPE_free_xmit - free array memory
        !            29:                MIDL_user_allocate - user-supplied memory allocator
        !            30:                MIDL_user_free - user-supplied routine to free memory
        !            31: 
        !            32:                ArrayWalkProc - utility to display the array
        !            33:                ListWalkProc - utility to display the linked list
        !            34:                InsertNewNode - utility to add a node to the list
        !            35: 
        !            36:     COMMENTS:  This sample program generates a linked list to
        !            37:                demonstrate how the list can be transmitted over
        !            38:                the network more efficiently as a sized array.
        !            39:                The pointers are rebuilt on the server side.
        !            40: 
        !            41:                The [transmit_as] attribute (used in the typedef of
        !            42:                PDOUBLE_LINK_TYPE in the file XMIT.IDL) requires the
        !            43:                four user-supplied functions whose names start with
        !            44:                the name of the presented type, PDOUBLE_LINK_TYPE.
        !            45: 
        !            46:                The [in, out] attributes applied to remote procedure
        !            47:                parameters require the two user-supplied functions
        !            48:                MIDL_user_allocate and MIDL_user_free.
        !            49: 
        !            50:                The other functions are utilities that are used to
        !            51:                build or display the data structures.
        !            52: 
        !            53: 
        !            54: ****************************************************************************/
        !            55: #include <stdio.h>
        !            56: #include <string.h>
        !            57: #include <stdlib.h>
        !            58: #include <rpc.h>       // RPC API functions, types
        !            59: #include "xmit.h"     // header file generated by MIDL compiler
        !            60: 
        !            61: #define PURPOSE \
        !            62: "This Microsoft RPC Version 1.0 sample program demonstrates\n\
        !            63: the use of the [transmit_as] attribute. For more information\n\
        !            64: about the attributes and the RPC API functions, see the\n\
        !            65: RPC programming guide and reference.\n\n"
        !            66: 
        !            67: #define MAX_ELEMENTS 50
        !            68: 
        !            69: void Usage(char * pszProgramName)
        !            70: {
        !            71:     fprintf(stderr, "%s", PURPOSE);
        !            72:     fprintf(stderr, "Usage:  %s\n", pszProgramName);
        !            73:     fprintf(stderr, " -p protocol_sequence\n");
        !            74:     fprintf(stderr, " -n network_address\n");
        !            75:     fprintf(stderr, " -e endpoint\n");
        !            76:     fprintf(stderr, " -o options\n");
        !            77:     fprintf(stderr, " -u uuid\n");
        !            78:     fprintf(stderr, " -c count_of_elements\n");
        !            79:     fprintf(stderr, " -v value\n");
        !            80:     fprintf(stderr, " -d delta\n");
        !            81: 
        !            82:     exit(1);
        !            83: }
        !            84: 
        !            85: DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious)
        !            86: {
        !            87: DOUBLE_LINK_TYPE * pNew;
        !            88: 
        !            89:     pNew = (DOUBLE_LINK_TYPE *) malloc(sizeof(DOUBLE_LINK_TYPE));
        !            90:     if (pNew != NULL) {
        !            91:        pNew->sNumber = sValue;     /* insert b between a and c */
        !            92:        pNew->pPrevious = pPrevious;             /* prev(b) = a */
        !            93:        if (pPrevious != NULL) {
        !            94:            pNew->pNext = pPrevious->pNext;      /* next(b) = c */
        !            95:            pPrevious->pNext = pNew;             /* next(a) = b */
        !            96:            if (pNew->pNext != NULL)
        !            97:                (pNew->pNext)->pPrevious = pNew; /* prev(c) = b */
        !            98:        }
        !            99:        else
        !           100:            pNew->pNext = NULL;
        !           101:     }
        !           102:     return(pNew);
        !           103: }
        !           104: 
        !           105: void ArrayWalkProc(DOUBLE_XMIT_TYPE * pArray)
        !           106: {
        !           107:     int i;
        !           108:     printf("Display contents of transmitted array:\n");
        !           109: 
        !           110:     for (i = 0; i < pArray->sSize; i++)
        !           111:        printf("pArray->asNumber[%d] = %d\n", i, pArray->asNumber[i]);
        !           112: }
        !           113: 
        !           114: void ListWalkProc(DOUBLE_LINK_TYPE * pList)
        !           115: {
        !           116:     printf("Display contents of doubly linked list:\n");
        !           117:     while (pList != NULL) {
        !           118:        printf("pList @0x%x = %d, Next = 0x%x\n", pList, pList->sNumber, pList->pNext);
        !           119:        pList = pList->pNext;
        !           120:     }
        !           121: }
        !           122: 
        !           123: void * MIDL_user_allocate(size_t len)
        !           124: {
        !           125:     return(malloc(len));
        !           126: }
        !           127: 
        !           128: void MIDL_user_free(void * ptr)
        !           129: {
        !           130:     free(ptr);
        !           131: }
        !           132: 
        !           133: /* free the doubly linked list */
        !           134: void DOUBLE_LINK_TYPE_free_inst (DOUBLE_LINK_TYPE * pList)
        !           135: {
        !           136:     while (pList->pNext != NULL)  /* go to end of list */
        !           137:        pList = pList->pNext;
        !           138:     for (pList = pList->pPrevious; pList != NULL; pList = pList->pPrevious)
        !           139:        free(pList->pNext);
        !           140: }
        !           141: 
        !           142: /* free the array structure */
        !           143: void DOUBLE_LINK_TYPE_free_xmit (DOUBLE_XMIT_TYPE * pSizedArray)
        !           144: {
        !           145:     free(pSizedArray);
        !           146: }
        !           147: 
        !           148: 
        !           149: /* convert from linked list to array */
        !           150: void DOUBLE_LINK_TYPE_to_xmit   (DOUBLE_LINK_TYPE  *  pList,
        !           151:                                  DOUBLE_XMIT_TYPE **  ppArray)
        !           152: {
        !           153:     short cCount = 0;
        !           154:     DOUBLE_LINK_TYPE * pHead = pList;  /* save pointer to start */
        !           155:     DOUBLE_XMIT_TYPE * pArray;
        !           156: 
        !           157:     /* count the number of elements to allocate memory */
        !           158:     for (; pList != NULL; pList = pList->pNext)
        !           159:        cCount++;
        !           160: 
        !           161:     /* allocate the memory for the array */
        !           162:     pArray = (DOUBLE_XMIT_TYPE *) malloc(sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short)));
        !           163:     pArray->sSize = cCount;
        !           164: 
        !           165:     /* copy the linked list contents into the array */
        !           166:     cCount = 0;
        !           167:     for (pList = pHead; pList != NULL; pList = pList->pNext)
        !           168:        pArray->asNumber[cCount++] = pList->sNumber;
        !           169: 
        !           170:     /* return the address of the pointer to the array */
        !           171:     *ppArray = pArray;
        !           172: }
        !           173: 
        !           174: /* convert from array to linked list */
        !           175: void DOUBLE_LINK_TYPE_from_xmit (DOUBLE_XMIT_TYPE * pArray,
        !           176:                                 DOUBLE_LINK_TYPE * pDblLinkedList)
        !           177: {
        !           178:     PDOUBLE_LINK_TYPE pCurrent, pNew;
        !           179: 
        !           180:     int i;
        !           181: 
        !           182:     pCurrent = pDblLinkedList;
        !           183:     pCurrent->sNumber = pArray->asNumber[0];
        !           184: 
        !           185:     DOUBLE_LINK_TYPE_free_inst(pCurrent);
        !           186:     pCurrent->pNext = NULL;     /* wipe out pointer to old list */
        !           187: 
        !           188:     for (i = 1; i < pArray->sSize; i++) {
        !           189:        pNew = InsertNewNode(pArray->asNumber[i], pCurrent);
        !           190:        pCurrent = pNew;
        !           191:     }
        !           192:     return;
        !           193: }
        !           194: 
        !           195: 
        !           196: /* main:  establish the binding to the server, call the remote procedure */
        !           197: void main(int argc, char **argv)
        !           198: {
        !           199:     RPC_STATUS status;             // returned by RPC API function
        !           200:     unsigned char * pszUuid = "12345678-1234-1234-1234-123456789ABC";
        !           201:     unsigned char * pszProtocolSequence = "ncacn_np";
        !           202:     unsigned char * pszNetworkAddress   = NULL;
        !           203:     unsigned char * pszEndpoint        = "\\pipe\\xmit";
        !           204:     unsigned char * pszOptions          = NULL;
        !           205:     unsigned char * pszStringBinding   = NULL;
        !           206:     int i;
        !           207:     int cElements = 10;
        !           208:     short sValue = 100;
        !           209:     short sDelta = 10;
        !           210: 
        !           211:     DOUBLE_LINK_TYPE * pFirst;
        !           212:     DOUBLE_LINK_TYPE * pCurrent, * pNew;
        !           213: 
        !           214:     // allow the user to override settings with command line switches
        !           215:     for (i = 1; i < argc; i++) {
        !           216:        if ((*argv[i] == '-') || (*argv[i] == '/')) {
        !           217:            switch (tolower(*(argv[i]+1))) {
        !           218:                case 'p':  // protocol sequence
        !           219:                    pszProtocolSequence = argv[++i];
        !           220:                    break;
        !           221:                case 'n':  // network address
        !           222:                    pszNetworkAddress = argv[++i];
        !           223:                    break;
        !           224:                case 'e':
        !           225:                    pszEndpoint = argv[++i];
        !           226:                    break;
        !           227:                case 'o':
        !           228:                    pszOptions = argv[++i];
        !           229:                    break;
        !           230:                case 'u':
        !           231:                    pszUuid = argv[++i];
        !           232:                    break;
        !           233:                case 'c':
        !           234:                    cElements = atoi(argv[++i]);
        !           235:                    if (cElements > MAX_ELEMENTS)
        !           236:                        cElements = MAX_ELEMENTS;
        !           237:                    break;
        !           238:                case 'v':
        !           239:                    sValue = (short)atoi(argv[++i]);
        !           240:                    break;
        !           241:                case 'd':
        !           242:                    sDelta = (short)atoi(argv[++i]);
        !           243:                    break;
        !           244: 
        !           245:                case 'h':
        !           246:                case '?':
        !           247:                default:
        !           248:                    Usage(argv[0]);
        !           249:            }
        !           250:        }
        !           251:        else
        !           252:            Usage(argv[0]);
        !           253:     }
        !           254: /* initialize a list with a number of elements */
        !           255:     pFirst = InsertNewNode(sValue, NULL);
        !           256:     pCurrent = pFirst; /* assign some values to the list nodes */
        !           257:     sValue += sDelta;  /* make them different values */
        !           258: 
        !           259:     for (i = 1; i < cElements; i++) {
        !           260:        pNew = InsertNewNode(sValue, pCurrent);
        !           261:        pCurrent = pNew;
        !           262:        sValue += sDelta;
        !           263:     }
        !           264:     printf("Client main: ");
        !           265:     ListWalkProc(pFirst);
        !           266: 
        !           267: /* Use a convenience function to concatenate the elements of the string */
        !           268: /* binding into the syntax needed by RpcBindingFromStringBinding.      */
        !           269: 
        !           270:     status = RpcStringBindingCompose(pszUuid,
        !           271:                                      pszProtocolSequence,
        !           272:                                      pszNetworkAddress,
        !           273:                                      pszEndpoint,
        !           274:                                      pszOptions,
        !           275:                                      &pszStringBinding);
        !           276:     printf("RpcStringBindingCompose returned 0x%x\n", status);
        !           277:     printf("pszStringBinding = %s\n", pszStringBinding);
        !           278:     if (status)
        !           279:        exit(2);
        !           280: 
        !           281: /* Set the binding handle that will be used to bind to the server. */
        !           282: 
        !           283:     status = RpcBindingFromStringBinding(pszStringBinding,
        !           284:                                         &hXmit);
        !           285:     printf("RpcBindingFromStringBinding returned 0x%x\n", status);
        !           286:     if (status)
        !           287:         exit(2);
        !           288: 
        !           289:     printf("Calling the remote procedure 'ModifyListProc'\n");
        !           290: 
        !           291:     ModifyListProc(pFirst);     // call the remote procedure
        !           292: 
        !           293:     printf("Calling the remote procedure 'Shutdown'\n");
        !           294:     Shutdown();                 // shut down the server side
        !           295: 
        !           296:     printf("After ModifyListProc, the list appears as follows:\n");
        !           297:     ListWalkProc(pFirst);  // call the utility that displays the list
        !           298: 
        !           299: /*  The calls to the remote procedures are complete. */
        !           300: /*  Free the string and the binding handle using RPC API calls. */
        !           301: 
        !           302:     status = RpcStringFree(&pszStringBinding); // remote calls done; unbind
        !           303:     printf("RpcStringFree returned 0x%x\n", status);
        !           304:     if (status)
        !           305:        exit(2);
        !           306: 
        !           307:     status = RpcBindingFree(&hXmit);   // remote calls done; unbind
        !           308:     printf("RpcBindingFree returned 0x%x\n", status);
        !           309:     if (status)
        !           310:        exit(2);
        !           311: 
        !           312:     exit(0); /* successful completion */
        !           313: }
        !           314: /* end \xmitc.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.