[EVENTLOG]
[reactos.git] / reactos / base / services / eventlog / eventlog.c
index 8582e94..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);
 
@@ -271,24 +395,24 @@ VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime)
     *pEventTime = (Time.ll - u1970.ll) / 10000000;
 }
 
-VOID PRINT_HEADER(PFILE_HEADER header)
+VOID PRINT_HEADER(PEVENTLOGHEADER header)
 {
-    DPRINT("SizeOfHeader = %d\n", header->SizeOfHeader);
+    DPRINT("HeaderSize = %d\n", header->HeaderSize);
     DPRINT("Signature = 0x%x\n", header->Signature);
     DPRINT("MajorVersion = %d\n", header->MajorVersion);
     DPRINT("MinorVersion = %d\n", header->MinorVersion);
-    DPRINT("FirstRecordOffset = %d\n", header->FirstRecordOffset);
-    DPRINT("EofOffset = 0x%x\n", header->EofOffset);
-    DPRINT("NextRecord = %d\n", header->NextRecord);
-    DPRINT("OldestRecord = %d\n", header->OldestRecord);
-    DPRINT("unknown1 = 0x%x\n", header->unknown1);
-    DPRINT("unknown2 = 0x%x\n", header->unknown2);
-    DPRINT("SizeOfHeader2 = %d\n", header->SizeOfHeader2);
+    DPRINT("StartOffset = %d\n", header->StartOffset);
+    DPRINT("EndOffset = 0x%x\n", header->EndOffset);
+    DPRINT("CurrentRecordNumber = %d\n", header->CurrentRecordNumber);
+    DPRINT("OldestRecordNumber = %d\n", header->OldestRecordNumber);
+    DPRINT("MaxSize = 0x%x\n", header->MaxSize);
+    DPRINT("Retention = 0x%x\n", header->Retention);
+    DPRINT("EndHeaderSize = %d\n", header->EndHeaderSize);
     DPRINT("Flags: ");
-    if (header->Flags & LOGFILE_FLAG1)  DPRINT("LOGFILE_FLAG1 ");
-    if (header->Flags & LOGFILE_FLAG2)  DPRINT("| LOGFILE_FLAG2 ");
-    if (header->Flags & LOGFILE_FLAG3)  DPRINT("| LOGFILE_FLAG3 ");
-    if (header->Flags & LOGFILE_FLAG4)  DPRINT("| LOGFILE_FLAG4");
+    if (header->Flags & ELF_LOGFILE_HEADER_DIRTY)  DPRINT("ELF_LOGFILE_HEADER_DIRTY");
+    if (header->Flags & ELF_LOGFILE_HEADER_WRAP)  DPRINT("| ELF_LOGFILE_HEADER_WRAP ");
+    if (header->Flags & ELF_LOGGFILE_LOGFULL_WRITTEN)  DPRINT("| ELF_LOGGFILE_LOGFULL_WRITTEN ");
+    if (header->Flags & ELF_LOGFILE_ARCHIVE_SET)  DPRINT("| ELF_LOGFILE_ARCHIVE_SET ");
     DPRINT("\n");
 }