[EVENTLOG]

Implement an event source list and use it to find the event log file for a given event source when an event was reported.

svn path=/trunk/; revision=51513
This commit is contained in:
Eric Kohl 2011-04-30 22:33:53 +00:00
parent 94050d9e54
commit 5dd119d642
5 changed files with 213 additions and 26 deletions

View file

@ -174,12 +174,11 @@ ServiceMain(DWORD argc,
}
BOOL LoadLogFile(HKEY hKey, WCHAR * LogName)
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);
@ -188,11 +187,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;
@ -203,29 +201,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);
@ -237,12 +233,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)
@ -251,6 +246,7 @@ BOOL LoadLogFiles(HKEY eventlogKey)
DWORD MaxLognameLen, LognameLen;
WCHAR *Buf = NULL;
INT i;
PLOGFILE pLogFile;
RegQueryInfoKey(eventlogKey,
NULL, NULL, NULL, NULL,
@ -288,10 +284,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;
@ -310,6 +312,7 @@ INT wmain()
HKEY elogKey;
LogfListInitialize();
InitEventSourceList();
MyHeap = HeapCreate(0, 1024 * 256, 0);

View file

@ -93,19 +93,17 @@ typedef struct _LOGFILE
LIST_ENTRY ListEntry;
} LOGFILE, *PLOGFILE;
#if 0
typedef struct _EVENTSOURCE
{
LIST_ENTRY EventSourceListEntry;
PLOGFILE LogFile;
ULONG CurrentRecord;
WCHAR szName[1];
} EVENTSOURCE, *PEVENTSOURCE;
#endif
typedef struct _LOGHANDLE
{
LIST_ENTRY LogHandleListEntry;
PEVENTSOURCE EventSource;
PLOGFILE LogFile;
ULONG CurrentRecord;
WCHAR szName[1];
@ -192,6 +190,17 @@ VOID EventTimeToSystemTime(DWORD EventTime,
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime,
DWORD * pEventTime);
/* eventsource.c */
VOID InitEventSourceList(VOID);
BOOL
LoadEventSources(HKEY hKey,
PLOGFILE pLogFile);
PEVENTSOURCE
GetEventSourceByName(LPCWSTR Name);
/* logport.c */
NTSTATUS WINAPI PortThreadRoutine(PVOID Param);

View file

@ -9,6 +9,7 @@
<library>rpcrt4</library>
<library>pseh</library>
<file>eventlog.c</file>
<file>eventsource.c</file>
<file>logport.c</file>
<file>eventlog.rc</file>
<file>rpc.c</file>

View file

@ -0,0 +1,150 @@
/*
* 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
*/
/* INCLUDES *****************************************************************/
#include "eventlog.h"
static LIST_ENTRY EventSourceListHead;
static CRITICAL_SECTION EventSourceListCs;
/* FUNCTIONS ****************************************************************/
VOID
InitEventSourceList(VOID)
{
InitializeCriticalSection(&EventSourceListCs);
InitializeListHead(&EventSourceListHead);
}
static VOID
DumpEventSourceList(VOID)
{
PLIST_ENTRY CurrentEntry;
PEVENTSOURCE EventSource;
DPRINT("DumpEventSourceList()\n");
EnterCriticalSection(&EventSourceListCs);
CurrentEntry = EventSourceListHead.Flink;
while (CurrentEntry != &EventSourceListHead)
{
EventSource = CONTAINING_RECORD(CurrentEntry,
EVENTSOURCE,
EventSourceListEntry);
DPRINT("EventSource->szName: %S\n", EventSource->szName);
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&EventSourceListCs);
DPRINT("Done\n");
}
BOOL
LoadEventSources(HKEY hKey,
PLOGFILE pLogFile)
{
PEVENTSOURCE lpEventSource;
DWORD dwMaxSubKeyLength;
DWORD dwEventSourceNameLength;
DWORD dwIndex;
WCHAR *Buf = NULL;
DPRINT("LoadEventSources\n");
RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, &dwMaxSubKeyLength, NULL,
NULL, NULL, NULL, NULL, NULL);
DPRINT("dwMaxSubKeyLength: %lu\n", dwMaxSubKeyLength);
dwMaxSubKeyLength++;
Buf = HeapAlloc(MyHeap, 0, dwMaxSubKeyLength * sizeof(WCHAR));
if (!Buf)
{
DPRINT1("Error: can't allocate heap!\n");
return FALSE;
}
dwEventSourceNameLength = dwMaxSubKeyLength;
dwIndex = 0;
while (RegEnumKeyExW(hKey,
dwIndex,
Buf,
&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)
{
wcscpy(lpEventSource->szName, Buf);
lpEventSource->LogFile = pLogFile;
DPRINT("Insert event source: %S\n", lpEventSource->szName);
EnterCriticalSection(&EventSourceListCs);
InsertTailList(&EventSourceListHead,
&lpEventSource->EventSourceListEntry);
LeaveCriticalSection(&EventSourceListCs);
}
dwEventSourceNameLength = dwMaxSubKeyLength;
dwIndex++;
}
HeapFree(MyHeap, 0, Buf);
DumpEventSourceList();
return TRUE;
}
PEVENTSOURCE
GetEventSourceByName(LPCWSTR Name)
{
PLIST_ENTRY CurrentEntry;
PEVENTSOURCE Result = NULL;
DPRINT("GetEventSourceByName(%S)\n", Name);
EnterCriticalSection(&EventSourceListCs);
CurrentEntry = EventSourceListHead.Flink;
while (CurrentEntry != &EventSourceListHead)
{
PEVENTSOURCE Item = CONTAINING_RECORD(CurrentEntry,
EVENTSOURCE,
EventSourceListEntry);
DPRINT("Item->szName: %S\n", Item->szName);
// if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))
if (_wcsicmp(Item->szName, Name) == 0)
{
DPRINT("Found it\n");
Result = Item;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&EventSourceListCs);
DPRINT("Done (Result: %p)\n", Result);
return Result;
}

View file

@ -49,6 +49,9 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
PLOGHANDLE lpLogHandle;
PLOGFILE currentLogFile = NULL;
INT i, LogsActive;
PEVENTSOURCE pEventSource;
DPRINT("ElfCreateEventLogHandle(Name: %S)\n", Name);
lpLogHandle = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGHANDLE)
+ ((wcslen(Name) + 1) * sizeof(WCHAR)));
@ -70,8 +73,24 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
/* If Creating, default to the Application Log in case we fail, as documented on MSDN */
if (Create == TRUE)
lpLogHandle->LogFile = LogfListItemByName(L"Application");
{
pEventSource = GetEventSourceByName(Name);
DPRINT("EventSource: %p\n", pEventSource);
if (pEventSource)
{
DPRINT("EventSource LogFile: %p\n", pEventSource->LogFile);
lpLogHandle->LogFile = pEventSource->LogFile;
}
else
{
DPRINT("EventSource LogFile: Application log file\n");
lpLogHandle->LogFile = LogfListItemByName(L"Application");
}
DPRINT("LogHandle LogFile: %p\n", lpLogHandle->LogFile);
}
else
{
lpLogHandle->LogFile = NULL;
for (i = 1; i <= LogsActive; i++)
@ -85,6 +104,7 @@ PLOGHANDLE ElfCreateEventLogHandle(LPCWSTR Name, BOOL Create)
break;
}
}
}
if (!lpLogHandle->LogFile)
goto Cleanup;
@ -267,6 +287,8 @@ NTSTATUS ElfrRegisterEventSourceW(
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
DPRINT1("ElfrRegisterEventSourceW()\n");
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
@ -274,6 +296,8 @@ NTSTATUS ElfrRegisterEventSourceW(
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
DPRINT1("ModuleName: %S\n", ModuleName->Buffer);
/*FIXME: UNCServerName must specify the server or empty for local */
/*FIXME: Must verify that caller has write access */