221 lines
8.5 KiB
C
221 lines
8.5 KiB
C
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
Microsoft RPC strout sample
|
|
|
|
FILE : server.c
|
|
|
|
USAGE : server -p protocol_sequence
|
|
-e endpoint
|
|
-a server principal name
|
|
|
|
PURPOSE : Server side of the RPC distributed application strout.
|
|
|
|
COMMENTS : This application uses the implicit binding method.
|
|
|
|
*************************************************************************/
|
|
#include "strout.h" /* Generated by the midl compiler */
|
|
#include "common.h" /* Common definitions in this file */
|
|
#include "spn.h"
|
|
|
|
/* Local Procedures */
|
|
void CleanUpServer(void);
|
|
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
/* Procedure : void Usage(_TUCHAR *) */
|
|
/* Desc : This procedure prints out an error message if the */
|
|
/* command line arguments are wrong */
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
void Usage(_TUCHAR * pszProgramName)
|
|
{
|
|
_tprintf_s(TEXT("USAGE : %s [-option]\n"), pszProgramName);
|
|
_tprintf_s(TEXT("Options : -p Protocol Sequence\n"));
|
|
_tprintf_s(TEXT(" -e Endpoint\n"));
|
|
_tprintf_s(TEXT(" -a Server Principal Name\n"));
|
|
exit(EXECUTION_OK);
|
|
}
|
|
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
/* The server main program */
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int nNumArgs, /* The number of command line arguments */
|
|
nIdx; /* Counter in loops */
|
|
RPC_STATUS nStatus; /* Error status returned */
|
|
|
|
// Variabels used for selecting the protocol and the endpoint
|
|
_TUCHAR *pszProtocolSequence = PROTOCOL_SEQUENCE;
|
|
_TUCHAR *pszEndpoint = END_POINT;
|
|
_TUCHAR *pszSpn = NULL;
|
|
_TUCHAR *pszSecurity = NULL;
|
|
|
|
|
|
/* Get a common handle on the command line arguments for both UNICODE */
|
|
/* and ASCII */
|
|
#ifdef _UNICODE
|
|
LPWSTR *pArglist = CommandLineToArgvW(GetCommandLine(), &nNumArgs);
|
|
if (NULL == pArglist)
|
|
{
|
|
_tprintf_s(TEXT("SERVER.C : CommandLineToArgW failed"));
|
|
exit(EXECUTION_FAILED);
|
|
}
|
|
#else
|
|
char **pArglist = argv;
|
|
nNumArgs = argc;
|
|
#endif
|
|
|
|
/* Allow the user to override settings with commandline switches */
|
|
for (nIdx = 1; nIdx < nNumArgs; nIdx++)
|
|
{
|
|
if((_tcscmp(pArglist[nIdx], TEXT("-p")) == 0) ||
|
|
(_tcscmp(pArglist[nIdx], TEXT("-P")) == 0))
|
|
{
|
|
pszProtocolSequence = pArglist[++nIdx];
|
|
}
|
|
else if((_tcscmp(pArglist[nIdx], TEXT("-a")) == 0) ||
|
|
(_tcscmp(pArglist[nIdx], TEXT("-A")) == 0))
|
|
{
|
|
pszSpn = pArglist[++nIdx];
|
|
}
|
|
else if((_tcscmp(pArglist[nIdx], TEXT("-e")) == 0) ||
|
|
(_tcscmp(pArglist[nIdx], TEXT("-E")) == 0))
|
|
{
|
|
pszEndpoint = pArglist[++nIdx];
|
|
}
|
|
|
|
|
|
else
|
|
{
|
|
Usage(pArglist[0]);
|
|
}
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
/* Register the interface with the RPC run-time library */
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
_tprintf_s(TEXT("Registering the interface\n"));
|
|
|
|
|
|
nStatus = RpcServerRegisterIfEx(strout_sample_v1_0_s_ifspec, NULL, NULL, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL );
|
|
|
|
|
|
EXIT_IF_FAIL(nStatus, "RpcServerRegisterIfEx");
|
|
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
/* 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_s(TEXT("Selecting the protocol sequence: \"%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");
|
|
|
|
/* User did not specify spn, construct one. */
|
|
if (pszSpn == NULL) {
|
|
MakeSpn(&pszSpn);
|
|
}
|
|
|
|
/* Using Negotiate as security provider */
|
|
nStatus = RpcServerRegisterAuthInfo(pszSpn,
|
|
RPC_C_AUTHN_GSS_NEGOTIATE,
|
|
NULL,
|
|
NULL);
|
|
|
|
printf_s("RpcServerRegisterAuthInfo returned 0x%x\n", nStatus);
|
|
if (nStatus) {
|
|
exit(nStatus);
|
|
}
|
|
|
|
nStatus = RpcServerRegisterIfEx(strout_sample_v1_0_s_ifspec, NULL, NULL, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL );
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
/* Now start listening for remote procedure calls from the client */
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
RpcTryExcept
|
|
{
|
|
_tprintf_s(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); // Cont. until expl. stopped
|
|
EXIT_IF_FAIL(nStatus, "RpcServerListen");
|
|
}
|
|
RpcExcept(DO_EXCEPTION)
|
|
{
|
|
// Print out the exception code
|
|
_tprintf_s(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 != pArglist)
|
|
free(pArglist);
|
|
#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_s(TEXT("Unregistering the Interface"));
|
|
nStatus = RpcServerUnregisterIf(
|
|
NULL, NULL, // Prevents server from receiving 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 nLen)
|
|
{
|
|
return (malloc(nLen));
|
|
}
|
|
|
|
void __RPC_API midl_user_free(void __RPC_FAR * lpvPointer)
|
|
{
|
|
if(NULL != lpvPointer)
|
|
free (lpvPointer);
|
|
}
|
|
|