ReactOS  0.4.12-dev-75-g00dd17e
file.c File Reference
#include "eventlog.h"
#include <ndk/iofuncs.h>
#include <ndk/kefuncs.h>
#include <debug.h>
Include dependency graph for file.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID LogfListInitialize (VOID)
 
PLOGFILE LogfListItemByName (LPCWSTR Name)
 
PLOGFILE LogfListItemByIndex (DWORD Index)
 
DWORD LogfListItemCount (VOID)
 
static VOID LogfListAddItem (PLOGFILE Item)
 
static VOID LogfListRemoveItem (PLOGFILE Item)
 
static PVOID NTAPI LogfpAlloc (IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)
 
static VOID NTAPI LogfpFree (IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)
 
static NTSTATUS NTAPI LogfpReadFile (IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, OUT PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T ReadLength OPTIONAL)
 
static NTSTATUS NTAPI LogfpWriteFile (IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, IN PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T WrittenLength OPTIONAL)
 
static NTSTATUS NTAPI LogfpSetFileSize (IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG OldFileSize)
 
static NTSTATUS NTAPI LogfpFlushFile (IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
 
NTSTATUS LogfCreate (PLOGFILE *LogFile, PCWSTR LogName, PUNICODE_STRING FileName, ULONG MaxSize, ULONG Retention, BOOLEAN Permanent, BOOLEAN Backup)
 
VOID LogfClose (PLOGFILE LogFile, BOOLEAN ForceClose)
 
VOID LogfCloseAll (VOID)
 
NTSTATUS LogfClearFile (PLOGFILE LogFile, PUNICODE_STRING BackupFileName)
 
NTSTATUS LogfBackupFile (PLOGFILE LogFile, PUNICODE_STRING BackupFileName)
 
static NTSTATUS ReadRecord (IN PEVTLOGFILE LogFile, IN ULONG RecordNumber, OUT PEVENTLOGRECORD Record, IN SIZE_T BufSize, OUT PSIZE_T BytesRead OPTIONAL, OUT PSIZE_T BytesNeeded OPTIONAL, IN BOOLEAN Ansi)
 
NTSTATUS LogfReadEvents (PLOGFILE LogFile, ULONG Flags, PULONG RecordNumber, ULONG BufSize, PBYTE Buffer, PULONG BytesRead, PULONG BytesNeeded, BOOLEAN Ansi)
 
NTSTATUS LogfWriteRecord (PLOGFILE LogFile, PEVENTLOGRECORD Record, SIZE_T BufSize)
 
PEVENTLOGRECORD LogfAllocAndBuildNewRecord (PSIZE_T pRecSize, ULONG Time, USHORT wType, USHORT wCategory, ULONG dwEventId, PUNICODE_STRING SourceName, PUNICODE_STRING ComputerName, ULONG dwSidLength, PSID pUserSid, USHORT wNumStrings, PWSTR pStrings, ULONG dwDataSize, PVOID pRawData)
 
VOID LogfReportEvent (USHORT wType, USHORT wCategory, ULONG dwEventId, USHORT wNumStrings, PWSTR pStrings, ULONG dwDataSize, PVOID pRawData)
 

Variables

static LIST_ENTRY LogFileListHead
 
static CRITICAL_SECTION LogFileListCs
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file file.c.

Function Documentation

◆ LogfAllocAndBuildNewRecord()

PEVENTLOGRECORD LogfAllocAndBuildNewRecord ( PSIZE_T  pRecSize,
ULONG  Time,
USHORT  wType,
USHORT  wCategory,
ULONG  dwEventId,
PUNICODE_STRING  SourceName,
PUNICODE_STRING  ComputerName,
ULONG  dwSidLength,
PSID  pUserSid,
USHORT  wNumStrings,
PWSTR  pStrings,
ULONG  dwDataSize,
PVOID  pRawData 
)

Definition at line 896 of file file.c.

Referenced by ElfrIntReportEventW(), LogfReportEvent(), and ProcessPortMessage().

909 {
910  SIZE_T RecSize;
911  SIZE_T SourceNameSize, ComputerNameSize, StringLen;
912  PBYTE Buffer;
913  PEVENTLOGRECORD pRec;
914  PWSTR str;
915  UINT i, pos;
916 
917  SourceNameSize = (SourceName && SourceName->Buffer) ? SourceName->Length : 0;
918  ComputerNameSize = (ComputerName && ComputerName->Buffer) ? ComputerName->Length : 0;
919 
920  RecSize = sizeof(EVENTLOGRECORD) + /* Add the sizes of the strings, NULL-terminated */
921  SourceNameSize + ComputerNameSize + 2*sizeof(UNICODE_NULL);
922 
923  /* Align on DWORD boundary for the SID */
924  RecSize = ROUND_UP(RecSize, sizeof(ULONG));
925 
926  RecSize += dwSidLength;
927 
928  /* Add the sizes for the strings array */
929  ASSERT((pStrings == NULL && wNumStrings == 0) ||
930  (pStrings != NULL && wNumStrings >= 0));
931  for (i = 0, str = pStrings; i < wNumStrings; i++)
932  {
933  StringLen = wcslen(str) + 1; // str must be != NULL
934  RecSize += StringLen * sizeof(WCHAR);
935  str += StringLen;
936  }
937 
938  /* Add the data size */
939  RecSize += dwDataSize;
940 
941  /* Align on DWORD boundary for the full structure */
942  RecSize = ROUND_UP(RecSize, sizeof(ULONG));
943 
944  /* Size of the trailing 'Length' member */
945  RecSize += sizeof(ULONG);
946 
947  Buffer = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RecSize);
948  if (!Buffer)
949  {
950  DPRINT1("Cannot allocate heap!\n");
951  return NULL;
952  }
953 
954  pRec = (PEVENTLOGRECORD)Buffer;
955  pRec->Length = RecSize;
956  pRec->Reserved = LOGFILE_SIGNATURE;
957 
958  /*
959  * Do not assign here any precomputed record number to the event record.
960  * The true record number will be assigned atomically and sequentially in
961  * LogfWriteRecord, so that all the event records will have consistent and
962  * unique record numbers.
963  */
964  pRec->RecordNumber = 0;
965 
966  /*
967  * Set the generated time, and temporarily set the written time
968  * with the generated time.
969  */
970  pRec->TimeGenerated = Time;
971  pRec->TimeWritten = Time;
972 
973  pRec->EventID = dwEventId;
974  pRec->EventType = wType;
975  pRec->EventCategory = wCategory;
976 
977  pos = sizeof(EVENTLOGRECORD);
978 
979  /* NOTE: Equivalents of RtlStringCbCopyUnicodeString calls */
980  if (SourceNameSize)
981  {
982  StringCbCopyNW((PWSTR)(Buffer + pos), SourceNameSize + sizeof(UNICODE_NULL),
983  SourceName->Buffer, SourceNameSize);
984  }
985  pos += SourceNameSize + sizeof(UNICODE_NULL);
986  if (ComputerNameSize)
987  {
988  StringCbCopyNW((PWSTR)(Buffer + pos), ComputerNameSize + sizeof(UNICODE_NULL),
989  ComputerName->Buffer, ComputerNameSize);
990  }
991  pos += ComputerNameSize + sizeof(UNICODE_NULL);
992 
993  /* Align on DWORD boundary for the SID */
994  pos = ROUND_UP(pos, sizeof(ULONG));
995 
996  pRec->UserSidLength = 0;
997  pRec->UserSidOffset = 0;
998  if (dwSidLength)
999  {
1000  RtlCopyMemory(Buffer + pos, pUserSid, dwSidLength);
1001  pRec->UserSidLength = dwSidLength;
1002  pRec->UserSidOffset = pos;
1003  pos += dwSidLength;
1004  }
1005 
1006  pRec->StringOffset = pos;
1007  for (i = 0, str = pStrings; i < wNumStrings; i++)
1008  {
1009  StringLen = wcslen(str) + 1; // str must be != NULL
1010  StringCchCopyW((PWSTR)(Buffer + pos), StringLen, str);
1011  str += StringLen;
1012  pos += StringLen * sizeof(WCHAR);
1013  }
1014  pRec->NumStrings = wNumStrings;
1015 
1016  pRec->DataLength = 0;
1017  pRec->DataOffset = 0;
1018  if (dwDataSize)
1019  {
1020  RtlCopyMemory(Buffer + pos, pRawData, dwDataSize);
1021  pRec->DataLength = dwDataSize;
1022  pRec->DataOffset = pos;
1023  pos += dwDataSize;
1024  }
1025 
1026  /* Align on DWORD boundary for the full structure */
1027  pos = ROUND_UP(pos, sizeof(ULONG));
1028 
1029  /* Initialize the trailing 'Length' member */
1030  *((PDWORD)(Buffer + pos)) = RecSize;
1031 
1032  *pRecSize = RecSize;
1033  return pRec;
1034 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc, size_t cbToCopy)
Definition: strsafe.h:255
uint16_t * PWSTR
Definition: typedefs.h:54
static ULONG
Definition: file.c:43
DWORD StringOffset
Definition: winnt_old.h:2648
#define WCHAR
Definition: msvc.h:43
struct _EVENTLOGRECORD EVENTLOGRECORD
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define UNICODE_NULL
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define GetProcessHeap()
Definition: compat.h:395
DWORD UserSidOffset
Definition: winnt_old.h:2650
#define LOGFILE_SIGNATURE
Definition: evtlib.h:43
unsigned int UINT
Definition: ndis.h:50
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _EVENTLOGRECORD * PEVENTLOGRECORD
DWORD RecordNumber
Definition: winnt_old.h:2639
ULONG_PTR SIZE_T
Definition: typedefs.h:78
DWORD TimeGenerated
Definition: winnt_old.h:2640
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD * PDWORD
Definition: pedump.c:68
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
DWORD UserSidLength
Definition: winnt_old.h:2649
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static PLARGE_INTEGER Time
Definition: time.c:105

◆ LogfBackupFile()

NTSTATUS LogfBackupFile ( PLOGFILE  LogFile,
PUNICODE_STRING  BackupFileName 
)

Definition at line 499 of file file.c.

Referenced by ElfrBackupELFW(), and LogfClearFile().

501 {
503  LOGFILE BackupLogFile;
506 
507  DPRINT("LogfBackupFile(%p, %wZ)\n", LogFile, BackupFileName);
508 
509  /* Lock the log file shared */
510  RtlAcquireResourceShared(&LogFile->Lock, TRUE);
511 
512  InitializeObjectAttributes(&ObjectAttributes,
513  BackupFileName,
515  NULL,
516  NULL);
517 
518  Status = NtCreateFile(&BackupLogFile.FileHandle,
520  &ObjectAttributes,
521  &IoStatusBlock,
522  NULL,
525  FILE_CREATE,
527  NULL,
528  0);
529  if (!NT_SUCCESS(Status))
530  {
531  DPRINT("Cannot create backup file `%wZ' (Status 0x%08lx)\n", BackupFileName, Status);
532  goto Quit;
533  }
534 
535  Status = ElfBackupFile(&LogFile->LogFile,
536  &BackupLogFile.LogFile);
537 
538 Quit:
539  /* Close the backup file */
540  if (BackupLogFile.FileHandle != NULL)
541  NtClose(BackupLogFile.FileHandle);
542 
543  /* Unlock the log file */
544  RtlReleaseResource(&LogFile->Lock);
545 
546  return Status;
547 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_CREATE
Definition: from_kernel.h:55
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
#define FILE_SHARE_READ
Definition: compat.h:125
EVTLOGFILE LogFile
Definition: eventlog.h:36
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
HANDLE FileHandle
Definition: eventlog.h:37
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
RTL_RESOURCE Lock
Definition: eventlog.h:39
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define GENERIC_READ
Definition: compat.h:124
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSTATUS NTAPI ElfBackupFile(IN PEVTLOGFILE LogFile, IN PEVTLOGFILE BackupLogFile)
Definition: evtlib.c:979
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocateSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
Definition: file.c:3735
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

◆ LogfClearFile()

NTSTATUS LogfClearFile ( PLOGFILE  LogFile,
PUNICODE_STRING  BackupFileName 
)

Definition at line 467 of file file.c.

Referenced by ElfrClearELFW().

469 {
471 
472  /* Lock the log file exclusive */
474 
475  if (BackupFileName->Length > 0)
476  {
477  /* Write a backup file */
478  Status = LogfBackupFile(LogFile, BackupFileName);
479  if (!NT_SUCCESS(Status))
480  {
481  DPRINT1("LogfBackupFile failed (Status 0x%08lx)\n", Status);
482  goto Quit;
483  }
484  }
485 
486  Status = ElfReCreateFile(&LogFile->LogFile);
487  if (!NT_SUCCESS(Status))
488  {
489  DPRINT1("LogfInitializeNew failed (Status 0x%08lx)\n", Status);
490  }
491 
492 Quit:
493  /* Unlock the log file */
494  RtlReleaseResource(&LogFile->Lock);
495  return Status;
496 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
EVTLOGFILE LogFile
Definition: eventlog.h:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
RTL_RESOURCE Lock
Definition: eventlog.h:39
Status
Definition: gdiplustypes.h:24
NTSTATUS LogfBackupFile(PLOGFILE LogFile, PUNICODE_STRING BackupFileName)
Definition: file.c:499
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI ElfReCreateFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:966
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

◆ LogfClose()

VOID LogfClose ( PLOGFILE  LogFile,
BOOLEAN  ForceClose 
)

Definition at line 428 of file file.c.

Referenced by ElfDeleteEventLogHandle(), and LogfCloseAll().

430 {
431  if (LogFile == NULL)
432  return;
433 
434  if (!ForceClose && LogFile->Permanent)
435  return;
436 
438 
439  LogfListRemoveItem(LogFile);
440 
441  ElfCloseFile(&LogFile->LogFile);
442  NtClose(LogFile->FileHandle);
443  LogfpFree(LogFile->LogName, 0, 0);
444 
445  RtlDeleteResource(&LogFile->Lock);
446 
447  LogfpFree(LogFile, 0, TAG_ELF);
448 
449  return;
450 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlDeleteResource(_In_ PRTL_RESOURCE Resource)
EVTLOGFILE LogFile
Definition: eventlog.h:36
smooth NULL
Definition: ftsmooth.c:416
static VOID NTAPI LogfpFree(IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:169
HANDLE FileHandle
Definition: eventlog.h:37
BOOL Permanent
Definition: eventlog.h:40
RTL_RESOURCE Lock
Definition: eventlog.h:39
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define TAG_ELF
Definition: evtlib.h:151
WCHAR * LogName
Definition: eventlog.h:38
VOID NTAPI ElfCloseFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1179
static VOID LogfListRemoveItem(PLOGFILE Item)
Definition: file.c:145
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

◆ LogfCloseAll()

VOID LogfCloseAll ( VOID  )

Definition at line 452 of file file.c.

Referenced by wmain().

453 {
455 
456  while (!IsListEmpty(&LogFileListHead))
457  {
459  }
460 
462 
464 }
VOID LogfClose(PLOGFILE LogFile, BOOLEAN ForceClose)
Definition: file.c:428
#define TRUE
Definition: types.h:120
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static LIST_ENTRY LogFileListHead
Definition: file.c:22
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ LogfCreate()

NTSTATUS LogfCreate ( PLOGFILE LogFile,
PCWSTR  LogName,
PUNICODE_STRING  FileName,
ULONG  MaxSize,
ULONG  Retention,
BOOLEAN  Permanent,
BOOLEAN  Backup 
)

Definition at line 294 of file file.c.

Referenced by ElfCreateBackupLogHandle(), and LoadLogFile().

301 {
305  FILE_STANDARD_INFORMATION FileStdInfo;
306  PLOGFILE pLogFile;
307  SIZE_T LogNameLen;
308  BOOLEAN CreateNew;
309 
310  pLogFile = LogfpAlloc(sizeof(*pLogFile), HEAP_ZERO_MEMORY, TAG_ELF);
311  if (!pLogFile)
312  {
313  DPRINT1("Cannot allocate heap!\n");
314  return STATUS_NO_MEMORY;
315  }
316 
317  LogNameLen = (LogName ? wcslen(LogName) : 0) + 1;
318  pLogFile->LogName = LogfpAlloc(LogNameLen * sizeof(WCHAR), HEAP_ZERO_MEMORY, 0);
319  if (pLogFile->LogName == NULL)
320  {
321  DPRINT1("Cannot allocate heap\n");
322  Status = STATUS_NO_MEMORY;
323  goto Quit;
324  }
325 
326  if (LogName)
327  StringCchCopyW(pLogFile->LogName, LogNameLen, LogName);
328 
329  InitializeObjectAttributes(&ObjectAttributes,
330  FileName,
332  NULL,
333  NULL);
334 
335  DPRINT("Going to create or open %wZ\n", FileName);
336  Status = NtCreateFile(&pLogFile->FileHandle,
337  Backup ? (GENERIC_READ | SYNCHRONIZE)
339  &ObjectAttributes,
340  &IoStatusBlock,
341  NULL,
344  Backup ? FILE_OPEN : FILE_OPEN_IF,
346  NULL,
347  0);
348  if (!NT_SUCCESS(Status))
349  {
350  DPRINT1("Cannot create file `%wZ' (Status 0x%08lx)\n", FileName, Status);
351  goto Quit;
352  }
353 
354  CreateNew = (IoStatusBlock.Information == FILE_CREATED);
355  DPRINT("%wZ %s successfully\n", FileName, CreateNew ? "created" : "opened");
356 
357  /*
358  * Retrieve the log file size and check whether the file is not too large;
359  * this log format only supports files of theoretical size < 0xFFFFFFFF .
360  *
361  * As it happens that, on Windows (and ReactOS), retrieving the End-Of-File
362  * information using NtQueryInformationFile with the FileEndOfFileInformation
363  * class is invalid (who knows why...), use instead the FileStandardInformation
364  * class, and the EndOfFile member of the returned FILE_STANDARD_INFORMATION
365  * structure will give the desired information.
366  */
367  Status = NtQueryInformationFile(pLogFile->FileHandle,
368  &IoStatusBlock,
369  &FileStdInfo,
370  sizeof(FileStdInfo),
372  if (!NT_SUCCESS(Status))
373  {
374  DPRINT1("EventLog: NtQueryInformationFile failed (Status 0x%08lx)\n", Status);
375  goto Quit;
376  }
377  if (FileStdInfo.EndOfFile.HighPart != 0)
378  {
379  DPRINT1("EventLog: Log `%wZ' is too large.\n", FileName);
380  Status = STATUS_EVENTLOG_FILE_CORRUPT; // STATUS_FILE_TOO_LARGE;
381  goto Quit;
382  }
383 
384  DPRINT("Initializing LogFile `%S'\n", pLogFile->LogName);
385 
386  Status = ElfCreateFile(&pLogFile->LogFile,
387  FileName,
388  FileStdInfo.EndOfFile.LowPart,
389  MaxSize,
390  Retention,
391  CreateNew,
392  Backup,
393  LogfpAlloc,
394  LogfpFree,
399  if (!NT_SUCCESS(Status))
400  goto Quit;
401 
402  pLogFile->Permanent = Permanent;
403 
404  RtlInitializeResource(&pLogFile->Lock);
405 
406  LogfListAddItem(pLogFile);
407 
408 Quit:
409  if (!NT_SUCCESS(Status))
410  {
411  if (pLogFile->FileHandle != NULL)
412  NtClose(pLogFile->FileHandle);
413 
414  if (pLogFile->LogName)
415  LogfpFree(pLogFile->LogName, 0, 0);
416 
417  LogfpFree(pLogFile, 0, TAG_ELF);
418  }
419  else
420  {
421  *LogFile = pLogFile;
422  }
423 
424  return Status;
425 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static NTSTATUS NTAPI LogfpWriteFile(IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, IN PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T WrittenLength OPTIONAL)
Definition: file.c:212
#define FILE_OPEN_IF
Definition: from_kernel.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_EVENTLOG_FILE_CORRUPT
Definition: ntstatus.h:617
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: evtlib.c:876
static PVOID NTAPI LogfpAlloc(IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:158
#define FILE_SHARE_READ
Definition: compat.h:125
EVTLOGFILE LogFile
Definition: eventlog.h:36
#define GENERIC_WRITE
Definition: nt_native.h:90
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
LARGE_INTEGER EndOfFile
Definition: nt_native.h:948
void DPRINT(...)
Definition: polytest.cpp:61
static VOID NTAPI LogfpFree(IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:169
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)
HANDLE FileHandle
Definition: eventlog.h:37
static NTSTATUS NTAPI LogfpSetFileSize(IN PEVTLOGFILE LogFile, IN ULONG FileSize, IN ULONG OldFileSize)
Definition: file.c:244
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
BOOL Permanent
Definition: eventlog.h:40
RTL_RESOURCE Lock
Definition: eventlog.h:39
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TAG_ELF
Definition: evtlib.h:151
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
WCHAR * LogName
Definition: eventlog.h:38
ULONG LowPart
Definition: typedefs.h:104
#define GENERIC_READ
Definition: compat.h:124
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocateSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength)
Definition: file.c:3735
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define FILE_CREATED
Definition: nt_native.h:770
static VOID LogfListAddItem(PLOGFILE Item)
Definition: file.c:137
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static NTSTATUS NTAPI LogfpFlushFile(IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: file.c:280
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static NTSTATUS NTAPI LogfpReadFile(IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, OUT PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T ReadLength OPTIONAL)
Definition: file.c:180

◆ LogfListAddItem()

static VOID LogfListAddItem ( PLOGFILE  Item)
static

Definition at line 137 of file file.c.

Referenced by LogfCreate().

138 {
142 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define InsertTailList(ListHead, Entry)
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
LIST_ENTRY ListEntry
Definition: eventlog.h:41
static LIST_ENTRY LogFileListHead
Definition: file.c:22
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ LogfListInitialize()

VOID LogfListInitialize ( VOID  )

Definition at line 27 of file file.c.

Referenced by wmain().

28 {
31 }
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
static LIST_ENTRY LogFileListHead
Definition: file.c:22
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

◆ LogfListItemByIndex()

PLOGFILE LogfListItemByIndex ( DWORD  Index)

Definition at line 93 of file file.c.

Referenced by ElfCreateEventLogHandle().

94 {
95  PLIST_ENTRY CurrentEntry;
97  DWORD i = 1;
98 
100 
101  CurrentEntry = LogFileListHead.Flink;
102  while (CurrentEntry != &LogFileListHead)
103  {
104  if (i == Index)
105  {
106  Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
107  break;
108  }
109 
110  CurrentEntry = CurrentEntry->Flink;
111  i++;
112  }
113 
115  return Result;
116 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned long DWORD
Definition: ntddk_ex.h:95
static LIST_ENTRY LogFileListHead
Definition: file.c:22
Definition: typedefs.h:117
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ LogfListItemByName()

PLOGFILE LogfListItemByName ( LPCWSTR  Name)

Definition at line 33 of file file.c.

Referenced by ElfCreateEventLogHandle(), and ProcessPortMessage().

34 {
35  PLIST_ENTRY CurrentEntry;
36  PLOGFILE Item, Result = NULL;
37 
38  ASSERT(Name);
39 
41 
42  CurrentEntry = LogFileListHead.Flink;
43  while (CurrentEntry != &LogFileListHead)
44  {
45  Item = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
46 
47  if (Item->LogName && !_wcsicmp(Item->LogName, Name))
48  {
49  Result = Item;
50  break;
51  }
52 
53  CurrentEntry = CurrentEntry->Flink;
54  }
55 
57  return Result;
58 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
WCHAR * LogName
Definition: eventlog.h:38
static LIST_ENTRY LogFileListHead
Definition: file.c:22
Definition: typedefs.h:117
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

◆ LogfListItemCount()

DWORD LogfListItemCount ( VOID  )

Definition at line 118 of file file.c.

Referenced by ElfCreateEventLogHandle().

119 {
120  PLIST_ENTRY CurrentEntry;
121  DWORD i = 0;
122 
124 
125  CurrentEntry = LogFileListHead.Flink;
126  while (CurrentEntry != &LogFileListHead)
127  {
128  CurrentEntry = CurrentEntry->Flink;
129  i++;
130  }
131 
133  return i;
134 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
unsigned long DWORD
Definition: ntddk_ex.h:95
static LIST_ENTRY LogFileListHead
Definition: file.c:22
Definition: typedefs.h:117
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ LogfListRemoveItem()

static VOID LogfListRemoveItem ( PLOGFILE  Item)
static

Definition at line 145 of file file.c.

Referenced by LogfClose().

146 {
148  RemoveEntryList(&Item->ListEntry);
150 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
LIST_ENTRY ListEntry
Definition: eventlog.h:41
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ LogfpAlloc()

static PVOID NTAPI LogfpAlloc ( IN SIZE_T  Size,
IN ULONG  Flags,
IN ULONG  Tag 
)
static

Definition at line 158 of file file.c.

Referenced by LogfCreate(), and ReadRecord().

161 {
164 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define GetProcessHeap()
Definition: compat.h:395
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
IN ULONG IN ULONG Tag
Definition: evtlib.h:159

◆ LogfpFlushFile()

static NTSTATUS NTAPI LogfpFlushFile ( IN PEVTLOGFILE  LogFile,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length 
)
static

Definition at line 280 of file file.c.

Referenced by LogfCreate().

283 {
284  PLOGFILE pLogFile = (PLOGFILE)LogFile;
286 
289 
290  return NtFlushBuffersFile(pLogFile->FileHandle, &IoStatusBlock);
291 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _LOGFILE * PLOGFILE
NTSTATUS NTAPI NtFlushBuffersFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: iofunc.c:1377
HANDLE FileHandle
Definition: eventlog.h:37
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75

◆ LogfpFree()

static VOID NTAPI LogfpFree ( IN PVOID  Ptr,
IN ULONG  Flags,
IN ULONG  Tag 
)
static

Definition at line 169 of file file.c.

Referenced by LogfClose(), LogfCreate(), and ReadRecord().

172 {
175 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define GetProcessHeap()
Definition: compat.h:395
IN ULONG IN ULONG Tag
Definition: evtlib.h:159

◆ LogfpReadFile()

static NTSTATUS NTAPI LogfpReadFile ( IN PEVTLOGFILE  LogFile,
IN PLARGE_INTEGER  FileOffset,
OUT PVOID  Buffer,
IN SIZE_T  Length,
OUT PSIZE_T ReadLength  OPTIONAL 
)
static

Definition at line 180 of file file.c.

Referenced by LogfCreate().

185 {
187  PLOGFILE pLogFile = (PLOGFILE)LogFile;
189 
190  if (ReadLength)
191  *ReadLength = 0;
192 
193  Status = NtReadFile(pLogFile->FileHandle,
194  NULL,
195  NULL,
196  NULL,
197  &IoStatusBlock,
198  Buffer,
199  Length,
200  FileOffset,
201  NULL);
202 
203  if (ReadLength)
204  *ReadLength = IoStatusBlock.Information;
205 
206  return Status;
207 }
struct _LOGFILE * PLOGFILE
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
HANDLE FileHandle
Definition: eventlog.h:37
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)

◆ LogfpSetFileSize()

static NTSTATUS NTAPI LogfpSetFileSize ( IN PEVTLOGFILE  LogFile,
IN ULONG  FileSize,
IN ULONG  OldFileSize 
)
static

Definition at line 244 of file file.c.

Referenced by LogfCreate().

247 {
249  PLOGFILE pLogFile = (PLOGFILE)LogFile;
251  FILE_END_OF_FILE_INFORMATION FileEofInfo;
252  FILE_ALLOCATION_INFORMATION FileAllocInfo;
253 
254  UNREFERENCED_PARAMETER(OldFileSize);
255 
256  // FIXME: Should we round up FileSize ??
257 
258  FileEofInfo.EndOfFile.QuadPart = FileSize;
259  Status = NtSetInformationFile(pLogFile->FileHandle,
260  &IoStatusBlock,
261  &FileEofInfo,
262  sizeof(FileEofInfo),
264  if (!NT_SUCCESS(Status))
265  return Status;
266 
267  FileAllocInfo.AllocationSize.QuadPart = FileSize;
268  Status = NtSetInformationFile(pLogFile->FileHandle,
269  &IoStatusBlock,
270  &FileAllocInfo,
271  sizeof(FileAllocInfo),
273 
274  return Status;
275 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _LOGFILE * PLOGFILE
LONG NTSTATUS
Definition: precomp.h:26
LARGE_INTEGER AllocationSize
Definition: winternl.h:688
HANDLE FileHandle
Definition: eventlog.h:37
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:2932
LONGLONG QuadPart
Definition: typedefs.h:112

◆ LogfpWriteFile()

static NTSTATUS NTAPI LogfpWriteFile ( IN PEVTLOGFILE  LogFile,
IN PLARGE_INTEGER  FileOffset,
IN PVOID  Buffer,
IN SIZE_T  Length,
OUT PSIZE_T WrittenLength  OPTIONAL 
)
static

Definition at line 212 of file file.c.

Referenced by LogfCreate().

217 {
219  PLOGFILE pLogFile = (PLOGFILE)LogFile;
221 
222  if (WrittenLength)
223  *WrittenLength = 0;
224 
225  Status = NtWriteFile(pLogFile->FileHandle,
226  NULL,
227  NULL,
228  NULL,
229  &IoStatusBlock,
230  Buffer,
231  Length,
232  FileOffset,
233  NULL);
234 
235  if (WrittenLength)
236  *WrittenLength = IoStatusBlock.Information;
237 
238  return Status;
239 }
struct _LOGFILE * PLOGFILE
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
HANDLE FileHandle
Definition: eventlog.h:37
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
Status
Definition: gdiplustypes.h:24
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75

◆ LogfReadEvents()

NTSTATUS LogfReadEvents ( PLOGFILE  LogFile,
ULONG  Flags,
PULONG  RecordNumber,
ULONG  BufSize,
PBYTE  Buffer,
PULONG  BytesRead,
PULONG  BytesNeeded,
BOOLEAN  Ansi 
)

Definition at line 721 of file file.c.

Referenced by ElfrReadELA(), and ElfrReadELW().

729 {
731  ULONG RecNum;
732  SIZE_T ReadLength, NeededSize;
733  ULONG BufferUsage;
734 
735  /* Parameters validation */
736 
737  /* EVENTLOG_SEQUENTIAL_READ and EVENTLOG_SEEK_READ are mutually exclusive */
740 
741  if (!(Flags & EVENTLOG_SEQUENTIAL_READ) && !(Flags & EVENTLOG_SEEK_READ))
743 
744  /* EVENTLOG_FORWARDS_READ and EVENTLOG_BACKWARDS_READ are mutually exclusive */
747 
748  if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ))
750 
751  if (!Buffer || !BytesRead || !BytesNeeded)
753 
754  /* In seek read mode, a record number of 0 is invalid */
755  if (!(Flags & EVENTLOG_SEQUENTIAL_READ) && (*RecordNumber == 0))
757 
758  /* Lock the log file shared */
759  RtlAcquireResourceShared(&LogFile->Lock, TRUE);
760 
761  /*
762  * In sequential read mode, a record number of 0 means we need
763  * to determine where to start the read operation. Otherwise
764  * we just use the provided record number.
765  */
766  if ((Flags & EVENTLOG_SEQUENTIAL_READ) && (*RecordNumber == 0))
767  {
768  if (Flags & EVENTLOG_FORWARDS_READ)
769  {
770  *RecordNumber = ElfGetOldestRecord(&LogFile->LogFile);
771  }
772  else // if (Flags & EVENTLOG_BACKWARDS_READ)
773  {
774  *RecordNumber = ElfGetCurrentRecord(&LogFile->LogFile) - 1;
775  }
776  }
777 
778  RecNum = *RecordNumber;
779 
780  *BytesRead = 0;
781  *BytesNeeded = 0;
782 
783  BufferUsage = 0;
784  do
785  {
786  Status = ReadRecord(&LogFile->LogFile,
787  RecNum,
788  (PEVENTLOGRECORD)(Buffer + BufferUsage),
789  BufSize - BufferUsage,
790  &ReadLength,
791  &NeededSize,
792  Ansi);
793  if (Status == STATUS_NOT_FOUND)
794  {
795  if (BufferUsage == 0)
796  {
797  Status = STATUS_END_OF_FILE;
798  goto Quit;
799  }
800  else
801  {
802  break;
803  }
804  }
805  else
806  if (Status == STATUS_BUFFER_TOO_SMALL)
807  {
808  if (BufferUsage == 0)
809  {
810  *BytesNeeded = NeededSize;
811  // Status = STATUS_BUFFER_TOO_SMALL;
812  goto Quit;
813  }
814  else
815  {
816  break;
817  }
818  }
819  else
820  if (!NT_SUCCESS(Status))
821  {
822  DPRINT1("ElfReadRecord failed (Status 0x%08lx)\n", Status);
823  goto Quit;
824  }
825 
826  /* Go to the next event record */
827  /*
828  * NOTE: This implicitly supposes that all the other record numbers
829  * are consecutive (and do not jump than more than one unit); but if
830  * it is not the case, then we would prefer here to call some
831  * "get_next_record_number" function.
832  */
833  if (Flags & EVENTLOG_FORWARDS_READ)
834  RecNum++;
835  else // if (Flags & EVENTLOG_BACKWARDS_READ)
836  RecNum--;
837 
838  BufferUsage += ReadLength;
839  }
840  while (BufferUsage <= BufSize);
841 
842  *BytesRead = BufferUsage;
843  *RecordNumber = RecNum;
844 
845  Status = STATUS_SUCCESS;
846 
847 Quit:
848  /* Unlock the log file */
849  RtlReleaseResource(&LogFile->Lock);
850 
851  if (!NT_SUCCESS(Status))
852  DPRINT1("LogfReadEvents failed (Status 0x%08lx)\n", Status);
853 
854  return Status;
855 }
ULONG NTAPI ElfGetOldestRecord(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1589
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
EVTLOGFILE LogFile
Definition: eventlog.h:36
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:52
#define EVENTLOG_BACKWARDS_READ
Definition: winnt_old.h:2627
#define STATUS_END_OF_FILE
Definition: shellext.h:50
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
Definition: bufpool.h:45
#define BufSize
Definition: FsRtlTunnel.c:28
#define STATUS_NOT_FOUND
Definition: shellext.h:55
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG NTAPI ElfGetCurrentRecord(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1598
#define EVENTLOG_SEQUENTIAL_READ
Definition: winnt_old.h:2624
RTL_RESOURCE Lock
Definition: eventlog.h:39
#define EVENTLOG_SEEK_READ
Definition: winnt_old.h:2625
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define EVENTLOG_FORWARDS_READ
Definition: winnt_old.h:2626
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
static NTSTATUS ReadRecord(IN PEVTLOGFILE LogFile, IN ULONG RecordNumber, OUT PEVENTLOGRECORD Record, IN SIZE_T BufSize, OUT PSIZE_T BytesRead OPTIONAL, OUT PSIZE_T BytesNeeded OPTIONAL, IN BOOLEAN Ansi)
Definition: file.c:551
return STATUS_SUCCESS
Definition: btrfs.c:2710
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

◆ LogfReportEvent()

VOID LogfReportEvent ( USHORT  wType,
USHORT  wCategory,
ULONG  dwEventId,
USHORT  wNumStrings,
PWSTR  pStrings,
ULONG  dwDataSize,
PVOID  pRawData 
)

Definition at line 1037 of file file.c.

Referenced by LogfFreeRecord(), ReportProductInfoEvent(), ServiceControlHandler(), and ServiceMain().

1044 {
1045  NTSTATUS Status;
1046  UNICODE_STRING SourceName, ComputerName;
1047  PEVENTLOGRECORD LogBuffer;
1048  LARGE_INTEGER SystemTime;
1049  ULONG Time;
1050  SIZE_T RecSize;
1051  DWORD dwComputerNameLength;
1052  WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1053 
1054  if (!EventLogSource)
1055  return;
1056 
1058 
1059  dwComputerNameLength = ARRAYSIZE(szComputerName);
1060  if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
1061  szComputerName[0] = L'\0';
1062 
1063  RtlInitUnicodeString(&ComputerName, szComputerName);
1064 
1065  NtQuerySystemTime(&SystemTime);
1066  RtlTimeToSecondsSince1970(&SystemTime, &Time);
1067 
1068  LogBuffer = LogfAllocAndBuildNewRecord(&RecSize,
1069  Time,
1070  wType,
1071  wCategory,
1072  dwEventId,
1073  &SourceName,
1074  &ComputerName,
1075  0,
1076  NULL,
1077  wNumStrings,
1078  pStrings,
1079  dwDataSize,
1080  pRawData);
1081  if (LogBuffer == NULL)
1082  {
1083  DPRINT1("LogfAllocAndBuildNewRecord failed!\n");
1084  return;
1085  }
1086 
1087  Status = LogfWriteRecord(EventLogSource->LogFile, LogBuffer, RecSize);
1088  if (!NT_SUCCESS(Status))
1089  {
1090  DPRINT1("ERROR writing to event log `%S' (Status 0x%08lx)\n",
1091  EventLogSource->LogFile->LogName, Status);
1092  }
1093 
1094  LogfFreeRecord(LogBuffer);
1095 }
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG NTSTATUS
Definition: precomp.h:26
static __inline void LogfFreeRecord(PEVENTLOGRECORD Record)
Definition: eventlog.h:143
PEVENTLOGRECORD LogfAllocAndBuildNewRecord(PSIZE_T pRecSize, ULONG Time, USHORT wType, USHORT wCategory, ULONG dwEventId, PUNICODE_STRING SourceName, PUNICODE_STRING ComputerName, ULONG dwSidLength, PSID pUserSid, USHORT wNumStrings, PWSTR pStrings, ULONG dwDataSize, PVOID pRawData)
Definition: file.c:896
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
Definition: compname.c:339
PLOGFILE LogFile
Definition: eventlog.h:47
WCHAR szName[1]
Definition: eventlog.h:48
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS LogfWriteRecord(PLOGFILE LogFile, PEVENTLOGRECORD Record, SIZE_T BufSize)
Definition: file.c:858
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
PEVENTSOURCE EventLogSource
Definition: eventlog.c:35
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1087
WCHAR * LogName
Definition: eventlog.h:38
Status
Definition: gdiplustypes.h:24
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:240
ULONG_PTR SIZE_T
Definition: typedefs.h:78
WCHAR SourceName[256]
Definition: arping.c:28
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
static PLARGE_INTEGER Time
Definition: time.c:105

◆ LogfWriteRecord()

NTSTATUS LogfWriteRecord ( PLOGFILE  LogFile,
PEVENTLOGRECORD  Record,
SIZE_T  BufSize 
)

Definition at line 858 of file file.c.

Referenced by ElfrIntReportEventW(), LogfReportEvent(), and ProcessPortMessage().

861 {
863  LARGE_INTEGER SystemTime;
864 
865  // ASSERT(sizeof(*Record) == sizeof(RecBuf));
866 
867  if (!Record || BufSize < sizeof(*Record))
869 
870  /* Lock the log file exclusive */
872 
873  /*
874  * Retrieve the record written time now, that will also be compared
875  * with the existing events timestamps in case the log is wrapping.
876  */
877  NtQuerySystemTime(&SystemTime);
878  RtlTimeToSecondsSince1970(&SystemTime, &Record->TimeWritten);
879 
880  Status = ElfWriteRecord(&LogFile->LogFile, Record, BufSize);
881  if (Status == STATUS_LOG_FILE_FULL)
882  {
883  /* The event log file is full, queue a message box for the user and exit */
884  // TODO!
885  DPRINT1("Log file `%S' is full!\n", LogFile->LogName);
886  }
887 
888  /* Unlock the log file */
889  RtlReleaseResource(&LogFile->Lock);
890 
891  return Status;
892 }
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_LOG_FILE_FULL
Definition: ntstatus.h:611
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
EVTLOGFILE LogFile
Definition: eventlog.h:36
#define BufSize
Definition: FsRtlTunnel.c:28
RTL_RESOURCE Lock
Definition: eventlog.h:39
NTSTATUS NTAPI ElfWriteRecord(IN PEVTLOGFILE LogFile, IN PEVENTLOGRECORD Record, IN SIZE_T BufSize)
Definition: evtlib.c:1269
WCHAR * LogName
Definition: eventlog.h:38
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)

◆ ReadRecord()

static NTSTATUS ReadRecord ( IN PEVTLOGFILE  LogFile,
IN ULONG  RecordNumber,
OUT PEVENTLOGRECORD  Record,
IN SIZE_T  BufSize,
OUT PSIZE_T BytesRead  OPTIONAL,
OUT PSIZE_T BytesNeeded  OPTIONAL,
IN BOOLEAN  Ansi 
)
static

Definition at line 551 of file file.c.

Referenced by LogfReadEvents().

558 {
560  PEVENTLOGRECORD UnicodeBuffer = NULL;
561  PEVENTLOGRECORD Src, Dst;
562  ANSI_STRING StringA;
564  PVOID SrcPtr, DstPtr;
565  DWORD i;
566  DWORD dwPadding;
567  DWORD dwRecordLength;
568  PDWORD pLength;
569 
570  if (!Ansi)
571  {
572  return ElfReadRecord(LogFile,
573  RecordNumber,
574  Record,
575  BufSize,
576  BytesRead,
577  BytesNeeded);
578  }
579 
580  if (BytesRead)
581  *BytesRead = 0;
582 
583  if (BytesNeeded)
584  *BytesNeeded = 0;
585 
586  UnicodeBuffer = LogfpAlloc(BufSize, HEAP_ZERO_MEMORY, TAG_ELF_BUF);
587  if (UnicodeBuffer == NULL)
588  {
589  DPRINT1("Alloc failed!\n");
590  return STATUS_NO_MEMORY;
591  }
592 
593  Status = ElfReadRecord(LogFile,
594  RecordNumber,
595  UnicodeBuffer,
596  BufSize,
597  BytesRead,
598  BytesNeeded);
599  if (!NT_SUCCESS(Status))
600  goto Quit;
601 
602  Src = UnicodeBuffer;
603  Dst = Record;
604 
605  Dst->Reserved = Src->Reserved;
606  Dst->RecordNumber = Src->RecordNumber;
607  Dst->TimeGenerated = Src->TimeGenerated;
608  Dst->TimeWritten = Src->TimeWritten;
609  Dst->EventID = Src->EventID;
610  Dst->EventType = Src->EventType;
611  Dst->EventCategory = Src->EventCategory;
612  Dst->NumStrings = Src->NumStrings;
613  Dst->UserSidLength = Src->UserSidLength;
614  Dst->DataLength = Src->DataLength;
615 
616  SrcPtr = (PVOID)((ULONG_PTR)Src + sizeof(EVENTLOGRECORD));
617  DstPtr = (PVOID)((ULONG_PTR)Dst + sizeof(EVENTLOGRECORD));
618 
619  /* Convert the module name */
620  RtlInitUnicodeString(&StringW, SrcPtr);
621  Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
622  if (NT_SUCCESS(Status))
623  {
624  RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
625  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringA.MaximumLength);
626 
627  RtlFreeAnsiString(&StringA);
628  }
629  else
630  {
631  RtlZeroMemory(DstPtr, StringW.MaximumLength / sizeof(WCHAR));
632  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringW.MaximumLength / sizeof(WCHAR));
633  }
634  SrcPtr = (PVOID)((ULONG_PTR)SrcPtr + StringW.MaximumLength);
635 
636  /* Convert the computer name */
637  RtlInitUnicodeString(&StringW, SrcPtr);
638  Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
639  if (NT_SUCCESS(Status))
640  {
641  RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
642  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringA.MaximumLength);
643 
644  RtlFreeAnsiString(&StringA);
645  }
646  else
647  {
648  RtlZeroMemory(DstPtr, StringW.MaximumLength / sizeof(WCHAR));
649  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringW.MaximumLength / sizeof(WCHAR));
650  }
651 
652  /* Add the padding and the User SID */
653  dwPadding = sizeof(ULONG) - (((ULONG_PTR)DstPtr - (ULONG_PTR)Dst) % sizeof(ULONG));
654  RtlZeroMemory(DstPtr, dwPadding);
655 
656  SrcPtr = (PVOID)((ULONG_PTR)Src + Src->UserSidOffset);
657  DstPtr = (PVOID)((ULONG_PTR)DstPtr + dwPadding);
658 
659  Dst->UserSidOffset = (DWORD)((ULONG_PTR)DstPtr - (ULONG_PTR)Dst);
660  RtlCopyMemory(DstPtr, SrcPtr, Src->UserSidLength);
661 
662  /* Convert the strings */
663  SrcPtr = (PVOID)((ULONG_PTR)Src + Src->StringOffset);
664  DstPtr = (PVOID)((ULONG_PTR)DstPtr + Src->UserSidLength);
665  Dst->StringOffset = (DWORD)((ULONG_PTR)DstPtr - (ULONG_PTR)Dst);
666 
667  for (i = 0; i < Dst->NumStrings; i++)
668  {
669  RtlInitUnicodeString(&StringW, SrcPtr);
670  Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
671  if (NT_SUCCESS(Status))
672  {
673  RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
674  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringA.MaximumLength);
675 
676  RtlFreeAnsiString(&StringA);
677  }
678  else
679  {
680  RtlZeroMemory(DstPtr, StringW.MaximumLength / sizeof(WCHAR));
681  DstPtr = (PVOID)((ULONG_PTR)DstPtr + StringW.MaximumLength / sizeof(WCHAR));
682  }
683  SrcPtr = (PVOID)((ULONG_PTR)SrcPtr + StringW.MaximumLength);
684  }
685 
686  /* Copy the binary data */
687  SrcPtr = (PVOID)((ULONG_PTR)Src + Src->DataOffset);
688  Dst->DataOffset = (ULONG_PTR)DstPtr - (ULONG_PTR)Dst;
689  RtlCopyMemory(DstPtr, SrcPtr, Src->DataLength);
690  DstPtr = (PVOID)((ULONG_PTR)DstPtr + Src->DataLength);
691 
692  /* Add the padding */
693  dwPadding = sizeof(ULONG) - (((ULONG_PTR)DstPtr - (ULONG_PTR)Dst) % sizeof(ULONG));
694  RtlZeroMemory(DstPtr, dwPadding);
695 
696  /* Set the record length at the beginning and the end of the record */
697  dwRecordLength = (DWORD)((ULONG_PTR)DstPtr + dwPadding + sizeof(ULONG) - (ULONG_PTR)Dst);
698  Dst->Length = dwRecordLength;
699  pLength = (PDWORD)((ULONG_PTR)DstPtr + dwPadding);
700  *pLength = dwRecordLength;
701 
702  if (BytesRead)
703  *BytesRead = dwRecordLength;
704 
705  Status = STATUS_SUCCESS;
706 
707 Quit:
708  LogfpFree(UnicodeBuffer, 0, TAG_ELF_BUF);
709 
710  return Status;
711 }
DWORD * pLength
Definition: msvc.h:79
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
static PVOID
Definition: file.c:43
USHORT MaximumLength
Definition: env_spec_w32.h:370
__wchar_t WCHAR
Definition: xmlstorage.h:180
static ULONG
Definition: file.c:43
LONG NTSTATUS
Definition: precomp.h:26
DWORD StringOffset
Definition: winnt_old.h:2648
static DWORD
Definition: file.c:30
static PVOID NTAPI LogfpAlloc(IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:158
#define WCHAR
Definition: msvc.h:43
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _EVENTLOGRECORD EVENTLOGRECORD
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
static VOID NTAPI LogfpFree(IN PVOID Ptr, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:169
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define BufSize
Definition: FsRtlTunnel.c:28
USHORT MaximumLength
Definition: env_spec_w32.h:377
DWORD UserSidOffset
Definition: winnt_old.h:2650
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD RecordNumber
Definition: winnt_old.h:2639
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: evtlib.c:1197
Status
Definition: gdiplustypes.h:24
#define Dst
Definition: mesh.h:153
static const WCHAR StringW[]
Definition: global.c:47
DWORD TimeGenerated
Definition: winnt_old.h:2640
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define TAG_ELF_BUF
Definition: evtlib.h:152
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD * PDWORD
Definition: pedump.c:68
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
DWORD UserSidLength
Definition: winnt_old.h:2649
return STATUS_SUCCESS
Definition: btrfs.c:2710
static ULONG_PTR
Definition: file.c:106
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255

Variable Documentation

◆ LogFileListCs

CRITICAL_SECTION LogFileListCs
static

Definition at line 23 of file file.c.

◆ LogFileListHead

LIST_ENTRY LogFileListHead
static

Definition at line 22 of file file.c.