mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
234 lines
6.5 KiB
C
234 lines
6.5 KiB
C
/*
|
|
* 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;
|
|
|
|
/* 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");
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
BOOL Success;
|
|
DWORD dwNumSubKeys, dwMaxSubKeyLength;
|
|
DWORD dwEventSourceNameLength, MaxValueLen;
|
|
DWORD dwIndex;
|
|
PWSTR Buf = NULL, SourceList = NULL, Source = NULL;
|
|
size_t cchRemaining = 0;
|
|
LONG Result;
|
|
|
|
DPRINT("LoadEventSources\n");
|
|
|
|
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(GetProcessHeap(), 0, dwMaxSubKeyLength * sizeof(WCHAR));
|
|
if (!Buf)
|
|
{
|
|
DPRINT1("Error: cannot allocate heap!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* 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,
|
|
Buf,
|
|
&dwEventSourceNameLength,
|
|
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
if (_wcsicmp(pLogFile->LogName, Buf) != 0)
|
|
{
|
|
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++;
|
|
}
|
|
|
|
/* 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();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
PEVENTSOURCE
|
|
GetEventSourceByName(LPCWSTR Name)
|
|
{
|
|
PLIST_ENTRY CurrentEntry;
|
|
PEVENTSOURCE Item, Result = NULL;
|
|
|
|
DPRINT("GetEventSourceByName(%S)\n", Name);
|
|
EnterCriticalSection(&EventSourceListCs);
|
|
|
|
CurrentEntry = EventSourceListHead.Flink;
|
|
while (CurrentEntry != &EventSourceListHead)
|
|
{
|
|
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;
|
|
}
|