/*************************************************************************
                    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 */
/*                  can	stop 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");
}
