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 / strout / client.c next >
C/C++ Source or Header  |  1996-07-23  |  8KB  |  196 lines

  1. /*************************************************************************
  2.                     Copyright Microsoft Corp. 1992-1996
  3.                         Remote Machine strout sample
  4.  
  5.   FILE      :   client.c
  6.  
  7.   USAGE     :   client  -n network_address
  8.                         -p protocol_sequence
  9.                         -e endpoint
  10.                         -o options
  11.  
  12.   PURPOSE   :   Client side of the RPC distributed application strout.
  13.  
  14.   COMMENTS  :   This program shows how to call remote procedures that
  15.                 allocate memory for a two dimensional array (an array of
  16.                 character pointers). It calls the server that allocates 
  17.                 memory to store all the environment strings in, and copies
  18.                 the environment variables to this memory. The client then 
  19.                 displays all the data on the client machine.
  20.  
  21.                 Since this program uses the implicit binding method, some 
  22.                 of the binding handling must be done at the client side
  23. *************************************************************************/
  24.  
  25. #include "strout.h"     /* Generated by the midl compiler               */
  26. #include "common.h"     /* Definitions that are common to all files        */
  27.  
  28.  
  29. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  30. /*  Procedure   :   void Usage(_TUCHAR *)                               */
  31. /*  Desc        :   This procedure prints out an error message if the   */
  32. /*                  command line arguments are wrong                    */
  33. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  34. void Usage(_TUCHAR * pszProgramName)
  35. {
  36.     _tprintf(TEXT("USAGE : %s [-option]\n"), pszProgramName);
  37.     _tprintf(TEXT("Options : -n Network Address\n"));
  38.     _tprintf(TEXT("          -p Protocol Sequence\n"));  
  39.     _tprintf(TEXT("          -e Endpoint\n"));  
  40.     _tprintf(TEXT("          -o Options\n"));  
  41.     exit(EXECUTION_FAILED);
  42. }
  43.  
  44.  
  45. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  46. /* The client main program                                              */
  47. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  48. int main(int argc, char *argv[])
  49. {
  50.     RPC_STATUS nStatus;     /* Return value from the RPC calls          */
  51.     unsigned int
  52.         nIdx,               /* Counter in loops                         */
  53.         nNumArgs;           /* Number of commandline arguments          */
  54.     unsigned long 
  55.         nNumLines = 0;      /* Number of lines in the environment block */
  56.     str    *pEnvBlock;         /* Pointer to an array of string pointers   */
  57.     
  58.     // These variables are used for the implicit binding
  59.     _TUCHAR    *pszUuid            = NULL;
  60.     _TUCHAR    *pszProtocolSequence= PROTOCOL_SEQUENCE;
  61.     _TUCHAR    *pszNetworkAddress  = NULL;    
  62.     _TUCHAR    *pszEndpoint        = END_POINT;
  63.     _TUCHAR    *pszOptions         = NULL;
  64.     _TUCHAR    *pszStringBinding   = NULL;
  65.     
  66.     /* Get a common handle on the command line arguments for both       */
  67.     /* UNICODE and ASCII                                                */
  68. #ifdef _UNICODE
  69.     LPWSTR    *szArglist = CommandLineToArgvW(GetCommandLine(), &nNumArgs);
  70.     if (NULL == szArglist)
  71.     {
  72.         _tprintf(TEXT("SERVER.C : CommandLineToArgW failed"));
  73.         exit(EXECUTION_FAILED);
  74.     }
  75. #else
  76.     char **szArglist= argv;
  77.     nNumArgs = argc;
  78. #endif
  79.  
  80.     /* Allow the user to override settings with commandline switches    */
  81.     for (nIdx = 1; nIdx < nNumArgs; nIdx++) 
  82.     {
  83.         if ((_tcscmp(szArglist[nIdx], TEXT("-n")) == 0) || 
  84.             (_tcscmp(szArglist[nIdx], TEXT("-N")) == 0))
  85.         {
  86.             pszNetworkAddress = szArglist[++nIdx];
  87.         }
  88.         else if((_tcscmp(szArglist[nIdx], TEXT("-p")) == 0) || 
  89.             (_tcscmp(szArglist[nIdx], TEXT("-P")) == 0))
  90.         {
  91.             pszProtocolSequence = szArglist[++nIdx];
  92.         }
  93.         else if((_tcscmp(szArglist[nIdx], TEXT("-e")) == 0) || 
  94.                 (_tcscmp(szArglist[nIdx], TEXT("-e")) == 0))
  95.         {
  96.             pszEndpoint = szArglist[++nIdx];
  97.         }
  98.         else if((_tcscmp(szArglist[nIdx], TEXT("-o")) == 0) || 
  99.                 (_tcscmp(szArglist[nIdx], TEXT("-O")) == 0))
  100.         {
  101.             pszOptions = szArglist[++nIdx];
  102.         }
  103.         else 
  104.         {
  105.             Usage(szArglist[0]);
  106.         }
  107.     }
  108.             
  109.  
  110.     /* Since we are using implicit binding, we need to do some binding  */
  111.     /* from the client side as well.                                    */
  112.     /* Use a function to concatenate the elements of the string         */
  113.     /* binding into the proper sequence                                 */
  114.     nStatus = RpcStringBindingCompose(    
  115.         pszUuid,                            
  116.         pszProtocolSequence,
  117.         pszNetworkAddress,
  118.         pszEndpoint,
  119.         pszOptions,
  120.         &pszStringBinding);
  121.     EXIT_IF_FAIL(nStatus, "RpcStringBindingCompose");
  122.  
  123.     /* Set the binding handle that will be used to bind to the server   */
  124.     nStatus = RpcBindingFromStringBinding(    
  125.         pszStringBinding,                    
  126.         &global_strout_sample_handle);      /* The global handle used   */
  127.     EXIT_IF_FAIL(nStatus, "RpcBindingFromStringBinding");
  128.  
  129.     /* Initialize the pointer to NULL */
  130.     pEnvBlock = NULL;
  131.     
  132.     RpcTryExcept                /* Catch any exception that occurs      */
  133.     {
  134.         /* Call the remote procedure */
  135.         _tprintf(TEXT("Calling the remote procedure \'GetRemoteEnv\' \n"));
  136.         GetRemoteEnv(&nNumLines, &pEnvBlock);
  137.     }
  138.     RpcExcept(DO_EXCEPTION)
  139.     {
  140.         _tprintf(TEXT("Run-time exception %08X = %d in %s\n"), 
  141.             RpcExceptionCode(), RpcExceptionCode(), TEXT(__FILE__));
  142.         exit(EXECUTION_FAILED);
  143.     }
  144.     RpcEndExcept
  145.  
  146.  
  147.     /* Print out the result */
  148.     _tprintf(TEXT("There are %d environment variables\n"), nNumLines);
  149.     _tprintf(TEXT("They are:\n"));
  150.     for (nIdx = 0; nIdx < nNumLines; nIdx++)
  151.     {
  152.         _tprintf(TEXT("\t%s\n"), pEnvBlock[nIdx]);
  153.     }
  154.     
  155.     
  156.     // Deallocate all the memory used for the EnvBlock
  157.     for (nIdx = 0; nIdx < nNumLines; nIdx++)
  158.     {
  159.         midl_user_free(pEnvBlock[nIdx]);
  160.     }
  161.     midl_user_free(pEnvBlock);
  162.  
  163.     // Deallocate the memory used for the ARGLIST if using UNICODE
  164. #ifdef _UNICODE
  165.     if (NULL != szArglist)
  166.         free(szArglist);
  167. #endif
  168.  
  169.     /* When the call is done, shut down the server application */
  170.     ShutDown();
  171.  
  172.     return (EXECUTION_OK);
  173. }
  174.  
  175.  
  176.  
  177. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  178. /* Procedure    :   midl_user_allocate() and midl_user_free()           */
  179. /* Desc.        :   These procedure are declared in the header file     */
  180. /*                  generated by the midl compiler. These procedures    */
  181. /*                  should be used for all memory allocation and        */
  182. /*                  deallocation.                                       */
  183. /*                  These procedures are also called by the stub code to*/
  184. /*                  allocate and free memory.                           */
  185. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  186. void __RPC_FAR * __RPC_API midl_user_allocate(size_t nLen)
  187. {
  188.     return (malloc(nLen));
  189. }
  190.  
  191. void __RPC_API midl_user_free(void __RPC_FAR * lpvPointer)
  192. {
  193.     if (lpvPointer != NULL)
  194.         free (lpvPointer);
  195. }
  196.