1 /* 2 * Copyright 2001, Ove Kåven, TransGaming Technologies Inc. 3 * Copyright 2002 Greg Turner 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include <stdio.h> 21 #include <stdarg.h> 22 #include <limits.h> 23 #include <assert.h> 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winnt.h" 28 #include "winsvc.h" 29 #include "irot_s.h" 30 #include "epm_s.h" 31 32 #include "wine/debug.h" 33 34 WINE_DEFAULT_DEBUG_CHANNEL(ole); 35 36 static WCHAR rpcssW[] = {'R','p','c','S','s',0}; 37 static HANDLE exit_event; 38 static SERVICE_STATUS_HANDLE service_handle; 39 40 static BOOL RPCSS_Initialize(void) 41 { 42 static unsigned short irot_protseq[] = IROT_PROTSEQ; 43 static unsigned short irot_endpoint[] = IROT_ENDPOINT; 44 static unsigned short epm_protseq[] = {'n','c','a','c','n','_','n','p',0}; 45 static unsigned short epm_endpoint[] = {'\\','p','i','p','e','\\','e','p','m','a','p','p','e','r',0}; 46 static unsigned short epm_protseq_lrpc[] = {'n','c','a','l','r','p','c',0}; 47 static unsigned short epm_endpoint_lrpc[] = {'e','p','m','a','p','p','e','r',0}; 48 RPC_STATUS status; 49 50 WINE_TRACE("\n"); 51 52 status = RpcServerRegisterIf(epm_v3_0_s_ifspec, NULL, NULL); 53 if (status != RPC_S_OK) 54 return status; 55 status = RpcServerRegisterIf(Irot_v0_2_s_ifspec, NULL, NULL); 56 if (status != RPC_S_OK) 57 { 58 RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, FALSE); 59 return FALSE; 60 } 61 62 status = RpcServerUseProtseqEpW(epm_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT, 63 epm_endpoint, NULL); 64 if (status != RPC_S_OK) 65 goto fail; 66 67 status = RpcServerUseProtseqEpW(epm_protseq_lrpc, RPC_C_PROTSEQ_MAX_REQS_DEFAULT, 68 epm_endpoint_lrpc, NULL); 69 if (status != RPC_S_OK) 70 goto fail; 71 72 status = RpcServerUseProtseqEpW(irot_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT, 73 irot_endpoint, NULL); 74 if (status != RPC_S_OK) 75 goto fail; 76 77 status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE); 78 if (status != RPC_S_OK) 79 goto fail; 80 81 return TRUE; 82 83 fail: 84 RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, FALSE); 85 RpcServerUnregisterIf(Irot_v0_2_s_ifspec, NULL, FALSE); 86 return FALSE; 87 } 88 89 static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context ) 90 { 91 SERVICE_STATUS status; 92 93 status.dwServiceType = SERVICE_WIN32; 94 #ifdef __REACTOS__ 95 status.dwControlsAccepted = 0; 96 #else 97 status.dwControlsAccepted = SERVICE_ACCEPT_STOP; 98 #endif 99 status.dwWin32ExitCode = 0; 100 status.dwServiceSpecificExitCode = 0; 101 status.dwCheckPoint = 0; 102 status.dwWaitHint = 0; 103 104 switch (ctrl) 105 { 106 case SERVICE_CONTROL_STOP: 107 case SERVICE_CONTROL_SHUTDOWN: 108 TRACE( "shutting down\n" ); 109 RpcMgmtStopServerListening( NULL ); 110 RpcServerUnregisterIf( epm_v3_0_s_ifspec, NULL, TRUE ); 111 RpcServerUnregisterIf( Irot_v0_2_s_ifspec, NULL, TRUE ); 112 status.dwCurrentState = SERVICE_STOP_PENDING; 113 status.dwControlsAccepted = 0; 114 SetServiceStatus( service_handle, &status ); 115 SetEvent( exit_event ); 116 return NO_ERROR; 117 default: 118 FIXME( "got service ctrl %x\n", ctrl ); 119 status.dwCurrentState = SERVICE_RUNNING; 120 SetServiceStatus( service_handle, &status ); 121 return NO_ERROR; 122 } 123 } 124 125 #ifdef __REACTOS__ 126 extern VOID DoRpcSsSetupConfiguration(VOID); 127 #endif 128 129 static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv ) 130 { 131 SERVICE_STATUS status; 132 133 TRACE( "starting service\n" ); 134 135 if (!RPCSS_Initialize()) return; 136 137 exit_event = CreateEventW( NULL, TRUE, FALSE, NULL ); 138 139 service_handle = RegisterServiceCtrlHandlerExW( rpcssW, service_handler, NULL ); 140 if (!service_handle) return; 141 142 status.dwServiceType = SERVICE_WIN32; 143 status.dwCurrentState = SERVICE_RUNNING; 144 #ifdef __REACTOS__ 145 status.dwControlsAccepted = 0; 146 #else 147 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 148 #endif 149 status.dwWin32ExitCode = 0; 150 status.dwServiceSpecificExitCode = 0; 151 status.dwCheckPoint = 0; 152 #ifdef __REACTOS__ 153 status.dwWaitHint = 0; 154 #else 155 status.dwWaitHint = 10000; 156 #endif 157 SetServiceStatus( service_handle, &status ); 158 159 #ifdef __REACTOS__ 160 DoRpcSsSetupConfiguration(); 161 #endif 162 163 WaitForSingleObject( exit_event, INFINITE ); 164 165 status.dwCurrentState = SERVICE_STOPPED; 166 status.dwControlsAccepted = 0; 167 SetServiceStatus( service_handle, &status ); 168 TRACE( "service stopped\n" ); 169 } 170 171 int wmain( int argc, WCHAR *argv[] ) 172 { 173 static const SERVICE_TABLE_ENTRYW service_table[] = 174 { 175 { rpcssW, ServiceMain }, 176 { NULL, NULL } 177 }; 178 179 StartServiceCtrlDispatcherW( service_table ); 180 return 0; 181 } 182