ReactOS  0.4.12-dev-14-gd0c8636
file.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS EventLog Service
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/services/eventlog/file.c
5  * PURPOSE: Event log file support wrappers
6  * COPYRIGHT: Copyright 2005 Saveliy Tretiakov
7  * Michael Martin
8  * Hermes Belusca-Maito
9  */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include "eventlog.h"
14 #include <ndk/iofuncs.h>
15 #include <ndk/kefuncs.h>
16 
17 #define NDEBUG
18 #include <debug.h>
19 
20 /* LOG FILE LIST - GLOBALS ***************************************************/
21 
24 
25 /* LOG FILE LIST - FUNCTIONS *************************************************/
26 
28 {
29  InitializeCriticalSection(&LogFileListCs);
30  InitializeListHead(&LogFileListHead);
31 }
32 
34 {
35  PLIST_ENTRY CurrentEntry;
36  PLOGFILE Item, Result = NULL;
37 
38  ASSERT(Name);
39 
40  EnterCriticalSection(&LogFileListCs);
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 
56  LeaveCriticalSection(&LogFileListCs);
57  return Result;
58 }
59 
60 #if 0
61 /* Index starting from 1 */
62 DWORD LogfListItemIndexByName(LPCWSTR Name)
63 {
64  PLIST_ENTRY CurrentEntry;
65  DWORD Result = 0;
66  DWORD i = 1;
67 
68  ASSERT(Name);
69 
70  EnterCriticalSection(&LogFileListCs);
71 
72  CurrentEntry = LogFileListHead.Flink;
73  while (CurrentEntry != &LogFileListHead)
74  {
75  PLOGFILE Item = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
76 
77  if (Item->LogName && !_wcsicmp(Item->LogName, Name))
78  {
79  Result = i;
80  break;
81  }
82 
83  CurrentEntry = CurrentEntry->Flink;
84  i++;
85  }
86 
87  LeaveCriticalSection(&LogFileListCs);
88  return Result;
89 }
90 #endif
91 
92 /* Index starting from 1 */
94 {
95  PLIST_ENTRY CurrentEntry;
97  DWORD i = 1;
98 
99  EnterCriticalSection(&LogFileListCs);
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 
114  LeaveCriticalSection(&LogFileListCs);
115  return Result;
116 }
117 
119 {
120  PLIST_ENTRY CurrentEntry;
121  DWORD i = 0;
122 
123  EnterCriticalSection(&LogFileListCs);
124 
125  CurrentEntry = LogFileListHead.Flink;
126  while (CurrentEntry != &LogFileListHead)
127  {
128  CurrentEntry = CurrentEntry->Flink;
129  i++;
130  }
131 
132  LeaveCriticalSection(&LogFileListCs);
133  return i;
134 }
135 
136 static VOID
138 {
139  EnterCriticalSection(&LogFileListCs);
140  InsertTailList(&LogFileListHead, &Item->ListEntry);
141  LeaveCriticalSection(&LogFileListCs);
142 }
143 
144 static VOID
146 {
147  EnterCriticalSection(&LogFileListCs);
148  RemoveEntryList(&Item->ListEntry);
149  LeaveCriticalSection(&LogFileListCs);
150 }
151 
152 
153 /* FUNCTIONS *****************************************************************/
154 
155 // PELF_ALLOCATE_ROUTINE
156 static
157 PVOID NTAPI
159  IN ULONG Flags,
160  IN ULONG Tag)
161 {
163  return RtlAllocateHeap(GetProcessHeap(), Flags, Size);
164 }
165 
166 // PELF_FREE_ROUTINE
167 static
168 VOID NTAPI
170  IN ULONG Flags,
171  IN ULONG Tag)
172 {
174  RtlFreeHeap(GetProcessHeap(), Flags, Ptr);
175 }
176 
177 // PELF_FILE_READ_ROUTINE
178 static
182  OUT PVOID Buffer,
183  IN SIZE_T Length,
184  OUT PSIZE_T ReadLength OPTIONAL)
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 }
208 
209 // PELF_FILE_WRITE_ROUTINE
210 static
214  IN PVOID Buffer,
215  IN SIZE_T Length,
216  OUT PSIZE_T WrittenLength OPTIONAL)
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 }
240 
241 // PELF_FILE_SET_SIZE_ROUTINE
242 static
245  IN ULONG FileSize, // SIZE_T
246  IN ULONG OldFileSize) // SIZE_T
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 }
276 
277 // PELF_FILE_FLUSH_ROUTINE
278 static
282  IN ULONG Length)
283 {
284  PLOGFILE pLogFile = (PLOGFILE)LogFile;
286 
287  UNREFERENCED_PARAMETER(FileOffset);
288  UNREFERENCED_PARAMETER(Length);
289 
290  return NtFlushBuffersFile(pLogFile->FileHandle, &IoStatusBlock);
291 }
292 
293 NTSTATUS
295  PCWSTR LogName,
297  ULONG MaxSize,
298  ULONG Retention,
299  BOOLEAN Permanent,
300  BOOLEAN Backup)
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 }
426 
427 VOID
429  BOOLEAN ForceClose)
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 }
451 
453 {
454  EnterCriticalSection(&LogFileListCs);
455 
456  while (!IsListEmpty(&LogFileListHead))
457  {
458  LogfClose(CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry), TRUE);
459  }
460 
461  LeaveCriticalSection(&LogFileListCs);
462 
463  DeleteCriticalSection(&LogFileListCs);
464 }
465 
466 NTSTATUS
468  PUNICODE_STRING BackupFileName)
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 }
497 
498 NTSTATUS
500  PUNICODE_STRING BackupFileName)
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 }
548 
549 
550 static NTSTATUS
552  IN ULONG RecordNumber,
554  IN SIZE_T BufSize, // Length
556  OUT PSIZE_T BytesNeeded OPTIONAL,
557  IN BOOLEAN Ansi)
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 }
712 
713 /*
714  * NOTE:
715  * 'RecordNumber' is a pointer to the record number at which the read operation
716  * should start. If the record number is 0 and the flags given in the 'Flags'
717  * parameter contain EVENTLOG_SEQUENTIAL_READ, an adequate record number is
718  * computed.
719  */
720 NTSTATUS
722  ULONG Flags,
723  PULONG RecordNumber,
724  ULONG BufSize,
725  PBYTE Buffer,
727  PULONG BytesNeeded,
728  BOOLEAN Ansi)
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 */
738  if ((Flags & EVENTLOG_SEQUENTIAL_READ) && (Flags & EVENTLOG_SEEK_READ))
740 
741  if (!(Flags & EVENTLOG_SEQUENTIAL_READ) && !(Flags & EVENTLOG_SEEK_READ))
743 
744  /* EVENTLOG_FORWARDS_READ and EVENTLOG_BACKWARDS_READ are mutually exclusive */
745  if ((Flags & EVENTLOG_FORWARDS_READ) && (Flags & EVENTLOG_BACKWARDS_READ))
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 }
856 
857 NTSTATUS
860  SIZE_T BufSize)
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 }
893 
894 
897  ULONG Time,
898  USHORT wType,
899  USHORT wCategory,
900  ULONG dwEventId,
902  PUNICODE_STRING ComputerName,
903  ULONG dwSidLength,
904  PSID pUserSid,
905  USHORT wNumStrings,
906  PWSTR pStrings,
907  ULONG dwDataSize,
908  PVOID pRawData)
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 }
1035 
1036 VOID
1038  USHORT wCategory,
1039  ULONG dwEventId,
1040  USHORT wNumStrings,
1041  PWSTR pStrings,
1042  ULONG dwDataSize,
1043  PVOID pRawData)
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 }
ULONG NTAPI ElfGetOldestRecord(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1589
DWORD * pLength
Definition: msvc.h:79
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
VOID LogfClose(PLOGFILE LogFile, BOOLEAN ForceClose)
Definition: file.c:428
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 IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI VOID NTAPI RtlDeleteResource(_In_ PRTL_RESOURCE Resource)
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
PLOGFILE LogfListItemByName(LPCWSTR Name)
Definition: file.c:33
static PVOID
Definition: file.c:43
USHORT MaximumLength
Definition: env_spec_w32.h:370
STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc, size_t cbToCopy)
Definition: strsafe.h:255
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct _LOGFILE * PLOGFILE
uint16_t * PWSTR
Definition: typedefs.h:54
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
static ULONG
Definition: file.c:43
#define STATUS_LOG_FILE_FULL
Definition: ntstatus.h:611
NTSTATUS LogfCreate(PLOGFILE *LogFile, PCWSTR LogName, PUNICODE_STRING FileName, ULONG MaxSize, ULONG Retention, BOOLEAN Permanent, BOOLEAN Backup)
Definition: file.c:294
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define FILE_CREATE
Definition: from_kernel.h:55
#define STATUS_EVENTLOG_FILE_CORRUPT
Definition: ntstatus.h:617
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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
DWORD StringOffset
Definition: winnt_old.h:2648
NTSTATUS NTAPI NtFlushBuffersFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: iofunc.c:1377
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 DWORD
Definition: file.c:30
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
Definition: compname.c:339
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define InsertTailList(ListHead, Entry)
static PVOID NTAPI LogfpAlloc(IN SIZE_T Size, IN ULONG Flags, IN ULONG Tag)
Definition: file.c:158
#define WCHAR
Definition: msvc.h:43
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
LARGE_INTEGER AllocationSize
Definition: winternl.h:688
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
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
struct _EVENTLOGRECORD EVENTLOGRECORD
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG_PTR * PSIZE_T
Definition: typedefs.h:78
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
#define GENERIC_WRITE
Definition: nt_native.h:90
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
PLOGFILE LogFile
Definition: eventlog.h:47
WCHAR szName[1]
Definition: eventlog.h:48
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
const WCHAR * str
unsigned char BOOLEAN
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS LogfWriteRecord(PLOGFILE LogFile, PEVENTLOGRECORD Record, SIZE_T BufSize)
Definition: file.c:858
_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
LARGE_INTEGER EndOfFile
Definition: nt_native.h:948
static CRITICAL_SECTION LogFileListCs
Definition: file.c:23
void DPRINT(...)
Definition: polytest.cpp:61
VOID LogfListInitialize(VOID)
Definition: file.c:27
Definition: bufpool.h:45
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
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
PLOGFILE LogfListItemByIndex(DWORD Index)
Definition: file.c:93
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:55
LIST_ENTRY ListEntry
Definition: eventlog.h:41
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 GetProcessHeap()
Definition: compat.h:395
DWORD UserSidOffset
Definition: winnt_old.h:2650
#define LOGFILE_SIGNATURE
Definition: evtlib.h:43
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG NTAPI ElfGetCurrentRecord(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1598
BOOL Permanent
Definition: eventlog.h:40
PEVENTSOURCE EventLogSource
Definition: eventlog.c:35
#define EVENTLOG_SEQUENTIAL_READ
Definition: winnt_old.h:2624
RTL_RESOURCE Lock
Definition: eventlog.h:39
unsigned int UINT
Definition: ndis.h:50
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSTATUS NTAPI ElfWriteRecord(IN PEVTLOGFILE LogFile, IN PEVENTLOGRECORD Record, IN SIZE_T BufSize)
Definition: evtlib.c:1269
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID LogfReportEvent(USHORT wType, USHORT wCategory, ULONG dwEventId, USHORT wNumStrings, PWSTR pStrings, ULONG dwDataSize, PVOID pRawData)
Definition: file.c:1037
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TAG_ELF
Definition: evtlib.h:151
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
struct _EVENTLOGRECORD * PEVENTLOGRECORD
static const WCHAR L[]
Definition: oid.c:1087
WCHAR * LogName
Definition: eventlog.h:38
static LIST_ENTRY LogFileListHead
Definition: file.c:22
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)
DWORD RecordNumber
Definition: winnt_old.h:2639
ULONG LowPart
Definition: typedefs.h:104
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define GENERIC_READ
Definition: compat.h:124
Definition: typedefs.h:117
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSTATUS LogfReadEvents(PLOGFILE LogFile, ULONG Flags, PULONG RecordNumber, ULONG BufSize, PBYTE Buffer, PULONG BytesRead, PULONG BytesNeeded, BOOLEAN Ansi)
Definition: file.c:721
#define EVENTLOG_SEEK_READ
Definition: winnt_old.h:2625
VOID NTAPI ElfCloseFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:1179
NTSTATUS NTAPI ElfBackupFile(IN PEVTLOGFILE LogFile, IN PEVTLOGFILE BackupLogFile)
Definition: evtlib.c:979
Status
Definition: gdiplustypes.h:24
#define Dst
Definition: mesh.h:153
static const WCHAR StringW[]
Definition: global.c:47
#define FILE_OPEN
Definition: from_kernel.h:54
NTSTATUS LogfBackupFile(PLOGFILE LogFile, PUNICODE_STRING BackupFileName)
Definition: file.c:499
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:240
ULONG_PTR SIZE_T
Definition: typedefs.h:78
DWORD TimeGenerated
Definition: winnt_old.h:2640
unsigned short USHORT
Definition: pedump.c:61
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#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
unsigned int * PULONG
Definition: retypes.h:1
#define TAG_ELF_BUF
Definition: evtlib.h:152
WCHAR SourceName[256]
Definition: arping.c:28
#define EVENTLOG_FORWARDS_READ
Definition: winnt_old.h:2626
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD * PDWORD
Definition: pedump.c:68
#define FILE_CREATED
Definition: nt_native.h:770
static VOID LogfListAddItem(PLOGFILE Item)
Definition: file.c:137
#define DPRINT1
Definition: precomp.h:8
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
VOID LogfCloseAll(VOID)
Definition: file.c:452
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static VOID LogfListRemoveItem(PLOGFILE Item)
Definition: file.c:145
static NTSTATUS NTAPI LogfpFlushFile(IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: file.c:280
const uint16_t * PCWSTR
Definition: typedefs.h:55
DWORD UserSidLength
Definition: winnt_old.h:2649
NTSTATUS LogfClearFile(PLOGFILE LogFile, PUNICODE_STRING BackupFileName)
Definition: file.c:467
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
DWORD LogfListItemCount(VOID)
Definition: file.c:118
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
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
static ULONG_PTR
Definition: file.c:106
BYTE * PBYTE
Definition: pedump.c:66
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
static PLARGE_INTEGER Time
Definition: time.c:105
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_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
NTSTATUS NTAPI ElfReCreateFile(IN PEVTLOGFILE LogFile)
Definition: evtlib.c:966
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
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)
LONGLONG QuadPart
Definition: typedefs.h:112
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)