PIPEPROC.C

/************************************************************************* 
Copyright Microsoft Corp. 1992-1996
Remote Machine pipe sample

FILE : pipeproc.c

PURPOSE :Remote procedures used in the RPC distributed application
pipe sample

COMMENTS : This file is linked together with the server side of the
application.

*************************************************************************/
#include "pipe.h" // Generated by the MIDL compiler
#include "common.h" // Common definitions is locataed in this file

#define MAX_BUFFER_SIZE 1000 // Buffer used on the server side


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Procedure : void ScrambleFile(unsigned long, CHAR_PIPE_TYPE *) */
/* Desc. : This procedure receives a file from the client, and */
/* then "encodes" the file by adding 1 to every */
/* character, and then sends the file back to the */
/* client. The file is sent back and forth using pipes */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void ScrambleFile(unsigned long nAction, CHAR_PIPE_TYPE *in_out_pipe)
{
FILE *fpTemp; // Pointer to the temporary file
_TUCHAR pcBuffer[MAX_BUFFER_SIZE]; // Buffer to store the elements in

unsigned long
nActualTransferCount, // Actual number of elements received
nIdx, // Counter in loop
nElementsToSend; // Number of elements to send to the client
BOOL bDone = FALSE; // Inidicates when the pipe is done


// Open up a file to temporary store the pulled data in
fpTemp = _tfopen(TEXT("tempfile.oak"), TEXT("w+"));

_tprintf(TEXT("Retrieving data from the client...\n"));
// First process the entire pull. Input pipes must be transmitted first
while(FALSE == bDone)
{
in_out_pipe->pull( // Grab a chunck of data from the client
in_out_pipe->state, // Pointer to the state
pcBuffer, // Buffer to put data in
MAX_BUFFER_SIZE, // Max number of elements to receive
&nActualTransferCount); // Actual number of elements received

// A data transfer count of 0 means the end of the pipe
if(nActualTransferCount == 0)
{
bDone = TRUE;
}
else // Save the data to an intermediate file
{
fwrite(pcBuffer, sizeof(_TUCHAR), nActualTransferCount, fpTemp);
}
}

// Reset the flag
bDone = FALSE;

// Reset the filehandle to point at start of file
fseek(fpTemp, 0, SEEK_SET);

_tprintf(TEXT("Sending the data back to the client...\n"));
// Now we can send the data back
while(FALSE == bDone)
{
// Read a number of bytes from the file, into the buffer
nElementsToSend = fread(pcBuffer,
sizeof(_TUCHAR),
MAX_BUFFER_SIZE,
fpTemp);

// If no more elements to send, we are done. Must send 0 to the
// client to notify that the pipe is empty
if(nElementsToSend == 0)
{
bDone = TRUE;
}

// According to the action, scramble or descramble the data
for (nIdx = 0; nIdx < nElementsToSend; nIdx++)
{
if(nAction == SCRAMBLE)
{
pcBuffer[nIdx]++;
}
else
{
pcBuffer[nIdx]--;
}
}

// Send the buffer to the client
in_out_pipe->push( // Send a chunck of data to the client
in_out_pipe->state, // Pointer to the state
pcBuffer, // Date to send is in this buffer
nElementsToSend); // The number of elements to send
}// End while (!done)

// Close the file
fclose(fpTemp);
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Procedure : void ShutDown(void); */
/* Desc. : This procedure send a message to the server that it */
/* canstop listening for remote procedure calls */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void ShutDown(void)
{
RPC_STATUS nStatus;

// Tell the server to stop listening for remote procedure calls
_tprintf(TEXT("Shutting down the server\n"));
nStatus = RpcMgmtStopServerListening(NULL);
EXIT_IF_FAIL(nStatus, "RpcMgmtStopServerListening");
}