mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 00:31:27 +00:00
[EVTLIB]: Create a EvtLib library for manipulating the event log file format from anywhere.
[EVENTLOG]: Make usage of this library. CORE-11868 #resolve #comment Committed in r73035. [EVENTLOG]: Protect the global handle table with a lock as it seems to me that this needs serialization. Please notify me if you think this is not actually necessary (and I'll revert that in case). svn path=/trunk/; revision=73035
This commit is contained in:
parent
34a06851d3
commit
1f9c38b3b9
9 changed files with 2472 additions and 1785 deletions
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
${REACTOS_SOURCE_DIR}/sdk/lib/evtlib
|
||||||
${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl
|
${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl
|
||||||
${CMAKE_CURRENT_BINARY_DIR})
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
@ -15,12 +16,13 @@ list(APPEND SOURCE
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/eventlogrpc_s.c)
|
${CMAKE_CURRENT_BINARY_DIR}/eventlogrpc_s.c)
|
||||||
|
|
||||||
add_executable(eventlog ${SOURCE} eventlog.rc)
|
add_executable(eventlog ${SOURCE} eventlog.rc)
|
||||||
|
add_pch(eventlog eventlog.h SOURCE)
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
target_link_libraries(eventlog ${PSEH_LIB})
|
target_link_libraries(eventlog ${PSEH_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_module_type(eventlog win32cui UNICODE)
|
set_module_type(eventlog win32cui UNICODE)
|
||||||
|
target_link_libraries(eventlog evtlib)
|
||||||
add_importlibs(eventlog advapi32 rpcrt4 msvcrt kernel32 ntdll)
|
add_importlibs(eventlog advapi32 rpcrt4 msvcrt kernel32 ntdll)
|
||||||
add_pch(eventlog eventlog.h SOURCE)
|
|
||||||
add_cd_file(TARGET eventlog DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET eventlog DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -541,49 +541,6 @@ bye_bye:
|
||||||
return RetCode;
|
return RetCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PRINT_HEADER(PEVENTLOGHEADER header)
|
|
||||||
{
|
|
||||||
ULONG Flags = header->Flags;
|
|
||||||
|
|
||||||
DPRINT("HeaderSize = %lu\n", header->HeaderSize);
|
|
||||||
DPRINT("Signature = 0x%x\n", header->Signature);
|
|
||||||
DPRINT("MajorVersion = %lu\n", header->MajorVersion);
|
|
||||||
DPRINT("MinorVersion = %lu\n", header->MinorVersion);
|
|
||||||
DPRINT("StartOffset = %lu\n", header->StartOffset);
|
|
||||||
DPRINT("EndOffset = 0x%x\n", header->EndOffset);
|
|
||||||
DPRINT("CurrentRecordNumber = %lu\n", header->CurrentRecordNumber);
|
|
||||||
DPRINT("OldestRecordNumber = %lu\n", header->OldestRecordNumber);
|
|
||||||
DPRINT("MaxSize = 0x%x\n", header->MaxSize);
|
|
||||||
DPRINT("Retention = 0x%x\n", header->Retention);
|
|
||||||
DPRINT("EndHeaderSize = %lu\n", header->EndHeaderSize);
|
|
||||||
DPRINT("Flags: ");
|
|
||||||
if (Flags & ELF_LOGFILE_HEADER_DIRTY)
|
|
||||||
{
|
|
||||||
DPRINT("ELF_LOGFILE_HEADER_DIRTY");
|
|
||||||
Flags &= ~ELF_LOGFILE_HEADER_DIRTY;
|
|
||||||
}
|
|
||||||
if (Flags) DPRINT(" | ");
|
|
||||||
if (Flags & ELF_LOGFILE_HEADER_WRAP)
|
|
||||||
{
|
|
||||||
DPRINT("ELF_LOGFILE_HEADER_WRAP");
|
|
||||||
Flags &= ~ELF_LOGFILE_HEADER_WRAP;
|
|
||||||
}
|
|
||||||
if (Flags) DPRINT(" | ");
|
|
||||||
if (Flags & ELF_LOGFILE_LOGFULL_WRITTEN)
|
|
||||||
{
|
|
||||||
DPRINT("ELF_LOGFILE_LOGFULL_WRITTEN");
|
|
||||||
Flags &= ~ELF_LOGFILE_LOGFULL_WRITTEN;
|
|
||||||
}
|
|
||||||
if (Flags) DPRINT(" | ");
|
|
||||||
if (Flags & ELF_LOGFILE_ARCHIVE_SET)
|
|
||||||
{
|
|
||||||
DPRINT("ELF_LOGFILE_ARCHIVE_SET");
|
|
||||||
Flags &= ~ELF_LOGFILE_ARCHIVE_SET;
|
|
||||||
}
|
|
||||||
if (Flags) DPRINT(" | 0x%x", Flags);
|
|
||||||
DPRINT("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
|
@ -23,82 +23,29 @@
|
||||||
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
|
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
|
||||||
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
|
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
|
||||||
|
|
||||||
|
#include <evtlib.h>
|
||||||
|
|
||||||
#include <eventlogrpc_s.h>
|
#include <eventlogrpc_s.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
// FIXME: For that we may directly include NTOS header??
|
||||||
typedef struct _IO_ERROR_LPC
|
typedef struct _IO_ERROR_LPC
|
||||||
{
|
{
|
||||||
PORT_MESSAGE Header;
|
PORT_MESSAGE Header;
|
||||||
IO_ERROR_LOG_MESSAGE Message;
|
IO_ERROR_LOG_MESSAGE Message;
|
||||||
} IO_ERROR_LPC, *PIO_ERROR_LPC;
|
} IO_ERROR_LPC, *PIO_ERROR_LPC;
|
||||||
|
|
||||||
|
// C_ASSERT(sizeof(IO_ERROR_LPC) == 0x100);
|
||||||
|
|
||||||
/*
|
/* Defined in evtlib.h */
|
||||||
* Our file format will be compatible with NT's
|
// #define LOGFILE_SIGNATURE 0x654c664c // "LfLe"
|
||||||
*/
|
|
||||||
#define MAJORVER 1
|
|
||||||
#define MINORVER 1
|
|
||||||
#define LOGFILE_SIGNATURE 0x654c664c
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Flags used in logfile header
|
|
||||||
*/
|
|
||||||
#define ELF_LOGFILE_HEADER_DIRTY 1
|
|
||||||
#define ELF_LOGFILE_HEADER_WRAP 2
|
|
||||||
#define ELF_LOGFILE_LOGFULL_WRITTEN 4
|
|
||||||
#define ELF_LOGFILE_ARCHIVE_SET 8
|
|
||||||
|
|
||||||
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
|
|
||||||
typedef struct _EVENTLOGHEADER
|
|
||||||
{
|
|
||||||
ULONG HeaderSize;
|
|
||||||
ULONG Signature;
|
|
||||||
ULONG MajorVersion;
|
|
||||||
ULONG MinorVersion;
|
|
||||||
ULONG StartOffset;
|
|
||||||
ULONG EndOffset;
|
|
||||||
ULONG CurrentRecordNumber;
|
|
||||||
ULONG OldestRecordNumber;
|
|
||||||
ULONG MaxSize;
|
|
||||||
ULONG Flags;
|
|
||||||
ULONG Retention;
|
|
||||||
ULONG EndHeaderSize;
|
|
||||||
} EVENTLOGHEADER, *PEVENTLOGHEADER;
|
|
||||||
|
|
||||||
typedef struct _EVENTLOGEOF
|
|
||||||
{
|
|
||||||
ULONG RecordSizeBeginning;
|
|
||||||
ULONG Ones;
|
|
||||||
ULONG Twos;
|
|
||||||
ULONG Threes;
|
|
||||||
ULONG Fours;
|
|
||||||
ULONG BeginRecord;
|
|
||||||
ULONG EndRecord;
|
|
||||||
ULONG CurrentRecordNumber;
|
|
||||||
ULONG OldestRecordNumber;
|
|
||||||
ULONG RecordSizeEnd;
|
|
||||||
} EVENTLOGEOF, *PEVENTLOGEOF;
|
|
||||||
|
|
||||||
#define EVENTLOGEOF_SIZE_FIXED (5 * sizeof(ULONG))
|
|
||||||
C_ASSERT(EVENTLOGEOF_SIZE_FIXED == FIELD_OFFSET(EVENTLOGEOF, BeginRecord));
|
|
||||||
|
|
||||||
typedef struct _EVENT_OFFSET_INFO
|
|
||||||
{
|
|
||||||
ULONG EventNumber;
|
|
||||||
ULONG EventOffset;
|
|
||||||
} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
|
|
||||||
|
|
||||||
typedef struct _LOGFILE
|
typedef struct _LOGFILE
|
||||||
{
|
{
|
||||||
HANDLE hFile;
|
EVTLOGFILE LogFile;
|
||||||
EVENTLOGHEADER Header;
|
HANDLE FileHandle;
|
||||||
ULONG CurrentSize; /* Equivalent to the file size, is <= MaxSize and can be extended to MaxSize if needed */
|
|
||||||
WCHAR *LogName;
|
WCHAR *LogName;
|
||||||
WCHAR *FileName;
|
|
||||||
RTL_RESOURCE Lock;
|
RTL_RESOURCE Lock;
|
||||||
PEVENT_OFFSET_INFO OffsetInfo;
|
|
||||||
ULONG OffsetInfoSize;
|
|
||||||
ULONG OffsetInfoNext;
|
|
||||||
BOOL Permanent;
|
BOOL Permanent;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
} LOGFILE, *PLOGFILE;
|
} LOGFILE, *PLOGFILE;
|
||||||
|
@ -128,7 +75,6 @@ typedef struct _LOGHANDLE
|
||||||
/* eventlog.c */
|
/* eventlog.c */
|
||||||
extern PEVENTSOURCE EventLogSource;
|
extern PEVENTSOURCE EventLogSource;
|
||||||
|
|
||||||
VOID PRINT_HEADER(PEVENTLOGHEADER header);
|
|
||||||
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
|
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,7 +96,28 @@ PLOGFILE LogfListItemByIndex(DWORD Index);
|
||||||
PLOGFILE LogfListItemByName(LPCWSTR Name);
|
PLOGFILE LogfListItemByName(LPCWSTR Name);
|
||||||
// DWORD LogfListItemIndexByName(WCHAR * Name);
|
// DWORD LogfListItemIndexByName(WCHAR * Name);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
LogfCreate(PLOGFILE* LogFile,
|
||||||
|
PCWSTR LogName,
|
||||||
|
PUNICODE_STRING FileName,
|
||||||
|
ULONG MaxSize,
|
||||||
|
ULONG Retention,
|
||||||
|
BOOLEAN Permanent,
|
||||||
|
BOOLEAN Backup);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
LogfClose(PLOGFILE LogFile,
|
||||||
|
BOOLEAN ForceClose);
|
||||||
|
|
||||||
|
VOID LogfCloseAll(VOID);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
LogfClearFile(PLOGFILE LogFile,
|
||||||
|
PUNICODE_STRING BackupFileName);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
LogfBackupFile(PLOGFILE LogFile,
|
||||||
|
PUNICODE_STRING BackupFileName);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LogfReadEvents(PLOGFILE LogFile,
|
LogfReadEvents(PLOGFILE LogFile,
|
||||||
|
@ -164,31 +131,8 @@ LogfReadEvents(PLOGFILE LogFile,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LogfWriteRecord(PLOGFILE LogFile,
|
LogfWriteRecord(PLOGFILE LogFile,
|
||||||
ULONG BufSize, // SIZE_T
|
PEVENTLOGRECORD Record,
|
||||||
PEVENTLOGRECORD Record);
|
SIZE_T BufSize);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
LogfClearFile(PLOGFILE LogFile,
|
|
||||||
PUNICODE_STRING BackupFileName);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
LogfBackupFile(PLOGFILE LogFile,
|
|
||||||
PUNICODE_STRING BackupFileName);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
LogfCreate(PLOGFILE* LogFile,
|
|
||||||
PCWSTR LogName,
|
|
||||||
PUNICODE_STRING FileName,
|
|
||||||
ULONG ulMaxSize,
|
|
||||||
ULONG ulRetention,
|
|
||||||
BOOLEAN Permanent,
|
|
||||||
BOOLEAN Backup);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
LogfClose(PLOGFILE LogFile,
|
|
||||||
BOOLEAN ForceClose);
|
|
||||||
|
|
||||||
VOID LogfCloseAll(VOID);
|
|
||||||
|
|
||||||
PEVENTLOGRECORD
|
PEVENTLOGRECORD
|
||||||
LogfAllocAndBuildNewRecord(PSIZE_T pRecSize,
|
LogfAllocAndBuildNewRecord(PSIZE_T pRecSize,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -187,11 +187,11 @@ NTSTATUS ProcessPortMessage(VOID)
|
||||||
|
|
||||||
if (!onLiveCD && SystemLog)
|
if (!onLiveCD && SystemLog)
|
||||||
{
|
{
|
||||||
Status = LogfWriteRecord(SystemLog, RecSize, pRec);
|
Status = LogfWriteRecord(SystemLog, pRec, RecSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
|
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
|
||||||
SystemLog->FileName, Status);
|
SystemLog->LogName, Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,27 +16,32 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
static LIST_ENTRY LogHandleListHead;
|
static LIST_ENTRY LogHandleListHead;
|
||||||
|
static CRITICAL_SECTION LogHandleListCs;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle);
|
||||||
|
|
||||||
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
|
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
|
||||||
{
|
{
|
||||||
RPC_STATUS Status;
|
RPC_STATUS Status;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&LogHandleListCs);
|
||||||
InitializeListHead(&LogHandleListHead);
|
InitializeListHead(&LogHandleListHead);
|
||||||
|
|
||||||
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL);
|
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL);
|
||||||
if (Status != RPC_S_OK)
|
if (Status != RPC_S_OK)
|
||||||
{
|
{
|
||||||
DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
|
DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
|
||||||
return 0;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = RpcServerRegisterIf(eventlog_v0_0_s_ifspec, NULL, NULL);
|
Status = RpcServerRegisterIf(eventlog_v0_0_s_ifspec, NULL, NULL);
|
||||||
if (Status != RPC_S_OK)
|
if (Status != RPC_S_OK)
|
||||||
{
|
{
|
||||||
DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status);
|
DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status);
|
||||||
return 0;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
|
Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
|
||||||
|
@ -45,6 +50,17 @@ DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
|
||||||
DPRINT("RpcServerListen() failed (Status %lx)\n", Status);
|
DPRINT("RpcServerListen() failed (Status %lx)\n", Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection(&LogHandleListCs);
|
||||||
|
while (!IsListEmpty(&LogHandleListHead))
|
||||||
|
{
|
||||||
|
IELF_HANDLE LogHandle = (IELF_HANDLE)CONTAINING_RECORD(LogHandleListHead.Flink, LOGHANDLE, LogHandleListEntry);
|
||||||
|
ElfDeleteEventLogHandle(&LogHandle);
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&LogHandleListCs);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
DeleteCriticalSection(&LogHandleListCs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +159,9 @@ Done:
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Append log handle */
|
/* Append log handle */
|
||||||
|
EnterCriticalSection(&LogHandleListCs);
|
||||||
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
|
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
|
||||||
|
LeaveCriticalSection(&LogHandleListCs);
|
||||||
*LogHandle = pLogHandle;
|
*LogHandle = pLogHandle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -199,7 +217,9 @@ Done:
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Append log handle */
|
/* Append log handle */
|
||||||
|
EnterCriticalSection(&LogHandleListCs);
|
||||||
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
|
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
|
||||||
|
LeaveCriticalSection(&LogHandleListCs);
|
||||||
*LogHandle = pLogHandle;
|
*LogHandle = pLogHandle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -215,21 +235,28 @@ static PLOGHANDLE
|
||||||
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PLOGHANDLE pLogHandle;
|
PLOGHANDLE Handle, pLogHandle = NULL;
|
||||||
|
|
||||||
|
EnterCriticalSection(&LogHandleListCs);
|
||||||
|
|
||||||
CurrentEntry = LogHandleListHead.Flink;
|
CurrentEntry = LogHandleListHead.Flink;
|
||||||
while (CurrentEntry != &LogHandleListHead)
|
while (CurrentEntry != &LogHandleListHead)
|
||||||
{
|
{
|
||||||
pLogHandle = CONTAINING_RECORD(CurrentEntry,
|
Handle = CONTAINING_RECORD(CurrentEntry,
|
||||||
LOGHANDLE,
|
LOGHANDLE,
|
||||||
LogHandleListEntry);
|
LogHandleListEntry);
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
|
||||||
if (pLogHandle == EventLogHandle)
|
if (Handle == EventLogHandle)
|
||||||
return pLogHandle;
|
{
|
||||||
|
pLogHandle = Handle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
LeaveCriticalSection(&LogHandleListCs);
|
||||||
|
|
||||||
|
return pLogHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,7 +269,10 @@ ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle)
|
||||||
if (!pLogHandle)
|
if (!pLogHandle)
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
EnterCriticalSection(&LogHandleListCs);
|
||||||
RemoveEntryList(&pLogHandle->LogHandleListEntry);
|
RemoveEntryList(&pLogHandle->LogHandleListEntry);
|
||||||
|
LeaveCriticalSection(&LogHandleListCs);
|
||||||
|
|
||||||
LogfClose(pLogHandle->LogFile, FALSE);
|
LogfClose(pLogHandle->LogFile, FALSE);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, pLogHandle);
|
HeapFree(GetProcessHeap(), 0, pLogHandle);
|
||||||
|
@ -321,6 +351,7 @@ ElfrNumberOfRecords(
|
||||||
{
|
{
|
||||||
PLOGHANDLE pLogHandle;
|
PLOGHANDLE pLogHandle;
|
||||||
PLOGFILE pLogFile;
|
PLOGFILE pLogFile;
|
||||||
|
ULONG OldestRecordNumber, CurrentRecordNumber;
|
||||||
|
|
||||||
DPRINT("ElfrNumberOfRecords()\n");
|
DPRINT("ElfrNumberOfRecords()\n");
|
||||||
|
|
||||||
|
@ -333,11 +364,19 @@ ElfrNumberOfRecords(
|
||||||
|
|
||||||
pLogFile = pLogHandle->LogFile;
|
pLogFile = pLogHandle->LogFile;
|
||||||
|
|
||||||
DPRINT("Oldest: %lu Current: %lu\n",
|
/* Lock the log file shared */
|
||||||
pLogFile->Header.OldestRecordNumber,
|
RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
|
||||||
pLogFile->Header.CurrentRecordNumber);
|
|
||||||
|
|
||||||
if (pLogFile->Header.OldestRecordNumber == 0)
|
OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile);
|
||||||
|
CurrentRecordNumber = ElfGetCurrentRecord(&pLogFile->LogFile);
|
||||||
|
|
||||||
|
/* Unlock the log file */
|
||||||
|
RtlReleaseResource(&pLogFile->Lock);
|
||||||
|
|
||||||
|
DPRINT("Oldest: %lu Current: %lu\n",
|
||||||
|
OldestRecordNumber, CurrentRecordNumber);
|
||||||
|
|
||||||
|
if (OldestRecordNumber == 0)
|
||||||
{
|
{
|
||||||
/* OldestRecordNumber == 0 when the log is empty */
|
/* OldestRecordNumber == 0 when the log is empty */
|
||||||
*NumberOfRecords = 0;
|
*NumberOfRecords = 0;
|
||||||
|
@ -345,8 +384,7 @@ ElfrNumberOfRecords(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The log contains events */
|
/* The log contains events */
|
||||||
*NumberOfRecords = pLogFile->Header.CurrentRecordNumber -
|
*NumberOfRecords = CurrentRecordNumber - OldestRecordNumber;
|
||||||
pLogFile->Header.OldestRecordNumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -360,6 +398,7 @@ ElfrOldestRecord(
|
||||||
PULONG OldestRecordNumber)
|
PULONG OldestRecordNumber)
|
||||||
{
|
{
|
||||||
PLOGHANDLE pLogHandle;
|
PLOGHANDLE pLogHandle;
|
||||||
|
PLOGFILE pLogFile;
|
||||||
|
|
||||||
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!pLogHandle)
|
if (!pLogHandle)
|
||||||
|
@ -368,7 +407,15 @@ ElfrOldestRecord(
|
||||||
if (!OldestRecordNumber)
|
if (!OldestRecordNumber)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
*OldestRecordNumber = pLogHandle->LogFile->Header.OldestRecordNumber;
|
pLogFile = pLogHandle->LogFile;
|
||||||
|
|
||||||
|
/* Lock the log file shared */
|
||||||
|
RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
|
||||||
|
|
||||||
|
*OldestRecordNumber = ElfGetOldestRecord(&pLogFile->LogFile);
|
||||||
|
|
||||||
|
/* Unlock the log file */
|
||||||
|
RtlReleaseResource(&pLogFile->Lock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -624,7 +671,7 @@ ElfrIntReportEventW(
|
||||||
DataSize,
|
DataSize,
|
||||||
Data);
|
Data);
|
||||||
|
|
||||||
Status = LogfWriteRecord(pLogHandle->LogFile, RecSize, LogBuffer);
|
Status = LogfWriteRecord(pLogHandle->LogFile, LogBuffer, RecSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
|
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
|
||||||
|
@ -1068,11 +1115,17 @@ ElfrGetLogInformation(
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PLOGHANDLE pLogHandle;
|
PLOGHANDLE pLogHandle;
|
||||||
|
PLOGFILE pLogFile;
|
||||||
|
|
||||||
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!pLogHandle)
|
if (!pLogHandle)
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
pLogFile = pLogHandle->LogFile;
|
||||||
|
|
||||||
|
/* Lock the log file shared */
|
||||||
|
RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
|
||||||
|
|
||||||
switch (InfoLevel)
|
switch (InfoLevel)
|
||||||
{
|
{
|
||||||
case EVENTLOG_FULL_INFO:
|
case EVENTLOG_FULL_INFO:
|
||||||
|
@ -1086,12 +1139,7 @@ ElfrGetLogInformation(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
efi->dwFull = !!(ElfGetFlags(&pLogFile->LogFile) & ELF_LOGFILE_LOGFULL_WRITTEN);
|
||||||
* FIXME. To check whether an event log is "full" one needs
|
|
||||||
* to compare its current size with respect to the maximum
|
|
||||||
* size threshold "MaxSize" contained in its header.
|
|
||||||
*/
|
|
||||||
efi->dwFull = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,6 +1148,9 @@ ElfrGetLogInformation(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unlock the log file */
|
||||||
|
RtlReleaseResource(&pLogFile->Lock);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,14 +1160,25 @@ NTSTATUS
|
||||||
ElfrFlushEL(
|
ElfrFlushEL(
|
||||||
IELF_HANDLE LogHandle)
|
IELF_HANDLE LogHandle)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
PLOGHANDLE pLogHandle;
|
PLOGHANDLE pLogHandle;
|
||||||
|
PLOGFILE pLogFile;
|
||||||
|
|
||||||
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
|
||||||
if (!pLogHandle)
|
if (!pLogHandle)
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
pLogFile = pLogHandle->LogFile;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
|
/* Lock the log file exclusive */
|
||||||
|
RtlAcquireResourceExclusive(&pLogFile->Lock, TRUE);
|
||||||
|
|
||||||
|
Status = ElfFlushFile(&pLogFile->LogFile);
|
||||||
|
|
||||||
|
/* Unlock the log file */
|
||||||
|
RtlReleaseResource(&pLogFile->Lock);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
5
reactos/sdk/lib/evtlib/CMakeLists.txt
Normal file
5
reactos/sdk/lib/evtlib/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
## FIXME: Make the library cross-compiling aware (like cmlib or inflib)
|
||||||
|
|
||||||
|
add_library(evtlib evtlib.c)
|
||||||
|
add_dependencies(evtlib xdk)
|
1660
reactos/sdk/lib/evtlib/evtlib.c
Normal file
1660
reactos/sdk/lib/evtlib/evtlib.c
Normal file
File diff suppressed because it is too large
Load diff
291
reactos/sdk/lib/evtlib/evtlib.h
Normal file
291
reactos/sdk/lib/evtlib/evtlib.h
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS EventLog File Library
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: sdk/lib/evtlib/evtlib.h
|
||||||
|
* PURPOSE: Provides a library for reading and writing EventLog files
|
||||||
|
* in the NT <= 5.2 (.evt) format.
|
||||||
|
* PROGRAMMERS: Copyright 2005 Saveliy Tretiakov
|
||||||
|
* Michael Martin
|
||||||
|
* Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EVTLIB_H__
|
||||||
|
#define __EVTLIB_H__
|
||||||
|
|
||||||
|
/* PSDK/NDK Headers */
|
||||||
|
// #define WIN32_NO_STATUS
|
||||||
|
// #include <windef.h>
|
||||||
|
// #include <winbase.h>
|
||||||
|
// #include <winnt.h>
|
||||||
|
|
||||||
|
#define NTOS_MODE_USER
|
||||||
|
#include <ndk/rtlfuncs.h>
|
||||||
|
|
||||||
|
#ifndef ROUND_DOWN
|
||||||
|
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ROUND_UP
|
||||||
|
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our file format will be compatible with NT's
|
||||||
|
*/
|
||||||
|
#define MAJORVER 1
|
||||||
|
#define MINORVER 1
|
||||||
|
#define LOGFILE_SIGNATURE 0x654c664c // "LfLe"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags used in the logfile header
|
||||||
|
*/
|
||||||
|
#define ELF_LOGFILE_HEADER_DIRTY 1
|
||||||
|
#define ELF_LOGFILE_HEADER_WRAP 2
|
||||||
|
#define ELF_LOGFILE_LOGFULL_WRITTEN 4
|
||||||
|
#define ELF_LOGFILE_ARCHIVE_SET 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On-disk event log structures (log file header, event record and EOF record).
|
||||||
|
* NOTE: Contrary to what MSDN claims, both the EVENTLOGHEADER and EVENTLOGEOF
|
||||||
|
* structures are absent from winnt.h .
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pshpack4.h> // pshpack1
|
||||||
|
|
||||||
|
// ELF_LOGFILE_HEADER
|
||||||
|
typedef struct _EVENTLOGHEADER
|
||||||
|
{
|
||||||
|
ULONG HeaderSize;
|
||||||
|
ULONG Signature;
|
||||||
|
ULONG MajorVersion;
|
||||||
|
ULONG MinorVersion;
|
||||||
|
ULONG StartOffset;
|
||||||
|
ULONG EndOffset;
|
||||||
|
ULONG CurrentRecordNumber;
|
||||||
|
ULONG OldestRecordNumber;
|
||||||
|
ULONG MaxSize;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Retention;
|
||||||
|
ULONG EndHeaderSize;
|
||||||
|
} EVENTLOGHEADER, *PEVENTLOGHEADER;
|
||||||
|
|
||||||
|
|
||||||
|
/* Those flags and structure are defined in winnt.h */
|
||||||
|
#ifndef _WINNT_
|
||||||
|
|
||||||
|
/* EventType flags */
|
||||||
|
#define EVENTLOG_SUCCESS 0
|
||||||
|
#define EVENTLOG_ERROR_TYPE 1
|
||||||
|
#define EVENTLOG_WARNING_TYPE 2
|
||||||
|
#define EVENTLOG_INFORMATION_TYPE 4
|
||||||
|
#define EVENTLOG_AUDIT_SUCCESS 8
|
||||||
|
#define EVENTLOG_AUDIT_FAILURE 16
|
||||||
|
|
||||||
|
typedef struct _EVENTLOGRECORD
|
||||||
|
{
|
||||||
|
ULONG Length; /* Length of full record, including the data portion */
|
||||||
|
ULONG Reserved;
|
||||||
|
ULONG RecordNumber;
|
||||||
|
ULONG TimeGenerated;
|
||||||
|
ULONG TimeWritten;
|
||||||
|
ULONG EventID;
|
||||||
|
USHORT EventType;
|
||||||
|
USHORT NumStrings; /* Number of strings in the 'Strings' array */
|
||||||
|
USHORT EventCategory;
|
||||||
|
USHORT ReservedFlags;
|
||||||
|
ULONG ClosingRecordNumber;
|
||||||
|
ULONG StringOffset;
|
||||||
|
ULONG UserSidLength;
|
||||||
|
ULONG UserSidOffset;
|
||||||
|
ULONG DataLength; /* Length of the data portion */
|
||||||
|
ULONG DataOffset; /* Offset from beginning of record */
|
||||||
|
/*
|
||||||
|
* Length-varying data:
|
||||||
|
*
|
||||||
|
* WCHAR SourceName[];
|
||||||
|
* WCHAR ComputerName[];
|
||||||
|
* SID UserSid; // Must be aligned on a DWORD boundary
|
||||||
|
* WCHAR Strings[];
|
||||||
|
* BYTE Data[];
|
||||||
|
* CHAR Pad[]; // Padding for DWORD boundary
|
||||||
|
* ULONG Length; // Same as the first 'Length' member at the beginning
|
||||||
|
*/
|
||||||
|
} EVENTLOGRECORD, *PEVENTLOGRECORD;
|
||||||
|
|
||||||
|
#endif // _WINNT_
|
||||||
|
|
||||||
|
|
||||||
|
// ELF_EOF_RECORD
|
||||||
|
typedef struct _EVENTLOGEOF
|
||||||
|
{
|
||||||
|
ULONG RecordSizeBeginning;
|
||||||
|
ULONG Ones;
|
||||||
|
ULONG Twos;
|
||||||
|
ULONG Threes;
|
||||||
|
ULONG Fours;
|
||||||
|
ULONG BeginRecord;
|
||||||
|
ULONG EndRecord;
|
||||||
|
ULONG CurrentRecordNumber;
|
||||||
|
ULONG OldestRecordNumber;
|
||||||
|
ULONG RecordSizeEnd;
|
||||||
|
} EVENTLOGEOF, *PEVENTLOGEOF;
|
||||||
|
|
||||||
|
#define EVENTLOGEOF_SIZE_FIXED (5 * sizeof(ULONG))
|
||||||
|
C_ASSERT(EVENTLOGEOF_SIZE_FIXED == FIELD_OFFSET(EVENTLOGEOF, BeginRecord));
|
||||||
|
|
||||||
|
#include <poppack.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _EVENT_OFFSET_INFO
|
||||||
|
{
|
||||||
|
ULONG EventNumber;
|
||||||
|
ULONG EventOffset;
|
||||||
|
} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
|
||||||
|
|
||||||
|
#define TAG_ELF ' flE'
|
||||||
|
#define TAG_ELF_BUF 'BflE'
|
||||||
|
|
||||||
|
struct _EVTLOGFILE;
|
||||||
|
|
||||||
|
typedef PVOID
|
||||||
|
(NTAPI *PELF_ALLOCATE_ROUTINE)(
|
||||||
|
IN SIZE_T Size,
|
||||||
|
IN ULONG Flags,
|
||||||
|
IN ULONG Tag
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID
|
||||||
|
(NTAPI *PELF_FREE_ROUTINE)(
|
||||||
|
IN PVOID Ptr,
|
||||||
|
IN ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS
|
||||||
|
(NTAPI *PELF_FILE_READ_ROUTINE)(
|
||||||
|
IN struct _EVTLOGFILE* LogFile,
|
||||||
|
IN PLARGE_INTEGER FileOffset,
|
||||||
|
OUT PVOID Buffer,
|
||||||
|
IN SIZE_T Length,
|
||||||
|
OUT PSIZE_T ReadLength OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS
|
||||||
|
(NTAPI *PELF_FILE_WRITE_ROUTINE)(
|
||||||
|
IN struct _EVTLOGFILE* LogFile,
|
||||||
|
IN PLARGE_INTEGER FileOffset,
|
||||||
|
IN PVOID Buffer,
|
||||||
|
IN SIZE_T Length,
|
||||||
|
OUT PSIZE_T WrittenLength OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS
|
||||||
|
(NTAPI *PELF_FILE_SET_SIZE_ROUTINE)(
|
||||||
|
IN struct _EVTLOGFILE* LogFile,
|
||||||
|
IN ULONG FileSize,
|
||||||
|
IN ULONG OldFileSize
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS
|
||||||
|
(NTAPI *PELF_FILE_FLUSH_ROUTINE)(
|
||||||
|
IN struct _EVTLOGFILE* LogFile,
|
||||||
|
IN PLARGE_INTEGER FileOffset,
|
||||||
|
IN ULONG Length
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _EVTLOGFILE
|
||||||
|
{
|
||||||
|
PELF_ALLOCATE_ROUTINE Allocate;
|
||||||
|
PELF_FREE_ROUTINE Free;
|
||||||
|
PELF_FILE_SET_SIZE_ROUTINE FileSetSize;
|
||||||
|
PELF_FILE_WRITE_ROUTINE FileWrite;
|
||||||
|
PELF_FILE_READ_ROUTINE FileRead;
|
||||||
|
PELF_FILE_FLUSH_ROUTINE FileFlush;
|
||||||
|
|
||||||
|
EVENTLOGHEADER Header;
|
||||||
|
ULONG CurrentSize; /* Equivalent to the file size, is <= MaxSize and can be extended to MaxSize if needed */
|
||||||
|
UNICODE_STRING FileName;
|
||||||
|
PEVENT_OFFSET_INFO OffsetInfo;
|
||||||
|
ULONG OffsetInfoSize;
|
||||||
|
ULONG OffsetInfoNext;
|
||||||
|
BOOLEAN ReadOnly;
|
||||||
|
} EVTLOGFILE, *PEVTLOGFILE;
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfCreateFile(
|
||||||
|
IN PEVTLOGFILE LogFile,
|
||||||
|
IN PUNICODE_STRING FileName OPTIONAL,
|
||||||
|
IN ULONG FileSize,
|
||||||
|
IN ULONG MaxSize,
|
||||||
|
IN ULONG Retention,
|
||||||
|
IN BOOLEAN CreateNew,
|
||||||
|
IN BOOLEAN ReadOnly,
|
||||||
|
IN PELF_ALLOCATE_ROUTINE Allocate,
|
||||||
|
IN PELF_FREE_ROUTINE Free,
|
||||||
|
IN PELF_FILE_SET_SIZE_ROUTINE FileSetSize,
|
||||||
|
IN PELF_FILE_WRITE_ROUTINE FileWrite,
|
||||||
|
IN PELF_FILE_READ_ROUTINE FileRead,
|
||||||
|
IN PELF_FILE_FLUSH_ROUTINE FileFlush); // What about Seek ??
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfReCreateFile(
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
// NTSTATUS
|
||||||
|
// ElfClearFile(PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfBackupFile(
|
||||||
|
IN PEVTLOGFILE LogFile,
|
||||||
|
IN PEVTLOGFILE BackupLogFile);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfFlushFile(
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ElfCloseFile( // ElfFree
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfReadRecord(
|
||||||
|
IN PEVTLOGFILE LogFile,
|
||||||
|
IN ULONG RecordNumber,
|
||||||
|
OUT PEVENTLOGRECORD Record,
|
||||||
|
IN SIZE_T BufSize, // Length
|
||||||
|
OUT PSIZE_T BytesRead OPTIONAL,
|
||||||
|
OUT PSIZE_T BytesNeeded OPTIONAL);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ElfWriteRecord(
|
||||||
|
IN PEVTLOGFILE LogFile,
|
||||||
|
IN PEVENTLOGRECORD Record,
|
||||||
|
IN SIZE_T BufSize);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ElfGetOldestRecord(
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ElfGetCurrentRecord(
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ElfGetFlags(
|
||||||
|
IN PEVTLOGFILE LogFile);
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
VOID PRINT_HEADER(PEVENTLOGHEADER Header);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __EVTLIB_H__ */
|
Loading…
Reference in a new issue