[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:
Hermès Bélusca-Maïto 2016-10-25 23:50:31 +00:00
parent 34a06851d3
commit 1f9c38b3b9
9 changed files with 2472 additions and 1785 deletions

View file

@ -1,5 +1,6 @@
include_directories(
${REACTOS_SOURCE_DIR}/sdk/lib/evtlib
${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl
${CMAKE_CURRENT_BINARY_DIR})
@ -15,12 +16,13 @@ list(APPEND SOURCE
${CMAKE_CURRENT_BINARY_DIR}/eventlogrpc_s.c)
add_executable(eventlog ${SOURCE} eventlog.rc)
add_pch(eventlog eventlog.h SOURCE)
if(NOT MSVC)
target_link_libraries(eventlog ${PSEH_LIB})
endif()
set_module_type(eventlog win32cui UNICODE)
target_link_libraries(eventlog evtlib)
add_importlibs(eventlog advapi32 rpcrt4 msvcrt kernel32 ntdll)
add_pch(eventlog eventlog.h SOURCE)
add_cd_file(TARGET eventlog DESTINATION reactos/system32 FOR all)

View file

@ -541,49 +541,6 @@ bye_bye:
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)
{
UINT i;

View file

@ -23,82 +23,29 @@
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
#include <evtlib.h>
#include <eventlogrpc_s.h>
#include <strsafe.h>
// FIXME: For that we may directly include NTOS header??
typedef struct _IO_ERROR_LPC
{
PORT_MESSAGE Header;
IO_ERROR_LOG_MESSAGE Message;
} IO_ERROR_LPC, *PIO_ERROR_LPC;
// C_ASSERT(sizeof(IO_ERROR_LPC) == 0x100);
/*
* Our file format will be compatible with NT's
*/
#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;
/* Defined in evtlib.h */
// #define LOGFILE_SIGNATURE 0x654c664c // "LfLe"
typedef struct _LOGFILE
{
HANDLE hFile;
EVENTLOGHEADER Header;
ULONG CurrentSize; /* Equivalent to the file size, is <= MaxSize and can be extended to MaxSize if needed */
EVTLOGFILE LogFile;
HANDLE FileHandle;
WCHAR *LogName;
WCHAR *FileName;
RTL_RESOURCE Lock;
PEVENT_OFFSET_INFO OffsetInfo;
ULONG OffsetInfoSize;
ULONG OffsetInfoNext;
BOOL Permanent;
LIST_ENTRY ListEntry;
} LOGFILE, *PLOGFILE;
@ -128,7 +75,6 @@ typedef struct _LOGHANDLE
/* eventlog.c */
extern PEVENTSOURCE EventLogSource;
VOID PRINT_HEADER(PEVENTLOGHEADER header);
VOID PRINT_RECORD(PEVENTLOGRECORD pRec);
@ -150,7 +96,28 @@ PLOGFILE LogfListItemByIndex(DWORD Index);
PLOGFILE LogfListItemByName(LPCWSTR 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
LogfReadEvents(PLOGFILE LogFile,
@ -164,31 +131,8 @@ LogfReadEvents(PLOGFILE LogFile,
NTSTATUS
LogfWriteRecord(PLOGFILE LogFile,
ULONG BufSize, // SIZE_T
PEVENTLOGRECORD Record);
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 Record,
SIZE_T BufSize);
PEVENTLOGRECORD
LogfAllocAndBuildNewRecord(PSIZE_T pRecSize,

File diff suppressed because it is too large Load diff

View file

@ -187,11 +187,11 @@ NTSTATUS ProcessPortMessage(VOID)
if (!onLiveCD && SystemLog)
{
Status = LogfWriteRecord(SystemLog, RecSize, pRec);
Status = LogfWriteRecord(SystemLog, pRec, RecSize);
if (!NT_SUCCESS(Status))
{
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
SystemLog->FileName, Status);
SystemLog->LogName, Status);
}
}

View file

@ -16,27 +16,32 @@
#include <debug.h>
static LIST_ENTRY LogHandleListHead;
static CRITICAL_SECTION LogHandleListCs;
/* FUNCTIONS ****************************************************************/
static NTSTATUS
ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle);
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
{
RPC_STATUS Status;
InitializeCriticalSection(&LogHandleListCs);
InitializeListHead(&LogHandleListHead);
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\EventLog", NULL);
if (Status != RPC_S_OK)
{
DPRINT("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
return 0;
goto Quit;
}
Status = RpcServerRegisterIf(eventlog_v0_0_s_ifspec, NULL, NULL);
if (Status != RPC_S_OK)
{
DPRINT("RpcServerRegisterIf() failed (Status %lx)\n", Status);
return 0;
goto Quit;
}
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);
}
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;
}
@ -143,7 +159,9 @@ Done:
if (NT_SUCCESS(Status))
{
/* Append log handle */
EnterCriticalSection(&LogHandleListCs);
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
LeaveCriticalSection(&LogHandleListCs);
*LogHandle = pLogHandle;
}
else
@ -199,7 +217,9 @@ Done:
if (NT_SUCCESS(Status))
{
/* Append log handle */
EnterCriticalSection(&LogHandleListCs);
InsertTailList(&LogHandleListHead, &pLogHandle->LogHandleListEntry);
LeaveCriticalSection(&LogHandleListCs);
*LogHandle = pLogHandle;
}
else
@ -215,21 +235,28 @@ static PLOGHANDLE
ElfGetLogHandleEntryByHandle(IELF_HANDLE EventLogHandle)
{
PLIST_ENTRY CurrentEntry;
PLOGHANDLE pLogHandle;
PLOGHANDLE Handle, pLogHandle = NULL;
EnterCriticalSection(&LogHandleListCs);
CurrentEntry = LogHandleListHead.Flink;
while (CurrentEntry != &LogHandleListHead)
{
pLogHandle = CONTAINING_RECORD(CurrentEntry,
LOGHANDLE,
LogHandleListEntry);
Handle = CONTAINING_RECORD(CurrentEntry,
LOGHANDLE,
LogHandleListEntry);
CurrentEntry = CurrentEntry->Flink;
if (pLogHandle == EventLogHandle)
return pLogHandle;
if (Handle == EventLogHandle)
{
pLogHandle = Handle;
break;
}
}
return NULL;
LeaveCriticalSection(&LogHandleListCs);
return pLogHandle;
}
@ -242,7 +269,10 @@ ElfDeleteEventLogHandle(PIELF_HANDLE LogHandle)
if (!pLogHandle)
return STATUS_INVALID_HANDLE;
EnterCriticalSection(&LogHandleListCs);
RemoveEntryList(&pLogHandle->LogHandleListEntry);
LeaveCriticalSection(&LogHandleListCs);
LogfClose(pLogHandle->LogFile, FALSE);
HeapFree(GetProcessHeap(), 0, pLogHandle);
@ -321,6 +351,7 @@ ElfrNumberOfRecords(
{
PLOGHANDLE pLogHandle;
PLOGFILE pLogFile;
ULONG OldestRecordNumber, CurrentRecordNumber;
DPRINT("ElfrNumberOfRecords()\n");
@ -333,11 +364,19 @@ ElfrNumberOfRecords(
pLogFile = pLogHandle->LogFile;
DPRINT("Oldest: %lu Current: %lu\n",
pLogFile->Header.OldestRecordNumber,
pLogFile->Header.CurrentRecordNumber);
/* Lock the log file shared */
RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
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 */
*NumberOfRecords = 0;
@ -345,8 +384,7 @@ ElfrNumberOfRecords(
else
{
/* The log contains events */
*NumberOfRecords = pLogFile->Header.CurrentRecordNumber -
pLogFile->Header.OldestRecordNumber;
*NumberOfRecords = CurrentRecordNumber - OldestRecordNumber;
}
return STATUS_SUCCESS;
@ -360,6 +398,7 @@ ElfrOldestRecord(
PULONG OldestRecordNumber)
{
PLOGHANDLE pLogHandle;
PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!pLogHandle)
@ -368,7 +407,15 @@ ElfrOldestRecord(
if (!OldestRecordNumber)
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;
}
@ -624,7 +671,7 @@ ElfrIntReportEventW(
DataSize,
Data);
Status = LogfWriteRecord(pLogHandle->LogFile, RecSize, LogBuffer);
Status = LogfWriteRecord(pLogHandle->LogFile, LogBuffer, RecSize);
if (!NT_SUCCESS(Status))
{
DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
@ -1068,11 +1115,17 @@ ElfrGetLogInformation(
{
NTSTATUS Status = STATUS_SUCCESS;
PLOGHANDLE pLogHandle;
PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!pLogHandle)
return STATUS_INVALID_HANDLE;
pLogFile = pLogHandle->LogFile;
/* Lock the log file shared */
RtlAcquireResourceShared(&pLogFile->Lock, TRUE);
switch (InfoLevel)
{
case EVENTLOG_FULL_INFO:
@ -1086,12 +1139,7 @@ ElfrGetLogInformation(
break;
}
/*
* 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;
efi->dwFull = !!(ElfGetFlags(&pLogFile->LogFile) & ELF_LOGFILE_LOGFULL_WRITTEN);
break;
}
@ -1100,6 +1148,9 @@ ElfrGetLogInformation(
break;
}
/* Unlock the log file */
RtlReleaseResource(&pLogFile->Lock);
return Status;
}
@ -1109,14 +1160,25 @@ NTSTATUS
ElfrFlushEL(
IELF_HANDLE LogHandle)
{
NTSTATUS Status;
PLOGHANDLE pLogHandle;
PLOGFILE pLogFile;
pLogHandle = ElfGetLogHandleEntryByHandle(LogHandle);
if (!pLogHandle)
return STATUS_INVALID_HANDLE;
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
pLogFile = pLogHandle->LogFile;
/* Lock the log file exclusive */
RtlAcquireResourceExclusive(&pLogFile->Lock, TRUE);
Status = ElfFlushFile(&pLogFile->LogFile);
/* Unlock the log file */
RtlReleaseResource(&pLogFile->Lock);
return Status;
}

View 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)

File diff suppressed because it is too large Load diff

View 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__ */