Annotation of mstools/samples/rpc/data/xmit/xmitc.c, revision 1.1.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.