home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- 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 : -s\tTo encode the file\n"));
- _tprintf(TEXT(" -u\tTo Decode the file\n"));
- _tprintf(TEXT(" -n\t<Network Address>\n"));
- _tprintf(TEXT(" -p\t<Protocol Sequence>\n"));
- _tprintf(TEXT(" -e\t<Endpoint>\n"));
- _tprintf(TEXT(" -o\t<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 %s\n"),
- 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 %s\n"),
- 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 error\n"));
- exit(EXECUTION_FAILED);
- }
- if(NULL == (pszNewFileName = (TCHAR *) midl_user_allocate(
- sizeof(TCHAR) * (_tcsclen(szArglist[2]) + 1))))
- {
- _tprintf(TEXT("Memory allocation error\n"));
- 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() returned\n"));
- }
- RpcExcept(DO_EXCEPTION)
- {
- _tprintf(TEXT("Run-time exception %08X = %d in %s\n"),
- 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);
- }
- }
-
-