home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / rpcsvc / client.c next >
C/C++ Source or Header  |  1997-10-05  |  15KB  |  598 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1995-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   client.c
  9. //
  10. //  PURPOSE:  This program is a command line oriented
  11. //            demonstration of the Simple RPC service sample.
  12. //
  13. //  FUNCTIONS:
  14. //    main(int argc, char **argv);
  15. //    StartTime()
  16. //    EndTime();
  17. //    DoTimings();
  18. //
  19. //  COMMENTS:
  20. //
  21. //  AUTHOR:
  22. //      Mario Goertzel - RPC Development
  23. //
  24. #include <windows.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <rpc.h>
  28. #include "rpcsvc.h"
  29.  
  30. void Usage(void)
  31. {
  32.     printf("Usage:\n"
  33.         "\t-n <server addr>  - Defaults to local machine\n"
  34.         "\t-t <protseq>      - Defaults to ncalrpc (fast, local only)\n"
  35.         "\t-i <iterations>   - Defaults to 100\n"
  36.         "\t-s <security lvl> - Default none, range none (1) to privacy (6)\n"
  37.         );
  38.     return;
  39. }
  40.  
  41.  
  42. //
  43. //  FUNCTIONS: StartTime()
  44. //             EndTime()
  45. //
  46. //  USAGE:
  47. //      StartTime();
  48. //        // Do some work.
  49. //      mseconds = EndTime();
  50. //
  51. //  RETURN VALUE:
  52. //      Milliseconds between StartTime() and EndTime() calls.
  53.  
  54. LARGE_INTEGER Time;
  55.  
  56. void StartTime(void)
  57. {
  58.     QueryPerformanceCounter(&Time);
  59. }
  60.  
  61. ULONG EndTime()
  62. {
  63.     LARGE_INTEGER liDiff;
  64.     LARGE_INTEGER liFreq;
  65.  
  66.     QueryPerformanceCounter(&liDiff);
  67.  
  68.     liDiff.QuadPart -= Time.QuadPart;
  69.     liDiff.QuadPart *= 1000; // Adjust to milliseconds, shouldn't overflow...
  70.  
  71.     (void)QueryPerformanceFrequency(&liFreq);
  72.  
  73.     return ((ULONG)(liDiff.QuadPart / liFreq.QuadPart));
  74. }
  75.  
  76. //
  77. //  FUNCTION: DoTimings
  78. //
  79. //  PURPOSE: Calls and times various RPC calls.
  80. //           (Avoid cluttering up main())
  81. //
  82. //  PARAMETERS:
  83. //    Binding     - Binding to the server.
  84. //    iIterations - Number of times to make each call.
  85. //
  86. //  RETURN VALUE:
  87. //    n/a
  88. //
  89. //
  90. void DoTimings(RPC_BINDING_HANDLE Binding,
  91.                UINT iIterations)
  92. {
  93.     ULONG mseconds;
  94.     UINT i;
  95.     RPC_STATUS status;
  96.     byte bBuffer[4096];
  97.     ULONG lBufferLength;
  98.     ULONG lBufferSize;
  99.  
  100.     // Time Pings() (void calls)
  101.  
  102.     StartTime();
  103.     for(i = iIterations; i; i--)
  104.         {
  105.         status = Ping(Binding);
  106.         if (status != RPC_S_OK)
  107.             goto Cleanup;
  108.         }
  109.     mseconds = EndTime();
  110.  
  111.     printf("%4d calls in %8d milliseconds - void calls.\n", iIterations, mseconds);
  112.  
  113.     // Time [in] buffer's
  114.     //
  115.  
  116.     lBufferLength = BUFFER_SIZE;
  117.     lBufferSize   = BUFFER_SIZE;
  118.     StartTime();
  119.     for(i = iIterations; i; i--)
  120.         {
  121.         status = BufferIn1(Binding, bBuffer, lBufferLength, lBufferSize);
  122.         if (status != RPC_S_OK)
  123.             {
  124.             goto Cleanup;
  125.             }
  126.         }
  127.     mseconds = EndTime();
  128.  
  129.     printf("%4d calls in %8d milliseconds - 100 byte buffer in (1).\n", iIterations, mseconds);
  130.  
  131.     lBufferLength = BUFFER_SIZE;
  132.  
  133.     StartTime();
  134.     for(i = iIterations; i; i--)
  135.         {
  136.         status = BufferIn3(Binding, bBuffer, lBufferLength);
  137.         if (status != RPC_S_OK)
  138.             {
  139.             goto Cleanup;
  140.             }
  141.         }
  142.     mseconds = EndTime();
  143.  
  144.     printf("%4d calls in %8d milliseconds - 100 byte buffer in (2).\n", iIterations, mseconds);
  145.  
  146.     lBufferLength = BUFFER_SIZE;
  147.  
  148.     StartTime();
  149.     for(i = iIterations; i; i--)
  150.         {
  151.         status = BufferIn3(Binding, bBuffer, lBufferLength);
  152.         if (status != RPC_S_OK)
  153.             {
  154.             goto Cleanup;
  155.             }
  156.         }
  157.     mseconds = EndTime();
  158.  
  159.     printf("%4d calls in %8d milliseconds - 100 byte buffer in (3).\n", iIterations, mseconds);
  160.  
  161.     // Time [out] buffer's
  162.  
  163.     lBufferLength = BUFFER_SIZE;
  164.  
  165.     StartTime();
  166.     for(i = iIterations; i; i--)
  167.         {
  168.         status = BufferOut1(Binding, bBuffer, &lBufferLength);
  169.         if (status != RPC_S_OK)
  170.             {
  171.             goto Cleanup;
  172.             }
  173.         }
  174.     mseconds = EndTime();
  175.  
  176.     printf("%4d calls in %8d milliseconds - 100 byte buffer out (1).\n", iIterations, mseconds);
  177.  
  178.     lBufferLength = BUFFER_SIZE;
  179.     lBufferSize   = BUFFER_SIZE;
  180.  
  181.     StartTime();
  182.     for(i = iIterations; i; i--)
  183.         {
  184.         status = BufferOut2(Binding, bBuffer, lBufferSize, &lBufferLength);
  185.         if (status != RPC_S_OK)
  186.             {
  187.             goto Cleanup;
  188.             }
  189.         }
  190.     mseconds = EndTime();
  191.  
  192.     printf("%4d calls in %8d milliseconds - 100 byte buffer out (2).\n", iIterations, mseconds);
  193.  
  194.     StartTime();
  195.     for(i = iIterations; i; i--)
  196.         {
  197.         BUFFER Buffer;
  198.         Buffer.BufferLength = 0;
  199.         Buffer.Buffer = 0;
  200.  
  201.         status = BufferOut3(Binding, &Buffer);
  202.         if (status != RPC_S_OK)
  203.             {
  204.             goto Cleanup;
  205.             }
  206.         MIDL_user_free(Buffer.Buffer);
  207.         }
  208.     mseconds = EndTime();
  209.  
  210.     printf("%4d calls in %8d milliseconds - 100 byte buffer out (3).\n", iIterations, mseconds);
  211.  
  212.     lBufferLength = BUFFER_SIZE;
  213.  
  214.     StartTime();
  215.     for(i = iIterations; i; i--)
  216.         {
  217.         status = BufferOut4(Binding, bBuffer, &lBufferLength);
  218.         if (status != RPC_S_OK)
  219.             {
  220.             goto Cleanup;
  221.             }
  222.         }
  223.     mseconds = EndTime();
  224.  
  225.     printf("%4d calls in %8d milliseconds - 100 byte buffer out (4).\n", iIterations, mseconds);
  226.  
  227.     // Time arrays of structures
  228.  
  229.     {
  230.     struct BAD1 abad1[50];
  231.     struct BAD2 abad2[50];
  232.     struct GOOD agood[50];
  233.  
  234.     for (i = 0; i < 50; i++)
  235.         {
  236.         abad2[i].e = (BAD_ENUM)i % 4 + 1;
  237.         agood[i].e = (GOOD_ENUM)i % 4 + 5;
  238.         }
  239.  
  240.     StartTime();
  241.     for(i = iIterations; i; i--)
  242.         {
  243.         status = StructsIn1(Binding, &abad1[0]);
  244.         if (status != RPC_S_OK)
  245.             {
  246.             goto Cleanup;
  247.             }
  248.         }
  249.     mseconds = EndTime();
  250.  
  251.     printf("%4d calls in %8d milliseconds - 2 mod 4 aligned structs.\n", iIterations, mseconds);
  252.  
  253.     StartTime();
  254.     for(i = iIterations; i; i--)
  255.         {
  256.         status = StructsIn2(Binding, &abad2[0]);
  257.         if (status != RPC_S_OK)
  258.             {
  259.             goto Cleanup;
  260.             }
  261.         }
  262.     mseconds = EndTime();
  263.  
  264.     printf("%4d calls in %8d milliseconds - structs with an enum.\n", iIterations, mseconds);
  265.  
  266.     StartTime();
  267.     for(i = iIterations; i; i--)
  268.         {
  269.         status = StructsIn3(Binding, &agood[0]);
  270.         if (status != RPC_S_OK)
  271.             {
  272.             goto Cleanup;
  273.             }
  274.         }
  275.     mseconds = EndTime();
  276.  
  277.     printf("%4d calls in %8d milliseconds - structs with v1_enum.\n", iIterations, mseconds);
  278.     }
  279.  
  280.     // Linked lists
  281.  
  282.     {
  283.     LIST list;
  284.     PLIST plist = &list;
  285.     for (i = 0; i < LIST_SIZE - 1; i++)
  286.         {
  287.         plist->pNext = MIDL_user_allocate(sizeof(LIST));
  288.         plist->data = i;
  289.         if (plist->pNext == 0)
  290.             {
  291.             status = RPC_S_OUT_OF_MEMORY;
  292.             goto Cleanup;
  293.             }
  294.         plist = plist->pNext;
  295.         }
  296.     plist->data = i;
  297.     plist->pNext = 0;
  298.     
  299.  
  300.     StartTime();
  301.     for(i = iIterations; i; i--)
  302.         {
  303.         status = ListIn(Binding, &list);
  304.         if (status != RPC_S_OK)
  305.             {
  306.             goto Cleanup;
  307.             }
  308.         }
  309.     mseconds = EndTime();
  310.  
  311.     printf("%4d calls in %8d milliseconds - [in] linked list.\n", iIterations, mseconds);
  312.  
  313.     StartTime();
  314.     for(i = iIterations; i; i--)
  315.         {
  316.         status = ListOut1(Binding, &list);
  317.         if (status != RPC_S_OK)
  318.             {
  319.             goto Cleanup;
  320.             }
  321.         // Freeing the list here would cause all the elements
  322.         // to be allocated again on the next call.
  323.         }
  324.     mseconds = EndTime();
  325.  
  326.     printf("%4d calls in %8d milliseconds - [out] linked list (1).\n", iIterations, mseconds);
  327.  
  328.     StartTime();
  329.     for(i = iIterations; i; i--)
  330.         {
  331.         status = ListOut2(Binding, &list);
  332.         if (status != RPC_S_OK)
  333.             {
  334.             goto Cleanup;
  335.             }
  336.         // Freeing the list here would cause all the elements
  337.         // to be allocated again on the next call.
  338.         }
  339.     mseconds = EndTime();
  340.  
  341.     printf("%4d calls in %8d milliseconds - [out] linked list (2).\n", iIterations, mseconds);
  342.  
  343.     // Free allocated elements of the list.
  344.     plist = list.pNext;
  345.     while(plist)
  346.         {
  347.         PLIST tmp = plist;
  348.         plist = plist->pNext;
  349.         MIDL_user_free(tmp);
  350.         }
  351.     }
  352.  
  353.     // Unions
  354.  
  355.     {
  356.     BAD_UNION badunionArray[UNION_ARRAY_LEN];
  357.     GOOD_UNION goodunion;
  358.     ARM_ONE armone;
  359.     ULONG ulArray[UNION_ARRAY_LEN];
  360.  
  361.     goodunion.Tag = 1;
  362.     goodunion.u.pOne = &armone;
  363.     armone.DataLength = UNION_ARRAY_LEN;
  364.     armone.Data = ulArray;
  365.  
  366.     for(i = 0; i < UNION_ARRAY_LEN; i++)
  367.         {
  368.         ulArray[i] = i;
  369.         badunionArray[i].Tag = 1;
  370.         badunionArray[i].u.ulData = i;
  371.         }
  372.  
  373.     StartTime();
  374.     for(i = iIterations; i; i--)
  375.         {
  376.         status = UnionCall1(Binding, UNION_ARRAY_LEN, badunionArray);
  377.         if (status != RPC_S_OK)
  378.             {
  379.             goto Cleanup;
  380.             }
  381.         }
  382.     mseconds = EndTime();
  383.  
  384.     printf("%4d calls in %8d milliseconds - [in] array of unions.\n", iIterations, mseconds);
  385.  
  386.     StartTime();
  387.     for(i = iIterations; i; i--)
  388.         {
  389.         status = UnionCall2(Binding, &goodunion);
  390.         if (status != RPC_S_OK)
  391.             {
  392.             goto Cleanup;
  393.             }
  394.         }
  395.     mseconds = EndTime();
  396.  
  397.     printf("%4d calls in %8d milliseconds - [in] union of arrays.\n", iIterations, mseconds);
  398.  
  399.     }
  400.  
  401.     // Time pings() (null calls) which impersonate the client.
  402.  
  403.     StartTime();
  404.     for(i = iIterations; i; i--)
  405.         {
  406.  
  407.         status = CheckSecurity(Binding);
  408.  
  409.         if (status != RPC_S_OK)
  410.             {
  411.             if (status == RPC_S_ACCESS_DENIED)
  412.                 {
  413.                 printf("Access denied, try -s 2 or higher.\n");
  414.                 return;
  415.                 }
  416.             goto Cleanup;
  417.             }
  418.  
  419.         }
  420.     mseconds = EndTime();
  421.  
  422.     printf("%4d calls in %8d milliseconds - void call w/ impersonation\n", iIterations, mseconds);
  423.  
  424. Cleanup:
  425.  
  426.     if (status != RPC_S_OK)
  427.         {
  428.         printf("Call failed - %d\n", status);
  429.         }
  430.  
  431.     return;
  432. }
  433.  
  434. //
  435. //  FUNCTION: main
  436. //
  437. //  PURPOSE: Parses arguments and binds to the server.
  438. //
  439. //  PARAMETERS:
  440. //    argc - number of command line arguments
  441. //    argv - array of command line arguments
  442. //
  443. //  RETURN VALUE:
  444. //    Program exit code.
  445. //
  446. //
  447. int main(int argc, char *argv[])
  448. {
  449.     char *serverAddress = NULL;
  450.     char *protocol = "ncalrpc";
  451.     UINT iIterations = 100;
  452.     unsigned char *stringBinding;
  453.     RPC_BINDING_HANDLE Binding;
  454.     RPC_STATUS status;
  455.     ULONG SecurityLevel = RPC_C_AUTHN_LEVEL_NONE;
  456.  
  457.     argc--;
  458.     argv++;
  459.     while(argc)
  460.         {
  461.         if (   argv[0][0] != '-'
  462.             && argv[0][0] != '/')
  463.             {
  464.             Usage();
  465.             return(1);
  466.             }
  467.  
  468.         switch(argv[0][1])
  469.             {
  470.             case 'n':
  471.                 if (argc < 2)
  472.                     {
  473.                     Usage();
  474.                     return(1);
  475.                     }
  476.                 serverAddress = argv[1];
  477.                 argc--;
  478.                 argv++;
  479.                 break;
  480.             case 't':
  481.                 if (argc < 2)
  482.                     {
  483.                     Usage();
  484.                     return(1);
  485.                     }
  486.                 protocol = argv[1];
  487.                 argc--;
  488.                 argv++;
  489.                 break;
  490.             case 'i':
  491.                 if (argc < 2)
  492.                     {
  493.                     Usage();
  494.                     return(1);
  495.                     }
  496.                 iIterations = atoi(argv[1]);
  497.                 argc--;
  498.                 argv++;
  499.                 break;
  500.             case 's':
  501.                 if (argc < 2)
  502.                     {
  503.                     Usage();
  504.                     return(1);
  505.                     }
  506.                 SecurityLevel = atoi(argv[1]);
  507.                 if (SecurityLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
  508.                     {
  509.                     Usage();
  510.                     return(1);
  511.                     }
  512.                 argc--;
  513.                 argv++;
  514.                 break;
  515.             default:
  516.                 Usage();
  517.                 return(1);
  518.                 break;
  519.             }
  520.  
  521.         argc--;
  522.         argv++;
  523.         }
  524.  
  525.     status = RpcStringBindingCompose(0,
  526.                                      protocol,
  527.                                      serverAddress,
  528.                                      0,
  529.                                      0,
  530.                                      &stringBinding);
  531.     if (status != RPC_S_OK)
  532.         {
  533.         printf("RpcStringBindingCompose failed - %d\n", status);
  534.         return(1);
  535.         }
  536.  
  537.     status = RpcBindingFromStringBinding(stringBinding, &Binding);
  538.  
  539.     if (status != RPC_S_OK)
  540.         {
  541.         printf("RpcBindingFromStringBinding failed - %d\n", status);
  542.         return(1);
  543.         }
  544.  
  545.     status =
  546.     RpcBindingSetAuthInfo(Binding,
  547.                           0,
  548.                           SecurityLevel,
  549.                           RPC_C_AUTHN_WINNT,
  550.                           0,
  551.                           0
  552.                          );
  553.  
  554.     if (status != RPC_S_OK)
  555.         {
  556.         printf("RpcBindingSetAuthInfo failed - %d\n", status);
  557.         return(1);
  558.         }
  559.  
  560.     status = Ping(Binding);
  561.  
  562.     if (status != RPC_S_OK)
  563.         {
  564.         printf("Ping failed - %d\n", status);
  565.         }
  566.  
  567.     printf("Connected.\n");
  568.  
  569.     //
  570.     // Call and time various RPC calls.
  571.     //
  572.  
  573.     DoTimings(Binding, iIterations);
  574.  
  575.     // Cleanup
  576.  
  577.     status = RpcBindingFree(&Binding);
  578.  
  579.     // ASSERT(status == RPC_S_OK):
  580.  
  581.     status = RpcStringFree(&stringBinding);
  582.  
  583.     // ASSERT(status == RPC_S_OK);
  584.  
  585.     return(0);
  586. }
  587.  
  588. void * __RPC_USER MIDL_user_allocate(size_t size)
  589. {
  590.     return(HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, size));
  591. }
  592.  
  593. void __RPC_USER MIDL_user_free( void *pointer)
  594. {
  595.     HeapFree(GetProcessHeap(), 0, pointer);
  596. }
  597.  
  598.