2 * service control manager
4 * ReactOS Operating System
6 * --------------------------------------------------------------------
8 * This software is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This software is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this software; see the file COPYING.LIB. If not, write
20 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
26 * - Services.exe is NOT a native application, it is a GUI app.
29 /* INCLUDES *****************************************************************/
36 int WINAPI
RegisterServicesProcess(DWORD ServicesProcessId
);
38 /* GLOBALS ******************************************************************/
40 #define PIPE_BUFSIZE 1024
41 #define PIPE_TIMEOUT 1000
43 BOOL ScmShutdown
= FALSE
;
46 /* FUNCTIONS *****************************************************************/
49 PrintString(LPCSTR fmt
, ...)
56 vsprintf(buffer
, fmt
, ap
);
59 OutputDebugStringA(buffer
);
65 ScmCreateStartEvent(PHANDLE StartEvent
)
69 hEvent
= CreateEvent(NULL
,
72 TEXT("SvcctrlStartEvent_A3752DX"));
75 if (GetLastError() == ERROR_ALREADY_EXISTS
)
77 hEvent
= OpenEvent(EVENT_ALL_ACCESS
,
79 TEXT("SvcctrlStartEvent_A3752DX"));
97 BOOL
ScmWaitForEvent()
101 hEvent
= OpenEvent(EVENT_ALL_ACCESS
,
103 TEXT("SvcctrlStartEvent_A3752DX"));
107 DWORD ret
= WaitForSingleObject(hEvent
,
110 if (ret
== WAIT_OBJECT_0
)
119 ScmNamedPipeHandleRequest(PVOID Request
,
124 DbgPrint("SCM READ: %s\n", Request
);
132 ScmNamedPipeThread(LPVOID Context
)
134 CHAR chRequest
[PIPE_BUFSIZE
];
135 CHAR chReply
[PIPE_BUFSIZE
];
142 hPipe
= (HANDLE
)Context
;
144 DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe
);
148 bSuccess
= ReadFile(hPipe
,
153 if (!bSuccess
|| cbBytesRead
== 0)
158 if (ScmNamedPipeHandleRequest(&chRequest
, cbBytesRead
, &chReply
, &cbReplyBytes
))
160 bSuccess
= WriteFile(hPipe
,
165 if (!bSuccess
|| cbReplyBytes
!= cbWritten
)
172 DPRINT("ScmNamedPipeThread(%x) - Disconnecting named pipe connection\n", hPipe
);
174 FlushFileBuffers(hPipe
);
175 DisconnectNamedPipe(hPipe
);
178 DPRINT("ScmNamedPipeThread(%x) - Done.\n", hPipe
);
180 return ERROR_SUCCESS
;
185 ScmCreateNamedPipe(VOID
)
192 DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n");
194 hPipe
= CreateNamedPipe(TEXT("\\\\.\\pipe\\Ntsvcs"),
196 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
197 PIPE_UNLIMITED_INSTANCES
,
202 if (hPipe
== INVALID_HANDLE_VALUE
)
204 DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError());
208 DPRINT("CreateNamedPipe() - calling ConnectNamedPipe(%x)\n", hPipe
);
209 bConnected
= ConnectNamedPipe(hPipe
,
210 NULL
) ? TRUE
: (GetLastError() == ERROR_PIPE_CONNECTED
);
211 DPRINT("CreateNamedPipe() - ConnectNamedPipe() returned %d\n", bConnected
);
215 DPRINT("Pipe connected\n");
216 hThread
= CreateThread(NULL
,
224 DPRINT("Could not create thread (%d)\n", GetLastError());
225 DisconnectNamedPipe(hPipe
);
227 DPRINT("CreateNamedPipe() - returning FALSE\n");
233 DPRINT("Pipe not connected\n");
235 DPRINT("CreateNamedPipe() - returning FALSE\n");
238 DPRINT("CreateNamedPipe() - returning TRUE\n");
244 ScmNamedPipeListenerThread(LPVOID Context
)
247 DPRINT("ScmNamedPipeListenerThread(%x) - aka SCM.\n", Context
);
249 // hPipe = (HANDLE)Context;
252 DPRINT("SCM: Waiting for new connection on named pipe...\n");
253 /* Create named pipe */
254 if (!ScmCreateNamedPipe())
256 DPRINT1("\nSCM: Failed to create named pipe\n");
260 DPRINT("\nSCM: named pipe session created.\n");
263 DPRINT("\n\nWARNING: ScmNamedPipeListenerThread(%x) - Aborted.\n\n", Context
);
264 return ERROR_SUCCESS
;
269 StartScmNamedPipeThreadListener(VOID
)
274 hThread
= CreateThread(NULL
,
276 ScmNamedPipeListenerThread
,
277 NULL
, /*(LPVOID)hPipe,*/
282 DPRINT1("SERVICES: Could not create thread (Status %lx)\n", GetLastError());
291 AcquireLoadDriverPrivilege(VOID
)
294 TOKEN_PRIVILEGES tkp
;
296 /* Get a token for this process */
297 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, &hToken
))
299 /* Get the LUID for the debug privilege */
300 LookupPrivilegeValue(NULL
, SE_LOAD_DRIVER_NAME
, &tkp
.Privileges
[0].Luid
);
302 /* One privilege to set */
303 tkp
.PrivilegeCount
= 1;
304 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
306 /* Get the debug privilege for this process */
307 AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0, (PTOKEN_PRIVILEGES
)NULL
, 0);
313 ShutdownHandlerRoutine(DWORD dwCtrlType
)
315 DPRINT1("ShutdownHandlerRoutine() called\n");
317 if (dwCtrlType
== CTRL_SHUTDOWN_EVENT
)
319 DPRINT1("Shutdown event received!\n");
322 /* FIXME: Shut all services down */
330 WinMain(HINSTANCE hInstance
,
331 HINSTANCE hPrevInstance
,
335 HANDLE hScmStartEvent
;
339 DPRINT("SERVICES: Service Control Manager\n");
341 /* Acquire privileges to load drivers */
342 AcquireLoadDriverPrivilege();
344 /* Create start event */
345 if (!ScmCreateStartEvent(&hScmStartEvent
))
347 DPRINT1("SERVICES: Failed to create start event\n");
351 DPRINT("SERVICES: created start event with handle %x.\n", hScmStartEvent
);
353 // ScmInitThreadManager();
355 /* FIXME: more initialization */
358 /* Create the service database */
359 dwError
= ScmCreateServiceDatabase();
360 if (dwError
!= ERROR_SUCCESS
)
362 DPRINT1("SERVICES: failed to create SCM database (Error %lu)\n", dwError
);
366 /* Update service database */
367 ScmGetBootAndSystemDriverState();
369 /* Start the RPC server */
372 /* Register service process with CSRSS */
373 RegisterServicesProcess(GetCurrentProcessId());
375 DPRINT("SERVICES: Initialized.\n");
377 /* Signal start event */
378 SetEvent(hScmStartEvent
);
380 /* Register event handler (used for system shutdown) */
381 SetConsoleCtrlHandler(ShutdownHandlerRoutine
, TRUE
);
383 /* Start auto-start services */
384 ScmAutoStartServices();
386 /* FIXME: more to do ? */
389 DPRINT("SERVICES: Running.\n");
392 hEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
394 WaitForSingleObject(hEvent
, INFINITE
);
402 DPRINT("SERVICES: Finished.\n");