Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenservices.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Service Control Manager 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: base/system/services/services.c 00005 * PURPOSE: Main SCM controller 00006 * COPYRIGHT: Copyright 2001-2005 Eric Kohl 00007 * Copyright 2007 Ged Murphy <gedmurphy@reactos.org> 00008 * 00009 */ 00010 00011 /* NOTE: 00012 * - Services.exe is NOT a native application, it is a GUI app. 00013 */ 00014 00015 /* INCLUDES *****************************************************************/ 00016 00017 #include "services.h" 00018 00019 #define NDEBUG 00020 #include <debug.h> 00021 00022 int WINAPI RegisterServicesProcess(DWORD ServicesProcessId); 00023 00024 /* GLOBALS ******************************************************************/ 00025 00026 #define PIPE_BUFSIZE 1024 00027 #define PIPE_TIMEOUT 1000 00028 00029 BOOL ScmShutdown = FALSE; 00030 static HANDLE hScmShutdownEvent = NULL; 00031 00032 00033 /* FUNCTIONS *****************************************************************/ 00034 00035 VOID 00036 PrintString(LPCSTR fmt, ...) 00037 { 00038 #if DBG 00039 CHAR buffer[512]; 00040 va_list ap; 00041 00042 va_start(ap, fmt); 00043 vsprintf(buffer, fmt, ap); 00044 va_end(ap); 00045 00046 OutputDebugStringA(buffer); 00047 #endif 00048 } 00049 00050 00051 VOID 00052 ScmLogError(DWORD dwEventId, 00053 WORD wStrings, 00054 LPCWSTR *lpStrings) 00055 { 00056 HANDLE hLog; 00057 00058 hLog = RegisterEventSourceW(NULL, 00059 L"Service Control Manager"); 00060 if (hLog == NULL) 00061 { 00062 DPRINT1("ScmLogEvent: RegisterEventSourceW failed %d\n", GetLastError()); 00063 return; 00064 } 00065 00066 if (!ReportEventW(hLog, 00067 EVENTLOG_ERROR_TYPE, 00068 0, 00069 dwEventId, 00070 NULL, // Sid, 00071 wStrings, 00072 0, 00073 lpStrings, 00074 NULL)) 00075 { 00076 DPRINT1("ScmLogEvent: ReportEventW failed %d\n", GetLastError()); 00077 } 00078 00079 DeregisterEventSource(hLog); 00080 } 00081 00082 00083 BOOL 00084 ScmCreateStartEvent(PHANDLE StartEvent) 00085 { 00086 HANDLE hEvent; 00087 00088 hEvent = CreateEvent(NULL, 00089 TRUE, 00090 FALSE, 00091 TEXT("SvcctrlStartEvent_A3752DX")); 00092 if (hEvent == NULL) 00093 { 00094 if (GetLastError() == ERROR_ALREADY_EXISTS) 00095 { 00096 hEvent = OpenEvent(EVENT_ALL_ACCESS, 00097 FALSE, 00098 TEXT("SvcctrlStartEvent_A3752DX")); 00099 if (hEvent == NULL) 00100 { 00101 return FALSE; 00102 } 00103 } 00104 else 00105 { 00106 return FALSE; 00107 } 00108 } 00109 00110 *StartEvent = hEvent; 00111 00112 return TRUE; 00113 } 00114 00115 00116 static VOID 00117 ScmWaitForLsass(VOID) 00118 { 00119 HANDLE hEvent; 00120 DWORD dwError; 00121 00122 hEvent = CreateEventW(NULL, 00123 TRUE, 00124 FALSE, 00125 L"LSA_RPC_SERVER_ACTIVE"); 00126 if (hEvent == NULL) 00127 { 00128 dwError = GetLastError(); 00129 DPRINT("Failed to create the notication event (Error %lu)\n", dwError); 00130 00131 if (dwError == ERROR_ALREADY_EXISTS) 00132 { 00133 hEvent = OpenEventW(SYNCHRONIZE, 00134 FALSE, 00135 L"LSA_RPC_SERVER_ACTIVE"); 00136 if (hEvent == NULL) 00137 { 00138 DPRINT1("Could not open the notification event (Error %lu)\n", GetLastError()); 00139 return; 00140 } 00141 } 00142 } 00143 00144 DPRINT("Wait for the LSA server!\n"); 00145 WaitForSingleObject(hEvent, INFINITE); 00146 DPRINT("LSA server running!\n"); 00147 00148 CloseHandle(hEvent); 00149 } 00150 00151 00152 BOOL 00153 ScmNamedPipeHandleRequest(PVOID Request, 00154 DWORD RequestSize, 00155 PVOID Reply, 00156 LPDWORD ReplySize) 00157 { 00158 DbgPrint("SCM READ: %s\n", Request); 00159 00160 *ReplySize = 0; 00161 return FALSE; 00162 } 00163 00164 00165 DWORD WINAPI 00166 ScmNamedPipeThread(LPVOID Context) 00167 { 00168 CHAR chRequest[PIPE_BUFSIZE]; 00169 CHAR chReply[PIPE_BUFSIZE]; 00170 DWORD cbReplyBytes; 00171 DWORD cbBytesRead; 00172 DWORD cbWritten; 00173 BOOL bSuccess; 00174 HANDLE hPipe; 00175 00176 hPipe = (HANDLE)Context; 00177 00178 DPRINT("ScmNamedPipeThread(%x) - Accepting SCM commands through named pipe\n", hPipe); 00179 00180 for (;;) 00181 { 00182 bSuccess = ReadFile(hPipe, 00183 &chRequest, 00184 PIPE_BUFSIZE, 00185 &cbBytesRead, 00186 NULL); 00187 if (!bSuccess || cbBytesRead == 0) 00188 { 00189 break; 00190 } 00191 00192 if (ScmNamedPipeHandleRequest(&chRequest, cbBytesRead, &chReply, &cbReplyBytes)) 00193 { 00194 bSuccess = WriteFile(hPipe, 00195 &chReply, 00196 cbReplyBytes, 00197 &cbWritten, 00198 NULL); 00199 if (!bSuccess || cbReplyBytes != cbWritten) 00200 { 00201 break; 00202 } 00203 } 00204 } 00205 00206 DPRINT("ScmNamedPipeThread(%x) - Disconnecting named pipe connection\n", hPipe); 00207 00208 FlushFileBuffers(hPipe); 00209 DisconnectNamedPipe(hPipe); 00210 CloseHandle(hPipe); 00211 00212 DPRINT("ScmNamedPipeThread(%x) - Done.\n", hPipe); 00213 00214 return ERROR_SUCCESS; 00215 } 00216 00217 00218 BOOL 00219 ScmCreateNamedPipe(VOID) 00220 { 00221 DWORD dwThreadId; 00222 BOOL bConnected; 00223 HANDLE hThread; 00224 HANDLE hPipe; 00225 00226 DPRINT("ScmCreateNamedPipe() - CreateNamedPipe(\"\\\\.\\pipe\\Ntsvcs\")\n"); 00227 00228 hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Ntsvcs"), 00229 PIPE_ACCESS_DUPLEX, 00230 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 00231 PIPE_UNLIMITED_INSTANCES, 00232 PIPE_BUFSIZE, 00233 PIPE_BUFSIZE, 00234 PIPE_TIMEOUT, 00235 NULL); 00236 if (hPipe == INVALID_HANDLE_VALUE) 00237 { 00238 DPRINT("CreateNamedPipe() failed (%d)\n", GetLastError()); 00239 return FALSE; 00240 } 00241 00242 DPRINT("CreateNamedPipe() - calling ConnectNamedPipe(%x)\n", hPipe); 00243 bConnected = ConnectNamedPipe(hPipe, 00244 NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 00245 DPRINT("CreateNamedPipe() - ConnectNamedPipe() returned %d\n", bConnected); 00246 00247 if (bConnected) 00248 { 00249 DPRINT("Pipe connected\n"); 00250 hThread = CreateThread(NULL, 00251 0, 00252 ScmNamedPipeThread, 00253 (LPVOID)hPipe, 00254 0, 00255 &dwThreadId); 00256 if (!hThread) 00257 { 00258 DPRINT("Could not create thread (%d)\n", GetLastError()); 00259 DisconnectNamedPipe(hPipe); 00260 CloseHandle(hPipe); 00261 DPRINT("CreateNamedPipe() - returning FALSE\n"); 00262 return FALSE; 00263 } 00264 00265 CloseHandle(hThread); 00266 } 00267 else 00268 { 00269 DPRINT("Pipe not connected\n"); 00270 CloseHandle(hPipe); 00271 DPRINT("CreateNamedPipe() - returning FALSE\n"); 00272 return FALSE; 00273 } 00274 DPRINT("CreateNamedPipe() - returning TRUE\n"); 00275 return TRUE; 00276 } 00277 00278 00279 DWORD WINAPI 00280 ScmNamedPipeListenerThread(LPVOID Context) 00281 { 00282 // HANDLE hPipe; 00283 DPRINT("ScmNamedPipeListenerThread(%x) - aka SCM.\n", Context); 00284 00285 // hPipe = (HANDLE)Context; 00286 for (;;) 00287 { 00288 DPRINT("SCM: Waiting for new connection on named pipe...\n"); 00289 /* Create named pipe */ 00290 if (!ScmCreateNamedPipe()) 00291 { 00292 DPRINT1("\nSCM: Failed to create named pipe\n"); 00293 break; 00294 //ExitThread(0); 00295 } 00296 DPRINT("\nSCM: named pipe session created.\n"); 00297 Sleep(10); 00298 } 00299 DPRINT("\n\nWARNING: ScmNamedPipeListenerThread(%x) - Aborted.\n\n", Context); 00300 return ERROR_SUCCESS; 00301 } 00302 00303 00304 BOOL 00305 StartScmNamedPipeThreadListener(VOID) 00306 { 00307 DWORD dwThreadId; 00308 HANDLE hThread; 00309 00310 hThread = CreateThread(NULL, 00311 0, 00312 ScmNamedPipeListenerThread, 00313 NULL, /*(LPVOID)hPipe,*/ 00314 0, 00315 &dwThreadId); 00316 if (!hThread) 00317 { 00318 DPRINT1("SERVICES: Could not create thread (Status %lx)\n", GetLastError()); 00319 return FALSE; 00320 } 00321 00322 CloseHandle(hThread); 00323 00324 return TRUE; 00325 } 00326 00327 00328 VOID FASTCALL 00329 AcquireLoadDriverPrivilege(VOID) 00330 { 00331 HANDLE hToken; 00332 TOKEN_PRIVILEGES tkp; 00333 00334 /* Get a token for this process */ 00335 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 00336 { 00337 /* Get the LUID for the debug privilege */ 00338 LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid); 00339 00340 /* One privilege to set */ 00341 tkp.PrivilegeCount = 1; 00342 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 00343 00344 /* Get the debug privilege for this process */ 00345 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 00346 } 00347 } 00348 00349 00350 BOOL WINAPI 00351 ShutdownHandlerRoutine(DWORD dwCtrlType) 00352 { 00353 DPRINT1("ShutdownHandlerRoutine() called\n"); 00354 00355 if (dwCtrlType & (CTRL_SHUTDOWN_EVENT | CTRL_LOGOFF_EVENT)) 00356 { 00357 DPRINT1("Shutdown event received!\n"); 00358 ScmShutdown = TRUE; 00359 00360 ScmAutoShutdownServices(); 00361 ScmShutdownServiceDatabase(); 00362 00363 /* Set the shutdwon event */ 00364 SetEvent(hScmShutdownEvent); 00365 } 00366 00367 return TRUE; 00368 } 00369 00370 00371 int WINAPI 00372 wWinMain(HINSTANCE hInstance, 00373 HINSTANCE hPrevInstance, 00374 LPWSTR lpCmdLine, 00375 int nShowCmd) 00376 { 00377 HANDLE hScmStartEvent; 00378 DWORD dwError; 00379 00380 DPRINT("SERVICES: Service Control Manager\n"); 00381 00382 /* Create start event */ 00383 if (!ScmCreateStartEvent(&hScmStartEvent)) 00384 { 00385 DPRINT1("SERVICES: Failed to create start event\n"); 00386 ExitThread(0); 00387 } 00388 00389 DPRINT("SERVICES: created start event with handle %p.\n", hScmStartEvent); 00390 00391 // ScmInitThreadManager(); 00392 00393 /* FIXME: more initialization */ 00394 00395 00396 /* Create the service database */ 00397 dwError = ScmCreateServiceDatabase(); 00398 if (dwError != ERROR_SUCCESS) 00399 { 00400 DPRINT1("SERVICES: failed to create SCM database (Error %lu)\n", dwError); 00401 CloseHandle(hScmStartEvent); 00402 ExitThread(0); 00403 } 00404 00405 /* Update service database */ 00406 ScmGetBootAndSystemDriverState(); 00407 00408 /* Start the RPC server */ 00409 ScmStartRpcServer(); 00410 00411 /* Register service process with CSRSS */ 00412 RegisterServicesProcess(GetCurrentProcessId()); 00413 00414 DPRINT("SERVICES: Initialized.\n"); 00415 00416 /* Signal start event */ 00417 SetEvent(hScmStartEvent); 00418 00419 /* Register event handler (used for system shutdown) */ 00420 SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE); 00421 00422 /* Wait for the LSA server */ 00423 ScmWaitForLsass(); 00424 00425 /* Acquire privileges to load drivers */ 00426 AcquireLoadDriverPrivilege(); 00427 00428 ScmInitNamedPipeCriticalSection(); 00429 00430 /* Start auto-start services */ 00431 ScmAutoStartServices(); 00432 00433 /* FIXME: more to do ? */ 00434 00435 00436 DPRINT("SERVICES: Running.\n"); 00437 00438 /* Create the shutdown event and wait until it gets set */ 00439 hScmShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 00440 if (hScmShutdownEvent) 00441 WaitForSingleObject(hScmShutdownEvent, INFINITE); 00442 00443 ScmDeleteNamedPipeCriticalSection(); 00444 00445 /* Close the shutdown event */ 00446 CloseHandle(hScmShutdownEvent); 00447 00448 /* Close the start event */ 00449 CloseHandle(hScmStartEvent); 00450 00451 DPRINT("SERVICES: Finished.\n"); 00452 00453 ExitThread(0); 00454 00455 return 0; 00456 } 00457 00458 /* EOF */ Generated on Sat May 26 2012 04:16:34 for ReactOS by
1.7.6.1
|