ReactOS  0.4.12-dev-18-gf469aca
rpcsrv.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Service Host
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: base/services/svchost/rpcsrv.c
5  * PURPOSE: RPC Service Support
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "svchost.h"
12 
13 /* GLOBALS *******************************************************************/
14 
17 
18 /* FUNCTIONS *****************************************************************/
19 
21 NTAPI
23  VOID
24  )
25 {
26  /* Clear the reference count and initialize the critical section */
27  RpcpNumInstances = 0;
28  return RtlInitializeCriticalSection((PVOID)&RpcpCriticalSection);
29 }
30 
32 NTAPI
34  _In_ RPC_IF_HANDLE IfSpec
35  )
36 {
37  RPC_STATUS rpcStatus;
38 
39  /* Unregister the interface */
40  rpcStatus = RpcServerUnregisterIf(IfSpec, NULL, TRUE);
41 
42  /* Acquire the lock while we dereference the RPC services */
43  EnterCriticalSection(&RpcpCriticalSection);
44  if (--RpcpNumInstances == 0)
45  {
46  /* All RPC services stopped, rundown the server */
49  }
50 
51  /* Release the lock and return the unregister result */
52  LeaveCriticalSection(&RpcpCriticalSection);
53  return I_RpcMapWin32Status(rpcStatus);
54 }
55 
57 NTAPI
59  _In_ RPC_IF_HANDLE IfSpec
60  )
61 {
62  RPC_STATUS rpcStatus;
63 
64  /* Unregister the interface */
65  rpcStatus = RpcServerUnregisterIfEx(IfSpec, NULL, TRUE);
66 
67  /* Acquire the lock while we dereference the RPC services */
68  EnterCriticalSection(&RpcpCriticalSection);
69  if (--RpcpNumInstances == 0)
70  {
71  /* All RPC services stopped, rundown the server */
74  }
75 
76  /* Release the lock and return the unregister result */
77  LeaveCriticalSection(&RpcpCriticalSection);
78  return I_RpcMapWin32Status(rpcStatus);
79 }
80 
82 NTAPI
84  _In_ LPCWSTR IfName,
85  _In_ RPC_IF_HANDLE IfSpec
86  )
87 {
88  PWCHAR endpointName;
89  NTSTATUS ntStatus;
90  RPC_STATUS rpcStatus;
91 
92  /* Allocate space for the interface name and the \\PIPE\\ prefix */
93  endpointName = LocalAlloc(0, sizeof(WCHAR) * wcslen(IfName) + 16);
94  if (endpointName)
95  {
96  /* Copy the prefix, and then the interface name */
97  wcscpy(endpointName, L"\\PIPE\\");
98  wcscat(endpointName, IfName);
99 
100  /* Create a named pipe endpoint with this name */
101  rpcStatus = RpcServerUseProtseqEpW(L"ncacn_np",
103  endpointName, NULL);
104  if ((rpcStatus != RPC_S_OK) && (rpcStatus != RPC_S_DUPLICATE_ENDPOINT))
105  {
106  /* We couldn't create it, or it already existed... */
107  DbgPrint("RpcServerUseProtseqW failed! rpcstatus = %u\n", rpcStatus);
108  }
109  else
110  {
111  /* It worked, register an interface on this endpoint now */
112  rpcStatus = RpcServerRegisterIf(IfSpec, 0, 0);
113  }
114 
115  /* In both success and failure, free the name, and convert the status */
116  LocalFree(endpointName);
117  ntStatus = I_RpcMapWin32Status(rpcStatus);
118  }
119  else
120  {
121  /* No memory, bail out */
122  ntStatus = STATUS_NO_MEMORY;
123  }
124 
125  /* Return back to the caller */
126  return ntStatus;
127 }
128 
129 NTSTATUS
130 NTAPI
132  _In_ LPCWSTR IfName,
133  _In_ RPC_IF_HANDLE IfSpec
134  )
135 {
136  NTSTATUS ntStatus;
137 
138  /* Acquire the lock while we instantiate a new interface */
139  EnterCriticalSection(&RpcpCriticalSection);
140 
141  /* Add this interface to the service */
142  ntStatus = RpcpAddInterface(IfName, IfSpec);
143  if (!ntStatus)
144  {
145  /* Increment the reference count to see if this was the first interface */
146  if (++RpcpNumInstances == 1)
147  {
148  /* It was, so put the server into listening mode now */
149  ntStatus = RpcServerListen(1, 12345, TRUE);
150  if (ntStatus == RPC_S_ALREADY_LISTENING) ntStatus = STATUS_SUCCESS;
151  }
152  }
153 
154  /* Release the lock and return back the result to the caller */
155  LeaveCriticalSection(&RpcpCriticalSection);
156  return I_RpcMapWin32Status(ntStatus);
157 }
158 
NTSTATUS NTAPI RpcpStartRpcServer(_In_ LPCWSTR IfName, _In_ RPC_IF_HANDLE IfSpec)
Definition: rpcsrv.c:131
#define TRUE
Definition: types.h:120
RPC_STATUS WINAPI RpcMgmtStopServerListening(RPC_BINDING_HANDLE Binding)
Definition: rpc_server.c:1599
#define DbgPrint
Definition: loader.c:25
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI RpcpAddInterface(_In_ LPCWSTR IfName, _In_ RPC_IF_HANDLE IfSpec)
Definition: rpcsrv.c:83
LONG NTSTATUS
Definition: precomp.h:26
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
LONG RpcpNumInstances
Definition: rpcsrv.c:15
NTSTATUS NTAPI RpcpInitRpcServer(VOID)
Definition: rpcsrv.c:22
uint16_t * PWCHAR
Definition: typedefs.h:54
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
RPC_STATUS WINAPI RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, UINT WaitForCallsToComplete)
Definition: rpc_server.c:1209
long RPC_STATUS
Definition: rpc.h:52
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1527
RPC_STATUS WINAPI RpcServerUnregisterIfEx(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, int RundownContextHandles)
Definition: rpc_server.c:1260
smooth NULL
Definition: ftsmooth.c:416
#define RPC_S_DUPLICATE_ENDPOINT
Definition: winerror.h:1048
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1123
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
NTSTATUS NTAPI RpcpStopRpcServerEx(_In_ RPC_IF_HANDLE IfSpec)
Definition: rpcsrv.c:58
static const WCHAR L[]
Definition: oid.c:1087
#define RPC_S_ALREADY_LISTENING
Definition: winerror.h:1024
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:934
#define _In_
Definition: no_sal2.h:204
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSTATUS NTAPI RpcpStopRpcServer(_In_ RPC_IF_HANDLE IfSpec)
Definition: rpcsrv.c:33
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define RPC_C_PROTSEQ_MAX_REQS_DEFAULT
Definition: rpcdce.h:123
CRITICAL_SECTION RpcpCriticalSection
Definition: rpcsrv.c:16
RPC_STATUS WINAPI RpcMgmtWaitServerListen(void)
Definition: rpc_server.c:1546
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
return STATUS_SUCCESS
Definition: btrfs.c:2710
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RPC_S_OK
Definition: rpcnterr.h:22
LONG WINAPI I_RpcMapWin32Status(RPC_STATUS status)
Definition: rpcrt4_main.c:741