[EVENTLOG]
[reactos.git] / reactos / base / services / eventlog / eventlog.c
index 9a2ddab..ee34a1d 100644 (file)
 
 /* GLOBALS ******************************************************************/
 
-VOID CALLBACK ServiceMain(DWORD argc, LPTSTR * argv);
-
-SERVICE_TABLE_ENTRY ServiceTable[2] =
+static VOID CALLBACK ServiceMain(DWORD, LPWSTR *);
+static WCHAR ServiceName[] = L"EventLog";
+static SERVICE_TABLE_ENTRYW ServiceTable[2] =
 {
-    { L"EventLog", (LPSERVICE_MAIN_FUNCTION) ServiceMain },
+    { ServiceName, ServiceMain },
     { NULL, NULL }
 };
 
+SERVICE_STATUS ServiceStatus;
+SERVICE_STATUS_HANDLE ServiceStatusHandle;
+
 BOOL onLiveCD = FALSE;  // On livecd events will go to debug output only
 HANDLE MyHeap = NULL;
 
 /* FUNCTIONS ****************************************************************/
 
-VOID CALLBACK ServiceMain(DWORD argc, LPTSTR * argv)
+static VOID
+UpdateServiceStatus(DWORD dwState)
+{
+    ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+    ServiceStatus.dwCurrentState = dwState;
+    ServiceStatus.dwControlsAccepted = 0;
+    ServiceStatus.dwWin32ExitCode = 0;
+    ServiceStatus.dwServiceSpecificExitCode = 0;
+    ServiceStatus.dwCheckPoint = 0;
+
+    if (dwState == SERVICE_START_PENDING ||
+        dwState == SERVICE_STOP_PENDING ||
+        dwState == SERVICE_PAUSE_PENDING ||
+        dwState == SERVICE_CONTINUE_PENDING)
+        ServiceStatus.dwWaitHint = 10000;
+    else
+        ServiceStatus.dwWaitHint = 0;
+
+    SetServiceStatus(ServiceStatusHandle,
+                     &ServiceStatus);
+}
+
+static DWORD WINAPI
+ServiceControlHandler(DWORD dwControl,
+                      DWORD dwEventType,
+                      LPVOID lpEventData,
+                      LPVOID lpContext)
+{
+    DPRINT("ServiceControlHandler() called\n");
+
+    switch (dwControl)
+    {
+        case SERVICE_CONTROL_STOP:
+            DPRINT("  SERVICE_CONTROL_STOP received\n");
+            UpdateServiceStatus(SERVICE_STOPPED);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_PAUSE:
+            DPRINT("  SERVICE_CONTROL_PAUSE received\n");
+            UpdateServiceStatus(SERVICE_PAUSED);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_CONTINUE:
+            DPRINT("  SERVICE_CONTROL_CONTINUE received\n");
+            UpdateServiceStatus(SERVICE_RUNNING);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_INTERROGATE:
+            DPRINT("  SERVICE_CONTROL_INTERROGATE received\n");
+            SetServiceStatus(ServiceStatusHandle,
+                             &ServiceStatus);
+            return ERROR_SUCCESS;
+
+        case SERVICE_CONTROL_SHUTDOWN:
+            DPRINT("  SERVICE_CONTROL_SHUTDOWN received\n");
+            UpdateServiceStatus(SERVICE_STOPPED);
+            return ERROR_SUCCESS;
+
+        default :
+            DPRINT1("  Control %lu received\n");
+            return ERROR_CALL_NOT_IMPLEMENTED;
+    }
+}
+
+
+static DWORD
+ServiceInit(VOID)
 {
     HANDLE hThread;
 
@@ -39,7 +108,10 @@ VOID CALLBACK ServiceMain(DWORD argc, LPTSTR * argv)
                            NULL);
 
     if (!hThread)
+    {
         DPRINT("Can't create PortThread\n");
+        return GetLastError();
+    }
     else
         CloseHandle(hThread);
 
@@ -52,17 +124,65 @@ VOID CALLBACK ServiceMain(DWORD argc, LPTSTR * argv)
                            NULL);
 
     if (!hThread)
+    {
         DPRINT("Can't create RpcThread\n");
+        return GetLastError();
+    }
     else
         CloseHandle(hThread);
+
+    return ERROR_SUCCESS;
 }
 
-BOOL LoadLogFile(HKEY hKey, WCHAR * LogName)
+
+static VOID CALLBACK
+ServiceMain(DWORD argc,
+            LPWSTR *argv)
+{
+    DWORD dwError;
+
+    UNREFERENCED_PARAMETER(argc);
+    UNREFERENCED_PARAMETER(argv);
+
+    DPRINT("ServiceMain() called\n");
+
+    ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
+                                                        ServiceControlHandler,
+                                                        NULL);
+    if (!ServiceStatusHandle)
+    {
+        dwError = GetLastError();
+        DPRINT1("RegisterServiceCtrlHandlerW() failed! (Error %lu)\n", dwError);
+        return;
+    }
+
+    UpdateServiceStatus(SERVICE_START_PENDING);
+
+    dwError = ServiceInit();
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("Service stopped (dwError: %lu\n", dwError);
+        UpdateServiceStatus(SERVICE_START_PENDING);
+    }
+    else
+    {
+        DPRINT("Service started\n");
+        UpdateServiceStatus(SERVICE_RUNNING);
+
+        LogfReportEvent(EVENTLOG_INFORMATION_TYPE,
+                        0,
+                        EVENT_EventlogStarted);
+    }
+
+    DPRINT("ServiceMain() done\n");
+}
+
+
+PLOGFILE LoadLogFile(HKEY hKey, WCHAR * LogName)
 {
     DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
     WCHAR *Buf = NULL, *Expanded = NULL;
     LONG Result;
-    BOOL ret = TRUE;
     PLOGFILE pLogf;
 
     DPRINT("LoadLogFile: %S\n", LogName);
@@ -71,11 +191,10 @@ BOOL LoadLogFile(HKEY hKey, WCHAR * LogName)
                     NULL, NULL, &MaxValueLen, NULL, NULL);
 
     Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
-
     if (!Buf)
     {
         DPRINT1("Can't allocate heap!\n");
-        return FALSE;
+        return NULL;
     }
 
     ValueLen = MaxValueLen;
@@ -86,29 +205,27 @@ BOOL LoadLogFile(HKEY hKey, WCHAR * LogName)
                              &Type,
                              (LPBYTE) Buf,
                              &ValueLen);
-
     if (Result != ERROR_SUCCESS)
     {
         DPRINT1("RegQueryValueEx failed: %d\n", GetLastError());
         HeapFree(MyHeap, 0, Buf);
-        return FALSE;
+        return NULL;
     }
 
     if (Type != REG_EXPAND_SZ && Type != REG_SZ)
     {
         DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type);
         HeapFree(MyHeap, 0, Buf);
-        return FALSE;
+        return NULL;
     }
 
     ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0);
     Expanded = HeapAlloc(MyHeap, 0, ExpandedLen * sizeof(WCHAR));
-
     if (!Expanded)
     {
         DPRINT1("Can't allocate heap!\n");
         HeapFree(MyHeap, 0, Buf);
-        return FALSE;
+        return NULL;
     }
 
     ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
@@ -120,12 +237,11 @@ BOOL LoadLogFile(HKEY hKey, WCHAR * LogName)
     if (pLogf == NULL)
     {
         DPRINT1("Failed to create %S!\n", Expanded);
-        ret = FALSE;
     }
 
     HeapFree(MyHeap, 0, Buf);
     HeapFree(MyHeap, 0, Expanded);
-    return ret;
+    return pLogf;
 }
 
 BOOL LoadLogFiles(HKEY eventlogKey)
@@ -134,6 +250,7 @@ BOOL LoadLogFiles(HKEY eventlogKey)
     DWORD MaxLognameLen, LognameLen;
     WCHAR *Buf = NULL;
     INT i;
+    PLOGFILE pLogFile;
 
     RegQueryInfoKey(eventlogKey,
                     NULL, NULL, NULL, NULL,
@@ -171,10 +288,16 @@ BOOL LoadLogFiles(HKEY eventlogKey)
             return FALSE;
         }
 
-        if (!LoadLogFile(SubKey, Buf))
-            DPRINT1("Failed to load %S\n", Buf);
-        else
+        pLogFile = LoadLogFile(SubKey, Buf);
+        if (pLogFile != NULL)
+        {
             DPRINT("Loaded %S\n", Buf);
+            LoadEventSources(SubKey, pLogFile);
+        }
+        else
+        {
+            DPRINT1("Failed to load %S\n", Buf);
+        }
 
         RegCloseKey(SubKey);
         LognameLen = MaxLognameLen;
@@ -193,6 +316,7 @@ INT wmain()
     HKEY elogKey;
 
     LogfListInitialize();
+    InitEventSourceList();
 
     MyHeap = HeapCreate(0, 1024 * 256, 0);