ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

services.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.