PIPEC.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*************************************************************************
  2.                     Copyright Microsoft Corp. 1992-1996
  3.                         Remote Machine pipe sample
  4.   
  5.     FILE        :   pipec.c
  6.     USAGE       :   client  <local file> <new file> [options]
  7.                         -s Scramble file
  8.                         -u Unscramble the file
  9.                         -n network_address
  10.                         -p protocol_sequence
  11.                         -e endpoint
  12.                         -o options
  13.     PURPOSE     :   Client side of the RPC distributed application pipes.
  14.   
  15.     COMMENTS    :   This program shows the client side an application that
  16.                     transfers a file from the client to the server, using 
  17.                     pipes. When the file is received at the server it 
  18.                     "encodes" the data by incrementing all the characters, 
  19.                     and sends the "encoded" file back to the client.
  20.                     Since this program uses the implicit binding method, 
  21.                     some of the binding handling must be done at the client 
  22.                     side
  23. *************************************************************************/
  24. #include "pipe.h"                   // Generated by the MIDL compiler
  25. #include "common.h"                 // Common definitions 
  26. #define CLIENT_BUFFER_SIZE  500     // Can send or recieve 500 elements 
  27. // Client side global variables
  28. pipe_state  in_out_pipe_state;      // Pipe state on the client side
  29. _TUCHAR     pcClientBuffer[CLIENT_BUFFER_SIZE];  // Buffer used in PipeAlloc
  30. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  31. /*  Procedure   :   void Usage(_TUCHAR *)                               */
  32. /*  Desc        :   This procedure prints out an error message if the   */
  33. /*                  command line arguments are wrong                    */
  34. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  35. void Usage(_TUCHAR * pszProgramName)
  36. {
  37.     _tprintf(TEXT("USAGE : %s <local_file> <new_file> [-option]n"), 
  38.         pszProgramName);
  39.     _tprintf(TEXT("Options : -stTo encode the filen"));
  40.     _tprintf(TEXT("          -utTo Decode the filen"));
  41.     _tprintf(TEXT("          -nt<Network Address>n"));
  42.     _tprintf(TEXT("          -pt<Protocol Sequence>n"));  
  43.     _tprintf(TEXT("          -et<Endpoint>n"));  
  44.     _tprintf(TEXT("          -ot<Options>n"));  
  45.     exit(EXECUTION_FAILED);
  46. }
  47. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  48. /*  Procedure   :   PipeAlloc                                           */
  49. /*  Desc        :   This procedure allocates a chunck of memory and     */
  50. /*                  returns a pointer to it.                            */
  51. /*                  In this sample the Alloc routine returns a pointer  */
  52. /*                  to the same global allocated memory every time.     */
  53. /*                  This can be done since after each Pull/Push, data   */
  54. /*                  is read/written to file.                            */
  55. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  56. void PipeAlloc(
  57.     char            *pcStateInfo,       // The state structure
  58.     unsigned long   nReqSize,           // Req. size of buffer in bytes
  59.     _TUCHAR         **pcAllocatedBuffer,// Pointer to the allocated buffer
  60.     unsigned long   *pnAllocatedSize)   // Size of allocated buf. in bytes
  61. {
  62.     // Since the memory is already allocated, just return a pointer to it
  63.     if(nReqSize > (CLIENT_BUFFER_SIZE * sizeof(_TUCHAR)))
  64.     {
  65.         *pnAllocatedSize = CLIENT_BUFFER_SIZE * sizeof(_TUCHAR);
  66.     }
  67.     else
  68.     {
  69.         *pnAllocatedSize = nReqSize;
  70.     }
  71.     *pcAllocatedBuffer = pcClientBuffer;
  72. }
  73. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  74. /*  Procedure   :   PipePull                                            */
  75. /*  Desc        :   This procedure is called by the stub when its ready */
  76. /*                  to send a chunck of the pipe to the server.         */
  77. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  78. void PipePull(
  79.     char            *pcStateInfo,   // The state struct on client side
  80.     _TUCHAR         *pcBuffer,      // Pointer to the buffer 
  81.     unsigned long   nMaxBufferSize, // Size of buffer in elements
  82.     unsigned long   *pnSizeToSend)  // Number of elements put in buffer
  83. {
  84.     // Declare a state variable 
  85.     pipe_state *psState = (pipe_state *) pcStateInfo;
  86.     // Open the local file, if it is not already opened 
  87.     if(psState->hOld == NULL)
  88.     {
  89.         if(NULL == (psState->hOld = 
  90.             _tfopen(psState->pszOldName, TEXT("rt"))))
  91.         {
  92.             _tprintf(TEXT("Could not open the file %sn"),
  93.                 psState->pszOldName);
  94.             exit(EXECUTION_FAILED);
  95.         }
  96.     }
  97.     // Read max_buffer_size into the buffer
  98.     *pnSizeToSend = fread(
  99.         pcBuffer, 
  100.         sizeof(_TUCHAR), 
  101.         nMaxBufferSize,
  102.         psState->hOld);
  103.     if(*pnSizeToSend == 0)      // When end of the data is reached
  104.     {                           // cleanup the application
  105.         fclose(psState->hOld);
  106.         psState->hOld = NULL;
  107.     }
  108. }
  109. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  110. /*  Procedure   :   PipePush                                            */
  111. /*  Desc        :   This procedure is called by the stub when a chunck  */
  112. /*                  of data is received from the server.                */
  113. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  114. void PipePush(
  115.     char            *nStateInfo,        // State structure on client side
  116.     _TUCHAR         *pcBuffer,          // Ptr to the buffer with the data
  117.     unsigned long   nNumberOfElements)  // Number of elements in the buffer
  118. {
  119.     // Declare a state variable 
  120.     pipe_state *psState = (pipe_state *) nStateInfo;
  121.     // Open the New file, if it is not already opened 
  122.     if(psState->hNew == NULL)
  123.     {
  124.         if(NULL == (psState->hNew = 
  125.             _tfopen(psState->pszNewName, TEXT("w"))))
  126.         {
  127.             _tprintf( TEXT("Unable to create the file %sn"), 
  128.                     psState->pszNewName);
  129.             exit(EXECUTION_FAILED);
  130.         }
  131.     }
  132.     // When number of elements received is 0, this is the end of the pipe
  133.     if(nNumberOfElements == 0)
  134.     {
  135.         // Clean up by closing the opened file 
  136.         fclose (psState->hNew);
  137.         psState->hNew = NULL;
  138.     }
  139.     else
  140.     {
  141.         // Write the buffer to the file 
  142.         fwrite(pcBuffer, sizeof(_TUCHAR), nNumberOfElements, psState->hNew);
  143.     }
  144. }
  145. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  146. /*  Client side main program                                            */
  147. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  148. int _CRTAPI1 main(int argc, char *argv[])
  149. {
  150.     RPC_STATUS      nStatus;        // Status returned from RPC-calls
  151.     CHAR_PIPE_TYPE  in_out_pipe;    // Pipe structure used for the pipe
  152.     TCHAR
  153.         *pszOldFileName,        // Name of the input file
  154.         *pszNewFileName;        // Name of the output file
  155.     unsigned long
  156.         nAction = SCRAMBLE,     // Scramble / Unscramble file
  157.         nIdx,                   // Counter in loops
  158.         nNumArgs;               // The number of args from the command line
  159.     // These variables are used for the implicit binding
  160.     _TUCHAR *pszUuid = NULL;
  161.     _TUCHAR *pszProtocolSequence= PROTOCOL_SEQUENCE;
  162.     _TUCHAR *pszNetworkAddress = NULL;
  163.     _TUCHAR *pszEndpoint = END_POINT;
  164.     _TUCHAR *pszOptions = NULL;
  165.     _TUCHAR *pszStringBinding = NULL;
  166.     // Get a common handle on the command line arguments for both 
  167.     // UNICODE and ASCII
  168. #ifdef _UNICODE
  169.     LPWSTR *szArglist= CommandLineToArgvW(GetCommandLine(), &nNumArgs);
  170.     if (NULL == szArglist)
  171.     {
  172.         _tprintf(TEXT("SERVER.C : CommandLineToArgW failed"));
  173.         exit(EXECUTION_FAILED);
  174.     }
  175. #else
  176.     char **szArglist = argv;
  177.     nNumArgs = argc;
  178. #endif
  179.     // Check to see that the call was correct
  180.     if (nNumArgs < 3)
  181.     {
  182.         Usage(szArglist[0]);
  183.     }
  184.     
  185.     // Allow the user to override settings with commandline switches    
  186.     for (nIdx = 3; nIdx < nNumArgs; nIdx++) 
  187.     {
  188.         if ((_tcscmp(szArglist[nIdx], TEXT("-n")) == 0) ||   
  189.             (_tcscmp(szArglist[nIdx], TEXT("-N")) == 0))
  190.         {
  191.             pszNetworkAddress = szArglist[++nIdx];
  192.         }
  193.         else if((_tcscmp(szArglist[nIdx], TEXT("-p")) == 0) || 
  194.             (_tcscmp(szArglist[nIdx], TEXT("-P")) == 0))
  195.         {
  196.             pszProtocolSequence = szArglist[++nIdx];
  197.         }
  198.         else if((_tcscmp(szArglist[nIdx], TEXT("-e")) == 0) || 
  199.                 (_tcscmp(szArglist[nIdx], TEXT("-e")) == 0))
  200.         {
  201.             pszEndpoint = szArglist[++nIdx];
  202.         }
  203.         else if((_tcscmp(szArglist[nIdx], TEXT("-o")) == 0) || 
  204.                (_tcscmp(szArglist[nIdx], TEXT("-O")) == 0))
  205.         {
  206.             pszOptions = szArglist[++nIdx];
  207.         }
  208.         else if((_tcscmp(szArglist[nIdx], TEXT("-s")) == 0) || 
  209.                 (_tcscmp(szArglist[nIdx], TEXT("-S")) == 0))
  210.         {
  211.             nAction = SCRAMBLE;    
  212.         }
  213.         else if((_tcscmp(szArglist[nIdx], TEXT("-u")) == 0) || 
  214.                 (_tcscmp(szArglist[nIdx], TEXT("-U")) == 0))
  215.         {
  216.             nAction = UNSCRAMBLE;
  217.         }
  218.         else  
  219.         {
  220.             Usage(szArglist[0]);
  221.         }
  222.     }
  223.     
  224.     // Allocate space for the filenames
  225.     if(NULL == (pszOldFileName = (TCHAR *) midl_user_allocate(
  226.         sizeof(TCHAR) * (_tcsclen(szArglist[1]) + 1))))
  227.     {
  228.         _tprintf(TEXT("Memory allocation errorn"));
  229.         exit(EXECUTION_FAILED);
  230.     }
  231.     if(NULL == (pszNewFileName = (TCHAR *) midl_user_allocate(
  232.         sizeof(TCHAR) * (_tcsclen(szArglist[2]) + 1))))
  233.     {
  234.         _tprintf(TEXT("Memory allocation errorn"));
  235.         exit(EXECUTION_FAILED);
  236.     }
  237.     // Initialize the state variables for the in pipe 
  238.     _tcscpy(pszOldFileName, szArglist[1]);
  239.     _tcscpy(pszNewFileName, szArglist[2]);
  240.     // Since we are doing implicit binding, we need to initialize the 
  241.     // global varaible global_pipe_sample_handle from the client.
  242.     // Use a function to concatenate the elements of the string         
  243.     // binding into the proper sequence                                 
  244.     nStatus = RpcStringBindingCompose( 
  245.         pszUuid,
  246.         pszProtocolSequence,
  247.         pszNetworkAddress,
  248.         pszEndpoint,
  249.         pszOptions,
  250.         &pszStringBinding); 
  251.     EXIT_IF_FAIL(nStatus, "RpcStringBindingCompose");
  252.     // Set the binding handle that will be used to bind to the server
  253.     nStatus = RpcBindingFromStringBinding(   
  254.         pszStringBinding,     
  255.         &global_pipe_sample_handle);        // The global handle
  256.     EXIT_IF_FAIL(nStatus, "RpcBindingFromStringBinding");
  257.     /* Initialize pipestructure */
  258.     in_out_pipe_state.hOld = NULL;
  259.     in_out_pipe_state.hNew = NULL;
  260.     in_out_pipe_state.pszOldName = pszOldFileName;
  261.     in_out_pipe_state.pszNewName = pszNewFileName;    
  262.     in_out_pipe.state = (char *) &in_out_pipe_state;
  263.     in_out_pipe.alloc = PipeAlloc;
  264.     in_out_pipe.pull = PipePull;
  265.     in_out_pipe.push = PipePush;
  266.     RpcTryExcept
  267.     {
  268.         // Call the remote procedure to send the file to remote machine
  269.         _tprintf(TEXT("Calling the remote procedure ScrambleFile()n"));
  270.         ScrambleFile(nAction, &in_out_pipe);
  271.         _tprintf(TEXT("Call to ScrambleFile() returnedn"));
  272.     }
  273.     RpcExcept(DO_EXCEPTION)
  274.     {
  275.         _tprintf(TEXT("Run-time exception %08X = %d in %sn"), 
  276.                 RpcExceptionCode(), RpcExceptionCode(), TEXT(__FILE__));
  277.         exit(EXECUTION_FAILED);
  278.     }
  279.     RpcEndExcept
  280.     // Deallocate the memory used for the names in the state variable
  281.     midl_user_free(pszOldFileName);
  282.     midl_user_free(pszNewFileName);
  283.     // Deallocate the memory used for the ARGLIST if using UNICODE
  284. #ifdef _UNICODE
  285.     if (NULL != szArglist)
  286.         free(szArglist);
  287. #endif
  288.     // Shut down the server 
  289.     ShutDown();
  290.     return (EXECUTION_OK);
  291. }
  292. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  293. /* Procedure    :   midl_user_allocate() and midl_user_free()           */
  294. /* Desc.        :   These procedure are declared in the header file     */
  295. /*                  generated by the midl compiler. These procedures    */
  296. /*                  should be used for all memory allocation and        */
  297. /*                  deallocation.                                       */
  298. /*                  These procedures are also called by the stub code to*/
  299. /*                  allocate and free memory.                           */
  300. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  301. void __RPC_FAR * __RPC_API midl_user_allocate(size_t nLen)
  302. {
  303.     return (malloc(nLen));
  304. }
  305. void __RPC_API midl_user_free(void __RPC_FAR * lpvPointer)
  306. {
  307.     if(NULL == lpvPointer)
  308.     {
  309.         free (lpvPointer);
  310.     }
  311. }