[TFTPD] Fix compilation, and use the #define MAX_SERVERS where needed instead of...
[reactos.git] / base / services / eventlog / eventsource.c
index 6182666..d93ff97 100644 (file)
@@ -1,15 +1,18 @@
 /*
- * PROJECT:          ReactOS kernel
- * LICENSE:          GPL - See COPYING in the top level directory
- * FILE:             base/services/eventlog/eventsource.c
- * PURPOSE:          Event logging service
- * COPYRIGHT:        Copyright 2011 Eric Kohl
+ * PROJECT:         ReactOS EventLog Service
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/services/eventlog/eventsource.c
+ * PURPOSE:         Event log sources support
+ * COPYRIGHT:       Copyright 2011 Eric Kohl
  */
 
 /* INCLUDES *****************************************************************/
 
 #include "eventlog.h"
 
+#define NDEBUG
+#include <debug.h>
+
 static LIST_ENTRY EventSourceListHead;
 static CRITICAL_SECTION EventSourceListCs;
 
@@ -50,34 +53,87 @@ DumpEventSourceList(VOID)
 }
 
 
+static BOOL
+AddNewEventSource(PLOGFILE pLogFile,
+                  PWSTR lpSourceName)
+{
+    PEVENTSOURCE lpEventSource;
+
+    lpEventSource = HeapAlloc(GetProcessHeap(), 0,
+                              FIELD_OFFSET(EVENTSOURCE, szName[wcslen(lpSourceName) + 1]));
+    if (lpEventSource != NULL)
+    {
+        wcscpy(lpEventSource->szName, lpSourceName);
+        lpEventSource->LogFile = pLogFile;
+
+        DPRINT("Insert event source: %S\n", lpEventSource->szName);
+
+        EnterCriticalSection(&EventSourceListCs);
+        InsertTailList(&EventSourceListHead,
+                       &lpEventSource->EventSourceListEntry);
+        LeaveCriticalSection(&EventSourceListCs);
+    }
+
+    return (lpEventSource != NULL);
+}
+
+
 BOOL
 LoadEventSources(HKEY hKey,
                  PLOGFILE pLogFile)
 {
-    PEVENTSOURCE lpEventSource;
-    DWORD dwMaxSubKeyLength;
-    DWORD dwEventSourceNameLength;
+    BOOL Success;
+    DWORD dwNumSubKeys, dwMaxSubKeyLength;
+    DWORD dwEventSourceNameLength, MaxValueLen;
     DWORD dwIndex;
-    WCHAR *Buf = NULL;
+    PWSTR Buf = NULL, SourceList = NULL, Source = NULL;
+    size_t cchRemaining = 0;
+    LONG Result;
 
     DPRINT("LoadEventSources\n");
 
-    RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, &dwMaxSubKeyLength, NULL,
-                     NULL, NULL, NULL, NULL, NULL);
-
-    DPRINT("dwMaxSubKeyLength: %lu\n", dwMaxSubKeyLength);
+    Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLength,
+                              NULL, NULL, NULL, NULL, NULL, NULL);
+    if (Result != ERROR_SUCCESS)
+    {
+        DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
+        return FALSE;
+    }
 
     dwMaxSubKeyLength++;
 
-    Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
+    Buf = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLength * sizeof(WCHAR));
     if (!Buf)
     {
-        DPRINT1("Error: can't allocate heap!\n");
+        DPRINT1("Error: cannot allocate heap!\n");
         return FALSE;
     }
 
-    dwEventSourceNameLength = dwMaxSubKeyLength;
+    /*
+     * Allocate a buffer for storing the names of the sources as a REG_MULTI_SZ
+     * in the registry. Also add the event log as its own source.
+     * Add a final NULL-terminator.
+     */
+    MaxValueLen = dwNumSubKeys * dwMaxSubKeyLength + wcslen(pLogFile->LogName) + 2;
+    SourceList = HeapAlloc(GetProcessHeap(), 0, MaxValueLen * sizeof(WCHAR));
+    if (!SourceList)
+    {
+        DPRINT1("Error: cannot allocate heap!\n");
+        /* It is not dramatic if we cannot create it */
+    }
+    else
+    {
+        cchRemaining = MaxValueLen;
+        Source = SourceList;
+    }
 
+    /*
+     * Enumerate all the subkeys of the event log key, that constitute
+     * all the possible event sources for this event log. At this point,
+     * skip the possible existing source having the same name as the
+     * event log, it will be added later on.
+     */
+    dwEventSourceNameLength = dwMaxSubKeyLength;
     dwIndex = 0;
     while (RegEnumKeyExW(hKey,
                          dwIndex,
@@ -85,28 +141,56 @@ LoadEventSources(HKEY hKey,
                          &dwEventSourceNameLength,
                          NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
     {
-        DPRINT("Event Source: %S\n", Buf);
-
-        lpEventSource = HeapAlloc(MyHeap, 0, sizeof(EVENTSOURCE) + wcslen(Buf) * sizeof(WCHAR));
-        if (lpEventSource != NULL)
+        if (_wcsicmp(pLogFile->LogName, Buf) != 0)
         {
-            wcscpy(lpEventSource->szName, Buf);
-            lpEventSource->LogFile = pLogFile;
-
-            DPRINT("Insert event source: %S\n", lpEventSource->szName);
-
-
-            EnterCriticalSection(&EventSourceListCs);
-            InsertTailList(&EventSourceListHead,
-                           &lpEventSource->EventSourceListEntry);
-            LeaveCriticalSection(&EventSourceListCs);
+            DPRINT("Event Source: %S\n", Buf);
+            Success = AddNewEventSource(pLogFile, Buf);
+            if (Success && (Source != NULL))
+            {
+                /* Append the event source name and an extra NULL-terminator */
+                StringCchCopyExW(Source, cchRemaining, Buf, &Source, &cchRemaining, 0);
+                if (cchRemaining > 0)
+                {
+                    *++Source = L'\0';
+                    cchRemaining--;
+                }
+            }
         }
 
         dwEventSourceNameLength = dwMaxSubKeyLength;
         dwIndex++;
     }
 
-    HeapFree(MyHeap, 0, Buf);
+    /* Finally, allow the event log itself to be its own source */
+    DPRINT("Event Source: %S\n", pLogFile->LogName);
+    Success = AddNewEventSource(pLogFile, pLogFile->LogName);
+    if (Success && (Source != NULL))
+    {
+        /* Append the event source name and an extra NULL-terminator */
+        StringCchCopyExW(Source, cchRemaining, pLogFile->LogName, &Source, &cchRemaining, 0);
+        if (cchRemaining > 0)
+        {
+            *++Source = L'\0';
+            cchRemaining--;
+        }
+    }
+
+    /* Save the list of sources in the registry */
+    Result = RegSetValueExW(hKey,
+                            L"Sources",
+                            0,
+                            REG_MULTI_SZ,
+                            (LPBYTE)SourceList,
+                            (MaxValueLen - cchRemaining + 1) * sizeof(WCHAR));
+    if (Result != ERROR_SUCCESS)
+    {
+        DPRINT1("RegSetValueExW failed: %lu\n", Result);
+    }
+
+    if (SourceList)
+        HeapFree(GetProcessHeap(), 0, SourceList);
+
+    HeapFree(GetProcessHeap(), 0, Buf);
 
     DumpEventSourceList();
 
@@ -118,7 +202,7 @@ PEVENTSOURCE
 GetEventSourceByName(LPCWSTR Name)
 {
     PLIST_ENTRY CurrentEntry;
-    PEVENTSOURCE Result = NULL;
+    PEVENTSOURCE Item, Result = NULL;
 
     DPRINT("GetEventSourceByName(%S)\n", Name);
     EnterCriticalSection(&EventSourceListCs);
@@ -126,9 +210,9 @@ GetEventSourceByName(LPCWSTR Name)
     CurrentEntry = EventSourceListHead.Flink;
     while (CurrentEntry != &EventSourceListHead)
     {
-        PEVENTSOURCE Item = CONTAINING_RECORD(CurrentEntry,
-                                              EVENTSOURCE,
-                                              EventSourceListEntry);
+        Item = CONTAINING_RECORD(CurrentEntry,
+                                 EVENTSOURCE,
+                                 EventSourceListEntry);
 
         DPRINT("Item->szName: %S\n", Item->szName);
 //        if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))