3 * service control manager
5 * ReactOS Operating System
7 * --------------------------------------------------------------------
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this software; see the file COPYING.LIB. If not, write
21 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
27 * - Services.exe is NOT a native application, it is a GUI app.
30 /* INCLUDES *****************************************************************/
32 #define NTOS_MODE_USER
43 /* GLOBALS ******************************************************************/
45 #define PIPE_BUFSIZE 1024
46 #define PIPE_TIMEOUT 1000
49 /* FUNCTIONS *****************************************************************/
52 PrintString(char* fmt,...)
59 vsprintf(buffer, fmt, ap);
62 OutputDebugStringA(buffer);
68 ScmCreateStartEvent(PHANDLE StartEvent)
72 hEvent = CreateEvent(NULL,
75 _T("SvcctrlStartEvent_A3725DX"));
77 if (GetLastError() == ERROR_ALREADY_EXISTS) {
78 hEvent = OpenEvent(EVENT_ALL_ACCESS,
80 _T("SvcctrlStartEvent_A3725DX"));
94 ScmNamedPipeHandleRequest(
100 DbgPrint("SCM READ: %s\n", Request);
109 ScmNamedPipeThread(LPVOID Context)
111 CHAR chRequest[PIPE_BUFSIZE];
112 CHAR chReply[PIPE_BUFSIZE];
119 hPipe = (HANDLE)Context;
121 DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe);
124 fSuccess = ReadFile(hPipe,
129 if (!fSuccess || cbBytesRead == 0) {
132 if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) {
133 fSuccess = WriteFile(hPipe,
138 if (!fSuccess || cbReplyBytes != cbWritten) {
143 DPRINT("ScmNamedPipeThread(%x) - Disconnecting named pipe connection\n", hPipe);
144 FlushFileBuffers(hPipe);
145 DisconnectNamedPipe(hPipe);
147 DPRINT("ScmNamedPipeThread(%x) - Done.\n", hPipe);
148 return ERROR_SUCCESS;
151 BOOL ScmCreateNamedPipe(VOID)
158 DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n");
160 hPipe = CreateNamedPipe("\\\\.\\pipe\\Ntsvcs",
162 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
163 PIPE_UNLIMITED_INSTANCES,
168 if (hPipe == INVALID_HANDLE_VALUE) {
169 DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError());
173 DPRINT("CreateNamedPipe() - calling ConnectNamedPipe(%x)\n", hPipe);
174 fConnected = ConnectNamedPipe(hPipe,
175 NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
176 DPRINT("CreateNamedPipe() - ConnectNamedPipe() returned %d\n", fConnected);
179 DPRINT("Pipe connected\n");
180 hThread = CreateThread(NULL,
187 DPRINT("Could not create thread (%d)\n", GetLastError());
188 DisconnectNamedPipe(hPipe);
190 DPRINT("CreateNamedPipe() - returning FALSE\n");
194 DPRINT("Pipe not connected\n");
196 DPRINT("CreateNamedPipe() - returning FALSE\n");
199 DPRINT("CreateNamedPipe() - returning TRUE\n");
205 ScmNamedPipeListenerThread(LPVOID Context)
208 DPRINT("ScmNamedPipeListenerThread(%x) - aka SCM.\n", Context);
210 // hPipe = (HANDLE)Context;
212 DPRINT("SCM: Waiting for new connection on named pipe...\n");
213 /* Create named pipe */
214 if (!ScmCreateNamedPipe()) {
215 DPRINT1("\nSCM: Failed to create named pipe\n");
219 DPRINT("\nSCM: named pipe session created.\n");
222 DPRINT("\n\nWARNING: ScmNamedPipeListenerThread(%x) - Aborted.\n\n", Context);
223 return ERROR_SUCCESS;
226 BOOL StartScmNamedPipeThreadListener(void)
231 hThread = CreateThread(NULL,
233 ScmNamedPipeListenerThread,
234 NULL, /*(LPVOID)hPipe,*/
239 DPRINT1("SERVICES: Could not create thread (Status %lx)\n", GetLastError());
246 WinMain(HINSTANCE hInstance,
247 HINSTANCE hPrevInstance,
251 HANDLE hScmStartEvent;
255 DPRINT("SERVICES: Service Control Manager\n");
257 /* Create start event */
258 if (!ScmCreateStartEvent(&hScmStartEvent))
260 DPRINT1("SERVICES: Failed to create start event\n");
264 DPRINT("SERVICES: created start event with handle %x.\n", hScmStartEvent);
266 /* FIXME: more initialization */
269 /* Create the service database */
270 Status = ScmCreateServiceDataBase();
271 if (!NT_SUCCESS(Status))
273 DPRINT1("SERVICES: failed to create SCM database (Status %lx)\n", Status);
277 /* Update service database */
278 ScmGetBootAndSystemDriverState();
281 DPRINT("SERVICES: Attempting to create named pipe...\n");
282 /* Create named pipe */
283 if (!ScmCreateNamedPipe()) {
284 DPRINT1("SERVICES: Failed to create named pipe\n");
287 DPRINT("SERVICES: named pipe created successfully.\n");
289 DPRINT("SERVICES: Attempting to create named pipe listener...\n");
290 if (!StartScmNamedPipeThreadListener()) {
291 DPRINT1("SERVICES: Failed to create named pipe listener thread.\n");
294 DPRINT("SERVICES: named pipe listener thread created.\n");
296 /* FIXME: create listener thread for pipe */
299 /* Register service process with CSRSS */
300 RegisterServicesProcess(GetCurrentProcessId());
302 DPRINT("SERVICES: Initialized.\n");
304 /* Signal start event */
305 SetEvent(hScmStartEvent);
307 /* FIXME: register event handler (used for system shutdown) */
308 // SetConsoleCtrlHandler(...);
311 /* Start auto-start services */
312 ScmAutoStartServices();
314 /* FIXME: more to do ? */
317 DPRINT("SERVICES: Running.\n");
320 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
321 WaitForSingleObject(hEvent, INFINITE);
329 DPRINT("SERVICES: Finished.\n");