2 * PROJECT: ReactOS kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: services/eventlog/file.c
5 * PURPOSE: Event logging service
6 * COPYRIGHT: Copyright 2005 Saveliy Tretiakov
10 /* INCLUDES *****************************************************************/
14 /* GLOBALS ******************************************************************/
16 static LIST_ENTRY LogFileListHead
;
17 static CRITICAL_SECTION LogFileListCs
;
19 /* FUNCTIONS ****************************************************************/
21 BOOL
LogfInitializeNew(PLOGFILE LogFile
)
26 ZeroMemory(&LogFile
->Header
, sizeof(EVENTLOGHEADER
));
27 SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
);
28 SetEndOfFile(LogFile
->hFile
);
30 LogFile
->Header
.HeaderSize
= sizeof(EVENTLOGHEADER
);
31 LogFile
->Header
.EndHeaderSize
= sizeof(EVENTLOGHEADER
);
32 LogFile
->Header
.StartOffset
= sizeof(EVENTLOGHEADER
);
33 LogFile
->Header
.EndOffset
= sizeof(EVENTLOGHEADER
);
34 LogFile
->Header
.MajorVersion
= MAJORVER
;
35 LogFile
->Header
.MinorVersion
= MINORVER
;
36 LogFile
->Header
.CurrentRecordNumber
= 1;
37 /* FIXME: Read MaxSize from registry for this LogFile.
38 But for now limit EventLog size to just under 5K. */
39 LogFile
->Header
.MaxSize
= 5000;
40 LogFile
->Header
.Signature
= LOGFILE_SIGNATURE
;
41 if (!WriteFile(LogFile
->hFile
,
43 sizeof(EVENTLOGHEADER
),
47 DPRINT1("WriteFile failed:%d!\n", GetLastError());
51 EofRec
.Ones
= 0x11111111;
52 EofRec
.Twos
= 0x22222222;
53 EofRec
.Threes
= 0x33333333;
54 EofRec
.Fours
= 0x44444444;
55 EofRec
.RecordSizeBeginning
= sizeof(EVENTLOGEOF
);
56 EofRec
.RecordSizeEnd
= sizeof(EVENTLOGEOF
);
57 EofRec
.CurrentRecordNumber
= LogFile
->Header
.CurrentRecordNumber
;
58 EofRec
.OldestRecordNumber
= LogFile
->Header
.OldestRecordNumber
;
59 EofRec
.BeginRecord
= LogFile
->Header
.StartOffset
;
60 EofRec
.EndRecord
= LogFile
->Header
.EndOffset
;
62 if (!WriteFile(LogFile
->hFile
,
68 DPRINT1("WriteFile failed:%d!\n", GetLastError());
72 if (!FlushFileBuffers(LogFile
->hFile
))
74 DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
81 BOOL
LogfInitializeExisting(PLOGFILE LogFile
)
84 DWORD dwRecordsNumber
= 0;
85 DWORD dwRecSize
, dwRecSign
, dwFilePointer
;
87 PEVENTLOGRECORD RecBuf
;
88 BOOL OvewrWrittenRecords
= FALSE
;
90 DPRINT("Initializing LogFile %S\n",LogFile
->LogName
);
92 if (SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
) ==
93 INVALID_SET_FILE_POINTER
)
95 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
99 if (!ReadFile(LogFile
->hFile
,
101 sizeof(EVENTLOGHEADER
),
105 DPRINT1("ReadFile failed! %d\n", GetLastError());
109 if (dwRead
!= sizeof(EVENTLOGHEADER
))
111 DPRINT("EventLog: Invalid file %S.\n", LogFile
->FileName
);
112 return LogfInitializeNew(LogFile
);
115 if (LogFile
->Header
.HeaderSize
!= sizeof(EVENTLOGHEADER
) ||
116 LogFile
->Header
.EndHeaderSize
!= sizeof(EVENTLOGHEADER
))
118 DPRINT("EventLog: Invalid header size in %S.\n", LogFile
->FileName
);
119 return LogfInitializeNew(LogFile
);
122 if (LogFile
->Header
.Signature
!= LOGFILE_SIGNATURE
)
124 DPRINT("EventLog: Invalid signature %x in %S.\n",
125 LogFile
->Header
.Signature
, LogFile
->FileName
);
126 return LogfInitializeNew(LogFile
);
129 if (LogFile
->Header
.EndOffset
> GetFileSize(LogFile
->hFile
, NULL
) + 1)
131 DPRINT("EventLog: Invalid eof offset %x in %S.\n",
132 LogFile
->Header
.EndOffset
, LogFile
->FileName
);
133 return LogfInitializeNew(LogFile
);
136 /* Set the read location to the oldest record */
137 dwFilePointer
= SetFilePointer(LogFile
->hFile
, LogFile
->Header
.StartOffset
, NULL
, FILE_BEGIN
);
138 if (dwFilePointer
== INVALID_SET_FILE_POINTER
)
140 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
146 dwFilePointer
= SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_CURRENT
);
148 if (dwFilePointer
== INVALID_SET_FILE_POINTER
)
150 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
154 /* If the EVENTLOGEOF info has been reached and the oldest record was not immediately after the Header */
155 if ((dwFilePointer
== LogFile
->Header
.EndOffset
) && (LogFile
->Header
.StartOffset
!= sizeof(EVENTLOGHEADER
)))
157 OvewrWrittenRecords
= TRUE
;
158 /* The file has records that overwrote old ones so read them */
159 dwFilePointer
= SetFilePointer(LogFile
->hFile
, sizeof(EVENTLOGHEADER
), NULL
, FILE_BEGIN
);
162 if (!ReadFile(LogFile
->hFile
,
168 DPRINT1("ReadFile failed! %d\n", GetLastError());
172 if (dwRead
!= sizeof(dwRecSize
))
175 if (!ReadFile(LogFile
->hFile
,
181 DPRINT1("ReadFile() failed! %d\n", GetLastError());
185 if (dwRead
!= sizeof(dwRecSize
))
188 if (dwRecSign
!= LOGFILE_SIGNATURE
||
189 dwRecSize
+ dwFilePointer
> GetFileSize(LogFile
->hFile
, NULL
) + 1 ||
190 dwRecSize
< sizeof(EVENTLOGRECORD
))
195 if (SetFilePointer(LogFile
->hFile
,
196 -((LONG
) sizeof(DWORD
) * 2),
198 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
200 DPRINT1("SetFilePointer() failed! %d", GetLastError());
204 RecBuf
= (PEVENTLOGRECORD
) HeapAlloc(MyHeap
, 0, dwRecSize
);
208 DPRINT1("Can't allocate heap!\n");
212 if (!ReadFile(LogFile
->hFile
, RecBuf
, dwRecSize
, &dwRead
, NULL
))
214 DPRINT1("ReadFile() failed! %d\n", GetLastError());
215 HeapFree(MyHeap
, 0, RecBuf
);
219 if (dwRead
!= dwRecSize
)
221 HeapFree(MyHeap
, 0, RecBuf
);
225 /* if OvewrWrittenRecords is TRUE and this record has already been read */
226 if ((OvewrWrittenRecords
== TRUE
) && (RecBuf
->RecordNumber
== LogFile
->Header
.OldestRecordNumber
))
228 HeapFree(MyHeap
, 0, RecBuf
);
232 pdwRecSize2
= (PDWORD
) (((PBYTE
) RecBuf
) + dwRecSize
- 4);
234 if (*pdwRecSize2
!= dwRecSize
)
236 DPRINT1("Invalid RecordSizeEnd of record %d (%x) in %S\n",
237 dwRecordsNumber
, *pdwRecSize2
, LogFile
->LogName
);
238 HeapFree(MyHeap
, 0, RecBuf
);
244 if (!LogfAddOffsetInformation(LogFile
,
245 RecBuf
->RecordNumber
,
248 DPRINT1("LogfAddOffsetInformation() failed!\n");
249 HeapFree(MyHeap
, 0, RecBuf
);
253 HeapFree(MyHeap
, 0, RecBuf
);
256 LogFile
->Header
.CurrentRecordNumber
= dwRecordsNumber
+ LogFile
->Header
.OldestRecordNumber
;
257 if (LogFile
->Header
.CurrentRecordNumber
== 0)
258 LogFile
->Header
.CurrentRecordNumber
= 1;
260 /* FIXME: Read MaxSize from registry for this LogFile.
261 But for now limit EventLog size to just under 5K. */
262 LogFile
->Header
.MaxSize
= 5000;
264 if (!SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
) ==
265 INVALID_SET_FILE_POINTER
)
267 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
271 if (!WriteFile(LogFile
->hFile
,
273 sizeof(EVENTLOGHEADER
),
277 DPRINT1("WriteFile failed! %d\n", GetLastError());
281 if (!FlushFileBuffers(LogFile
->hFile
))
283 DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
290 PLOGFILE
LogfCreate(WCHAR
* LogName
, WCHAR
* FileName
)
293 BOOL bResult
, bCreateNew
= FALSE
;
295 LogFile
= (LOGFILE
*) HeapAlloc(MyHeap
, HEAP_ZERO_MEMORY
, sizeof(LOGFILE
));
298 DPRINT1("Can't allocate heap!\n");
302 LogFile
->hFile
= CreateFile(FileName
,
303 GENERIC_READ
| GENERIC_WRITE
,
307 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_RANDOM_ACCESS
,
310 if (LogFile
->hFile
== INVALID_HANDLE_VALUE
)
312 DPRINT1("Can't create file %S.\n", FileName
);
313 HeapFree(MyHeap
, 0, LogFile
);
317 bCreateNew
= (GetLastError() == ERROR_ALREADY_EXISTS
) ? FALSE
: TRUE
;
320 (WCHAR
*) HeapAlloc(MyHeap
,
322 (lstrlenW(LogName
) + 1) * sizeof(WCHAR
));
324 if (LogFile
->LogName
)
325 lstrcpyW(LogFile
->LogName
, LogName
);
328 DPRINT1("Can't allocate heap\n");
329 HeapFree(MyHeap
, 0, LogFile
);
334 (WCHAR
*) HeapAlloc(MyHeap
,
336 (lstrlenW(FileName
) + 1) * sizeof(WCHAR
));
338 if (LogFile
->FileName
)
339 lstrcpyW(LogFile
->FileName
, FileName
);
342 DPRINT1("Can't allocate heap\n");
346 LogFile
->OffsetInfo
=
347 (PEVENT_OFFSET_INFO
) HeapAlloc(MyHeap
,
349 sizeof(EVENT_OFFSET_INFO
) * 64);
351 if (!LogFile
->OffsetInfo
)
353 DPRINT1("Can't allocate heap\n");
357 LogFile
->OffsetInfoSize
= 64;
360 bResult
= LogfInitializeNew(LogFile
);
362 bResult
= LogfInitializeExisting(LogFile
);
367 InitializeCriticalSection(&LogFile
->cs
);
368 LogfListAddItem(LogFile
);
374 if (LogFile
->OffsetInfo
)
375 HeapFree(MyHeap
, 0, LogFile
->OffsetInfo
);
377 if (LogFile
->FileName
)
378 HeapFree(MyHeap
, 0, LogFile
->FileName
);
380 if (LogFile
->LogName
)
381 HeapFree(MyHeap
, 0, LogFile
->LogName
);
383 HeapFree(MyHeap
, 0, LogFile
);
389 VOID
LogfClose(PLOGFILE LogFile
)
394 EnterCriticalSection(&LogFile
->cs
);
396 FlushFileBuffers(LogFile
->hFile
);
397 CloseHandle(LogFile
->hFile
);
398 LogfListRemoveItem(LogFile
);
400 DeleteCriticalSection(&LogFile
->cs
);
402 HeapFree(MyHeap
, 0, LogFile
->LogName
);
403 HeapFree(MyHeap
, 0, LogFile
->FileName
);
404 HeapFree(MyHeap
, 0, LogFile
->OffsetInfo
);
405 HeapFree(MyHeap
, 0, LogFile
);
410 VOID
LogfCloseAll(VOID
)
412 while (!IsListEmpty(&LogFileListHead
))
414 LogfClose(LogfListHead());
417 DeleteCriticalSection(&LogFileListCs
);
420 VOID
LogfListInitialize(VOID
)
422 InitializeCriticalSection(&LogFileListCs
);
423 InitializeListHead(&LogFileListHead
);
426 PLOGFILE
LogfListHead(VOID
)
428 return CONTAINING_RECORD(LogFileListHead
.Flink
, LOGFILE
, ListEntry
);
431 PLOGFILE
LogfListItemByName(WCHAR
* Name
)
433 PLIST_ENTRY CurrentEntry
;
434 PLOGFILE Result
= NULL
;
436 EnterCriticalSection(&LogFileListCs
);
438 CurrentEntry
= LogFileListHead
.Flink
;
439 while (CurrentEntry
!= &LogFileListHead
)
441 PLOGFILE Item
= CONTAINING_RECORD(CurrentEntry
,
445 if (Item
->LogName
&& !lstrcmpi(Item
->LogName
, Name
))
451 CurrentEntry
= CurrentEntry
->Flink
;
454 LeaveCriticalSection(&LogFileListCs
);
458 /* Index starting from 1 */
459 INT
LogfListItemIndexByName(WCHAR
* Name
)
461 PLIST_ENTRY CurrentEntry
;
465 EnterCriticalSection(&LogFileListCs
);
467 CurrentEntry
= LogFileListHead
.Flink
;
468 while (CurrentEntry
!= &LogFileListHead
)
470 PLOGFILE Item
= CONTAINING_RECORD(CurrentEntry
,
474 if (Item
->LogName
&& !lstrcmpi(Item
->LogName
, Name
))
480 CurrentEntry
= CurrentEntry
->Flink
;
484 LeaveCriticalSection(&LogFileListCs
);
488 /* Index starting from 1 */
489 PLOGFILE
LogfListItemByIndex(INT Index
)
491 PLIST_ENTRY CurrentEntry
;
492 PLOGFILE Result
= NULL
;
495 EnterCriticalSection(&LogFileListCs
);
497 CurrentEntry
= LogFileListHead
.Flink
;
498 while (CurrentEntry
!= &LogFileListHead
)
502 Result
= CONTAINING_RECORD(CurrentEntry
, LOGFILE
, ListEntry
);
506 CurrentEntry
= CurrentEntry
->Flink
;
510 LeaveCriticalSection(&LogFileListCs
);
514 INT
LogfListItemCount()
516 PLIST_ENTRY CurrentEntry
;
519 EnterCriticalSection(&LogFileListCs
);
521 CurrentEntry
= LogFileListHead
.Flink
;
522 while (CurrentEntry
!= &LogFileListHead
)
524 CurrentEntry
= CurrentEntry
->Flink
;
528 LeaveCriticalSection(&LogFileListCs
);
532 VOID
LogfListAddItem(PLOGFILE Item
)
534 EnterCriticalSection(&LogFileListCs
);
535 InsertTailList(&LogFileListHead
, &Item
->ListEntry
);
536 LeaveCriticalSection(&LogFileListCs
);
539 VOID
LogfListRemoveItem(PLOGFILE Item
)
541 EnterCriticalSection(&LogFileListCs
);
542 RemoveEntryList(&Item
->ListEntry
);
543 LeaveCriticalSection(&LogFileListCs
);
546 DWORD
LogfReadEvent(PLOGFILE LogFile
,
548 DWORD
* RecordNumber
,
554 DWORD dwOffset
, dwRead
, dwRecSize
;
555 DWORD dwBufferUsage
= 0, dwRecNum
;
557 if (Flags
& EVENTLOG_FORWARDS_READ
&& Flags
& EVENTLOG_BACKWARDS_READ
)
558 return ERROR_INVALID_PARAMETER
;
560 if (!(Flags
& EVENTLOG_FORWARDS_READ
) && !(Flags
& EVENTLOG_BACKWARDS_READ
))
561 return ERROR_INVALID_PARAMETER
;
563 if (!Buffer
|| !BytesRead
|| !BytesNeeded
)
564 return ERROR_INVALID_PARAMETER
;
566 if ((*RecordNumber
==0) && !(EVENTLOG_SEQUENTIAL_READ
))
568 return ERROR_INVALID_PARAMETER
;
571 dwRecNum
= *RecordNumber
;
572 EnterCriticalSection(&LogFile
->cs
);
577 dwOffset
= LogfOffsetByNumber(LogFile
, dwRecNum
);
581 LeaveCriticalSection(&LogFile
->cs
);
582 return ERROR_HANDLE_EOF
;
585 if (SetFilePointer(LogFile
->hFile
, dwOffset
, NULL
, FILE_BEGIN
) ==
586 INVALID_SET_FILE_POINTER
)
588 DPRINT1("SetFilePointer() failed!\n");
592 if (!ReadFile(LogFile
->hFile
, &dwRecSize
, sizeof(DWORD
), &dwRead
, NULL
))
594 DPRINT1("ReadFile() failed!\n");
598 if (dwRecSize
> BufSize
)
600 *BytesNeeded
= dwRecSize
;
601 LeaveCriticalSection(&LogFile
->cs
);
602 return ERROR_INSUFFICIENT_BUFFER
;
605 if (SetFilePointer(LogFile
->hFile
,
606 -((LONG
) sizeof(DWORD
)),
608 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
610 DPRINT1("SetFilePointer() failed!\n");
614 if (!ReadFile(LogFile
->hFile
, Buffer
, dwRecSize
, &dwRead
, NULL
))
616 DPRINT1("ReadFile() failed!\n");
620 dwBufferUsage
+= dwRead
;
622 while (dwBufferUsage
<= BufSize
)
624 if (Flags
& EVENTLOG_FORWARDS_READ
)
629 dwOffset
= LogfOffsetByNumber(LogFile
, dwRecNum
);
633 if (SetFilePointer(LogFile
->hFile
, dwOffset
, NULL
, FILE_BEGIN
) ==
634 INVALID_SET_FILE_POINTER
)
636 DPRINT1("SetFilePointer() failed!\n");
640 if (!ReadFile(LogFile
->hFile
,
646 DPRINT1("ReadFile() failed!\n");
650 if (dwBufferUsage
+ dwRecSize
> BufSize
)
653 if (SetFilePointer(LogFile
->hFile
,
654 -((LONG
) sizeof(DWORD
)),
656 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
658 DPRINT1("SetFilePointer() failed!\n");
662 if (!ReadFile(LogFile
->hFile
,
663 Buffer
+ dwBufferUsage
,
668 DPRINT1("ReadFile() failed!\n");
672 dwBufferUsage
+= dwRead
;
675 *BytesRead
= dwBufferUsage
;
676 * RecordNumber
= dwRecNum
;
677 LeaveCriticalSection(&LogFile
->cs
);
678 return ERROR_SUCCESS
;
681 DPRINT1("LogfReadEvent failed with %x\n",GetLastError());
682 LeaveCriticalSection(&LogFile
->cs
);
683 return GetLastError();
686 BOOL
LogfWriteData(PLOGFILE LogFile
, DWORD BufSize
, PBYTE Buffer
)
692 PEVENTLOGRECORD RecBuf
;
693 LARGE_INTEGER logFileSize
;
701 SystemTimeToEventTime(&st
, &((PEVENTLOGRECORD
) Buffer
)->TimeWritten
);
703 EnterCriticalSection(&LogFile
->cs
);
705 if (!GetFileSizeEx(LogFile
->hFile
, &logFileSize
))
710 /* If the size of the file is over MaxSize */
711 if ((logFileSize
.QuadPart
+ BufSize
)> LogFile
->Header
.MaxSize
)
713 ULONG OverWriteLength
= 0;
714 WriteOffSet
= LogfOffsetByNumber(LogFile
, LogFile
->Header
.OldestRecordNumber
);
715 RecBuf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(EVENTLOGRECORD
));
716 /* Determine how many records need to be overwritten */
719 DPRINT("EventLogFile has reached maximume size\n");
723 DPRINT1("Failed to allocate buffer for OldestRecord!\n");
724 HeapFree(GetProcessHeap(), 0, RecBuf
);
725 LeaveCriticalSection(&LogFile
->cs
);
729 /* Get the oldest record data */
730 RecOffSet
= LogfOffsetByNumber(LogFile
, LogFile
->Header
.OldestRecordNumber
);
732 if (SetFilePointer(LogFile
->hFile
,
735 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
737 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
738 HeapFree(GetProcessHeap(), 0, RecBuf
);
739 LeaveCriticalSection(&LogFile
->cs
);
743 if (!ReadFile(LogFile
->hFile
, RecBuf
, sizeof(EVENTLOGRECORD
), &dwRead
, NULL
))
745 DPRINT1("ReadFile() failed!\n");
746 HeapFree(GetProcessHeap(), 0, RecBuf
);
747 LeaveCriticalSection(&LogFile
->cs
);
751 if (RecBuf
->Reserved
!= LOGFILE_SIGNATURE
)
753 DPRINT1("LogFile corrupt!\n");
757 LogfDeleteOffsetInformation(LogFile
,LogFile
->Header
.OldestRecordNumber
);
759 LogFile
->Header
.OldestRecordNumber
++;
761 OverWriteLength
+= RecBuf
->Length
;
762 /* Check the size of the record as the record adding may be larger */
763 if (OverWriteLength
>= BufSize
)
765 DPRINT("Record will fit. Lenght %d, BufSize %d\n", OverWriteLength
, BufSize
);
766 LogFile
->Header
.StartOffset
= LogfOffsetByNumber(LogFile
, LogFile
->Header
.OldestRecordNumber
);
770 HeapFree(GetProcessHeap(), 0, RecBuf
);
773 WriteOffSet
= LogFile
->Header
.EndOffset
;
775 if (SetFilePointer(LogFile
->hFile
,
778 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
780 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
781 LeaveCriticalSection(&LogFile
->cs
);
785 if (!WriteFile(LogFile
->hFile
, Buffer
, BufSize
, &dwWritten
, NULL
))
787 DPRINT1("WriteFile() failed! %d\n", GetLastError());
788 LeaveCriticalSection(&LogFile
->cs
);
792 if (!LogfAddOffsetInformation(LogFile
,
793 LogFile
->Header
.CurrentRecordNumber
,
796 LeaveCriticalSection(&LogFile
->cs
);
800 LogFile
->Header
.CurrentRecordNumber
++;
802 if (LogFile
->Header
.OldestRecordNumber
== 0)
803 LogFile
->Header
.OldestRecordNumber
= 1;
805 if (WriteOffSet
== LogFile
->Header
.EndOffset
)
807 LogFile
->Header
.EndOffset
+= dwWritten
;
809 if (SetFilePointer(LogFile
->hFile
,
810 LogFile
->Header
.EndOffset
,
812 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
814 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
815 LeaveCriticalSection(&LogFile
->cs
);
819 EofRec
.Ones
= 0x11111111;
820 EofRec
.Twos
= 0x22222222;
821 EofRec
.Threes
= 0x33333333;
822 EofRec
.Fours
= 0x44444444;
823 EofRec
.RecordSizeBeginning
= sizeof(EVENTLOGEOF
);
824 EofRec
.RecordSizeEnd
= sizeof(EVENTLOGEOF
);
825 EofRec
.CurrentRecordNumber
= LogFile
->Header
.CurrentRecordNumber
;
826 EofRec
.OldestRecordNumber
= LogFile
->Header
.OldestRecordNumber
;
827 EofRec
.BeginRecord
= LogFile
->Header
.StartOffset
;
828 EofRec
.EndRecord
= LogFile
->Header
.EndOffset
;
830 if (!WriteFile(LogFile
->hFile
,
836 DPRINT1("WriteFile() failed! %d\n", GetLastError());
837 LeaveCriticalSection(&LogFile
->cs
);
841 if (SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
) ==
842 INVALID_SET_FILE_POINTER
)
844 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
845 LeaveCriticalSection(&LogFile
->cs
);
849 if (!WriteFile(LogFile
->hFile
,
851 sizeof(EVENTLOGHEADER
),
855 DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
856 LeaveCriticalSection(&LogFile
->cs
);
860 if (!FlushFileBuffers(LogFile
->hFile
))
862 LeaveCriticalSection(&LogFile
->cs
);
863 DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
867 LeaveCriticalSection(&LogFile
->cs
);
871 ULONG
LogfOffsetByNumber(PLOGFILE LogFile
, DWORD RecordNumber
)
873 /* Returns 0 if nothing found. */
877 for (i
= 0; i
< LogFile
->OffsetInfoNext
; i
++)
879 if (LogFile
->OffsetInfo
[i
].EventNumber
== RecordNumber
)
880 return LogFile
->OffsetInfo
[i
].EventOffset
;
885 DWORD
LogfGetOldestRecord(PLOGFILE LogFile
)
887 return LogFile
->Header
.OldestRecordNumber
;
890 DWORD
LogfGetCurrentRecord(PLOGFILE LogFile
)
892 return LogFile
->Header
.CurrentRecordNumber
;
895 BOOL
LogfDeleteOffsetInformation(PLOGFILE LogFile
, ULONG ulNumber
)
899 if (ulNumber
!= LogFile
->OffsetInfo
[0].EventNumber
)
904 for (i
=0;i
<LogFile
->OffsetInfoNext
-1; i
++)
906 LogFile
->OffsetInfo
[i
].EventNumber
= LogFile
->OffsetInfo
[i
+1].EventNumber
;
907 LogFile
->OffsetInfo
[i
].EventOffset
= LogFile
->OffsetInfo
[i
+1].EventOffset
;
909 LogFile
->OffsetInfoNext
--;
913 BOOL
LogfAddOffsetInformation(PLOGFILE LogFile
, ULONG ulNumber
, ULONG ulOffset
)
915 LPVOID NewOffsetInfo
;
917 if (LogFile
->OffsetInfoNext
== LogFile
->OffsetInfoSize
)
919 NewOffsetInfo
= HeapReAlloc(MyHeap
,
922 (LogFile
->OffsetInfoSize
+ 64) *
923 sizeof(EVENT_OFFSET_INFO
));
927 DPRINT1("Can't reallocate heap.\n");
931 LogFile
->OffsetInfo
= (PEVENT_OFFSET_INFO
) NewOffsetInfo
;
932 LogFile
->OffsetInfoSize
+= 64;
935 LogFile
->OffsetInfo
[LogFile
->OffsetInfoNext
].EventNumber
= ulNumber
;
936 LogFile
->OffsetInfo
[LogFile
->OffsetInfoNext
].EventOffset
= ulOffset
;
937 LogFile
->OffsetInfoNext
++;
942 PBYTE
LogfAllocAndBuildNewRecord(LPDWORD lpRecSize
,
943 DWORD dwRecordNumber
,
948 LPCWSTR ComputerName
,
957 PEVENTLOGRECORD pRec
;
960 UINT i
, pos
, nStrings
;
964 sizeof(EVENTLOGRECORD
) + (lstrlenW(ComputerName
) +
965 lstrlenW(SourceName
) + 2) * sizeof(WCHAR
);
967 if (dwRecSize
% 4 != 0)
968 dwRecSize
+= 4 - (dwRecSize
% 4);
970 dwRecSize
+= dwSidLength
;
972 for (i
= 0, str
= lpStrings
; i
< wNumStrings
; i
++)
974 dwRecSize
+= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
975 str
+= lstrlenW(str
) + 1;
978 dwRecSize
+= dwDataSize
;
979 if (dwRecSize
% 4 != 0)
980 dwRecSize
+= 4 - (dwRecSize
% 4);
984 Buffer
= (BYTE
*) HeapAlloc(MyHeap
, HEAP_ZERO_MEMORY
, dwRecSize
);
988 DPRINT1("Can't allocate heap!\n");
992 pRec
= (PEVENTLOGRECORD
) Buffer
;
993 pRec
->Length
= dwRecSize
;
994 pRec
->Reserved
= LOGFILE_SIGNATURE
;
995 pRec
->RecordNumber
= dwRecordNumber
;
997 GetSystemTime(&SysTime
);
998 SystemTimeToEventTime(&SysTime
, &pRec
->TimeGenerated
);
999 SystemTimeToEventTime(&SysTime
, &pRec
->TimeWritten
);
1001 pRec
->EventID
= dwEventId
;
1002 pRec
->EventType
= wType
;
1003 pRec
->NumStrings
= wNumStrings
;
1004 pRec
->EventCategory
= wCategory
;
1006 pos
= sizeof(EVENTLOGRECORD
);
1008 lstrcpyW((WCHAR
*) (Buffer
+ pos
), SourceName
);
1009 pos
+= (lstrlenW(SourceName
) + 1) * sizeof(WCHAR
);
1010 lstrcpyW((WCHAR
*) (Buffer
+ pos
), ComputerName
);
1011 pos
+= (lstrlenW(ComputerName
) + 1) * sizeof(WCHAR
);
1013 pRec
->UserSidOffset
= pos
;
1017 pos
+= 4 - (pos
% 4);
1018 CopyMemory(Buffer
+ pos
, lpUserSid
, dwSidLength
);
1019 pRec
->UserSidLength
= dwSidLength
;
1020 pRec
->UserSidOffset
= pos
;
1024 pRec
->StringOffset
= pos
;
1025 for (i
= 0, str
= lpStrings
, nStrings
= 0; i
< wNumStrings
; i
++)
1027 lstrcpyW((WCHAR
*) (Buffer
+ pos
), str
);
1028 pos
+= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
1029 str
+= lstrlenW(str
) + 1;
1032 pRec
->NumStrings
= nStrings
;
1034 pRec
->DataOffset
= pos
;
1037 pRec
->DataLength
= dwDataSize
;
1038 CopyMemory(Buffer
+ pos
, lpRawData
, dwDataSize
);
1043 pos
+= 4 - (pos
% 4);
1045 *((PDWORD
) (Buffer
+ pos
)) = dwRecSize
;
1047 *lpRecSize
= dwRecSize
;