ReactOS 0.4.17-dev-470-gf9e3448
evtlib.c File Reference
#include "evtlib.h"
#include <debug.h>
Include dependency graph for evtlib.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define EVTLTRACE(fmt, ...)   DPRINT("EvtLib: " fmt, ##__VA_ARGS__)
 
#define EVTLTRACE1(fmt, ...)   DPRINT1("EvtLib: " fmt, ##__VA_ARGS__)
 
#define EVENTLOG_FILE_GRANULARITY   (64 * 1024)
 
#define OFFSET_INFO_INCREMENT   64
 

Functions

static NTSTATUS ReadLogBuffer (IN PEVTLOGFILE LogFile, OUT PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T ReadLength OPTIONAL, IN PLARGE_INTEGER ByteOffset, OUT PLARGE_INTEGER NextOffset OPTIONAL)
 
static NTSTATUS WriteLogBuffer (IN PEVTLOGFILE LogFile, IN PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T WrittenLength OPTIONAL, IN PLARGE_INTEGER ByteOffset, OUT PLARGE_INTEGER NextOffset OPTIONAL)
 
static ULONG ElfpOffsetByNumber (IN PEVTLOGFILE LogFile, IN ULONG RecordNumber)
 
static BOOL ElfpAddOffsetInformation (IN PEVTLOGFILE LogFile, IN ULONG ulNumber, IN ULONG ulOffset)
 
static BOOL ElfpDeleteOffsetInformation (IN PEVTLOGFILE LogFile, IN ULONG ulNumberMin, IN ULONG ulNumberMax)
 
static NTSTATUS ElfpInitNewFile (IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG MaxSize, IN ULONG Retention)
 
static NTSTATUS ElfpInitExistingFile (IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG Retention)
 
NTSTATUS NTAPI ElfCreateFile (IN OUT 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)
 
NTSTATUS NTAPI ElfReCreateFile (IN PEVTLOGFILE LogFile)
 
NTSTATUS NTAPI ElfBackupFile (IN PEVTLOGFILE LogFile, IN PEVTLOGFILE BackupLogFile)
 
NTSTATUS NTAPI ElfFlushFile (IN PEVTLOGFILE LogFile)
 
VOID NTAPI ElfCloseFile (IN PEVTLOGFILE LogFile)
 
NTSTATUS NTAPI ElfReadRecord (IN PEVTLOGFILE LogFile, IN ULONG RecordNumber, OUT PEVENTLOGRECORD Record, IN SIZE_T BufSize, 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)
 

Variables

static const EVENTLOGEOF EOFRecord
 

Macro Definition Documentation

◆ EVENTLOG_FILE_GRANULARITY

#define EVENTLOG_FILE_GRANULARITY   (64 * 1024)

Definition at line 26 of file evtlib.c.

◆ EVTLTRACE

#define EVTLTRACE (   fmt,
  ... 
)    DPRINT("EvtLib: " fmt, ##__VA_ARGS__)

Definition at line 19 of file evtlib.c.

◆ EVTLTRACE1

#define EVTLTRACE1 (   fmt,
  ... 
)    DPRINT1("EvtLib: " fmt, ##__VA_ARGS__)

Definition at line 21 of file evtlib.c.

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file evtlib.c.

◆ OFFSET_INFO_INCREMENT

#define OFFSET_INFO_INCREMENT   64

Definition at line 213 of file evtlib.c.

Function Documentation

◆ ElfBackupFile()

NTSTATUS NTAPI ElfBackupFile ( IN PEVTLOGFILE  LogFile,
IN PEVTLOGFILE  BackupLogFile 
)

Definition at line 992 of file evtlib.c.

995{
997
999 SIZE_T ReadLength, WrittenLength;
1001 EVENTLOGRECORD RecBuf;
1002 EVENTLOGEOF EofRec;
1003 ULONG i;
1004 ULONG RecOffset;
1005 PVOID Buffer = NULL;
1006
1007 ASSERT(LogFile);
1008
1009 RtlZeroMemory(BackupLogFile, sizeof(*BackupLogFile));
1010
1011 BackupLogFile->FileSetSize = LogFile->FileSetSize;
1012 BackupLogFile->FileWrite = LogFile->FileWrite;
1013 BackupLogFile->FileFlush = LogFile->FileFlush;
1014
1015 // BackupLogFile->CurrentSize = LogFile->CurrentSize;
1016
1017 BackupLogFile->ReadOnly = FALSE;
1018
1019 /* Initialize the (dirty) log file header */
1020 Header = &BackupLogFile->Header;
1021 Header->HeaderSize = sizeof(EVENTLOGHEADER);
1022 Header->Signature = LOGFILE_SIGNATURE;
1023 Header->MajorVersion = MAJORVER;
1024 Header->MinorVersion = MINORVER;
1025 Header->StartOffset = sizeof(EVENTLOGHEADER);
1026 Header->EndOffset = sizeof(EVENTLOGHEADER);
1027 Header->CurrentRecordNumber = 1;
1028 Header->OldestRecordNumber = 0;
1029 Header->MaxSize = LogFile->Header.MaxSize;
1031 Header->Retention = LogFile->Header.Retention;
1032 Header->EndHeaderSize = sizeof(EVENTLOGHEADER);
1033
1034 /* Write the (dirty) log file header */
1035 FileOffset.QuadPart = 0LL;
1036 Status = BackupLogFile->FileWrite(BackupLogFile,
1037 &FileOffset,
1038 Header,
1039 sizeof(EVENTLOGHEADER),
1040 &WrittenLength);
1041 if (!NT_SUCCESS(Status))
1042 {
1043 EVTLTRACE1("Failed to write the log file header (Status 0x%08lx)\n", Status);
1044 goto Quit;
1045 }
1046
1047 for (i = LogFile->Header.OldestRecordNumber; i < LogFile->Header.CurrentRecordNumber; i++)
1048 {
1049 RecOffset = ElfpOffsetByNumber(LogFile, i);
1050 if (RecOffset == 0)
1051 break;
1052
1053 /* Read the next EVENTLOGRECORD header at once (it cannot be split) */
1054 FileOffset.QuadPart = RecOffset;
1055 Status = LogFile->FileRead(LogFile,
1056 &FileOffset,
1057 &RecBuf,
1058 sizeof(RecBuf),
1059 &ReadLength);
1060 if (!NT_SUCCESS(Status))
1061 {
1062 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
1063 goto Quit;
1064 }
1065
1066 // if (ReadLength != sizeof(RecBuf))
1067 // break;
1068
1069 Buffer = LogFile->Allocate(RecBuf.Length, 0, TAG_ELF_BUF);
1070 if (Buffer == NULL)
1071 {
1072 EVTLTRACE1("Allocate() failed!\n");
1073 goto Quit;
1074 }
1075
1076 /* Read the full EVENTLOGRECORD (header + data) with wrapping */
1077 Status = ReadLogBuffer(LogFile,
1078 Buffer,
1079 RecBuf.Length,
1080 &ReadLength,
1081 &FileOffset,
1082 NULL);
1083 if (!NT_SUCCESS(Status))
1084 {
1085 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
1086 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1087 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1088 goto Quit;
1089 }
1090
1091 /* Write the event record (no wrap for the backup log) */
1092 Status = BackupLogFile->FileWrite(BackupLogFile,
1093 NULL,
1094 Buffer,
1095 RecBuf.Length,
1096 &WrittenLength);
1097 if (!NT_SUCCESS(Status))
1098 {
1099 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1100 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1101 goto Quit;
1102 }
1103
1104 /* Update the header information */
1105 Header->EndOffset += RecBuf.Length;
1106
1107 /* Free the buffer */
1108 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1109 Buffer = NULL;
1110 }
1111
1112// Quit:
1113
1114 /* Initialize the ELF_EOF_RECORD and write it (no wrap for the backup log) */
1115 RtlCopyMemory(&EofRec, &EOFRecord, sizeof(EOFRecord));
1116 EofRec.BeginRecord = Header->StartOffset;
1117 EofRec.EndRecord = Header->EndOffset;
1118 EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
1119 EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
1120
1121 Status = BackupLogFile->FileWrite(BackupLogFile,
1122 NULL,
1123 &EofRec,
1124 sizeof(EofRec),
1125 &WrittenLength);
1126 if (!NT_SUCCESS(Status))
1127 {
1128 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1129 goto Quit;
1130 }
1131
1132 /* Update the header information */
1133 Header->CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
1134 Header->OldestRecordNumber = LogFile->Header.OldestRecordNumber;
1135 Header->MaxSize = ROUND_UP(Header->EndOffset + sizeof(EofRec), sizeof(ULONG));
1136 Header->Flags = 0; // FIXME?
1137
1138 /* Flush the log file - Write the (clean) log file header */
1139 Status = ElfFlushFile(BackupLogFile);
1140
1141Quit:
1142 return Status;
1143}
ULONG ReadLength
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
Definition: Header.h:9
Header(const std::string &filename_)
Definition: Header.h:18
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
static const EVENTLOGEOF EOFRecord
Definition: evtlib.c:28
static ULONG ElfpOffsetByNumber(IN PEVTLOGFILE LogFile, IN ULONG RecordNumber)
Definition: evtlib.c:199
static NTSTATUS ReadLogBuffer(IN PEVTLOGFILE LogFile, OUT PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T ReadLength OPTIONAL, IN PLARGE_INTEGER ByteOffset, OUT PLARGE_INTEGER NextOffset OPTIONAL)
Definition: evtlib.c:39
NTSTATUS NTAPI ElfFlushFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1147
#define EVTLTRACE1(fmt,...)
Definition: evtlib.c:21
#define LOGFILE_SIGNATURE
Definition: evtlib.h:43
#define TAG_ELF_BUF
Definition: evtlib.h:152
#define MAJORVER
Definition: evtlib.h:41
#define MINORVER
Definition: evtlib.h:42
#define ELF_LOGFILE_HEADER_DIRTY
Definition: evtlib.h:48
struct _EVENTLOGHEADER EVENTLOGHEADER
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
ULONG EndRecord
Definition: evtlib.h:133
ULONG CurrentRecordNumber
Definition: evtlib.h:134
ULONG BeginRecord
Definition: evtlib.h:132
ULONG OldestRecordNumber
Definition: evtlib.h:135
#define LL
Definition: tui.h:166
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59

Referenced by LogfBackupFile().

◆ ElfCloseFile()

VOID NTAPI ElfCloseFile ( IN PEVTLOGFILE  LogFile)

Definition at line 1192 of file evtlib.c.

1194{
1195 ASSERT(LogFile);
1196
1197 /* Flush the log file */
1198 ElfFlushFile(LogFile);
1199
1200 /* Free the data */
1201 LogFile->Free(LogFile->OffsetInfo, 0, TAG_ELF);
1202
1203 if (LogFile->FileName.Buffer)
1204 LogFile->Free(LogFile->FileName.Buffer, 0, TAG_ELF);
1205 RtlInitEmptyUnicodeString(&LogFile->FileName, NULL, 0);
1206}
#define TAG_ELF
Definition: evtlib.h:151

Referenced by LogfClose().

◆ ElfCreateFile()

NTSTATUS NTAPI ElfCreateFile ( IN OUT 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 
)

Definition at line 889 of file evtlib.c.

903{
905
906 ASSERT(LogFile);
907
908 /* Creating a new log file with the 'ReadOnly' flag set is incompatible */
909 if (CreateNew && ReadOnly)
911
912 RtlZeroMemory(LogFile, sizeof(*LogFile));
913
914 LogFile->Allocate = Allocate;
915 LogFile->Free = Free;
916 LogFile->FileSetSize = FileSetSize;
917 LogFile->FileWrite = FileWrite;
918 LogFile->FileRead = FileRead;
919 LogFile->FileFlush = FileFlush;
920
921 /* Copy the log file name if provided (optional) */
922 RtlInitEmptyUnicodeString(&LogFile->FileName, NULL, 0);
923 if (FileName && FileName->Buffer && FileName->Length &&
924 (FileName->Length <= FileName->MaximumLength))
925 {
926 LogFile->FileName.Buffer = LogFile->Allocate(FileName->Length,
928 TAG_ELF);
929 if (LogFile->FileName.Buffer)
930 {
931 LogFile->FileName.MaximumLength = FileName->Length;
932 RtlCopyUnicodeString(&LogFile->FileName, FileName);
933 }
934 }
935
936 LogFile->OffsetInfo = LogFile->Allocate(OFFSET_INFO_INCREMENT * sizeof(EVENT_OFFSET_INFO),
938 TAG_ELF);
939 if (LogFile->OffsetInfo == NULL)
940 {
941 EVTLTRACE1("Cannot allocate heap\n");
943 goto Quit;
944 }
945 LogFile->OffsetInfoSize = OFFSET_INFO_INCREMENT;
946 LogFile->OffsetInfoNext = 0;
947
948 // FIXME: Always use the regitry values for MaxSize,
949 // even for existing logs!
950
951 // FIXME: On Windows, EventLog uses the MaxSize setting
952 // from the registry itself; the MaxSize from the header
953 // is just for information purposes.
954
955 EVTLTRACE("Initializing log file `%wZ'\n", &LogFile->FileName);
956
957 LogFile->ReadOnly = ReadOnly; // !CreateNew && ReadOnly;
958
959 if (CreateNew)
960 Status = ElfpInitNewFile(LogFile, FileSize, MaxSize, Retention);
961 else
962 Status = ElfpInitExistingFile(LogFile, FileSize, /* MaxSize, */ Retention);
963
964Quit:
965 if (!NT_SUCCESS(Status))
966 {
967 if (LogFile->OffsetInfo)
968 LogFile->Free(LogFile->OffsetInfo, 0, TAG_ELF);
969
970 if (LogFile->FileName.Buffer)
971 LogFile->Free(LogFile->FileName.Buffer, 0, TAG_ELF);
972 }
973
974 return Status;
975}
_In_ PATA_DEVICE_REQUEST _In_ BOOLEAN Allocate
Definition: ata_shared.h:437
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define EVTLTRACE(fmt,...)
Definition: evtlib.c:19
static NTSTATUS ElfpInitNewFile(IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG MaxSize, IN ULONG Retention)
Definition: evtlib.c:299
static NTSTATUS ElfpInitExistingFile(IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG Retention)
Definition: evtlib.c:392
#define OFFSET_INFO_INCREMENT
Definition: evtlib.c:213
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
@ ReadOnly
Definition: arc.h:89
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:815

Referenced by LogfCreate().

◆ ElfFlushFile()

NTSTATUS NTAPI ElfFlushFile ( IN PEVTLOGFILE  LogFile)

Definition at line 1147 of file evtlib.c.

1149{
1152 SIZE_T WrittenLength;
1153
1154 ASSERT(LogFile);
1155
1156 if (LogFile->ReadOnly)
1157 return STATUS_SUCCESS; // STATUS_ACCESS_DENIED;
1158
1159 /*
1160 * NOTE that both the EOF record *AND* the log file header
1161 * are supposed to be already updated!
1162 * We just remove the dirty log bit.
1163 */
1164 LogFile->Header.Flags &= ~ELF_LOGFILE_HEADER_DIRTY;
1165
1166 /* Update the log file header */
1167 FileOffset.QuadPart = 0LL;
1168 Status = LogFile->FileWrite(LogFile,
1169 &FileOffset,
1170 &LogFile->Header,
1171 sizeof(EVENTLOGHEADER),
1172 &WrittenLength);
1173 if (!NT_SUCCESS(Status))
1174 {
1175 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1176 return Status;
1177 }
1178
1179 /* Flush the log file */
1180 Status = LogFile->FileFlush(LogFile, NULL, 0);
1181 if (!NT_SUCCESS(Status))
1182 {
1183 EVTLTRACE1("FileFlush() failed (Status 0x%08lx)\n", Status);
1184 return Status;
1185 }
1186
1187 return STATUS_SUCCESS;
1188}
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925

Referenced by ElfBackupFile(), ElfCloseFile(), ElfpInitExistingFile(), ElfrFlushEL(), and ElfWriteRecord().

◆ ElfGetCurrentRecord()

ULONG NTAPI ElfGetCurrentRecord ( IN PEVTLOGFILE  LogFile)

Definition at line 1625 of file evtlib.c.

1627{
1628 ASSERT(LogFile);
1629 return LogFile->Header.CurrentRecordNumber;
1630}

Referenced by ElfrNumberOfRecords(), and LogfReadEvents().

◆ ElfGetFlags()

ULONG NTAPI ElfGetFlags ( IN PEVTLOGFILE  LogFile)

Definition at line 1634 of file evtlib.c.

1636{
1637 ASSERT(LogFile);
1638 return LogFile->Header.Flags;
1639}

Referenced by ElfrGetLogInformation().

◆ ElfGetOldestRecord()

ULONG NTAPI ElfGetOldestRecord ( IN PEVTLOGFILE  LogFile)

Definition at line 1616 of file evtlib.c.

1618{
1619 ASSERT(LogFile);
1620 return LogFile->Header.OldestRecordNumber;
1621}

Referenced by ElfrNumberOfRecords(), ElfrOldestRecord(), and LogfReadEvents().

◆ ElfpAddOffsetInformation()

static BOOL ElfpAddOffsetInformation ( IN PEVTLOGFILE  LogFile,
IN ULONG  ulNumber,
IN ULONG  ulOffset 
)
static

Definition at line 216 of file evtlib.c.

220{
221 PVOID NewOffsetInfo;
222
223 if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
224 {
225 /* Allocate a new offset table */
226 NewOffsetInfo = LogFile->Allocate((LogFile->OffsetInfoSize + OFFSET_INFO_INCREMENT) *
227 sizeof(EVENT_OFFSET_INFO),
229 TAG_ELF);
230 if (!NewOffsetInfo)
231 {
232 EVTLTRACE1("Cannot reallocate heap.\n");
233 return FALSE;
234 }
235
236 /* Free the old offset table and use the new one */
237 if (LogFile->OffsetInfo)
238 {
239 /* Copy the handles from the old table to the new one */
240 RtlCopyMemory(NewOffsetInfo,
241 LogFile->OffsetInfo,
242 LogFile->OffsetInfoSize * sizeof(EVENT_OFFSET_INFO));
243 LogFile->Free(LogFile->OffsetInfo, 0, TAG_ELF);
244 }
245 LogFile->OffsetInfo = (PEVENT_OFFSET_INFO)NewOffsetInfo;
246 LogFile->OffsetInfoSize += OFFSET_INFO_INCREMENT;
247 }
248
249 LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
250 LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
251 LogFile->OffsetInfoNext++;
252
253 return TRUE;
254}
#define TRUE
Definition: types.h:120
struct _EVENT_OFFSET_INFO * PEVENT_OFFSET_INFO

Referenced by ElfpInitExistingFile(), and ElfWriteRecord().

◆ ElfpDeleteOffsetInformation()

static BOOL ElfpDeleteOffsetInformation ( IN PEVTLOGFILE  LogFile,
IN ULONG  ulNumberMin,
IN ULONG  ulNumberMax 
)
static

Definition at line 257 of file evtlib.c.

261{
262 UINT i;
263
264 if (ulNumberMin > ulNumberMax)
265 return FALSE;
266
267 /* Remove records ulNumberMin to ulNumberMax inclusive */
268 while (ulNumberMin <= ulNumberMax)
269 {
270 /*
271 * As the offset information is listed in increasing order, and we want
272 * to keep the list without holes, we demand that ulNumberMin is the first
273 * element in the list.
274 */
275 if (ulNumberMin != LogFile->OffsetInfo[0].EventNumber)
276 return FALSE;
277
278 /*
279 * RtlMoveMemory(&LogFile->OffsetInfo[0],
280 * &LogFile->OffsetInfo[1],
281 * sizeof(EVENT_OFFSET_INFO) * (LogFile->OffsetInfoNext - 1));
282 */
283 for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
284 {
285 LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
286 LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
287 }
288 LogFile->OffsetInfoNext--;
289
290 /* Go to the next offset information */
291 ulNumberMin++;
292 }
293
294 return TRUE;
295}
unsigned int UINT
Definition: sysinfo.c:13

Referenced by ElfWriteRecord().

◆ ElfpInitExistingFile()

static NTSTATUS ElfpInitExistingFile ( IN PEVTLOGFILE  LogFile,
IN ULONG  FileSize,
IN ULONG  Retention 
)
static

Definition at line 392 of file evtlib.c.

397{
399 LARGE_INTEGER FileOffset, NextOffset;
401 ULONG RecordNumber = 0;
402 ULONG RecOffset;
403 PULONG pRecSize2;
404 EVENTLOGEOF EofRec;
405 EVENTLOGRECORD RecBuf;
406 PEVENTLOGRECORD pRecBuf;
407 BOOLEAN Wrapping = FALSE;
408 BOOLEAN IsLogDirty = FALSE;
409
410 /* Read the log header */
411 FileOffset.QuadPart = 0LL;
412 Status = LogFile->FileRead(LogFile,
413 &FileOffset,
414 &LogFile->Header,
415 sizeof(EVENTLOGHEADER),
416 &ReadLength);
417 if (!NT_SUCCESS(Status))
418 {
419 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
420 return STATUS_EVENTLOG_FILE_CORRUPT; // return Status;
421 }
422 if (ReadLength != sizeof(EVENTLOGHEADER))
423 {
424 EVTLTRACE("Invalid file `%wZ'.\n", &LogFile->FileName);
426 }
427
428 /* Header validity checks */
429
430 if (LogFile->Header.HeaderSize != sizeof(EVENTLOGHEADER) ||
431 LogFile->Header.EndHeaderSize != sizeof(EVENTLOGHEADER))
432 {
433 EVTLTRACE("Invalid header size in `%wZ'.\n", &LogFile->FileName);
435 }
436
437 if (LogFile->Header.Signature != LOGFILE_SIGNATURE)
438 {
439 EVTLTRACE("Invalid signature %x in `%wZ'.\n",
440 LogFile->Header.Signature, &LogFile->FileName);
442 }
443
444 IsLogDirty = (LogFile->Header.Flags & ELF_LOGFILE_HEADER_DIRTY);
445
446 /* If the log is read-only (e.g. a backup log) and is dirty, then it is corrupted */
447 if (LogFile->ReadOnly && IsLogDirty)
448 {
449 EVTLTRACE("Read-only log `%wZ' is dirty.\n", &LogFile->FileName);
451 }
452
453 LogFile->CurrentSize = FileSize;
454 // FIXME!! What to do? And what to do if the MaxSize from the registry
455 // is strictly less than the CurrentSize?? Should we "reduce" the log size
456 // by clearing it completely??
457 // --> ANSWER: Save the new MaxSize somewhere, and only when the log is
458 // being cleared, use the new MaxSize to resize (ie. shrink) it.
459 // LogFile->FileSetSize(LogFile, LogFile->CurrentSize, 0);
460
461 /* Adjust the log maximum size if needed */
462 if (LogFile->CurrentSize > LogFile->Header.MaxSize)
463 LogFile->Header.MaxSize = LogFile->CurrentSize;
464
465 /*
466 * Reset the log retention value. The value stored
467 * in the log file is just for information purposes.
468 */
469 LogFile->Header.Retention = Retention;
470
471 /*
472 * For a non-read-only dirty log, the most up-to-date information about
473 * the Start/End offsets and the Oldest and Current event record numbers
474 * are found in the EOF record. We need to locate the EOF record without
475 * relying on the log header's EndOffset, then patch the log header with
476 * the values from the EOF record.
477 */
478 if ((LogFile->Header.EndOffset >= sizeof(EVENTLOGHEADER)) &&
479 (LogFile->Header.EndOffset < LogFile->CurrentSize) &&
480 (LogFile->Header.EndOffset & 3) == 0) // EndOffset % sizeof(ULONG) == 0
481 {
482 /* The header EOF offset may be valid, try to start with it */
483 RecOffset = LogFile->Header.EndOffset;
484 }
485 else
486 {
487 /* The header EOF offset could not be valid, so start from the beginning */
488 RecOffset = sizeof(EVENTLOGHEADER);
489 }
490
491 FileOffset.QuadPart = RecOffset;
492 Wrapping = FALSE;
493
494 for (;;)
495 {
496 if (Wrapping && FileOffset.QuadPart >= RecOffset)
497 {
498 EVTLTRACE1("EOF record not found!\n");
500 }
501
502 /* Attempt to read the fixed part of an EVENTLOGEOF (may wrap) */
503 Status = ReadLogBuffer(LogFile,
504 &EofRec,
506 &ReadLength,
507 &FileOffset,
508 NULL);
509 if (!NT_SUCCESS(Status))
510 {
511 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
513 }
515 {
516 EVTLTRACE1("Cannot read at most an EOF record!\n");
518 }
519
520 /* Is it an EVENTLOGEOF record? */
522 {
523 DPRINT("Found EOF record at %llx\n", FileOffset.QuadPart);
524
525 /* Got it! Break the loop and continue */
526 break;
527 }
528
529 /* No, continue looping */
530 if (*(PULONG)((ULONG_PTR)&EofRec + sizeof(ULONG)) == *(PULONG)(&EOFRecord))
531 FileOffset.QuadPart += sizeof(ULONG);
532 else
533 if (*(PULONG)((ULONG_PTR)&EofRec + 2*sizeof(ULONG)) == *(PULONG)(&EOFRecord))
534 FileOffset.QuadPart += 2*sizeof(ULONG);
535 else
536 if (*(PULONG)((ULONG_PTR)&EofRec + 3*sizeof(ULONG)) == *(PULONG)(&EOFRecord))
537 FileOffset.QuadPart += 3*sizeof(ULONG);
538 else
539 if (*(PULONG)((ULONG_PTR)&EofRec + 4*sizeof(ULONG)) == *(PULONG)(&EOFRecord))
540 FileOffset.QuadPart += 4*sizeof(ULONG);
541 else
542 FileOffset.QuadPart += 5*sizeof(ULONG); // EVENTLOGEOF_SIZE_FIXED
543
544 if (FileOffset.QuadPart >= LogFile->CurrentSize /* LogFile->Header.MaxSize */)
545 {
546 /* Wrap the offset */
547 FileOffset.QuadPart -= LogFile->CurrentSize /* LogFile->Header.MaxSize */ - sizeof(EVENTLOGHEADER);
548 Wrapping = TRUE;
549 }
550 }
551 /*
552 * The only way to be there is to have found a valid EOF record.
553 * Otherwise the previous loop has failed and STATUS_EVENTLOG_FILE_CORRUPT
554 * was returned.
555 */
556
557 /* Read the full EVENTLOGEOF (may wrap) and validate it */
558 Status = ReadLogBuffer(LogFile,
559 &EofRec,
560 sizeof(EofRec),
561 &ReadLength,
562 &FileOffset,
563 NULL);
564 if (!NT_SUCCESS(Status))
565 {
566 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
568 }
569 if (ReadLength != sizeof(EofRec))
570 {
571 EVTLTRACE1("Cannot read the full EOF record!\n");
573 }
574
575 /* Complete validity checks */
576 if ((EofRec.RecordSizeEnd != EofRec.RecordSizeBeginning) ||
577 (EofRec.EndRecord != FileOffset.QuadPart))
578 {
579 DPRINT1("EOF record %llx is corrupted (0x%x vs. 0x%x ; 0x%x vs. 0x%llx), expected 0x%x 0x%x!\n",
580 FileOffset.QuadPart,
581 EofRec.RecordSizeEnd, EofRec.RecordSizeBeginning,
582 EofRec.EndRecord, FileOffset.QuadPart,
584 DPRINT1("RecordSizeEnd = 0x%x\n", EofRec.RecordSizeEnd);
585 DPRINT1("RecordSizeBeginning = 0x%x\n", EofRec.RecordSizeBeginning);
586 DPRINT1("EndRecord = 0x%x\n", EofRec.EndRecord);
588 }
589
590 /* The EOF record is valid, break the loop and continue */
591
592 /* If the log is not dirty, the header values should correspond to the EOF ones */
593 if (!IsLogDirty)
594 {
595 if ( (LogFile->Header.StartOffset != EofRec.BeginRecord) ||
596 (LogFile->Header.EndOffset != EofRec.EndRecord) ||
597 (LogFile->Header.CurrentRecordNumber != EofRec.CurrentRecordNumber) ||
598 (LogFile->Header.OldestRecordNumber != EofRec.OldestRecordNumber) )
599 {
600 DPRINT1("\n"
601 "Log header or EOF record is corrupted:\n"
602 " StartOffset: 0x%x, expected 0x%x; EndOffset: 0x%x, expected 0x%x;\n"
603 " CurrentRecordNumber: %d, expected %d; OldestRecordNumber: %d, expected %d.\n",
604 LogFile->Header.StartOffset, EofRec.BeginRecord,
605 LogFile->Header.EndOffset , EofRec.EndRecord,
606 LogFile->Header.CurrentRecordNumber, EofRec.CurrentRecordNumber,
607 LogFile->Header.OldestRecordNumber , EofRec.OldestRecordNumber);
608
610 }
611 }
612
613 /* If the log is dirty, patch the log header with the values from the EOF record */
614 if (!LogFile->ReadOnly && IsLogDirty)
615 {
616 LogFile->Header.StartOffset = EofRec.BeginRecord;
617 LogFile->Header.EndOffset = EofRec.EndRecord;
618 LogFile->Header.CurrentRecordNumber = EofRec.CurrentRecordNumber;
619 LogFile->Header.OldestRecordNumber = EofRec.OldestRecordNumber;
620 }
621
622 /*
623 * FIXME! During operations the EOF record is the one that is the most
624 * updated (its Oldest & Current record numbers are always up-to
625 * date) while the ones from the header may be unsync. When closing
626 * (or flushing?) the event log, the header's record numbers get
627 * updated with the same values as the ones stored in the EOF record.
628 */
629
630 /* Verify Start/End offsets boundaries */
631
632 if ((LogFile->Header.StartOffset >= LogFile->CurrentSize) ||
633 (LogFile->Header.StartOffset & 3) != 0) // StartOffset % sizeof(ULONG) != 0
634 {
635 EVTLTRACE("Invalid start offset 0x%x in `%wZ'.\n",
636 LogFile->Header.StartOffset, &LogFile->FileName);
638 }
639 if ((LogFile->Header.EndOffset >= LogFile->CurrentSize) ||
640 (LogFile->Header.EndOffset & 3) != 0) // EndOffset % sizeof(ULONG) != 0
641 {
642 EVTLTRACE("Invalid EOF offset 0x%x in `%wZ'.\n",
643 LogFile->Header.EndOffset, &LogFile->FileName);
645 }
646
647 if ((LogFile->Header.StartOffset != LogFile->Header.EndOffset) &&
648 (LogFile->Header.MaxSize - LogFile->Header.StartOffset < sizeof(EVENTLOGRECORD)))
649 {
650 /*
651 * If StartOffset does not point to EndOffset i.e. to an EVENTLOGEOF,
652 * it should point to a non-splitted EVENTLOGRECORD.
653 */
654 EVTLTRACE("Invalid start offset 0x%x in `%wZ'.\n",
655 LogFile->Header.StartOffset, &LogFile->FileName);
657 }
658
659 if ((LogFile->Header.StartOffset < LogFile->Header.EndOffset) &&
660 (LogFile->Header.EndOffset - LogFile->Header.StartOffset < sizeof(EVENTLOGRECORD)))
661 {
662 /*
663 * In non-wrapping case, there must be enough space between StartOffset
664 * and EndOffset to contain at least a full EVENTLOGRECORD.
665 */
666 EVTLTRACE("Invalid start offset 0x%x or end offset 0x%x in `%wZ'.\n",
667 LogFile->Header.StartOffset, LogFile->Header.EndOffset, &LogFile->FileName);
669 }
670
671 if (LogFile->Header.StartOffset <= LogFile->Header.EndOffset)
672 {
673 /*
674 * Non-wrapping case: the (wrapping) free space starting at EndOffset
675 * must be able to contain an EVENTLOGEOF.
676 */
677 if (LogFile->Header.MaxSize - LogFile->Header.EndOffset +
678 LogFile->Header.StartOffset - sizeof(EVENTLOGHEADER) < sizeof(EVENTLOGEOF))
679 {
680 EVTLTRACE("Invalid EOF offset 0x%x in `%wZ'.\n",
681 LogFile->Header.EndOffset, &LogFile->FileName);
683 }
684 }
685 else // if (LogFile->Header.StartOffset > LogFile->Header.EndOffset)
686 {
687 /*
688 * Wrapping case: the free space between EndOffset and StartOffset
689 * must be able to contain an EVENTLOGEOF.
690 */
691 if (LogFile->Header.StartOffset - LogFile->Header.EndOffset < sizeof(EVENTLOGEOF))
692 {
693 EVTLTRACE("Invalid EOF offset 0x%x in `%wZ'.\n",
694 LogFile->Header.EndOffset, &LogFile->FileName);
696 }
697 }
698
699 /* Start enumerating the event records from the beginning */
700 RecOffset = LogFile->Header.StartOffset;
701 FileOffset.QuadPart = RecOffset;
702 Wrapping = FALSE;
703
704 // // FIXME! FIXME!
705 // if (!(LogFile->Header.Flags & ELF_LOGFILE_HEADER_WRAP))
706 // {
707 // DPRINT1("Log file was wrapping but the flag was not set! Fixing...\n");
708 // LogFile->Header.Flags |= ELF_LOGFILE_HEADER_WRAP;
709 // }
710
711 DPRINT("StartOffset = 0x%x, EndOffset = 0x%x\n",
712 LogFile->Header.StartOffset, LogFile->Header.EndOffset);
713
714 /*
715 * For non-read-only logs of size < MaxSize, reorganize the events
716 * such that they do not wrap as soon as we write new ones.
717 */
718#if 0
719 if (!LogFile->ReadOnly)
720 {
721 pRecBuf = LogFile->Allocate(RecBuf.Length, 0, TAG_ELF_BUF);
722 if (pRecBuf == NULL)
723 {
724 DPRINT1("Cannot allocate temporary buffer, skip event reorganization.\n");
725 goto Continue;
726 }
727
728 // TODO: Do the job!
729 }
730
731Continue:
732
733 DPRINT1("StartOffset = 0x%x, EndOffset = 0x%x\n",
734 LogFile->Header.StartOffset, LogFile->Header.EndOffset);
735#endif
736
737 while (FileOffset.QuadPart != LogFile->Header.EndOffset)
738 {
739 if (Wrapping && FileOffset.QuadPart >= RecOffset)
740 {
741 /* We have finished enumerating all the event records */
742 break;
743 }
744
745 /* Read the next EVENTLOGRECORD header at once (it cannot be split) */
746 Status = LogFile->FileRead(LogFile,
747 &FileOffset,
748 &RecBuf,
749 sizeof(RecBuf),
750 &ReadLength);
751 if (!NT_SUCCESS(Status))
752 {
753 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
755 }
756 if (ReadLength != sizeof(RecBuf))
757 {
758 DPRINT1("Length != sizeof(RecBuf)\n");
759 break;
760 }
761
762 if (RecBuf.Reserved != LOGFILE_SIGNATURE ||
763 RecBuf.Length < sizeof(EVENTLOGRECORD))
764 {
765 DPRINT1("RecBuf problem\n");
766 break;
767 }
768
769 /* Allocate a full EVENTLOGRECORD (header + data) */
770 pRecBuf = LogFile->Allocate(RecBuf.Length, 0, TAG_ELF_BUF);
771 if (pRecBuf == NULL)
772 {
773 EVTLTRACE1("Cannot allocate heap!\n");
774 return STATUS_NO_MEMORY;
775 }
776
777 /* Attempt to read the full EVENTLOGRECORD (can wrap) */
778 Status = ReadLogBuffer(LogFile,
779 pRecBuf,
780 RecBuf.Length,
781 &ReadLength,
782 &FileOffset,
783 &NextOffset);
784 if (!NT_SUCCESS(Status))
785 {
786 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
787 LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
789 }
790 if (ReadLength != RecBuf.Length)
791 {
792 DPRINT1("Oh oh!!\n");
793 LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
794 break;
795 }
796
797 // /* If OverWrittenRecords is TRUE and this record has already been read */
798 // if (OverWrittenRecords && (pRecBuf->RecordNumber == LogFile->Header.OldestRecordNumber))
799 // {
800 // LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
801 // break;
802 // }
803
804 pRecSize2 = (PULONG)((ULONG_PTR)pRecBuf + RecBuf.Length - 4);
805
806 if (*pRecSize2 != RecBuf.Length)
807 {
808 EVTLTRACE1("Invalid RecordSizeEnd of record %d (0x%x) in `%wZ'\n",
809 RecordNumber, *pRecSize2, &LogFile->FileName);
810 LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
811 break;
812 }
813
814 EVTLTRACE("Add new record %d @ offset 0x%x\n", pRecBuf->RecordNumber, FileOffset.QuadPart);
815
816 RecordNumber++;
817
818 if (!ElfpAddOffsetInformation(LogFile,
819 pRecBuf->RecordNumber,
820 FileOffset.QuadPart))
821 {
822 EVTLTRACE1("ElfpAddOffsetInformation() failed!\n");
823 LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
825 }
826
827 LogFile->Free(pRecBuf, 0, TAG_ELF_BUF);
828
829 if (NextOffset.QuadPart == LogFile->Header.EndOffset)
830 {
831 /* We have finished enumerating all the event records */
832 DPRINT("NextOffset.QuadPart == LogFile->Header.EndOffset, break\n");
833 break;
834 }
835
836 /*
837 * If this was the last event record before the end of the log file,
838 * the next one should start at the beginning of the log and the space
839 * between the last event record and the end of the file is padded.
840 */
841 if (LogFile->Header.MaxSize - NextOffset.QuadPart < sizeof(EVENTLOGRECORD))
842 {
843 /* Wrap to the beginning of the log */
844 DPRINT("Wrap!\n");
845 NextOffset.QuadPart = sizeof(EVENTLOGHEADER);
846 }
847
848 /*
849 * If the next offset to read is below the current offset,
850 * this means we are wrapping.
851 */
852 if (FileOffset.QuadPart > NextOffset.QuadPart)
853 {
854 DPRINT("Wrapping = TRUE;\n");
855 Wrapping = TRUE;
856 }
857
858 /* Move the current offset */
859 FileOffset = NextOffset;
860 }
861
862 /* If the event log was empty, it will now contain one record */
863 if (RecordNumber != 0 && LogFile->Header.OldestRecordNumber == 0)
864 LogFile->Header.OldestRecordNumber = 1;
865
866 LogFile->Header.CurrentRecordNumber = RecordNumber + LogFile->Header.OldestRecordNumber;
867 if (LogFile->Header.CurrentRecordNumber == 0)
868 LogFile->Header.CurrentRecordNumber = 1;
869
870 /* Flush the log if it is not read-only */
871 if (!LogFile->ReadOnly)
872 {
873 Status = ElfFlushFile(LogFile);
874 if (!NT_SUCCESS(Status))
875 {
876 EVTLTRACE1("ElfFlushFile() failed (Status 0x%08lx)\n", Status);
877 return STATUS_EVENTLOG_FILE_CORRUPT; // Status;
878 }
879 }
880
881 return STATUS_SUCCESS;
882}
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
static BOOL ElfpAddOffsetInformation(IN PEVTLOGFILE LogFile, IN ULONG ulNumber, IN ULONG ulOffset)
Definition: evtlib.c:216
#define EVENTLOGEOF_SIZE_FIXED
Definition: evtlib.h:139
#define STATUS_EVENTLOG_FILE_CORRUPT
Definition: ntstatus.h:725
#define DPRINT
Definition: sndvol32.h:73
ULONG RecordSizeBeginning
Definition: evtlib.h:127
ULONG RecordSizeEnd
Definition: evtlib.h:136
DWORD RecordNumber
Definition: winnt_old.h:3084
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by ElfCreateFile().

◆ ElfpInitNewFile()

static NTSTATUS ElfpInitNewFile ( IN PEVTLOGFILE  LogFile,
IN ULONG  FileSize,
IN ULONG  MaxSize,
IN ULONG  Retention 
)
static

Definition at line 299 of file evtlib.c.

304{
307 SIZE_T WrittenLength;
308 EVENTLOGEOF EofRec;
309 ULONG InitialSize;
310
311 /* Initialize the event log header */
312 RtlZeroMemory(&LogFile->Header, sizeof(EVENTLOGHEADER));
313
314 LogFile->Header.HeaderSize = sizeof(EVENTLOGHEADER);
315 LogFile->Header.Signature = LOGFILE_SIGNATURE;
316 LogFile->Header.MajorVersion = MAJORVER;
317 LogFile->Header.MinorVersion = MINORVER;
318
319 /* Set the offset to the oldest record */
320 LogFile->Header.StartOffset = sizeof(EVENTLOGHEADER);
321 /* Set the offset to the ELF_EOF_RECORD */
322 LogFile->Header.EndOffset = sizeof(EVENTLOGHEADER);
323 /* Set the number of the next record that will be added */
324 LogFile->Header.CurrentRecordNumber = 1;
325 /* The event log is empty, there is no record so far */
326 LogFile->Header.OldestRecordNumber = 0;
327
328 /*
329 * Windows keeps the file size in 64 kB chunks. The used log area is tracked
330 * by the header offsets and the EOF record, not by the physical file EOF.
331 */
332 InitialSize = sizeof(EVENTLOGHEADER) + sizeof(EVENTLOGEOF); // TODO: Consider FileSize as well.
333 InitialSize = ROUND_UP(InitialSize, EVENTLOG_FILE_GRANULARITY);
334 LogFile->CurrentSize = InitialSize;
335 Status = LogFile->FileSetSize(LogFile, LogFile->CurrentSize, FileSize);
336 if (!NT_SUCCESS(Status))
337 {
338 EVTLTRACE1("FileSetSize() failed (Status 0x%08lx)\n", Status);
339 return Status;
340 }
341
342 /* Ensure that the log maximum size is greater than the initial file size */
343 MaxSize = max(MaxSize, InitialSize);
344 LogFile->Header.MaxSize = ROUND_UP(MaxSize, EVENTLOG_FILE_GRANULARITY);
345
346 LogFile->Header.Flags = 0;
347 LogFile->Header.Retention = Retention;
348 LogFile->Header.EndHeaderSize = sizeof(EVENTLOGHEADER);
349
350 /* Write the header */
351 FileOffset.QuadPart = 0LL;
352 Status = LogFile->FileWrite(LogFile,
353 &FileOffset,
354 &LogFile->Header,
355 sizeof(EVENTLOGHEADER),
356 &WrittenLength);
357 if (!NT_SUCCESS(Status))
358 {
359 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
360 return Status;
361 }
362
363 /* Initialize the ELF_EOF_RECORD and write it */
364 RtlCopyMemory(&EofRec, &EOFRecord, sizeof(EOFRecord));
365 EofRec.BeginRecord = LogFile->Header.StartOffset;
366 EofRec.EndRecord = LogFile->Header.EndOffset;
367 EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
368 EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
369
370 Status = LogFile->FileWrite(LogFile,
371 NULL,
372 &EofRec,
373 sizeof(EofRec),
374 &WrittenLength);
375 if (!NT_SUCCESS(Status))
376 {
377 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
378 return Status;
379 }
380
381 Status = LogFile->FileFlush(LogFile, NULL, 0);
382 if (!NT_SUCCESS(Status))
383 {
384 EVTLTRACE1("FileFlush() failed (Status 0x%08lx)\n", Status);
385 return Status;
386 }
387
388 return STATUS_SUCCESS;
389}
#define EVENTLOG_FILE_GRANULARITY
Definition: evtlib.c:26
#define max(a, b)
Definition: svc.c:63

Referenced by ElfCreateFile(), and ElfReCreateFile().

◆ ElfpOffsetByNumber()

static ULONG ElfpOffsetByNumber ( IN PEVTLOGFILE  LogFile,
IN ULONG  RecordNumber 
)
static

Definition at line 199 of file evtlib.c.

202{
203 UINT i;
204
205 for (i = 0; i < LogFile->OffsetInfoNext; i++)
206 {
207 if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
208 return LogFile->OffsetInfo[i].EventOffset;
209 }
210 return 0;
211}

Referenced by ElfBackupFile(), ElfReadRecord(), and ElfWriteRecord().

◆ ElfReadRecord()

NTSTATUS NTAPI ElfReadRecord ( IN PEVTLOGFILE  LogFile,
IN ULONG  RecordNumber,
OUT PEVENTLOGRECORD  Record,
IN SIZE_T  BufSize,
OUT PSIZE_T BytesRead  OPTIONAL,
OUT PSIZE_T BytesNeeded  OPTIONAL 
)

Definition at line 1210 of file evtlib.c.

1217{
1220 ULONG RecOffset;
1221 ULONG RecSize;
1223
1224 ASSERT(LogFile);
1225
1226 if (BytesRead)
1227 *BytesRead = 0;
1228
1229 if (BytesNeeded)
1230 *BytesNeeded = 0;
1231
1232 /* Retrieve the offset of the event record */
1233 RecOffset = ElfpOffsetByNumber(LogFile, RecordNumber);
1234 if (RecOffset == 0)
1235 return STATUS_NOT_FOUND;
1236
1237 /* Retrieve its full size */
1238 FileOffset.QuadPart = RecOffset;
1239 Status = LogFile->FileRead(LogFile,
1240 &FileOffset,
1241 &RecSize,
1242 sizeof(RecSize),
1243 &ReadLength);
1244 if (!NT_SUCCESS(Status))
1245 {
1246 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
1247 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1248 return Status;
1249 }
1250
1251 /* Check whether the buffer is big enough to hold the event record */
1252 if (BufSize < RecSize)
1253 {
1254 if (BytesNeeded)
1255 *BytesNeeded = RecSize;
1256
1258 }
1259
1260 /* Read the event record into the buffer */
1261 FileOffset.QuadPart = RecOffset;
1262 Status = ReadLogBuffer(LogFile,
1263 Record,
1264 RecSize,
1265 &ReadLength,
1266 &FileOffset,
1267 NULL);
1268 if (!NT_SUCCESS(Status))
1269 {
1270 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
1271 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1272 }
1273
1274 if (BytesRead)
1276
1277 return Status;
1278}
#define BufSize
Definition: FsRtlTunnel.c:28
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:320

Referenced by ReadRecord().

◆ ElfReCreateFile()

NTSTATUS NTAPI ElfReCreateFile ( IN PEVTLOGFILE  LogFile)

Definition at line 979 of file evtlib.c.

981{
982 ASSERT(LogFile);
983
984 return ElfpInitNewFile(LogFile,
985 LogFile->CurrentSize,
986 LogFile->Header.MaxSize,
987 LogFile->Header.Retention);
988}

Referenced by LogfClearFile().

◆ ElfWriteRecord()

NTSTATUS NTAPI ElfWriteRecord ( IN PEVTLOGFILE  LogFile,
IN PEVENTLOGRECORD  Record,
IN SIZE_T  BufSize 
)

Definition at line 1282 of file evtlib.c.

1286{
1288 LARGE_INTEGER FileOffset, NextOffset;
1289 SIZE_T ReadLength, WrittenLength;
1290 EVENTLOGEOF EofRec;
1291 EVENTLOGRECORD RecBuf;
1292 ULONG FreeSpace = 0;
1293 ULONG UpperBound;
1294 ULONG RecOffset, WriteOffset;
1295
1296 ASSERT(LogFile);
1297
1298 if (LogFile->ReadOnly)
1299 return STATUS_ACCESS_DENIED;
1300
1301 // ASSERT(sizeof(*Record) == sizeof(RecBuf));
1302
1303 if (!Record || BufSize < sizeof(*Record))
1305
1306 Record->RecordNumber = LogFile->Header.CurrentRecordNumber;
1307
1308 /* Compute the available log free space */
1309 if (LogFile->Header.StartOffset <= LogFile->Header.EndOffset)
1310 FreeSpace = LogFile->Header.MaxSize - LogFile->Header.EndOffset + LogFile->Header.StartOffset - sizeof(EVENTLOGHEADER);
1311 else // if (LogFile->Header.StartOffset > LogFile->Header.EndOffset)
1312 FreeSpace = LogFile->Header.StartOffset - LogFile->Header.EndOffset;
1313
1314 LogFile->Header.Flags |= ELF_LOGFILE_HEADER_DIRTY;
1315
1316 /* If the event log was empty, it will now contain one record */
1317 if (LogFile->Header.OldestRecordNumber == 0)
1318 LogFile->Header.OldestRecordNumber = 1;
1319
1320 /* By default we append the new record at the old EOF record offset */
1321 WriteOffset = LogFile->Header.EndOffset;
1322
1323 /*
1324 * Check whether the log is going to wrap (the events being overwritten).
1325 */
1326
1327 if (LogFile->Header.StartOffset <= LogFile->Header.EndOffset)
1328 UpperBound = LogFile->Header.MaxSize;
1329 else // if (LogFile->Header.StartOffset > LogFile->Header.EndOffset)
1330 UpperBound = LogFile->Header.StartOffset;
1331
1332 // if (LogFile->Header.MaxSize - WriteOffset < BufSize + sizeof(EofRec))
1333 if (UpperBound - WriteOffset < BufSize + sizeof(EofRec))
1334 {
1335 EVTLTRACE("The event log file has reached maximum size (0x%x), wrapping...\n"
1336 "UpperBound = 0x%x, WriteOffset = 0x%x, BufSize = 0x%x\n",
1337 LogFile->Header.MaxSize, UpperBound, WriteOffset, BufSize);
1338 /* This will be done later */
1339 }
1340
1341 if ( (LogFile->Header.StartOffset < LogFile->Header.EndOffset) &&
1342 (LogFile->Header.MaxSize - WriteOffset < sizeof(RecBuf)) ) // (UpperBound - WriteOffset < sizeof(RecBuf))
1343 {
1344 // ASSERT(UpperBound == LogFile->Header.MaxSize);
1345 // ASSERT(WriteOffset == LogFile->Header.EndOffset);
1346
1347 /*
1348 * We cannot fit the EVENTLOGRECORD header of the buffer before
1349 * the end of the file. We need to pad the end of the log with
1350 * 0x00000027, normally we will need to pad at most 0x37 bytes
1351 * (corresponding to sizeof(EVENTLOGRECORD) - 1).
1352 */
1353
1354 /* Rewind to the beginning of the log, just after the header */
1355 WriteOffset = sizeof(EVENTLOGHEADER);
1356 UpperBound = LogFile->Header.StartOffset;
1357
1358 FreeSpace = LogFile->Header.StartOffset - WriteOffset;
1359
1360 LogFile->Header.Flags |= ELF_LOGFILE_HEADER_WRAP;
1361 }
1362 /*
1363 * Otherwise, we can fit the header and only part
1364 * of the data will overwrite the oldest records.
1365 *
1366 * It might be possible that all the event record can fit in one piece,
1367 * but that the EOF record needs to be split. This is not a problem,
1368 * EVENTLOGEOF can be splitted while EVENTLOGRECORD cannot be.
1369 */
1370
1371 if (UpperBound - WriteOffset < BufSize + sizeof(EofRec))
1372 {
1373 ULONG OrgOldestRecordNumber, OldestRecordNumber;
1374
1375 // DPRINT("EventLogFile has reached maximum size, wrapping...\n");
1376
1377 OldestRecordNumber = OrgOldestRecordNumber = LogFile->Header.OldestRecordNumber;
1378
1379 // FIXME: Assert whether LogFile->Header.StartOffset is the beginning of a record???
1380 // NOTE: It should be, by construction (and this should have been checked when
1381 // initializing a new, or existing log).
1382
1383 /*
1384 * Determine how many old records need to be overwritten.
1385 * Check the size of the record as the record added may be larger.
1386 * Need to take into account that we append the EOF record.
1387 */
1388 while (FreeSpace < BufSize + sizeof(EofRec))
1389 {
1390 /* Get the oldest record data */
1391 RecOffset = ElfpOffsetByNumber(LogFile, OldestRecordNumber);
1392 if (RecOffset == 0)
1393 {
1394 EVTLTRACE1("Record number %d cannot be found, or log file is full and cannot wrap!\n", OldestRecordNumber);
1395 LogFile->Header.Flags |= ELF_LOGFILE_LOGFULL_WRITTEN;
1396 return STATUS_LOG_FILE_FULL;
1397 }
1398
1399 RtlZeroMemory(&RecBuf, sizeof(RecBuf));
1400
1401 FileOffset.QuadPart = RecOffset;
1402 Status = LogFile->FileRead(LogFile,
1403 &FileOffset,
1404 &RecBuf,
1405 sizeof(RecBuf),
1406 &ReadLength);
1407 if (!NT_SUCCESS(Status))
1408 {
1409 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
1410 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1411 return Status;
1412 }
1413
1414 if (RecBuf.Reserved != LOGFILE_SIGNATURE)
1415 {
1416 EVTLTRACE1("The event log file is corrupted!\n");
1418 }
1419
1420 /*
1421 * Check whether this event can be overwritten by comparing its
1422 * written timestamp with the log's retention value. This value
1423 * is the time interval, in seconds, that events records are
1424 * protected from being overwritten.
1425 *
1426 * If the retention value is zero the events are always overwritten.
1427 *
1428 * If the retention value is non-zero, when the age of an event,
1429 * in seconds, reaches or exceeds this value, it can be overwritten.
1430 * Also if the events are in the future, we do not overwrite them.
1431 */
1432 if (LogFile->Header.Retention != 0 &&
1433 (Record->TimeWritten < RecBuf.TimeWritten ||
1434 (Record->TimeWritten >= RecBuf.TimeWritten &&
1435 Record->TimeWritten - RecBuf.TimeWritten < LogFile->Header.Retention)))
1436 {
1437 EVTLTRACE1("The event log file is full and cannot wrap because of the retention policy.\n");
1438 LogFile->Header.Flags |= ELF_LOGFILE_LOGFULL_WRITTEN;
1439 return STATUS_LOG_FILE_FULL;
1440 }
1441
1442 /*
1443 * Advance the oldest record number, add the event record length
1444 * (as long as it is valid...) then take account for the possible
1445 * paddind after the record, in case this is the last one at the
1446 * end of the file.
1447 */
1448 OldestRecordNumber++;
1449 RecOffset += RecBuf.Length;
1450 FreeSpace += RecBuf.Length;
1451
1452 /*
1453 * If this was the last event record before the end of the log file,
1454 * the next one should start at the beginning of the log and the space
1455 * between the last event record and the end of the file is padded.
1456 */
1457 if (LogFile->Header.MaxSize - RecOffset < sizeof(EVENTLOGRECORD))
1458 {
1459 /* Add the padding size */
1460 FreeSpace += LogFile->Header.MaxSize - RecOffset;
1461 }
1462 }
1463
1464 EVTLTRACE("Record will fit. FreeSpace %d, BufSize %d\n", FreeSpace, BufSize);
1465
1466 /* The log records are wrapping */
1467 LogFile->Header.Flags |= ELF_LOGFILE_HEADER_WRAP;
1468
1469
1470 // FIXME: May lead to corruption if the other subsequent calls fail...
1471
1472 /*
1473 * We have validated all the region of events to be discarded,
1474 * now we can perform their deletion.
1475 */
1476 ElfpDeleteOffsetInformation(LogFile, OrgOldestRecordNumber, OldestRecordNumber - 1);
1477 LogFile->Header.OldestRecordNumber = OldestRecordNumber;
1478 LogFile->Header.StartOffset = ElfpOffsetByNumber(LogFile, OldestRecordNumber);
1479 if (LogFile->Header.StartOffset == 0)
1480 {
1481 /*
1482 * We have deleted all the existing event records to make place
1483 * for the new one. We can put it at the start of the event log.
1484 */
1485 LogFile->Header.StartOffset = sizeof(EVENTLOGHEADER);
1486 WriteOffset = LogFile->Header.StartOffset;
1487 LogFile->Header.EndOffset = WriteOffset;
1488 }
1489
1490 EVTLTRACE("MaxSize = 0x%x, StartOffset = 0x%x, WriteOffset = 0x%x, EndOffset = 0x%x, BufSize = 0x%x\n"
1491 "OldestRecordNumber = %d\n",
1492 LogFile->Header.MaxSize, LogFile->Header.StartOffset, WriteOffset, LogFile->Header.EndOffset, BufSize,
1493 OldestRecordNumber);
1494 }
1495
1496 /*
1497 * Expand the log file if needed.
1498 * NOTE: It may be needed to perform this task a bit sooner if we need
1499 * such a thing for performing read operations, in the future...
1500 * Or if this operation needs to modify 'FreeSpace'...
1501 */
1502 if (LogFile->CurrentSize < LogFile->Header.MaxSize)
1503 {
1504 ULONG NewSize = WriteOffset + BufSize + sizeof(EofRec);
1505
1506 if (WriteOffset < LogFile->Header.EndOffset || NewSize > LogFile->Header.MaxSize)
1507 NewSize = LogFile->Header.MaxSize;
1508 else
1510
1511 if (NewSize > LogFile->CurrentSize)
1512 {
1513 EVTLTRACE1("Expanding the log file from %lu to %lu\n",
1514 LogFile->CurrentSize, NewSize);
1515 Status = LogFile->FileSetSize(LogFile, NewSize, LogFile->CurrentSize);
1516 if (!NT_SUCCESS(Status))
1517 {
1518 EVTLTRACE1("FileSetSize() failed (Status 0x%08lx)\n", Status);
1519 return Status;
1520 }
1521 LogFile->CurrentSize = NewSize;
1522 }
1523 }
1524
1525 /* Since we can write events in the log, clear the log full flag */
1526 LogFile->Header.Flags &= ~ELF_LOGFILE_LOGFULL_WRITTEN;
1527
1528 /* Pad the end of the log */
1529 // if (LogFile->Header.EndOffset + sizeof(RecBuf) > LogFile->Header.MaxSize)
1530 if (WriteOffset < LogFile->Header.EndOffset)
1531 {
1532 /* Pad all the space from LogFile->Header.EndOffset to LogFile->Header.MaxSize */
1533 WrittenLength = ROUND_DOWN(LogFile->Header.MaxSize - LogFile->Header.EndOffset, sizeof(ULONG));
1534 RtlFillMemoryUlong(&RecBuf, WrittenLength, 0x00000027);
1535
1536 FileOffset.QuadPart = LogFile->Header.EndOffset;
1537 Status = LogFile->FileWrite(LogFile,
1538 &FileOffset,
1539 &RecBuf,
1540 WrittenLength,
1541 &WrittenLength);
1542 if (!NT_SUCCESS(Status))
1543 {
1544 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1545 // return Status;
1546 }
1547 }
1548
1549 /* Write the event record buffer with possible wrap at offset sizeof(EVENTLOGHEADER) */
1550 FileOffset.QuadPart = WriteOffset;
1551 Status = WriteLogBuffer(LogFile,
1552 Record,
1553 BufSize,
1554 &WrittenLength,
1555 &FileOffset,
1556 &NextOffset);
1557 if (!NT_SUCCESS(Status))
1558 {
1559 EVTLTRACE1("WriteLogBuffer failed (Status 0x%08lx)\n", Status);
1560 return Status;
1561 }
1562 /* FileOffset now contains the offset just after the end of the record buffer */
1563 FileOffset = NextOffset;
1564
1565 if (!ElfpAddOffsetInformation(LogFile,
1566 Record->RecordNumber,
1567 WriteOffset))
1568 {
1569 return STATUS_NO_MEMORY; // STATUS_EVENTLOG_FILE_CORRUPT;
1570 }
1571
1572 LogFile->Header.CurrentRecordNumber++;
1573 if (LogFile->Header.CurrentRecordNumber == 0)
1574 LogFile->Header.CurrentRecordNumber = 1;
1575
1576 /*
1577 * Write the new EOF record offset just after the event record.
1578 * The EOF record can wrap (be splitted) if less than sizeof(EVENTLOGEOF)
1579 * bytes remains between the end of the record and the end of the log file.
1580 */
1581 LogFile->Header.EndOffset = FileOffset.QuadPart;
1582
1583 RtlCopyMemory(&EofRec, &EOFRecord, sizeof(EOFRecord));
1584 EofRec.BeginRecord = LogFile->Header.StartOffset;
1585 EofRec.EndRecord = LogFile->Header.EndOffset;
1586 EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
1587 EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
1588
1589 // FileOffset.QuadPart = LogFile->Header.EndOffset;
1590 Status = WriteLogBuffer(LogFile,
1591 &EofRec,
1592 sizeof(EofRec),
1593 &WrittenLength,
1594 &FileOffset,
1595 &NextOffset);
1596 if (!NT_SUCCESS(Status))
1597 {
1598 EVTLTRACE1("WriteLogBuffer failed (Status 0x%08lx)\n", Status);
1599 return Status;
1600 }
1601 FileOffset = NextOffset;
1602
1603 /* Flush the log file */
1604 Status = ElfFlushFile(LogFile);
1605 if (!NT_SUCCESS(Status))
1606 {
1607 EVTLTRACE1("ElfFlushFile() failed (Status 0x%08lx)\n", Status);
1608 return STATUS_EVENTLOG_FILE_CORRUPT; // Status;
1609 }
1610
1611 return Status;
1612}
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
static BOOL ElfpDeleteOffsetInformation(IN PEVTLOGFILE LogFile, IN ULONG ulNumberMin, IN ULONG ulNumberMax)
Definition: evtlib.c:257
static NTSTATUS WriteLogBuffer(IN PEVTLOGFILE LogFile, IN PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T WrittenLength OPTIONAL, IN PLARGE_INTEGER ByteOffset, OUT PLARGE_INTEGER NextOffset OPTIONAL)
Definition: evtlib.c:113
#define ELF_LOGFILE_LOGFULL_WRITTEN
Definition: evtlib.h:50
#define ELF_LOGFILE_HEADER_WRAP
Definition: evtlib.h:49
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define STATUS_LOG_FILE_FULL
Definition: ntstatus.h:719
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1921

Referenced by LogfWriteRecord().

◆ ReadLogBuffer()

static NTSTATUS ReadLogBuffer ( IN PEVTLOGFILE  LogFile,
OUT PVOID  Buffer,
IN SIZE_T  Length,
OUT PSIZE_T ReadLength  OPTIONAL,
IN PLARGE_INTEGER  ByteOffset,
OUT PLARGE_INTEGER NextOffset  OPTIONAL 
)
static

Definition at line 39 of file evtlib.c.

46{
50 SIZE_T ReadBufLength = 0, OldReadBufLength;
51
52 ASSERT(LogFile->CurrentSize <= LogFile->Header.MaxSize);
53 ASSERT(ByteOffset->QuadPart <= LogFile->CurrentSize);
54
55 if (ReadLength)
56 *ReadLength = 0;
57
58 if (NextOffset)
59 NextOffset->QuadPart = 0LL;
60
61 /* Read the first part of the buffer */
63 BufSize = min(Length, LogFile->CurrentSize - FileOffset.QuadPart);
64
65 Status = LogFile->FileRead(LogFile,
67 Buffer,
68 BufSize,
69 &ReadBufLength);
70 if (!NT_SUCCESS(Status))
71 {
72 EVTLTRACE("FileRead() failed (Status 0x%08lx)\n", Status);
73 return Status;
74 }
75
76 if (Length > BufSize)
77 {
78 OldReadBufLength = ReadBufLength;
79
80 /*
81 * The buffer was splitted in two, its second part
82 * is to be read at the beginning of the log.
83 */
86 FileOffset.QuadPart = sizeof(EVENTLOGHEADER);
87
88 Status = LogFile->FileRead(LogFile,
90 Buffer,
91 BufSize,
92 &ReadBufLength);
93 if (!NT_SUCCESS(Status))
94 {
95 EVTLTRACE("FileRead() failed (Status 0x%08lx)\n", Status);
96 return Status;
97 }
98 /* Add the read number of bytes from the first read */
99 ReadBufLength += OldReadBufLength;
100 }
101
102 if (ReadLength)
103 *ReadLength = ReadBufLength;
104
105 /* We return the offset just after the end of the read buffer */
106 if (NextOffset)
107 NextOffset->QuadPart = FileOffset.QuadPart + BufSize;
108
109 return Status;
110}
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
#define min(a, b)
Definition: monoChain.cc:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
void * PVOID
Definition: typedefs.h:50

Referenced by ElfBackupFile(), ElfpInitExistingFile(), and ElfReadRecord().

◆ WriteLogBuffer()

static NTSTATUS WriteLogBuffer ( IN PEVTLOGFILE  LogFile,
IN PVOID  Buffer,
IN SIZE_T  Length,
OUT PSIZE_T WrittenLength  OPTIONAL,
IN PLARGE_INTEGER  ByteOffset,
OUT PLARGE_INTEGER NextOffset  OPTIONAL 
)
static

Definition at line 113 of file evtlib.c.

120{
124 SIZE_T WrittenBufLength = 0, OldWrittenBufLength;
125
126 /* We must have write access to the log file */
127 ASSERT(!LogFile->ReadOnly);
128
129 /*
130 * It is expected that the log file is already correctly expanded
131 * before we can write in it. Therefore the following assertions hold.
132 */
133 ASSERT(LogFile->CurrentSize <= LogFile->Header.MaxSize);
134 ASSERT(ByteOffset->QuadPart <= LogFile->CurrentSize);
135
136 if (WrittenLength)
137 *WrittenLength = 0;
138
139 if (NextOffset)
140 NextOffset->QuadPart = 0LL;
141
142 /* Write the first part of the buffer */
144 BufSize = min(Length, LogFile->CurrentSize - FileOffset.QuadPart);
145
146 Status = LogFile->FileWrite(LogFile,
147 &FileOffset,
148 Buffer,
149 BufSize,
150 &WrittenBufLength);
151 if (!NT_SUCCESS(Status))
152 {
153 EVTLTRACE("FileWrite() failed (Status 0x%08lx)\n", Status);
154 return Status;
155 }
156
157 if (Length > BufSize)
158 {
159 OldWrittenBufLength = WrittenBufLength;
160
161 /*
162 * The buffer was splitted in two, its second part
163 * is written at the beginning of the log.
164 */
167 FileOffset.QuadPart = sizeof(EVENTLOGHEADER);
168
169 Status = LogFile->FileWrite(LogFile,
170 &FileOffset,
171 Buffer,
172 BufSize,
173 &WrittenBufLength);
174 if (!NT_SUCCESS(Status))
175 {
176 EVTLTRACE("FileWrite() failed (Status 0x%08lx)\n", Status);
177 return Status;
178 }
179 /* Add the written number of bytes from the first write */
180 WrittenBufLength += OldWrittenBufLength;
181
182 /* The log wraps */
183 LogFile->Header.Flags |= ELF_LOGFILE_HEADER_WRAP;
184 }
185
186 if (WrittenLength)
187 *WrittenLength = WrittenBufLength;
188
189 /* We return the offset just after the end of the written buffer */
190 if (NextOffset)
191 NextOffset->QuadPart = FileOffset.QuadPart + BufSize;
192
193 return Status;
194}

Referenced by ElfWriteRecord().

Variable Documentation

◆ EOFRecord

const EVENTLOGEOF EOFRecord
static
Initial value:
=
{
sizeof(EOFRecord),
0x11111111, 0x22222222, 0x33333333, 0x44444444,
0, 0, 0, 0,
sizeof(EOFRecord)
}

Definition at line 28 of file evtlib.c.

Referenced by ElfBackupFile(), ElfpInitExistingFile(), ElfpInitNewFile(), and ElfWriteRecord().