PIPES.C

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

FILE : pipes.c

USAGE : server -p protocol_sequence
-e endpoint

PURPOSE : Server side of the RPC distributed application pipe.

COMMENTS : This application uses the implicit binding method.

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

// Local Procedures
void CleanUpServer(); // Unregisters the interface

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* 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 [-option]\n"), pszProgramName);
_tprintf(TEXT("Options : -p Protocol Sequence\n"));
_tprintf(TEXT(" -e Endpoint\n"));
exit(EXECUTION_FAILED);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* The server main program */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int _CRTAPI1 main(int argc, char *argv[])
{
RPC_STATUS nStatus; // Error status returned
int nNumArgs; // Number of command line arguments
int nIdx; // Counter in loops

// Variabels used for selecting the protocol and the endpoint
_TUCHAR *pszProtocolSequence = PROTOCOL_SEQUENCE;
_TUCHAR *pszEndpoint = END_POINT;
_TUCHAR *pszSecurity = 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

/* Allow the user to override settings with commandline switches */
for (nIdx = 1; nIdx < nNumArgs; nIdx++)
{
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
{
Usage(szArglist[0]);
}
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Register the interface with the RPC run-time library */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
_tprintf(TEXT("Registering the interface\n"));
nStatus = RpcServerRegisterIf(
pipe_sample_v1_0_s_ifspec, // Interface specification
NULL, // UUID to associate with MgrEnv arg.
NULL); // Managers entry point vector. (None)
EXIT_IF_FAIL(nStatus, "RpcServerRegisterIf");


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Select Protocal sequence : This sample uses namedpipes as the */
/* default protocol. The RpcServerUseProtseqEp function tells the */
/* RPC run-time library to use the specified protocol sequence */
/* combined with the specified endpoint for receiving remote */
/* procedure calls */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
_tprintf(TEXT("Selecting the protocol sequence to use.\t\"%s\"\n"),
pszProtocolSequence);
nStatus = RpcServerUseProtseqEp(
pszProtocolSequence, // String with the protocol in
RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Max number of calls
pszEndpoint, // Endpoint addres information
pszSecurity); // Security
EXIT_IF_FAIL(nStatus, "RpcServerUseProtseqsEp");


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Now start listening for remote procedure calls from the client */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RpcTryExcept
{
_tprintf(TEXT("Listening for remote calls...\n"));
nStatus = RpcServerListen(
1, // The minimum number of calls
RPC_C_LISTEN_MAX_CALLS_DEFAULT, // The maximum number of calls
FALSE); // Continue until stopped
EXIT_IF_FAIL(nStatus, "RpcServerListen");
}
RpcExcept(DO_EXCEPTION)
{
// Print out the exception code
_tprintf(TEXT("Run-time exception %u in %s at line %d\n"),
RpcExceptionCode(), TEXT(__FILE__), __LINE__);
exit(EXECUTION_FAILED);
}
RpcEndExcept

// If no exceptions occured, clean up the server and exit
CleanUpServer();

// Deallocate the memory used for the ARGLIST if using UNICODE
#ifdef _UNICODE
if (NULL != szArglist)
free(szArglist);
#endif

return (EXECUTION_OK);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Procedure : void CleanUpServer(RPC_BINDING_VECTOR); */
/* Desc. : This procedure will unregister the interface */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void CleanUpServer(void)
{
RPC_STATUS nStatus; // Error status returned from RPC calls

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Unregister the interface from the RPC run-time library */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
_tprintf(TEXT("Unregistering the Interface"));
nStatus = RpcServerUnregisterIf(
NULL, NULL, // Prevents server from receiving any new remote calls
FALSE); // Wait until all the active calls are complete
EXIT_IF_FAIL(nStatus, "RpcServerUnRegisterIf");
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* 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 len)
{
return (malloc(len));
}

void __RPC_API midl_user_free(void __RPC_FAR * ptr)
{
if(NULL != ptr)
free (ptr);
}