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 15 LONG RpcpNumInstances; 16 CRITICAL_SECTION RpcpCriticalSection; 17 18 /* FUNCTIONS *****************************************************************/ 19 20 NTSTATUS 21 NTAPI 22 RpcpInitRpcServer ( 23 VOID 24 ) 25 { 26 /* Clear the reference count and initialize the critical section */ 27 RpcpNumInstances = 0; 28 return RtlInitializeCriticalSection((PVOID)&RpcpCriticalSection); 29 } 30 31 NTSTATUS 32 NTAPI 33 RpcpStopRpcServer ( 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 */ 47 RpcMgmtStopServerListening(NULL); 48 RpcMgmtWaitServerListen(); 49 } 50 51 /* Release the lock and return the unregister result */ 52 LeaveCriticalSection(&RpcpCriticalSection); 53 return I_RpcMapWin32Status(rpcStatus); 54 } 55 56 NTSTATUS 57 NTAPI 58 RpcpStopRpcServerEx ( 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 */ 72 RpcMgmtStopServerListening(NULL); 73 RpcMgmtWaitServerListen(); 74 } 75 76 /* Release the lock and return the unregister result */ 77 LeaveCriticalSection(&RpcpCriticalSection); 78 return I_RpcMapWin32Status(rpcStatus); 79 } 80 81 NTSTATUS 82 NTAPI 83 RpcpAddInterface ( 84 _In_ PCWSTR 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", 102 RPC_C_PROTSEQ_MAX_REQS_DEFAULT, 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 131 RpcpStartRpcServer ( 132 _In_ PCWSTR 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 159