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
44 /* GLOBALS ******************************************************************/
46 #define PIPE_BUFSIZE 1024
47 #define PIPE_TIMEOUT 1000
50 /* FUNCTIONS *****************************************************************/
53 PrintString(char* fmt,...)
60 vsprintf(buffer, fmt, ap);
63 OutputDebugStringA(buffer);
69 ScmCreateStartEvent(PHANDLE StartEvent)
73 hEvent = CreateEvent(NULL,
76 _T("SvcctrlStartEvent_A3725DX"));
78 if (GetLastError() == ERROR_ALREADY_EXISTS) {
79 hEvent = OpenEvent(EVENT_ALL_ACCESS,
81 _T("SvcctrlStartEvent_A3725DX"));
95 ScmNamedPipeHandleRequest(
101 DbgPrint("SCM READ: %s\n", Request);
110 ScmNamedPipeThread(LPVOID Context)
112 CHAR chRequest[PIPE_BUFSIZE];
113 CHAR chReply[PIPE_BUFSIZE];
120 hPipe = (HANDLE)Context;
122 DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe);
125 fSuccess = ReadFile(hPipe,
130 if (!fSuccess || cbBytesRead == 0) {
133 if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) {
134 fSuccess = WriteFile(hPipe,
139 if (!fSuccess || cbReplyBytes != cbWritten) {
144 DPRINT("ScmNamedPipeThread(%x) - Disconnecting named pipe connection\n", hPipe);
145 FlushFileBuffers(hPipe);
146 DisconnectNamedPipe(hPipe);
148 DPRINT("ScmNamedPipeThread(%x) - Done.\n", hPipe);
149 return ERROR_SUCCESS;
152 BOOL ScmCreateNamedPipe(VOID)
159 DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n");
161 hPipe = CreateNamedPipe("\\\\.\\pipe\\Ntsvcs",
163 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
164 PIPE_UNLIMITED_INSTANCES,
169 if (hPipe == INVALID_HANDLE_VALUE) {
170 DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError());
174 DPRINT("CreateNamedPipe() - calling ConnectNamedPipe(%x)\n", hPipe);
175 fConnected = ConnectNamedPipe(hPipe,
176 NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
177 DPRINT("CreateNamedPipe() - ConnectNamedPipe() returned %d\n", fConnected);
180 DPRINT("Pipe connected\n");
181 hThread = CreateThread(NULL,
188 DPRINT("Could not create thread (%d)\n", GetLastError());
189 DisconnectNamedPipe(hPipe);
191 DPRINT("CreateNamedPipe() - returning FALSE\n");
195 DPRINT("Pipe not connected\n");
197 DPRINT("CreateNamedPipe() - returning FALSE\n");
200 DPRINT("CreateNamedPipe() - returning TRUE\n");
206 ScmNamedPipeListenerThread(LPVOID Context)
209 DPRINT("ScmNamedPipeListenerThread(%x) - aka SCM.\n", Context);
211 // hPipe = (HANDLE)Context;
213 PrintString("SCM: Waiting for new connection on named pipe...\n");
214 /* Create named pipe */
215 if (!ScmCreateNamedPipe()) {
216 PrintString("\nSCM: Failed to create named pipe\n");
220 PrintString("\nSCM: named pipe session created.\n");
223 DPRINT("\n\nWARNING: ScmNamedPipeListenerThread(%x) - Aborted.\n\n", Context);
224 return ERROR_SUCCESS;
227 BOOL StartScmNamedPipeThreadListener(void)
232 hThread = CreateThread(NULL,
234 ScmNamedPipeListenerThread,
235 NULL, /*(LPVOID)hPipe,*/
240 PrintString("SERVICES: Could not create thread (Status %lx)\n", GetLastError());
247 WinMain(HINSTANCE hInstance,
248 HINSTANCE hPrevInstance,
252 HANDLE hScmStartEvent;
256 PrintString("SERVICES: Service Control Manager\n");
258 /* Create start event */
259 if (!ScmCreateStartEvent(&hScmStartEvent))
261 PrintString("SERVICES: Failed to create start event\n");
265 PrintString("SERVICES: created start event with handle %x.\n", hScmStartEvent);
267 /* FIXME: more initialization */
270 /* Create the service database */
271 Status = ScmCreateServiceDataBase();
272 if (!NT_SUCCESS(Status))
274 PrintString("SERVICES: failed to create SCM database (Status %lx)\n", Status);
278 /* Update service database */
279 ScmGetBootAndSystemDriverState();
282 PrintString("SERVICES: Attempting to create named pipe...\n");
283 /* Create named pipe */
284 if (!ScmCreateNamedPipe()) {
285 PrintString("SERVICES: Failed to create named pipe\n");
288 PrintString("SERVICES: named pipe created successfully.\n");
290 PrintString("SERVICES: Attempting to create named pipe listener...\n");
291 if (!StartScmNamedPipeThreadListener()) {
292 PrintString("SERVICES: Failed to create named pipe listener thread.\n");
295 PrintString("SERVICES: named pipe listener thread created.\n");
297 /* FIXME: create listener thread for pipe */
300 /* Register service process with CSRSS */
301 RegisterServicesProcess(GetCurrentProcessId());
303 PrintString("SERVICES: Initialized.\n");
305 /* Signal start event */
306 SetEvent(hScmStartEvent);
308 /* FIXME: register event handler (used for system shutdown) */
309 // SetConsoleCtrlHandler(...);
312 /* Start auto-start services */
313 ScmAutoStartServices();
315 /* FIXME: more to do ? */
318 PrintString("SERVICES: Running.\n");
321 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
322 WaitForSingleObject(hEvent, INFINITE);
330 PrintString("SERVICES: Finished.\n");