[RPCSS] During the setup phase, the RPCSS service, initially running under the LocalS...
[reactos.git] / base / services / rpcss / rpcss_main.c
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 status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
95 status.dwWin32ExitCode = 0;
96 status.dwServiceSpecificExitCode = 0;
97 status.dwCheckPoint = 0;
98 status.dwWaitHint = 0;
99
100 switch (ctrl)
101 {
102 case SERVICE_CONTROL_STOP:
103 case SERVICE_CONTROL_SHUTDOWN:
104 TRACE( "shutting down\n" );
105 RpcMgmtStopServerListening( NULL );
106 RpcServerUnregisterIf( epm_v3_0_s_ifspec, NULL, TRUE );
107 RpcServerUnregisterIf( Irot_v0_2_s_ifspec, NULL, TRUE );
108 status.dwCurrentState = SERVICE_STOP_PENDING;
109 status.dwControlsAccepted = 0;
110 SetServiceStatus( service_handle, &status );
111 SetEvent( exit_event );
112 return NO_ERROR;
113 default:
114 FIXME( "got service ctrl %x\n", ctrl );
115 status.dwCurrentState = SERVICE_RUNNING;
116 SetServiceStatus( service_handle, &status );
117 return NO_ERROR;
118 }
119 }
120
121 #ifdef __REACTOS__
122 extern VOID DoRpcSsSetupConfiguration(VOID);
123 #endif
124
125 static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
126 {
127 SERVICE_STATUS status;
128
129 TRACE( "starting service\n" );
130
131 if (!RPCSS_Initialize()) return;
132
133 exit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
134
135 service_handle = RegisterServiceCtrlHandlerExW( rpcssW, service_handler, NULL );
136 if (!service_handle) return;
137
138 status.dwServiceType = SERVICE_WIN32;
139 status.dwCurrentState = SERVICE_RUNNING;
140 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
141 status.dwWin32ExitCode = 0;
142 status.dwServiceSpecificExitCode = 0;
143 status.dwCheckPoint = 0;
144 status.dwWaitHint = 10000;
145 SetServiceStatus( service_handle, &status );
146
147 #ifdef __REACTOS__
148 DoRpcSsSetupConfiguration();
149 #endif
150
151 WaitForSingleObject( exit_event, INFINITE );
152
153 status.dwCurrentState = SERVICE_STOPPED;
154 status.dwControlsAccepted = 0;
155 SetServiceStatus( service_handle, &status );
156 TRACE( "service stopped\n" );
157 }
158
159 int wmain( int argc, WCHAR *argv[] )
160 {
161 static const SERVICE_TABLE_ENTRYW service_table[] =
162 {
163 { rpcssW, ServiceMain },
164 { NULL, NULL }
165 };
166
167 StartServiceCtrlDispatcherW( service_table );
168 return 0;
169 }