ReactOS 0.4.15-dev-8413-gc1c91f2
evtlib.h File Reference
#include <ndk/rtlfuncs.h>
#include <pshpack4.h>
#include <poppack.h>
Include dependency graph for evtlib.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _EVENTLOGHEADER
 
struct  _EVENTLOGRECORD
 
struct  _EVENTLOGEOF
 
struct  _EVENT_OFFSET_INFO
 
struct  _EVTLOGFILE
 

Macros

#define NTOS_MODE_USER
 
#define ROUND_DOWN(n, align)   (((ULONG)n) & ~((align) - 1l))
 
#define ROUND_UP(n, align)   ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
 
#define MAJORVER   1
 
#define MINORVER   1
 
#define LOGFILE_SIGNATURE   0x654c664c
 
#define ELF_LOGFILE_HEADER_DIRTY   1
 
#define ELF_LOGFILE_HEADER_WRAP   2
 
#define ELF_LOGFILE_LOGFULL_WRITTEN   4
 
#define ELF_LOGFILE_ARCHIVE_SET   8
 
#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
 
#define EVENTLOGEOF_SIZE_FIXED   (5 * sizeof(ULONG))
 
#define TAG_ELF   ' flE'
 
#define TAG_ELF_BUF   'BflE'
 

Typedefs

typedef struct _EVENTLOGHEADER EVENTLOGHEADER
 
typedef struct _EVENTLOGHEADERPEVENTLOGHEADER
 
typedef struct _EVENTLOGRECORD EVENTLOGRECORD
 
typedef struct _EVENTLOGRECORDPEVENTLOGRECORD
 
typedef struct _EVENTLOGEOF EVENTLOGEOF
 
typedef struct _EVENTLOGEOFPEVENTLOGEOF
 
typedef struct _EVENT_OFFSET_INFO EVENT_OFFSET_INFO
 
typedef struct _EVENT_OFFSET_INFOPEVENT_OFFSET_INFO
 
typedef PVOID(NTAPIPELF_ALLOCATE_ROUTINE) (IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)
 
typedef VOID(NTAPIPELF_FREE_ROUTINE) (IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)
 
typedef NTSTATUS(NTAPIPELF_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(NTAPIPELF_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(NTAPIPELF_FILE_SET_SIZE_ROUTINE) (IN struct _EVTLOGFILE *LogFile, IN ULONG FileSize, IN ULONG OldFileSize)
 
typedef NTSTATUS(NTAPIPELF_FILE_FLUSH_ROUTINE) (IN struct _EVTLOGFILE *LogFile, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
 
typedef struct _EVTLOGFILE EVTLOGFILE
 
typedef struct _EVTLOGFILEPEVTLOGFILE
 

Functions

 C_ASSERT (EVENTLOGEOF_SIZE_FIXED==FIELD_OFFSET(EVENTLOGEOF, BeginRecord))
 
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)
 

Macro Definition Documentation

◆ ELF_LOGFILE_ARCHIVE_SET

#define ELF_LOGFILE_ARCHIVE_SET   8

Definition at line 51 of file evtlib.h.

◆ ELF_LOGFILE_HEADER_DIRTY

#define ELF_LOGFILE_HEADER_DIRTY   1

Definition at line 48 of file evtlib.h.

◆ ELF_LOGFILE_HEADER_WRAP

#define ELF_LOGFILE_HEADER_WRAP   2

Definition at line 49 of file evtlib.h.

◆ ELF_LOGFILE_LOGFULL_WRITTEN

#define ELF_LOGFILE_LOGFULL_WRITTEN   4

Definition at line 50 of file evtlib.h.

◆ EVENTLOG_AUDIT_FAILURE

#define EVENTLOG_AUDIT_FAILURE   16

Definition at line 88 of file evtlib.h.

◆ EVENTLOG_AUDIT_SUCCESS

#define EVENTLOG_AUDIT_SUCCESS   8

Definition at line 87 of file evtlib.h.

◆ EVENTLOG_ERROR_TYPE

#define EVENTLOG_ERROR_TYPE   1

Definition at line 84 of file evtlib.h.

◆ EVENTLOG_INFORMATION_TYPE

#define EVENTLOG_INFORMATION_TYPE   4

Definition at line 86 of file evtlib.h.

◆ EVENTLOG_SUCCESS

#define EVENTLOG_SUCCESS   0

Definition at line 83 of file evtlib.h.

◆ EVENTLOG_WARNING_TYPE

#define EVENTLOG_WARNING_TYPE   2

Definition at line 85 of file evtlib.h.

◆ EVENTLOGEOF_SIZE_FIXED

#define EVENTLOGEOF_SIZE_FIXED   (5 * sizeof(ULONG))

Definition at line 139 of file evtlib.h.

◆ LOGFILE_SIGNATURE

#define LOGFILE_SIGNATURE   0x654c664c

Definition at line 43 of file evtlib.h.

◆ MAJORVER

#define MAJORVER   1

Definition at line 41 of file evtlib.h.

◆ MINORVER

#define MINORVER   1

Definition at line 42 of file evtlib.h.

◆ NTOS_MODE_USER

#define NTOS_MODE_USER

Definition at line 27 of file evtlib.h.

◆ ROUND_DOWN

#define ROUND_DOWN (   n,
  align 
)    (((ULONG)n) & ~((align) - 1l))

Definition at line 31 of file evtlib.h.

◆ ROUND_UP

#define ROUND_UP (   n,
  align 
)    ROUND_DOWN(((ULONG)n) + (align) - 1, (align))

Definition at line 35 of file evtlib.h.

◆ TAG_ELF

#define TAG_ELF   ' flE'

Definition at line 151 of file evtlib.h.

◆ TAG_ELF_BUF

#define TAG_ELF_BUF   'BflE'

Definition at line 152 of file evtlib.h.

Typedef Documentation

◆ EVENT_OFFSET_INFO

◆ EVENTLOGEOF

◆ EVENTLOGHEADER

◆ EVENTLOGRECORD

◆ EVTLOGFILE

◆ PELF_ALLOCATE_ROUTINE

typedef PVOID(NTAPI * PELF_ALLOCATE_ROUTINE) (IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)

Definition at line 156 of file evtlib.h.

◆ PELF_FILE_FLUSH_ROUTINE

typedef NTSTATUS(NTAPI * PELF_FILE_FLUSH_ROUTINE) (IN struct _EVTLOGFILE *LogFile, IN PLARGE_INTEGER FileOffset, IN ULONG Length)

Definition at line 195 of file evtlib.h.

◆ PELF_FILE_READ_ROUTINE

Definition at line 170 of file evtlib.h.

◆ PELF_FILE_SET_SIZE_ROUTINE

typedef NTSTATUS(NTAPI * PELF_FILE_SET_SIZE_ROUTINE) (IN struct _EVTLOGFILE *LogFile, IN ULONG FileSize, IN ULONG OldFileSize)

Definition at line 188 of file evtlib.h.

◆ PELF_FILE_WRITE_ROUTINE

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)

Definition at line 179 of file evtlib.h.

◆ PELF_FREE_ROUTINE

typedef VOID(NTAPI * PELF_FREE_ROUTINE) (IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)

Definition at line 163 of file evtlib.h.

◆ PEVENT_OFFSET_INFO

◆ PEVENTLOGEOF

◆ PEVENTLOGHEADER

◆ PEVENTLOGRECORD

◆ PEVTLOGFILE

Function Documentation

◆ C_ASSERT()

C_ASSERT ( EVENTLOGEOF_SIZE_FIXED  = =FIELD_OFFSET(EVENTLOGEOF, BeginRecord))

◆ ElfBackupFile()

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

Definition at line 979 of file evtlib.c.

982{
984
986 SIZE_T ReadLength, WrittenLength;
988 EVENTLOGRECORD RecBuf;
989 EVENTLOGEOF EofRec;
990 ULONG i;
991 ULONG RecOffset;
992 PVOID Buffer = NULL;
993
994 ASSERT(LogFile);
995
996 RtlZeroMemory(BackupLogFile, sizeof(*BackupLogFile));
997
998 BackupLogFile->FileSetSize = LogFile->FileSetSize;
999 BackupLogFile->FileWrite = LogFile->FileWrite;
1000 BackupLogFile->FileFlush = LogFile->FileFlush;
1001
1002 // BackupLogFile->CurrentSize = LogFile->CurrentSize;
1003
1004 BackupLogFile->ReadOnly = FALSE;
1005
1006 /* Initialize the (dirty) log file header */
1007 Header = &BackupLogFile->Header;
1008 Header->HeaderSize = sizeof(EVENTLOGHEADER);
1009 Header->Signature = LOGFILE_SIGNATURE;
1010 Header->MajorVersion = MAJORVER;
1011 Header->MinorVersion = MINORVER;
1012 Header->StartOffset = sizeof(EVENTLOGHEADER);
1013 Header->EndOffset = sizeof(EVENTLOGHEADER);
1014 Header->CurrentRecordNumber = 1;
1015 Header->OldestRecordNumber = 0;
1016 Header->MaxSize = LogFile->Header.MaxSize;
1018 Header->Retention = LogFile->Header.Retention;
1019 Header->EndHeaderSize = sizeof(EVENTLOGHEADER);
1020
1021 /* Write the (dirty) log file header */
1022 FileOffset.QuadPart = 0LL;
1023 Status = BackupLogFile->FileWrite(BackupLogFile,
1024 &FileOffset,
1025 Header,
1026 sizeof(EVENTLOGHEADER),
1027 &WrittenLength);
1028 if (!NT_SUCCESS(Status))
1029 {
1030 EVTLTRACE1("Failed to write the log file header (Status 0x%08lx)\n", Status);
1031 goto Quit;
1032 }
1033
1034 for (i = LogFile->Header.OldestRecordNumber; i < LogFile->Header.CurrentRecordNumber; i++)
1035 {
1036 RecOffset = ElfpOffsetByNumber(LogFile, i);
1037 if (RecOffset == 0)
1038 break;
1039
1040 /* Read the next EVENTLOGRECORD header at once (it cannot be split) */
1041 FileOffset.QuadPart = RecOffset;
1042 Status = LogFile->FileRead(LogFile,
1043 &FileOffset,
1044 &RecBuf,
1045 sizeof(RecBuf),
1046 &ReadLength);
1047 if (!NT_SUCCESS(Status))
1048 {
1049 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
1050 goto Quit;
1051 }
1052
1053 // if (ReadLength != sizeof(RecBuf))
1054 // break;
1055
1056 Buffer = LogFile->Allocate(RecBuf.Length, 0, TAG_ELF_BUF);
1057 if (Buffer == NULL)
1058 {
1059 EVTLTRACE1("Allocate() failed!\n");
1060 goto Quit;
1061 }
1062
1063 /* Read the full EVENTLOGRECORD (header + data) with wrapping */
1064 Status = ReadLogBuffer(LogFile,
1065 Buffer,
1066 RecBuf.Length,
1067 &ReadLength,
1068 &FileOffset,
1069 NULL);
1070 if (!NT_SUCCESS(Status))
1071 {
1072 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
1073 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1074 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1075 goto Quit;
1076 }
1077
1078 /* Write the event record (no wrap for the backup log) */
1079 Status = BackupLogFile->FileWrite(BackupLogFile,
1080 NULL,
1081 Buffer,
1082 RecBuf.Length,
1083 &WrittenLength);
1084 if (!NT_SUCCESS(Status))
1085 {
1086 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1087 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1088 goto Quit;
1089 }
1090
1091 /* Update the header information */
1092 Header->EndOffset += RecBuf.Length;
1093
1094 /* Free the buffer */
1095 LogFile->Free(Buffer, 0, TAG_ELF_BUF);
1096 Buffer = NULL;
1097 }
1098
1099// Quit:
1100
1101 /* Initialize the ELF_EOF_RECORD and write it (no wrap for the backup log) */
1102 RtlCopyMemory(&EofRec, &EOFRecord, sizeof(EOFRecord));
1103 EofRec.BeginRecord = Header->StartOffset;
1104 EofRec.EndRecord = Header->EndOffset;
1105 EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
1106 EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
1107
1108 Status = BackupLogFile->FileWrite(BackupLogFile,
1109 NULL,
1110 &EofRec,
1111 sizeof(EofRec),
1112 &WrittenLength);
1113 if (!NT_SUCCESS(Status))
1114 {
1115 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1116 goto Quit;
1117 }
1118
1119 /* Update the header information */
1120 Header->CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
1121 Header->OldestRecordNumber = LogFile->Header.OldestRecordNumber;
1122 Header->MaxSize = ROUND_UP(Header->EndOffset + sizeof(EofRec), sizeof(ULONG));
1123 Header->Flags = 0; // FIXME?
1124
1125 /* Flush the log file - Write the (clean) log file header */
1126 Status = ElfFlushFile(BackupLogFile);
1127
1128Quit:
1129 return Status;
1130}
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:26
#define EVTLTRACE1(...)
Definition: evtlib.c:21
static ULONG ElfpOffsetByNumber(IN PEVTLOGFILE LogFile, IN ULONG RecordNumber)
Definition: evtlib.c:197
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:37
NTSTATUS NTAPI ElfFlushFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1134
#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:25
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:167
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 1179 of file evtlib.c.

1181{
1182 ASSERT(LogFile);
1183
1184 /* Flush the log file */
1185 ElfFlushFile(LogFile);
1186
1187 /* Free the data */
1188 LogFile->Free(LogFile->OffsetInfo, 0, TAG_ELF);
1189
1190 if (LogFile->FileName.Buffer)
1191 LogFile->Free(LogFile->FileName.Buffer, 0, TAG_ELF);
1192 RtlInitEmptyUnicodeString(&LogFile->FileName, NULL, 0);
1193}
#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 876 of file evtlib.c.

890{
892
893 ASSERT(LogFile);
894
895 /* Creating a new log file with the 'ReadOnly' flag set is incompatible */
896 if (CreateNew && ReadOnly)
898
899 RtlZeroMemory(LogFile, sizeof(*LogFile));
900
901 LogFile->Allocate = Allocate;
902 LogFile->Free = Free;
903 LogFile->FileSetSize = FileSetSize;
904 LogFile->FileWrite = FileWrite;
905 LogFile->FileRead = FileRead;
906 LogFile->FileFlush = FileFlush;
907
908 /* Copy the log file name if provided (optional) */
909 RtlInitEmptyUnicodeString(&LogFile->FileName, NULL, 0);
910 if (FileName && FileName->Buffer && FileName->Length &&
911 (FileName->Length <= FileName->MaximumLength))
912 {
913 LogFile->FileName.Buffer = LogFile->Allocate(FileName->Length,
915 TAG_ELF);
916 if (LogFile->FileName.Buffer)
917 {
918 LogFile->FileName.MaximumLength = FileName->Length;
919 RtlCopyUnicodeString(&LogFile->FileName, FileName);
920 }
921 }
922
923 LogFile->OffsetInfo = LogFile->Allocate(OFFSET_INFO_INCREMENT * sizeof(EVENT_OFFSET_INFO),
925 TAG_ELF);
926 if (LogFile->OffsetInfo == NULL)
927 {
928 EVTLTRACE1("Cannot allocate heap\n");
930 goto Quit;
931 }
932 LogFile->OffsetInfoSize = OFFSET_INFO_INCREMENT;
933 LogFile->OffsetInfoNext = 0;
934
935 // FIXME: Always use the regitry values for MaxSize,
936 // even for existing logs!
937
938 // FIXME: On Windows, EventLog uses the MaxSize setting
939 // from the registry itself; the MaxSize from the header
940 // is just for information purposes.
941
942 EVTLTRACE("Initializing log file `%wZ'\n", &LogFile->FileName);
943
944 LogFile->ReadOnly = ReadOnly; // !CreateNew && ReadOnly;
945
946 if (CreateNew)
947 Status = ElfpInitNewFile(LogFile, FileSize, MaxSize, Retention);
948 else
949 Status = ElfpInitExistingFile(LogFile, FileSize, /* MaxSize, */ Retention);
950
951Quit:
952 if (!NT_SUCCESS(Status))
953 {
954 if (LogFile->OffsetInfo)
955 LogFile->Free(LogFile->OffsetInfo, 0, TAG_ELF);
956
957 if (LogFile->FileName.Buffer)
958 LogFile->Free(LogFile->FileName.Buffer, 0, TAG_ELF);
959 }
960
961 return Status;
962}
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static NTSTATUS ElfpInitNewFile(IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG MaxSize, IN ULONG Retention)
Definition: evtlib.c:297
static NTSTATUS ElfpInitExistingFile(IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG Retention)
Definition: evtlib.c:379
#define OFFSET_INFO_INCREMENT
Definition: evtlib.c:211
#define EVTLTRACE(...)
Definition: evtlib.c:19
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
@ ReadOnly
Definition: arc.h:80
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:814
_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 1134 of file evtlib.c.

1136{
1139 SIZE_T WrittenLength;
1140
1141 ASSERT(LogFile);
1142
1143 if (LogFile->ReadOnly)
1144 return STATUS_SUCCESS; // STATUS_ACCESS_DENIED;
1145
1146 /*
1147 * NOTE that both the EOF record *AND* the log file header
1148 * are supposed to be already updated!
1149 * We just remove the dirty log bit.
1150 */
1151 LogFile->Header.Flags &= ~ELF_LOGFILE_HEADER_DIRTY;
1152
1153 /* Update the log file header */
1154 FileOffset.QuadPart = 0LL;
1155 Status = LogFile->FileWrite(LogFile,
1156 &FileOffset,
1157 &LogFile->Header,
1158 sizeof(EVENTLOGHEADER),
1159 &WrittenLength);
1160 if (!NT_SUCCESS(Status))
1161 {
1162 EVTLTRACE1("FileWrite() failed (Status 0x%08lx)\n", Status);
1163 return Status;
1164 }
1165
1166 /* Flush the log file */
1167 Status = LogFile->FileFlush(LogFile, NULL, 0);
1168 if (!NT_SUCCESS(Status))
1169 {
1170 EVTLTRACE1("FileFlush() failed (Status 0x%08lx)\n", Status);
1171 return Status;
1172 }
1173
1174 return STATUS_SUCCESS;
1175}
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 1598 of file evtlib.c.

1600{
1601 ASSERT(LogFile);
1602 return LogFile->Header.CurrentRecordNumber;
1603}

Referenced by ElfrNumberOfRecords(), and LogfReadEvents().

◆ ElfGetFlags()

ULONG NTAPI ElfGetFlags ( IN PEVTLOGFILE  LogFile)

Definition at line 1607 of file evtlib.c.

1609{
1610 ASSERT(LogFile);
1611 return LogFile->Header.Flags;
1612}

Referenced by ElfrGetLogInformation().

◆ ElfGetOldestRecord()

ULONG NTAPI ElfGetOldestRecord ( IN PEVTLOGFILE  LogFile)

Definition at line 1589 of file evtlib.c.

1591{
1592 ASSERT(LogFile);
1593 return LogFile->Header.OldestRecordNumber;
1594}

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

◆ 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 1197 of file evtlib.c.

1204{
1207 ULONG RecOffset;
1208 ULONG RecSize;
1210
1211 ASSERT(LogFile);
1212
1213 if (BytesRead)
1214 *BytesRead = 0;
1215
1216 if (BytesNeeded)
1217 *BytesNeeded = 0;
1218
1219 /* Retrieve the offset of the event record */
1220 RecOffset = ElfpOffsetByNumber(LogFile, RecordNumber);
1221 if (RecOffset == 0)
1222 return STATUS_NOT_FOUND;
1223
1224 /* Retrieve its full size */
1225 FileOffset.QuadPart = RecOffset;
1226 Status = LogFile->FileRead(LogFile,
1227 &FileOffset,
1228 &RecSize,
1229 sizeof(RecSize),
1230 &ReadLength);
1231 if (!NT_SUCCESS(Status))
1232 {
1233 EVTLTRACE1("FileRead() failed (Status 0x%08lx)\n", Status);
1234 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1235 return Status;
1236 }
1237
1238 /* Check whether the buffer is big enough to hold the event record */
1239 if (BufSize < RecSize)
1240 {
1241 if (BytesNeeded)
1242 *BytesNeeded = RecSize;
1243
1245 }
1246
1247 /* Read the event record into the buffer */
1248 FileOffset.QuadPart = RecOffset;
1249 Status = ReadLogBuffer(LogFile,
1250 Record,
1251 RecSize,
1252 &ReadLength,
1253 &FileOffset,
1254 NULL);
1255 if (!NT_SUCCESS(Status))
1256 {
1257 EVTLTRACE1("ReadLogBuffer failed (Status 0x%08lx)\n", Status);
1258 // Status = STATUS_EVENTLOG_FILE_CORRUPT;
1259 }
1260
1261 if (BytesRead)
1263
1264 return Status;
1265}
#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:268

Referenced by ReadRecord().

◆ ElfReCreateFile()

NTSTATUS NTAPI ElfReCreateFile ( IN PEVTLOGFILE  LogFile)

Definition at line 966 of file evtlib.c.

968{
969 ASSERT(LogFile);
970
971 return ElfpInitNewFile(LogFile,
972 LogFile->CurrentSize,
973 LogFile->Header.MaxSize,
974 LogFile->Header.Retention);
975}

Referenced by LogfClearFile().

◆ ElfWriteRecord()

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

Definition at line 1269 of file evtlib.c.

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