PIPEC.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:
Windows编程
开发平台:
Visual C++
- /*************************************************************************
- Copyright Microsoft Corp. 1992-1996
- Remote Machine pipe sample
- FILE : pipec.c
- USAGE : client <local file> <new file> [options]
- -s Scramble file
- -u Unscramble the file
- -n network_address
- -p protocol_sequence
- -e endpoint
- -o options
- PURPOSE : Client side of the RPC distributed application pipes.
- COMMENTS : This program shows the client side an application that
- transfers a file from the client to the server, using
- pipes. When the file is received at the server it
- "encodes" the data by incrementing all the characters,
- and sends the "encoded" file back to the client.
- Since this program uses the implicit binding method,
- some of the binding handling must be done at the client
- side
- *************************************************************************/
- #include "pipe.h" // Generated by the MIDL compiler
- #include "common.h" // Common definitions
- #define CLIENT_BUFFER_SIZE 500 // Can send or recieve 500 elements
- // Client side global variables
- pipe_state in_out_pipe_state; // Pipe state on the client side
- _TUCHAR pcClientBuffer[CLIENT_BUFFER_SIZE]; // Buffer used in PipeAlloc
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Procedure : void Usage(_TUCHAR *) */
- /* Desc : This procedure prints out an error message if the */
- /* command line arguments are wrong */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- void Usage(_TUCHAR * pszProgramName)
- {
- _tprintf(TEXT("USAGE : %s <local_file> <new_file> [-option]n"),
- pszProgramName);
- _tprintf(TEXT("Options : -stTo encode the filen"));
- _tprintf(TEXT(" -utTo Decode the filen"));
- _tprintf(TEXT(" -nt<Network Address>n"));
- _tprintf(TEXT(" -pt<Protocol Sequence>n"));
- _tprintf(TEXT(" -et<Endpoint>n"));
- _tprintf(TEXT(" -ot<Options>n"));
- exit(EXECUTION_FAILED);
- }
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Procedure : PipeAlloc */
- /* Desc : This procedure allocates a chunck of memory and */
- /* returns a pointer to it. */
- /* In this sample the Alloc routine returns a pointer */
- /* to the same global allocated memory every time. */
- /* This can be done since after each Pull/Push, data */
- /* is read/written to file. */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- void PipeAlloc(
- char *pcStateInfo, // The state structure
- unsigned long nReqSize, // Req. size of buffer in bytes
- _TUCHAR **pcAllocatedBuffer,// Pointer to the allocated buffer
- unsigned long *pnAllocatedSize) // Size of allocated buf. in bytes
- {
- // Since the memory is already allocated, just return a pointer to it
- if(nReqSize > (CLIENT_BUFFER_SIZE * sizeof(_TUCHAR)))
- {
- *pnAllocatedSize = CLIENT_BUFFER_SIZE * sizeof(_TUCHAR);
- }
- else
- {
- *pnAllocatedSize = nReqSize;
- }
- *pcAllocatedBuffer = pcClientBuffer;
- }
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Procedure : PipePull */
- /* Desc : This procedure is called by the stub when its ready */
- /* to send a chunck of the pipe to the server. */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- void PipePull(
- char *pcStateInfo, // The state struct on client side
- _TUCHAR *pcBuffer, // Pointer to the buffer
- unsigned long nMaxBufferSize, // Size of buffer in elements
- unsigned long *pnSizeToSend) // Number of elements put in buffer
- {
- // Declare a state variable
- pipe_state *psState = (pipe_state *) pcStateInfo;
- // Open the local file, if it is not already opened
- if(psState->hOld == NULL)
- {
- if(NULL == (psState->hOld =
- _tfopen(psState->pszOldName, TEXT("rt"))))
- {
- _tprintf(TEXT("Could not open the file %sn"),
- psState->pszOldName);
- exit(EXECUTION_FAILED);
- }
- }
- // Read max_buffer_size into the buffer
- *pnSizeToSend = fread(
- pcBuffer,
- sizeof(_TUCHAR),
- nMaxBufferSize,
- psState->hOld);
- if(*pnSizeToSend == 0) // When end of the data is reached
- { // cleanup the application
- fclose(psState->hOld);
- psState->hOld = NULL;
- }
- }
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Procedure : PipePush */
- /* Desc : This procedure is called by the stub when a chunck */
- /* of data is received from the server. */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- void PipePush(
- char *nStateInfo, // State structure on client side
- _TUCHAR *pcBuffer, // Ptr to the buffer with the data
- unsigned long nNumberOfElements) // Number of elements in the buffer
- {
- // Declare a state variable
- pipe_state *psState = (pipe_state *) nStateInfo;
- // Open the New file, if it is not already opened
- if(psState->hNew == NULL)
- {
- if(NULL == (psState->hNew =
- _tfopen(psState->pszNewName, TEXT("w"))))
- {
- _tprintf( TEXT("Unable to create the file %sn"),
- psState->pszNewName);
- exit(EXECUTION_FAILED);
- }
- }
- // When number of elements received is 0, this is the end of the pipe
- if(nNumberOfElements == 0)
- {
- // Clean up by closing the opened file
- fclose (psState->hNew);
- psState->hNew = NULL;
- }
- else
- {
- // Write the buffer to the file
- fwrite(pcBuffer, sizeof(_TUCHAR), nNumberOfElements, psState->hNew);
- }
- }
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Client side main program */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- int _CRTAPI1 main(int argc, char *argv[])
- {
- RPC_STATUS nStatus; // Status returned from RPC-calls
- CHAR_PIPE_TYPE in_out_pipe; // Pipe structure used for the pipe
- TCHAR
- *pszOldFileName, // Name of the input file
- *pszNewFileName; // Name of the output file
- unsigned long
- nAction = SCRAMBLE, // Scramble / Unscramble file
- nIdx, // Counter in loops
- nNumArgs; // The number of args from the command line
- // These variables are used for the implicit binding
- _TUCHAR *pszUuid = NULL;
- _TUCHAR *pszProtocolSequence= PROTOCOL_SEQUENCE;
- _TUCHAR *pszNetworkAddress = NULL;
- _TUCHAR *pszEndpoint = END_POINT;
- _TUCHAR *pszOptions = NULL;
- _TUCHAR *pszStringBinding = NULL;
- // Get a common handle on the command line arguments for both
- // UNICODE and ASCII
- #ifdef _UNICODE
- LPWSTR *szArglist= CommandLineToArgvW(GetCommandLine(), &nNumArgs);
- if (NULL == szArglist)
- {
- _tprintf(TEXT("SERVER.C : CommandLineToArgW failed"));
- exit(EXECUTION_FAILED);
- }
- #else
- char **szArglist = argv;
- nNumArgs = argc;
- #endif
- // Check to see that the call was correct
- if (nNumArgs < 3)
- {
- Usage(szArglist[0]);
- }
- // Allow the user to override settings with commandline switches
- for (nIdx = 3; nIdx < nNumArgs; nIdx++)
- {
- if ((_tcscmp(szArglist[nIdx], TEXT("-n")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-N")) == 0))
- {
- pszNetworkAddress = szArglist[++nIdx];
- }
- else if((_tcscmp(szArglist[nIdx], TEXT("-p")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-P")) == 0))
- {
- pszProtocolSequence = szArglist[++nIdx];
- }
- else if((_tcscmp(szArglist[nIdx], TEXT("-e")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-e")) == 0))
- {
- pszEndpoint = szArglist[++nIdx];
- }
- else if((_tcscmp(szArglist[nIdx], TEXT("-o")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-O")) == 0))
- {
- pszOptions = szArglist[++nIdx];
- }
- else if((_tcscmp(szArglist[nIdx], TEXT("-s")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-S")) == 0))
- {
- nAction = SCRAMBLE;
- }
- else if((_tcscmp(szArglist[nIdx], TEXT("-u")) == 0) ||
- (_tcscmp(szArglist[nIdx], TEXT("-U")) == 0))
- {
- nAction = UNSCRAMBLE;
- }
- else
- {
- Usage(szArglist[0]);
- }
- }
- // Allocate space for the filenames
- if(NULL == (pszOldFileName = (TCHAR *) midl_user_allocate(
- sizeof(TCHAR) * (_tcsclen(szArglist[1]) + 1))))
- {
- _tprintf(TEXT("Memory allocation errorn"));
- exit(EXECUTION_FAILED);
- }
- if(NULL == (pszNewFileName = (TCHAR *) midl_user_allocate(
- sizeof(TCHAR) * (_tcsclen(szArglist[2]) + 1))))
- {
- _tprintf(TEXT("Memory allocation errorn"));
- exit(EXECUTION_FAILED);
- }
- // Initialize the state variables for the in pipe
- _tcscpy(pszOldFileName, szArglist[1]);
- _tcscpy(pszNewFileName, szArglist[2]);
- // Since we are doing implicit binding, we need to initialize the
- // global varaible global_pipe_sample_handle from the client.
- // Use a function to concatenate the elements of the string
- // binding into the proper sequence
- nStatus = RpcStringBindingCompose(
- pszUuid,
- pszProtocolSequence,
- pszNetworkAddress,
- pszEndpoint,
- pszOptions,
- &pszStringBinding);
- EXIT_IF_FAIL(nStatus, "RpcStringBindingCompose");
- // Set the binding handle that will be used to bind to the server
- nStatus = RpcBindingFromStringBinding(
- pszStringBinding,
- &global_pipe_sample_handle); // The global handle
- EXIT_IF_FAIL(nStatus, "RpcBindingFromStringBinding");
- /* Initialize pipestructure */
- in_out_pipe_state.hOld = NULL;
- in_out_pipe_state.hNew = NULL;
- in_out_pipe_state.pszOldName = pszOldFileName;
- in_out_pipe_state.pszNewName = pszNewFileName;
- in_out_pipe.state = (char *) &in_out_pipe_state;
- in_out_pipe.alloc = PipeAlloc;
- in_out_pipe.pull = PipePull;
- in_out_pipe.push = PipePush;
- RpcTryExcept
- {
- // Call the remote procedure to send the file to remote machine
- _tprintf(TEXT("Calling the remote procedure ScrambleFile()n"));
- ScrambleFile(nAction, &in_out_pipe);
- _tprintf(TEXT("Call to ScrambleFile() returnedn"));
- }
- RpcExcept(DO_EXCEPTION)
- {
- _tprintf(TEXT("Run-time exception %08X = %d in %sn"),
- RpcExceptionCode(), RpcExceptionCode(), TEXT(__FILE__));
- exit(EXECUTION_FAILED);
- }
- RpcEndExcept
- // Deallocate the memory used for the names in the state variable
- midl_user_free(pszOldFileName);
- midl_user_free(pszNewFileName);
- // Deallocate the memory used for the ARGLIST if using UNICODE
- #ifdef _UNICODE
- if (NULL != szArglist)
- free(szArglist);
- #endif
- // Shut down the server
- ShutDown();
- return (EXECUTION_OK);
- }
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- /* Procedure : midl_user_allocate() and midl_user_free() */
- /* Desc. : These procedure are declared in the header file */
- /* generated by the midl compiler. These procedures */
- /* should be used for all memory allocation and */
- /* deallocation. */
- /* These procedures are also called by the stub code to*/
- /* allocate and free memory. */
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
- void __RPC_FAR * __RPC_API midl_user_allocate(size_t nLen)
- {
- return (malloc(nLen));
- }
- void __RPC_API midl_user_free(void __RPC_FAR * lpvPointer)
- {
- if(NULL == lpvPointer)
- {
- free (lpvPointer);
- }
- }