mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
6.8 KiB
288 lines
6.8 KiB
/*++
|
|
|
|
Copyright (c) 1990-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
RpcServ.c
|
|
|
|
Abstract:
|
|
|
|
This file contains routines for starting and stoping RPC servers.
|
|
|
|
NetpInitRpcServer
|
|
NetpStartRpcServer
|
|
NetpStopRpcServer
|
|
|
|
Author:
|
|
|
|
Dan Lafferty danl 09-May-1991
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
26-May-1993 Danl
|
|
Added call to RpcMgmtWaitServerListen when shutting down the last
|
|
RPC server in the process. This fixes the problem where if we
|
|
shut down all the RPC services in lmsvcs.exe (but the process stays
|
|
up due to other services), and then start them up again, all calls
|
|
to those RPC interfaces would return RPC_SERVER_BUSY.
|
|
|
|
18-May-1993 Danl
|
|
Changed RpcServerUnregisterIf so that it waits for outstanding RPC
|
|
calls to complete.
|
|
|
|
29-Jan-1993 Danl
|
|
Free memory allocated for Endpoint and Security Descriptor. Also,
|
|
fix it so StartListen() is only called if RpcServerRegisterIf()
|
|
succeeeds.
|
|
|
|
23-Oct-1991 Danl
|
|
Added Critical Section Locks and made sure the instance count gets
|
|
incremented. Added NetpInitRpcServer().
|
|
|
|
09-May-1991 Danl
|
|
Created
|
|
|
|
--*/
|
|
|
|
//
|
|
// INCLUDES
|
|
//
|
|
|
|
// These must be included first:
|
|
#include <nt.h> // DbgPrint
|
|
#include <ntrtl.h> // DbgPrint
|
|
#include <windef.h> // win32 typedefs
|
|
#include <lmcons.h> // NET_API_STATUS
|
|
#include <rpc.h> // rpc prototypes
|
|
#include <netlib.h>
|
|
#include <rpcutil.h>
|
|
#include <nturtl.h> // needed for winbase.h
|
|
#include <winbase.h> // LocalAlloc
|
|
|
|
// These may be included in any order:
|
|
#include <ntrtl.h> // DbgPrint
|
|
#include <lmerr.h> // NetError codes
|
|
#include <rpcutil.h> // MIDL_user_allocate(), MIDL_user_free().
|
|
#include <string.h> // for strcpy strcat strlen memcmp
|
|
#include <tstring.h> // for STRCPY STRCAT STRLEN memcmp
|
|
#include <debuglib.h> // IF_DEBUG
|
|
#include <netdebug.h> // FORMAT_NTSTATUS, NetpKdPrint(()).
|
|
|
|
//
|
|
// GLOBALS
|
|
//
|
|
|
|
static CRITICAL_SECTION RpcpCriticalSection;
|
|
static DWORD RpcpNumInstances;
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NetpInitRpcServer(
|
|
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;
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NetpStartRpcServer(
|
|
IN LPTSTR 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 - This is a pointer to a character string that identifies
|
|
the interface.
|
|
|
|
InterfaceSpecification - Supplies a description of the interface to
|
|
be added.
|
|
|
|
Return Value:
|
|
|
|
NERR_Success, or any RPC error codes, or any windows error codes that
|
|
can be returned by LocalAlloc.
|
|
|
|
--*/
|
|
{
|
|
RPC_STATUS RpcStatus;
|
|
LPTSTR Endpoint=NULL;
|
|
DWORD status;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor=NULL;
|
|
BOOLEAN Bool;
|
|
|
|
Endpoint = (LPTSTR)LocalAlloc(0, STRSIZE(InterfaceName) + STRSIZE(NT_PIPE_PREFIX));
|
|
if (Endpoint == 0) {
|
|
status = GetLastError();
|
|
IF_DEBUG(RPC) {
|
|
NetpKdPrint(("NetpStartRpcServer:LocalAlloc Failure %ld\n",status));
|
|
}
|
|
return(status);
|
|
}
|
|
|
|
STRCPY(Endpoint, NT_PIPE_PREFIX);
|
|
STRCAT(Endpoint, InterfaceName);
|
|
|
|
IF_DEBUG(RPC) {
|
|
NetpKdPrint(("Creating Interface: %s\n", Endpoint));
|
|
}
|
|
|
|
//
|
|
// All code from this point on must goto a CleanExit prior to returning.
|
|
//
|
|
EnterCriticalSection(&RpcpCriticalSection);
|
|
|
|
IF_DEBUG(RPC) {
|
|
NetpKdPrint(("[NetpStartRpcServer]Adding Address & Interface...\n"));
|
|
}
|
|
|
|
//
|
|
// 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 doesn't know how to copy a security descriptor,
|
|
// so just allocate this and leave it around for the time being.
|
|
// We need to fix this before we ship.
|
|
//
|
|
|
|
|
|
SecurityDescriptor = (PSECURITY_DESCRIPTOR)LocalAlloc(
|
|
LMEM_FIXED,
|
|
sizeof( SECURITY_DESCRIPTOR ));
|
|
|
|
if (SecurityDescriptor == NULL) {
|
|
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
|
|
);
|
|
|
|
ASSERT( Bool );
|
|
|
|
RpcStatus = RpcServerUseProtseqEp(
|
|
TEXT("ncacn_np"),
|
|
10,
|
|
Endpoint,
|
|
SecurityDescriptor);
|
|
|
|
|
|
if ((RpcStatus != RPC_S_OK) && (RpcStatus != RPC_S_DUPLICATE_ENDPOINT)) {
|
|
|
|
IF_DEBUG(RPC) {
|
|
NetpKdPrint(("RpcServerUseProtseqA failed! rpcstatus = %u\n",RpcStatus));
|
|
}
|
|
goto CleanExit;
|
|
}
|
|
|
|
RpcStatus = RpcServerRegisterIf(InterfaceSpecification, 0, 0);
|
|
|
|
if (RpcStatus != RPC_S_OK) {
|
|
IF_DEBUG(RPC) {
|
|
NetpKdPrint(("RpcServerRegisterIf failed! rpcstatus = %u\n",RpcStatus));
|
|
}
|
|
goto CleanExit;
|
|
}
|
|
|
|
RpcpNumInstances++;
|
|
|
|
if (RpcpNumInstances == 1) {
|
|
RpcStatus = RpcServerListen(1, 12345, 1);
|
|
if ( RpcStatus == RPC_S_ALREADY_LISTENING ) {
|
|
RpcStatus = RPC_S_OK;
|
|
}
|
|
}
|
|
|
|
CleanExit:
|
|
LeaveCriticalSection(&RpcpCriticalSection);
|
|
if (Endpoint != NULL) {
|
|
LocalFree(Endpoint);
|
|
}
|
|
if (SecurityDescriptor != NULL) {
|
|
LocalFree(SecurityDescriptor);
|
|
}
|
|
return NetpRpcStatusToApiStatus(RpcStatus);
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
NetpStopRpcServer(
|
|
IN RPC_IF_HANDLE InterfaceSpecification
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Deletes the interface.
|
|
|
|
Arguments:
|
|
|
|
InterfaceSpecification - Supplies a description of the interface to
|
|
be deleted.
|
|
|
|
Return Value:
|
|
|
|
NERR_Success, 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 NetpRpcStatusToApiStatus(RpcStatus);
|
|
}
|