2 * Copyright 2001, Ove Kåven, TransGaming Technologies Inc.
3 * Copyright 2002 Greg Turner
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.
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.
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
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
37 static WCHAR rpcssW
[] = {'R','p','c','S','s',0};
38 static HANDLE exit_event
;
39 static SERVICE_STATUS_HANDLE service_handle
;
41 HRESULT __cdecl
irpcss_get_thread_seq_id(handle_t h
, DWORD
*id
)
43 static LONG thread_seq_id
;
44 *id
= InterlockedIncrement(&thread_seq_id
);
48 static RPC_STATUS
RPCSS_Initialize(void)
50 static unsigned short irot_protseq
[] = IROT_PROTSEQ
;
51 static unsigned short irot_endpoint
[] = IROT_ENDPOINT
;
52 static unsigned short epm_protseq
[] = {'n','c','a','c','n','_','n','p',0};
53 static unsigned short epm_endpoint
[] = {'\\','p','i','p','e','\\','e','p','m','a','p','p','e','r',0};
54 static unsigned short epm_protseq_lrpc
[] = {'n','c','a','l','r','p','c',0};
55 static unsigned short epm_endpoint_lrpc
[] = {'e','p','m','a','p','p','e','r',0};
56 static unsigned short irpcss_protseq
[] = IRPCSS_PROTSEQ
;
57 static unsigned short irpcss_endpoint
[] = IRPCSS_ENDPOINT
;
58 static const struct protseq_map
60 unsigned short *protseq
;
61 unsigned short *endpoint
;
64 { epm_protseq
, epm_endpoint
},
65 { epm_protseq_lrpc
, epm_endpoint_lrpc
},
66 { irot_protseq
, irot_endpoint
},
67 { irpcss_protseq
, irpcss_endpoint
},
69 RPC_IF_HANDLE ifspecs
[] =
80 for (i
= 0, j
= 0; i
< ARRAY_SIZE(ifspecs
); ++i
, j
= i
)
82 status
= RpcServerRegisterIf(ifspecs
[i
], NULL
, NULL
);
83 if (status
!= RPC_S_OK
)
87 for (i
= 0; i
< ARRAY_SIZE(protseqs
); ++i
)
89 status
= RpcServerUseProtseqEpW(protseqs
[i
].protseq
, RPC_C_PROTSEQ_MAX_REQS_DEFAULT
,
90 protseqs
[i
].endpoint
, NULL
);
91 if (status
!= RPC_S_OK
)
95 status
= RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, TRUE
);
96 if (status
!= RPC_S_OK
)
102 for (i
= 0; i
< j
; ++i
)
103 RpcServerUnregisterIf(ifspecs
[i
], NULL
, FALSE
);
108 static DWORD WINAPI
service_handler( DWORD ctrl
, DWORD event_type
, LPVOID event_data
, LPVOID context
)
110 SERVICE_STATUS status
;
112 status
.dwServiceType
= SERVICE_WIN32
;
113 status
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
;
114 status
.dwWin32ExitCode
= 0;
115 status
.dwServiceSpecificExitCode
= 0;
116 status
.dwCheckPoint
= 0;
117 status
.dwWaitHint
= 0;
121 case SERVICE_CONTROL_STOP
:
122 case SERVICE_CONTROL_SHUTDOWN
:
123 TRACE( "shutting down\n" );
124 RpcMgmtStopServerListening( NULL
);
125 RpcServerUnregisterIf( epm_v3_0_s_ifspec
, NULL
, TRUE
);
126 RpcServerUnregisterIf( Irot_v0_2_s_ifspec
, NULL
, TRUE
);
127 status
.dwCurrentState
= SERVICE_STOP_PENDING
;
128 status
.dwControlsAccepted
= 0;
129 SetServiceStatus( service_handle
, &status
);
130 SetEvent( exit_event
);
133 FIXME( "got service ctrl %x\n", ctrl
);
134 status
.dwCurrentState
= SERVICE_RUNNING
;
135 SetServiceStatus( service_handle
, &status
);
140 static void WINAPI
ServiceMain( DWORD argc
, LPWSTR
*argv
)
142 SERVICE_STATUS status
;
145 TRACE( "starting service\n" );
147 if ((ret
= RPCSS_Initialize()))
149 WARN("Failed to initialize rpc interfaces, status %d.\n", ret
);
153 exit_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
155 service_handle
= RegisterServiceCtrlHandlerExW( rpcssW
, service_handler
, NULL
);
156 if (!service_handle
) return;
158 status
.dwServiceType
= SERVICE_WIN32
;
159 status
.dwCurrentState
= SERVICE_RUNNING
;
160 status
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
| SERVICE_ACCEPT_SHUTDOWN
;
161 status
.dwWin32ExitCode
= 0;
162 status
.dwServiceSpecificExitCode
= 0;
163 status
.dwCheckPoint
= 0;
164 status
.dwWaitHint
= 10000;
165 SetServiceStatus( service_handle
, &status
);
167 WaitForSingleObject( exit_event
, INFINITE
);
169 status
.dwCurrentState
= SERVICE_STOPPED
;
170 status
.dwControlsAccepted
= 0;
171 SetServiceStatus( service_handle
, &status
);
172 TRACE( "service stopped\n" );
175 int __cdecl
wmain( int argc
, WCHAR
*argv
[] )
177 static const SERVICE_TABLE_ENTRYW service_table
[] =
179 { rpcssW
, ServiceMain
},
183 StartServiceCtrlDispatcherW( service_table
);