reactos/base/services/eventlog/eventlog.c
Timo Kreuzer 9ea495ba33 Create a branch for header work.
svn path=/branches/header-work/; revision=45691
2010-02-26 22:57:55 +00:00

442 lines
12 KiB
C

/*
* PROJECT: ReactOS kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: services/eventlog/eventlog.c
* PURPOSE: Event logging service
* COPYRIGHT: Copyright 2002 Eric Kohl
* Copyright 2005 Saveliy Tretiakov
*/
/* INCLUDES *****************************************************************/
#include "eventlog.h"
/* GLOBALS ******************************************************************/
static VOID CALLBACK ServiceMain(DWORD, LPWSTR *);
static WCHAR ServiceName[] = L"EventLog";
static SERVICE_TABLE_ENTRYW ServiceTable[2] =
{
{ ServiceName, ServiceMain },
{ NULL, NULL }
};
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
HANDLE MyHeap = NULL;
/* FUNCTIONS ****************************************************************/
static DWORD WINAPI
ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext)
{
/* FIXME */
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
return ERROR_SUCCESS;
}
static DWORD
ServiceInit(VOID)
{
HANDLE hThread;
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)
PortThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Can't create PortThread\n");
return GetLastError();
}
else
CloseHandle(hThread);
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)
RpcThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Can't create RpcThread\n");
return GetLastError();
}
else
CloseHandle(hThread);
return ERROR_SUCCESS;
}
static VOID CALLBACK
ServiceMain(DWORD argc,
LPWSTR *argv)
{
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
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;
}
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 2000;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
dwError = ServiceInit();
if (dwError != ERROR_SUCCESS)
{
DPRINT1("Service stopped\n");
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
}
else
{
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
}
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
DPRINT("ServiceMain() done\n");
}
BOOL 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);
RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &MaxValueLen, NULL, NULL);
Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
if (!Buf)
{
DPRINT1("Can't allocate heap!\n");
return FALSE;
}
ValueLen = MaxValueLen;
Result = RegQueryValueEx(hKey,
L"File",
NULL,
&Type,
(LPBYTE) Buf,
&ValueLen);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryValueEx failed: %d\n", GetLastError());
HeapFree(MyHeap, 0, Buf);
return FALSE;
}
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;
}
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;
}
ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
DPRINT("%S -> %S\n", Buf, Expanded);
pLogf = LogfCreate(LogName, Expanded);
if (pLogf == NULL)
{
DPRINT1("Failed to create %S!\n", Expanded);
ret = FALSE;
}
HeapFree(MyHeap, 0, Buf);
HeapFree(MyHeap, 0, Expanded);
return ret;
}
BOOL LoadLogFiles(HKEY eventlogKey)
{
LONG result;
DWORD MaxLognameLen, LognameLen;
WCHAR *Buf = NULL;
INT i;
RegQueryInfoKey(eventlogKey,
NULL, NULL, NULL, NULL,
&MaxLognameLen,
NULL, NULL, NULL, NULL, NULL, NULL);
MaxLognameLen++;
Buf = HeapAlloc(MyHeap, 0, MaxLognameLen * sizeof(WCHAR));
if (!Buf)
{
DPRINT1("Error: can't allocate heap!\n");
return FALSE;
}
i = 0;
LognameLen = MaxLognameLen;
while (RegEnumKeyEx(eventlogKey,
i,
Buf,
&LognameLen,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY SubKey;
DPRINT("%S\n", Buf);
result = RegOpenKeyEx(eventlogKey, Buf, 0, KEY_ALL_ACCESS, &SubKey);
if (result != ERROR_SUCCESS)
{
DPRINT1("Failed to open %S key.\n", Buf);
HeapFree(MyHeap, 0, Buf);
return FALSE;
}
if (!LoadLogFile(SubKey, Buf))
DPRINT1("Failed to load %S\n", Buf);
else
DPRINT("Loaded %S\n", Buf);
RegCloseKey(SubKey);
LognameLen = MaxLognameLen;
i++;
}
HeapFree(MyHeap, 0, Buf);
return TRUE;
}
INT wmain()
{
WCHAR LogPath[MAX_PATH];
INT RetCode = 0;
LONG result;
HKEY elogKey;
LogfListInitialize();
MyHeap = HeapCreate(0, 1024 * 256, 0);
if (!MyHeap)
{
DPRINT1("FATAL ERROR, can't create heap.\n");
RetCode = 1;
goto bye_bye;
}
GetWindowsDirectory(LogPath, MAX_PATH);
if (GetDriveType(LogPath) == DRIVE_CDROM)
{
DPRINT("LiveCD detected\n");
onLiveCD = TRUE;
}
else
{
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Services\\EventLog",
0,
KEY_ALL_ACCESS,
&elogKey);
if (result != ERROR_SUCCESS)
{
DPRINT1("Fatal error: can't open eventlog registry key.\n");
RetCode = 1;
goto bye_bye;
}
LoadLogFiles(elogKey);
}
StartServiceCtrlDispatcher(ServiceTable);
bye_bye:
LogfCloseAll();
if (MyHeap)
HeapDestroy(MyHeap);
return RetCode;
}
VOID EventTimeToSystemTime(DWORD EventTime, SYSTEMTIME * pSystemTime)
{
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
FILETIME ftLocal;
union
{
FILETIME ft;
ULONGLONG ll;
} u1970, uUCT;
uUCT.ft.dwHighDateTime = 0;
uUCT.ft.dwLowDateTime = EventTime;
SystemTimeToFileTime(&st1970, &u1970.ft);
uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
FileTimeToSystemTime(&ftLocal, pSystemTime);
}
VOID SystemTimeToEventTime(SYSTEMTIME * pSystemTime, DWORD * pEventTime)
{
SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
union
{
FILETIME ft;
ULONGLONG ll;
} Time, u1970;
SystemTimeToFileTime(pSystemTime, &Time.ft);
SystemTimeToFileTime(&st1970, &u1970.ft);
*pEventTime = (Time.ll - u1970.ll) / 10000000;
}
VOID PRINT_HEADER(PEVENTLOGHEADER header)
{
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("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 & 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");
}
VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
{
UINT i;
WCHAR *str;
SYSTEMTIME time;
DPRINT("Length = %d\n", pRec->Length);
DPRINT("Reserved = 0x%x\n", pRec->Reserved);
DPRINT("RecordNumber = %d\n", pRec->RecordNumber);
EventTimeToSystemTime(pRec->TimeGenerated, &time);
DPRINT("TimeGenerated = %d.%d.%d %d:%d:%d\n",
time.wDay, time.wMonth, time.wYear,
time.wHour, time.wMinute, time.wSecond);
EventTimeToSystemTime(pRec->TimeWritten, &time);
DPRINT("TimeWritten = %d.%d.%d %d:%d:%d\n",
time.wDay, time.wMonth, time.wYear,
time.wHour, time.wMinute, time.wSecond);
DPRINT("EventID = %d\n", pRec->EventID);
switch (pRec->EventType)
{
case EVENTLOG_ERROR_TYPE:
DPRINT("EventType = EVENTLOG_ERROR_TYPE\n");
break;
case EVENTLOG_WARNING_TYPE:
DPRINT("EventType = EVENTLOG_WARNING_TYPE\n");
break;
case EVENTLOG_INFORMATION_TYPE:
DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n");
break;
case EVENTLOG_AUDIT_SUCCESS:
DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n");
break;
case EVENTLOG_AUDIT_FAILURE:
DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n");
break;
default:
DPRINT("EventType = %d\n", pRec->EventType);
}
DPRINT("NumStrings = %d\n", pRec->NumStrings);
DPRINT("EventCategory = %d\n", pRec->EventCategory);
DPRINT("ReservedFlags = 0x%x\n", pRec->ReservedFlags);
DPRINT("ClosingRecordNumber = %d\n", pRec->ClosingRecordNumber);
DPRINT("StringOffset = %d\n", pRec->StringOffset);
DPRINT("UserSidLength = %d\n", pRec->UserSidLength);
DPRINT("UserSidOffset = %d\n", pRec->UserSidOffset);
DPRINT("DataLength = %d\n", pRec->DataLength);
DPRINT("DataOffset = %d\n", pRec->DataOffset);
DPRINT("SourceName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD)));
i = (lstrlenW((WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD))) + 1) *
sizeof(WCHAR);
DPRINT("ComputerName: %S\n", (WCHAR *) (((PBYTE) pRec) + sizeof(EVENTLOGRECORD) + i));
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
{
DPRINT("Strings:\n");
str = (WCHAR *) (((PBYTE) pRec) + pRec->StringOffset);
for (i = 0; i < pRec->NumStrings; i++)
{
DPRINT("[%d] %S\n", i, str);
str = str + lstrlenW(str) + 1;
}
}
DPRINT("Length2 = %d\n", *(PDWORD) (((PBYTE) pRec) + pRec->Length - 4));
}