xref: /reactos/base/services/rpcss/rpcss_main.c (revision c7bba39a)
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 static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
122 {
123     SERVICE_STATUS status;
124 
125     TRACE( "starting service\n" );
126 
127     if (!RPCSS_Initialize()) return;
128 
129     exit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
130 
131     service_handle = RegisterServiceCtrlHandlerExW( rpcssW, service_handler, NULL );
132     if (!service_handle) return;
133 
134     status.dwServiceType             = SERVICE_WIN32;
135     status.dwCurrentState            = SERVICE_RUNNING;
136     status.dwControlsAccepted        = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
137     status.dwWin32ExitCode           = 0;
138     status.dwServiceSpecificExitCode = 0;
139     status.dwCheckPoint              = 0;
140     status.dwWaitHint                = 10000;
141     SetServiceStatus( service_handle, &status );
142 
143     WaitForSingleObject( exit_event, INFINITE );
144 
145     status.dwCurrentState     = SERVICE_STOPPED;
146     status.dwControlsAccepted = 0;
147     SetServiceStatus( service_handle, &status );
148     TRACE( "service stopped\n" );
149 }
150 
151 int wmain( int argc, WCHAR *argv[] )
152 {
153     static const SERVICE_TABLE_ENTRYW service_table[] =
154     {
155         { rpcssW, ServiceMain },
156         { NULL, NULL }
157     };
158 
159     StartServiceCtrlDispatcherW( service_table );
160     return 0;
161 }
162