reactos/base/services/eventlog/eventlog.c

621 lines
18 KiB
C
Raw Permalink Normal View History

/*
* PROJECT: ReactOS EventLog Service
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/services/eventlog/eventlog.c
* PURPOSE: Event logging service
* COPYRIGHT: Copyright 2002 Eric Kohl
* Copyright 2005 Saveliy Tretiakov
* Hermes Belusca-Maito
*/
/* INCLUDES *****************************************************************/
#include "eventlog.h"
#include <stdio.h>
#include <netevent.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ******************************************************************/
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
static VOID CALLBACK ServiceMain(DWORD, LPWSTR*);
static WCHAR ServiceName[] = L"EventLog";
static SERVICE_TABLE_ENTRYW ServiceTable[2] =
{
{ ServiceName, ServiceMain },
{ NULL, NULL }
};
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
BOOL onLiveCD = FALSE; // On LiveCD events will go to debug output only
PEVENTSOURCE EventLogSource = NULL;
/* FUNCTIONS ****************************************************************/
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");
LogfReportEvent(EVENTLOG_INFORMATION_TYPE,
0,
EVENT_EventlogStopped, 0, NULL, 0, NULL);
/* Stop listening to incoming RPC messages */
RpcMgmtStopServerListening(NULL);
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");
LogfReportEvent(EVENTLOG_INFORMATION_TYPE,
0,
EVENT_EventlogStopped, 0, NULL, 0, NULL);
UpdateServiceStatus(SERVICE_STOPPED);
return ERROR_SUCCESS;
default:
DPRINT1(" Control %lu received\n", dwControl);
return ERROR_CALL_NOT_IMPLEMENTED;
}
}
static DWORD
ServiceInit(VOID)
{
HANDLE hThread;
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)PortThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Cannot create PortThread\n");
return GetLastError();
}
else
CloseHandle(hThread);
hThread = CreateThread(NULL,
0,
RpcThreadRoutine,
NULL,
0,
NULL);
if (!hThread)
{
DPRINT("Cannot create RpcThread\n");
return GetLastError();
}
else
CloseHandle(hThread);
return ERROR_SUCCESS;
}
static VOID
ReportProductInfoEvent(VOID)
{
OSVERSIONINFOW versionInfo;
WCHAR szBuffer[512];
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
PWSTR str;
size_t cchRemain;
HKEY hKey;
DWORD dwValueLength;
DWORD dwType;
LONG lResult = ERROR_SUCCESS;
ZeroMemory(&versionInfo, sizeof(versionInfo));
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
/* Get version information */
if (!GetVersionExW(&versionInfo))
return;
ZeroMemory(szBuffer, sizeof(szBuffer));
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
str = szBuffer;
cchRemain = ARRAYSIZE(szBuffer);
/* Write the version number into the buffer */
StringCchPrintfExW(str, cchRemain,
&str, &cchRemain, 0,
L"%lu.%lu",
versionInfo.dwMajorVersion,
versionInfo.dwMinorVersion);
str++;
cchRemain++;
/* Write the build number into the buffer */
StringCchPrintfExW(str, cchRemain,
&str, &cchRemain, 0,
L"%lu",
versionInfo.dwBuildNumber);
str++;
cchRemain++;
/* Write the service pack info into the buffer */
StringCchCopyExW(str, cchRemain,
versionInfo.szCSDVersion,
&str, &cchRemain, 0);
str++;
cchRemain++;
/* Read 'CurrentType' from the registry and write it into the buffer */
lResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
0,
KEY_QUERY_VALUE,
&hKey);
if (lResult == ERROR_SUCCESS)
{
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
dwValueLength = cchRemain;
lResult = RegQueryValueExW(hKey,
L"CurrentType",
NULL,
&dwType,
(LPBYTE)str,
&dwValueLength);
RegCloseKey(hKey);
}
/* Log the product information */
LogfReportEvent(EVENTLOG_INFORMATION_TYPE,
0,
EVENT_EventLogProductInfo,
4,
szBuffer,
0,
NULL);
}
static VOID CALLBACK
ServiceMain(DWORD argc,
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
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);
ReportProductInfoEvent();
LogfReportEvent(EVENTLOG_INFORMATION_TYPE,
0,
EVENT_EventlogStarted,
0,
NULL,
0,
NULL);
}
DPRINT("ServiceMain() done\n");
}
static PLOGFILE
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
LoadLogFile(HKEY hKey, PWSTR LogName)
{
DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
PWSTR Buf = NULL, Expanded = NULL;
LONG Result;
PLOGFILE pLogf = NULL;
UNICODE_STRING FileName;
ULONG ulMaxSize, ulRetention;
NTSTATUS Status;
DPRINT("LoadLogFile: `%S'\n", LogName);
Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, &MaxValueLen, NULL, NULL);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
return NULL;
}
MaxValueLen = ROUND_DOWN(MaxValueLen, sizeof(WCHAR));
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
Buf = HeapAlloc(GetProcessHeap(), 0, MaxValueLen);
if (!Buf)
{
DPRINT1("Cannot allocate heap!\n");
return NULL;
}
ValueLen = MaxValueLen;
Result = RegQueryValueExW(hKey,
L"File",
NULL,
&Type,
(LPBYTE)Buf,
&ValueLen);
/*
* If we failed, because the registry value was inexistent
* or the value type was incorrect, create a new "File" value
* that holds the default event log path.
*/
if ((Result != ERROR_SUCCESS) || (Type != REG_EXPAND_SZ && Type != REG_SZ))
{
MaxValueLen = (wcslen(L"%SystemRoot%\\System32\\Config\\") +
wcslen(LogName) + wcslen(L".evt") + 1) * sizeof(WCHAR);
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
Expanded = HeapReAlloc(GetProcessHeap(), 0, Buf, MaxValueLen);
if (!Expanded)
{
DPRINT1("Cannot reallocate heap!\n");
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Buf);
return NULL;
}
Buf = Expanded;
StringCbCopyW(Buf, MaxValueLen, L"%SystemRoot%\\System32\\Config\\");
StringCbCatW(Buf, MaxValueLen, LogName);
StringCbCatW(Buf, MaxValueLen, L".evt");
ValueLen = MaxValueLen;
Result = RegSetValueExW(hKey,
L"File",
0,
REG_EXPAND_SZ,
(LPBYTE)Buf,
ValueLen);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegSetValueExW failed: %lu\n", Result);
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Buf);
return NULL;
}
}
ExpandedLen = ExpandEnvironmentStringsW(Buf, NULL, 0);
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
Expanded = HeapAlloc(GetProcessHeap(), 0, ExpandedLen * sizeof(WCHAR));
if (!Expanded)
{
DPRINT1("Cannot allocate heap!\n");
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Buf);
return NULL;
}
ExpandEnvironmentStringsW(Buf, Expanded, ExpandedLen);
if (!RtlDosPathNameToNtPathName_U(Expanded, &FileName, NULL, NULL))
{
DPRINT1("Cannot convert path!\n");
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Expanded);
HeapFree(GetProcessHeap(), 0, Buf);
return NULL;
}
DPRINT("%S -> %S\n", Buf, Expanded);
ValueLen = sizeof(ulMaxSize);
Result = RegQueryValueExW(hKey,
L"MaxSize",
NULL,
&Type,
(LPBYTE)&ulMaxSize,
&ValueLen);
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
{
ulMaxSize = 512 * 1024; /* 512 kBytes */
Result = RegSetValueExW(hKey,
L"MaxSize",
0,
REG_DWORD,
(LPBYTE)&ulMaxSize,
sizeof(ulMaxSize));
}
ValueLen = sizeof(ulRetention);
Result = RegQueryValueExW(hKey,
L"Retention",
NULL,
&Type,
(LPBYTE)&ulRetention,
&ValueLen);
if ((Result != ERROR_SUCCESS) || (Type != REG_DWORD))
{
/* On Windows 2003 it is 604800 (secs) == 7 days */
ulRetention = 0;
Result = RegSetValueExW(hKey,
L"Retention",
0,
REG_DWORD,
(LPBYTE)&ulRetention,
sizeof(ulRetention));
}
// TODO: Add, or use, default values for "AutoBackupLogFiles" (REG_DWORD)
// and "CustomSD" (REG_SZ).
Status = LogfCreate(&pLogf, LogName, &FileName, ulMaxSize, ulRetention, TRUE, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create %S! (Status %08lx)\n", Expanded, Status);
}
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Expanded);
HeapFree(GetProcessHeap(), 0, Buf);
return pLogf;
}
static BOOL
LoadLogFiles(HKEY eventlogKey)
{
LONG Result;
DWORD MaxLognameLen, LognameLen;
DWORD dwIndex;
PWSTR Buf = NULL;
PLOGFILE pLogFile;
Result = RegQueryInfoKeyW(eventlogKey, NULL, NULL, NULL, NULL, &MaxLognameLen,
NULL, NULL, NULL, NULL, NULL, NULL);
if (Result != ERROR_SUCCESS)
{
DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
return FALSE;
}
MaxLognameLen++;
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
Buf = HeapAlloc(GetProcessHeap(), 0, MaxLognameLen * sizeof(WCHAR));
if (!Buf)
{
DPRINT1("Error: cannot allocate heap!\n");
return FALSE;
}
LognameLen = MaxLognameLen;
dwIndex = 0;
while (RegEnumKeyExW(eventlogKey,
dwIndex,
Buf,
&LognameLen,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY SubKey;
DPRINT("%S\n", Buf);
Result = RegOpenKeyExW(eventlogKey, Buf, 0, KEY_ALL_ACCESS, &SubKey);
if (Result != ERROR_SUCCESS)
{
DPRINT1("Failed to open %S key.\n", Buf);
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Buf);
return FALSE;
}
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;
dwIndex++;
}
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
HeapFree(GetProcessHeap(), 0, Buf);
return TRUE;
}
int wmain(int argc, WCHAR* argv[])
{
INT RetCode = 0;
LONG Result;
HKEY elogKey;
WCHAR LogPath[MAX_PATH];
LogfListInitialize();
InitEventSourceList();
GetSystemWindowsDirectoryW(LogPath, ARRAYSIZE(LogPath));
if (GetDriveTypeW(LogPath) == DRIVE_CDROM)
{
DPRINT("LiveCD detected\n");
onLiveCD = TRUE;
}
else
{
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Services\\EventLog",
0,
KEY_ALL_ACCESS,
&elogKey);
if (Result != ERROR_SUCCESS)
{
DPRINT1("Fatal error: cannot open eventlog registry key.\n");
RetCode = 1;
goto bye_bye;
}
LoadLogFiles(elogKey);
}
EventLogSource = GetEventSourceByName(L"EventLog");
if (!EventLogSource)
{
DPRINT1("The 'EventLog' source is unavailable. The EventLog service will not be able to log its own events.\n");
}
StartServiceCtrlDispatcher(ServiceTable);
bye_bye:
LogfCloseAll();
return RetCode;
}
VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
{
UINT i;
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
PWSTR str;
LARGE_INTEGER SystemTime;
TIME_FIELDS Time;
DPRINT1("PRINT_RECORD(0x%p)\n", pRec);
DbgPrint("Length = %lu\n", pRec->Length);
DbgPrint("Reserved = 0x%x\n", pRec->Reserved);
DbgPrint("RecordNumber = %lu\n", pRec->RecordNumber);
RtlSecondsSince1970ToTime(pRec->TimeGenerated, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
DbgPrint("TimeGenerated = %hu.%hu.%hu %hu:%hu:%hu\n",
Time.Day, Time.Month, Time.Year,
Time.Hour, Time.Minute, Time.Second);
RtlSecondsSince1970ToTime(pRec->TimeWritten, &SystemTime);
RtlTimeToTimeFields(&SystemTime, &Time);
DbgPrint("TimeWritten = %hu.%hu.%hu %hu:%hu:%hu\n",
Time.Day, Time.Month, Time.Year,
Time.Hour, Time.Minute, Time.Second);
DbgPrint("EventID = %lu\n", pRec->EventID);
switch (pRec->EventType)
{
case EVENTLOG_ERROR_TYPE:
DbgPrint("EventType = EVENTLOG_ERROR_TYPE\n");
break;
case EVENTLOG_WARNING_TYPE:
DbgPrint("EventType = EVENTLOG_WARNING_TYPE\n");
break;
case EVENTLOG_INFORMATION_TYPE:
DbgPrint("EventType = EVENTLOG_INFORMATION_TYPE\n");
break;
case EVENTLOG_AUDIT_SUCCESS:
DbgPrint("EventType = EVENTLOG_AUDIT_SUCCESS\n");
break;
case EVENTLOG_AUDIT_FAILURE:
DbgPrint("EventType = EVENTLOG_AUDIT_FAILURE\n");
break;
default:
DbgPrint("EventType = %hu\n", pRec->EventType);
}
DbgPrint("NumStrings = %hu\n", pRec->NumStrings);
DbgPrint("EventCategory = %hu\n", pRec->EventCategory);
DbgPrint("ReservedFlags = 0x%x\n", pRec->ReservedFlags);
DbgPrint("ClosingRecordNumber = %lu\n", pRec->ClosingRecordNumber);
DbgPrint("StringOffset = %lu\n", pRec->StringOffset);
DbgPrint("UserSidLength = %lu\n", pRec->UserSidLength);
DbgPrint("UserSidOffset = %lu\n", pRec->UserSidOffset);
DbgPrint("DataLength = %lu\n", pRec->DataLength);
DbgPrint("DataOffset = %lu\n", pRec->DataOffset);
i = sizeof(EVENTLOGRECORD);
DbgPrint("SourceName: %S\n", (PWSTR)((ULONG_PTR)pRec + i));
i += (wcslen((PWSTR)((ULONG_PTR)pRec + i)) + 1) * sizeof(WCHAR);
DbgPrint("ComputerName: %S\n", (PWSTR)((ULONG_PTR)pRec + i));
if (pRec->StringOffset < pRec->Length && pRec->NumStrings)
{
DbgPrint("Strings:\n");
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
str = (PWSTR)((ULONG_PTR)pRec + pRec->StringOffset);
for (i = 0; i < pRec->NumStrings; i++)
{
DbgPrint("[%u] %S\n", i, str);
[EVENTLOG] - Get rid of MyHeap. - Continue using safe string functions. - Allow event logs themselves to be their own source. And store the full list of log sources in the "Sources" registry multi-string value. - Correctly compute the number of records. - Correctly return the event number and the write timestamp of reported events. - Use a helper function for ElfrReportEventW/A and for ElfrReportEventAndSourceW that is now implemented. - Rewrite the file.c functions using NT-APIs almost exclusively for file operations. - Modify the logic of LogfReadEvents so that a RecordNumber == 0 in sequential read mode means we need to determine where to start the read operation, depending on whether a forwards-read or a backwards-read is performed. The log handle's CurrentRecord member is therefore initialized to 0 before usage. - Adjust LogfAllocAndBuildNewRecord to take in input the event generation timestamp. - Do not "compute" the RecordNumber of the new event in LogfAllocAndBuildNewRecord; it will be consistently assigned by LogfWriteRecord. - Correctly initialize the OldestRecordNumber to zero for new (empty) logs. - Perform extensive log validity checks when opening existing logs: log header and EOF record as well as boundary checks. - Rewrite almost of the functions to support event log wrapping (see https://msdn.microsoft.com/en-us/library/windows/desktop/bb309026(v=vs.85).aspx ) and splitted records. Now our event logs are not corrupted anymore, and are readable under Windows 2k/xp/2k3/Vista+. - As a consequence of supporting wrapping event logs we need to iterate through them at loading time in order to locate the valid EOF record (indeed it may happen that the log header is not correctly synced, and its Start/EndOffsets are invalid. The EOF record offsets contain on the other way the correct values). The file.c fixes are a bit still work-in-progress, but the bulk of the code works. It is extensively tested in situ in my local VM since 2 months now. CORE-11843 #resolve svn path=/trunk/; revision=72236
2016-08-16 21:08:15 +00:00
str += wcslen(str) + 1;
}
}
DbgPrint("Length2 = %lu\n", *(PULONG)((ULONG_PTR)pRec + pRec->Length - 4));
}