diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/rpc/server.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/nw/rpc/server.c')
-rw-r--r-- | private/nw/rpc/server.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/private/nw/rpc/server.c b/private/nw/rpc/server.c new file mode 100644 index 000000000..f9825d3ef --- /dev/null +++ b/private/nw/rpc/server.c @@ -0,0 +1,362 @@ +/*++ + +Copyright (c) 1990-1993 Microsoft Corporation + +Module Name: + + server.c + +Abstract: + + This file contains commonly used server-side RPC functions, + such as starting and stoping RPC servers. + +Author: + + Dan Lafferty danl 09-May-1991 + +Environment: + + User Mode - Win32 + +Revision History: + + 09-May-1991 Danl + Created + + 03-July-1991 JimK + Copied from a net-specific file. + + 18-Feb-1992 Danl + Added support for multiple endpoints & interfaces per server. + + 10-Feb-1993 RitaW + Copied to the NetWare tree so that the LPC transport can used for + the local case. + +--*/ + +// +// INCLUDES +// + +#include <nt.h> // DbgPrint +#include <ntrtl.h> // DbgPrint +#include <windef.h> // win32 typedefs +#include <rpc.h> // rpc prototypes +#include <nturtl.h> // needed for winbase.h +#include <winbase.h> // LocalAlloc + +#include <stdlib.h> // for wcscpy wcscat +#include <tstr.h> // WCSSIZE + +#include <nwrpcp.h> + + +#define NT_PIPE_PREFIX_W L"\\PIPE\\" + +// +// GLOBALS +// + +static CRITICAL_SECTION RpcpCriticalSection; +static DWORD RpcpNumInstances; + + + +VOID +RpcpInitRpcServer( + VOID + ) + +/*++ + +Routine Description: + + This function initializes the critical section used to protect the + global server handle and instance count. + +Arguments: + + none + +Return Value: + + none + +--*/ +{ + InitializeCriticalSection(&RpcpCriticalSection); + RpcpNumInstances = 0; +} + + +RPC_STATUS +RpcpAddInterface( + IN LPWSTR InterfaceName, + IN RPC_IF_HANDLE InterfaceSpecification + ) + +/*++ + +Routine Description: + + Starts an RPC Server, adds the address (or port/pipe), and adds the + interface (dispatch table). + +Arguments: + + InterfaceName - points to the name of the interface. + + InterfaceSpecification - Supplies the interface handle for the + interface which we wish to add. + +Return Value: + + RPC_S_OK - Indicates the server was successfully started. + + Other - Status values that may be returned by: + + RpcServerRegisterIf() + RpcServerUseProtseqEp() + + , or any RPC error codes, or any windows error codes that + can be returned by LocalAlloc. + +--*/ +{ + RPC_STATUS RpcStatus; + LPWSTR Endpoint = NULL; + + PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; + BOOL Bool; + + +#if 0 + // We need to concatenate \pipe\ to the front of the interface name. + + Endpoint = LocalAlloc(0, sizeof(NT_PIPE_PREFIX_W) + WCSSIZE(InterfaceName)); + if (Endpoint == 0) { + return(STATUS_NO_MEMORY); + } + wcscpy(Endpoint, NT_PIPE_PREFIX_W ); + wcscat(Endpoint,InterfaceName); +#endif + + // + // Croft up a security descriptor that will grant everyone + // all access to the object (basically, no security) + // + // We do this by putting in a NULL Dacl. + // + // BUGBUG: rpc should copy the security descriptor, + // Since it currently doesn't, simply allocate it for now and + // leave it around forever. + // + + SecurityDescriptor = (PVOID) LocalAlloc(LMEM_FIXED, sizeof( SECURITY_DESCRIPTOR)); + if (SecurityDescriptor == 0) { + RpcStatus = RPC_S_OUT_OF_MEMORY; + goto CleanExit; + } + + InitializeSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); + + Bool = SetSecurityDescriptorDacl ( + SecurityDescriptor, + TRUE, // Dacl present + NULL, // NULL Dacl + FALSE // Not defaulted + ); + + // + // There's no way the above call can fail. But check anyway. + // + ASSERT( Bool ); + +#if 0 + // Ignore the second argument for now. + + RpcStatus = RpcServerUseProtseqEpW(L"ncacn_np", 10, Endpoint, SecurityDescriptor); + + // If RpcpStartRpcServer and then RpcpStopRpcServer have already + // been called, the endpoint will have already been added but not + // removed (because there is no way to do it). If the endpoint is + // already there, it is ok. + + if ( (RpcStatus != RPC_S_OK) + && (RpcStatus != RPC_S_DUPLICATE_ENDPOINT)) { + + KdPrint(("RpcServerUseProtseqW failed! rpcstatus = %u\n",RpcStatus)); + goto CleanExit; + } +#endif // #if 0 + + + RpcStatus = RpcServerUseProtseqEpW(L"ncalrpc", 10, InterfaceName, SecurityDescriptor); + + // If RpcpStartRpcServer and then RpcpStopRpcServer have already + // been called, the endpoint will have already been added but not + // removed (because there is no way to do it). If the endpoint is + // already there, it is ok. + + if ((RpcStatus != RPC_S_OK) + && (RpcStatus != RPC_S_DUPLICATE_ENDPOINT)) { + + KdPrint(("RpcServerUseProtseqW failed! rpcstatus = %u\n",RpcStatus)); + goto CleanExit; + } + + RpcStatus = RpcServerRegisterIf(InterfaceSpecification, 0, 0); + +CleanExit: + if ( Endpoint != NULL ) { + LocalFree(Endpoint); + } + + return RpcStatus; +} + + +RPC_STATUS +RpcpStartRpcServer( + IN LPWSTR InterfaceName, + IN RPC_IF_HANDLE InterfaceSpecification + ) + +/*++ + +Routine Description: + + Starts an RPC Server, adds the address (or port/pipe), and adds the + interface (dispatch table). + +Arguments: + + InterfaceName - points to the name of the interface. + + InterfaceSpecification - Supplies the interface handle for the + interface which we wish to add. + +Return Value: + + RPC_S_OK - Indicates the server was successfully started. + + Other - Status values that may be returned by: + + RpcServerRegisterIf() + RpcServerUseProtseqEp() + + , or any RPC error codes, or any windows error codes that + can be returned by LocalAlloc. + +--*/ +{ + RPC_STATUS RpcStatus; + + EnterCriticalSection(&RpcpCriticalSection); + + RpcStatus = RpcpAddInterface( InterfaceName, + InterfaceSpecification ); + + if ( RpcStatus != RPC_S_OK ) { + LeaveCriticalSection(&RpcpCriticalSection); + return RpcStatus; + } + + RpcpNumInstances++; + + if (RpcpNumInstances == 1) { + + + // The first argument specifies the minimum number of threads to + // be created to handle calls; the second argument specifies the + // maximum number of concurrent calls allowed. The last argument + // indicates not to wait. + + RpcStatus = RpcServerListen(1,12345, 1); + if ( RpcStatus == RPC_S_ALREADY_LISTENING ) { + RpcStatus = RPC_S_OK; + } + } + + LeaveCriticalSection(&RpcpCriticalSection); + return RpcStatus; +} + + +RPC_STATUS +RpcpDeleteInterface( + IN RPC_IF_HANDLE InterfaceSpecification + ) + +/*++ + +Routine Description: + + Deletes the interface. This is likely + to be caused by an invalid handle. If an attempt to add the same + interface or address again, then an error will be generated at that + time. + +Arguments: + + InterfaceSpecification - A handle for the interface that is to be removed. + +Return Value: + + RPC_S_OK, or any RPC error codes that can be returned from + RpcServerUnregisterIf. + +--*/ +{ + RPC_STATUS RpcStatus; + + + RpcStatus = RpcServerUnregisterIf(InterfaceSpecification, 0, 1); + + return RpcStatus; +} + + +RPC_STATUS +RpcpStopRpcServer( + IN RPC_IF_HANDLE InterfaceSpecification + ) + +/*++ + +Routine Description: + + Deletes the interface. This is likely + to be caused by an invalid handle. If an attempt to add the same + interface or address again, then an error will be generated at that + time. + +Arguments: + + InterfaceSpecification - A handle for the interface that is to be removed. + +Return Value: + + RPC_S_OK, or any RPC error codes that can be returned from + RpcServerUnregisterIf. + +--*/ +{ + RPC_STATUS RpcStatus; + + + RpcStatus = RpcServerUnregisterIf(InterfaceSpecification, 0, 1); + EnterCriticalSection(&RpcpCriticalSection); + + RpcpNumInstances--; + if (RpcpNumInstances == 0) { + RpcMgmtStopServerListening(0); + RpcMgmtWaitServerListen(); + } + + LeaveCriticalSection(&RpcpCriticalSection); + + return RpcStatus; +} |