reactos/base/services/svchost/rpcsrv.c

159 lines
4.3 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Service Host
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: base/services/svchost/rpcsrv.c
* PURPOSE: RPC Service Support
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES ******************************************************************/
#include "svchost.h"
/* GLOBALS *******************************************************************/
LONG RpcpNumInstances;
CRITICAL_SECTION RpcpCriticalSection;
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
RpcpInitRpcServer (
VOID
)
{
/* Clear the reference count and initialize the critical section */
RpcpNumInstances = 0;
return RtlInitializeCriticalSection((PVOID)&RpcpCriticalSection);
}
NTSTATUS
NTAPI
RpcpStopRpcServer (
_In_ RPC_IF_HANDLE IfSpec
)
{
RPC_STATUS rpcStatus;
/* Unregister the interface */
rpcStatus = RpcServerUnregisterIf(IfSpec, NULL, TRUE);
/* Acquire the lock while we dereference the RPC services */
EnterCriticalSection(&RpcpCriticalSection);
if (--RpcpNumInstances == 0)
{
/* All RPC services stopped, rundown the server */
RpcMgmtStopServerListening(NULL);
RpcMgmtWaitServerListen();
}
/* Release the lock and return the unregister result */
LeaveCriticalSection(&RpcpCriticalSection);
return I_RpcMapWin32Status(rpcStatus);
}
NTSTATUS
NTAPI
RpcpStopRpcServerEx (
_In_ RPC_IF_HANDLE IfSpec
)
{
RPC_STATUS rpcStatus;
/* Unregister the interface */
rpcStatus = RpcServerUnregisterIfEx(IfSpec, NULL, TRUE);
/* Acquire the lock while we dereference the RPC services */
EnterCriticalSection(&RpcpCriticalSection);
if (--RpcpNumInstances == 0)
{
/* All RPC services stopped, rundown the server */
RpcMgmtStopServerListening(NULL);
RpcMgmtWaitServerListen();
}
/* Release the lock and return the unregister result */
LeaveCriticalSection(&RpcpCriticalSection);
return I_RpcMapWin32Status(rpcStatus);
}
NTSTATUS
NTAPI
RpcpAddInterface (
_In_ PCWSTR IfName,
_In_ RPC_IF_HANDLE IfSpec
)
{
PWCHAR endpointName;
NTSTATUS ntStatus;
RPC_STATUS rpcStatus;
/* Allocate space for the interface name and the \\PIPE\\ prefix */
endpointName = LocalAlloc(0, sizeof(WCHAR) * wcslen(IfName) + 16);
if (endpointName)
{
/* Copy the prefix, and then the interface name */
wcscpy(endpointName, L"\\PIPE\\");
wcscat(endpointName, IfName);
/* Create a named pipe endpoint with this name */
rpcStatus = RpcServerUseProtseqEpW(L"ncacn_np",
RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
endpointName, NULL);
if ((rpcStatus != RPC_S_OK) && (rpcStatus != RPC_S_DUPLICATE_ENDPOINT))
{
/* We couldn't create it, or it already existed... */
DbgPrint("RpcServerUseProtseqW failed! rpcstatus = %u\n", rpcStatus);
}
else
{
/* It worked, register an interface on this endpoint now */
rpcStatus = RpcServerRegisterIf(IfSpec, 0, 0);
}
/* In both success and failure, free the name, and convert the status */
LocalFree(endpointName);
ntStatus = I_RpcMapWin32Status(rpcStatus);
}
else
{
/* No memory, bail out */
ntStatus = STATUS_NO_MEMORY;
}
/* Return back to the caller */
return ntStatus;
}
NTSTATUS
NTAPI
RpcpStartRpcServer (
_In_ PCWSTR IfName,
_In_ RPC_IF_HANDLE IfSpec
)
{
NTSTATUS ntStatus;
/* Acquire the lock while we instantiate a new interface */
EnterCriticalSection(&RpcpCriticalSection);
/* Add this interface to the service */
ntStatus = RpcpAddInterface(IfName, IfSpec);
if (!ntStatus)
{
/* Increment the reference count to see if this was the first interface */
if (++RpcpNumInstances == 1)
{
/* It was, so put the server into listening mode now */
ntStatus = RpcServerListen(1, 12345, TRUE);
if (ntStatus == RPC_S_ALREADY_LISTENING) ntStatus = STATUS_SUCCESS;
}
}
/* Release the lock and return back the result to the caller */
LeaveCriticalSection(&RpcpCriticalSection);
return I_RpcMapWin32Status(ntStatus);
}