reactos/base/services/svchost/rpcsrv.c
Hermès Bélusca-Maïto 3d3a5aa02e
[SDK:REACTOS][SVCHOST] Add/complete all missing definitions in the SVCHOST global header. (#4295)
Following commit 24a727a23, give a lift to the SVCHOST global header
and add & complete all the missing definitions.

- Based on https://www.geoffchappell.com/studies/windows/win32/services/svchost/process/globaldata.htm
  from public debug symbols (e.g. svchost, mswsock, w32time, wscsvc...),
  adjust some of our symbols' names.

- Make the header C++-compatible.

- Even if the start/stop RPC server functions return an error code whose
  underlying storage type is a 32-bit long, they don't return an RPC
  status error code, but an NT status. Thus, use the adequate type
  instead.

- The PSVCHOST_STOP_CALLBACK is nothing but a WAITORTIMERCALLBACK function.

- Take the opportunity to fix some of these functions' SAL annotations.

- Remark: "LP" for pointers is old-fashioned Windows, avoid this in NT code.

[MSWSOCK][SECLOGON] Do the minor adjustments. Remove unnecessary function casts.
2022-04-01 04:55:31 +02:00

159 lines
4.3 KiB
C

/*
* 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);
}