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
9 /* INCLUDES *****************************************************************/
13 /* GLOBALS ******************************************************************/
15 static LIST_ENTRY LogFileListHead
;
16 static CRITICAL_SECTION LogFileListCs
;
18 /* FUNCTIONS ****************************************************************/
20 BOOL
LogfInitializeNew(PLOGFILE LogFile
)
25 ZeroMemory(&LogFile
->Header
, sizeof(EVENTLOGHEADER
));
26 SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
);
27 SetEndOfFile(LogFile
->hFile
);
29 LogFile
->Header
.HeaderSize
= sizeof(EVENTLOGHEADER
);
30 LogFile
->Header
.EndHeaderSize
= sizeof(EVENTLOGHEADER
);
31 LogFile
->Header
.StartOffset
= sizeof(EVENTLOGHEADER
);
32 LogFile
->Header
.EndOffset
= sizeof(EVENTLOGHEADER
);
33 LogFile
->Header
.MajorVersion
= MAJORVER
;
34 LogFile
->Header
.MinorVersion
= MINORVER
;
35 LogFile
->Header
.CurrentRecordNumber
= 1;
36 /* FIXME: Read MaxSize from registry for this LogFile.
37 But for now limit EventLog size to just under 5K. */
38 LogFile
->Header
.MaxSize
= 5000;
39 LogFile
->Header
.Signature
= LOGFILE_SIGNATURE
;
40 if (!WriteFile(LogFile
->hFile
,
42 sizeof(EVENTLOGHEADER
),
46 DPRINT1("WriteFile failed:%d!\n", GetLastError());
50 EofRec
.Ones
= 0x11111111;
51 EofRec
.Twos
= 0x22222222;
52 EofRec
.Threes
= 0x33333333;
53 EofRec
.Fours
= 0x44444444;
54 EofRec
.RecordSizeBeginning
= sizeof(EVENTLOGEOF
);
55 EofRec
.RecordSizeEnd
= sizeof(EVENTLOGEOF
);
56 EofRec
.CurrentRecordNumber
= LogFile
->Header
.CurrentRecordNumber
;
57 EofRec
.OldestRecordNumber
= LogFile
->Header
.OldestRecordNumber
;
58 EofRec
.BeginRecord
= LogFile
->Header
.StartOffset
;
59 EofRec
.EndRecord
= LogFile
->Header
.EndOffset
;
61 if (!WriteFile(LogFile
->hFile
,
67 DPRINT1("WriteFile failed:%d!\n", GetLastError());
71 if (!FlushFileBuffers(LogFile
->hFile
))
73 DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
80 BOOL
LogfInitializeExisting(PLOGFILE LogFile
)
83 DWORD dwRecordsNumber
= 0;
84 DWORD dwRecSize
, dwRecSign
, dwFilePointer
;
86 PEVENTLOGRECORD RecBuf
;
88 if (SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
) ==
89 INVALID_SET_FILE_POINTER
)
91 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
95 if (!ReadFile(LogFile
->hFile
,
97 sizeof(EVENTLOGHEADER
),
101 DPRINT1("ReadFile failed! %d\n", GetLastError());
105 if (dwRead
!= sizeof(EVENTLOGHEADER
))
107 DPRINT("EventLog: Invalid file %S.\n", LogFile
->FileName
);
108 return LogfInitializeNew(LogFile
);
111 if (LogFile
->Header
.HeaderSize
!= sizeof(EVENTLOGHEADER
) ||
112 LogFile
->Header
.EndHeaderSize
!= sizeof(EVENTLOGHEADER
))
114 DPRINT("EventLog: Invalid header size in %S.\n", LogFile
->FileName
);
115 return LogfInitializeNew(LogFile
);
118 if (LogFile
->Header
.Signature
!= LOGFILE_SIGNATURE
)
120 DPRINT("EventLog: Invalid signature %x in %S.\n",
121 LogFile
->Header
.Signature
, LogFile
->FileName
);
122 return LogfInitializeNew(LogFile
);
125 if (LogFile
->Header
.EndOffset
> GetFileSize(LogFile
->hFile
, NULL
) + 1)
127 DPRINT("EventLog: Invalid eof offset %x in %S.\n",
128 LogFile
->Header
.EndOffset
, LogFile
->FileName
);
129 return LogfInitializeNew(LogFile
);
134 dwFilePointer
= SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_CURRENT
);
136 if (dwFilePointer
== INVALID_SET_FILE_POINTER
)
138 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
142 if (!ReadFile(LogFile
->hFile
,
148 DPRINT1("ReadFile failed! %d\n", GetLastError());
152 if (dwRead
!= sizeof(dwRecSize
))
155 if (!ReadFile(LogFile
->hFile
,
161 DPRINT1("ReadFile() failed! %d\n", GetLastError());
165 if (dwRead
!= sizeof(dwRecSize
))
168 if (dwRecSign
!= LOGFILE_SIGNATURE
||
169 dwRecSize
+ dwFilePointer
> GetFileSize(LogFile
->hFile
, NULL
) + 1 ||
170 dwRecSize
< sizeof(EVENTLOGRECORD
))
175 if (SetFilePointer(LogFile
->hFile
,
176 -((LONG
) sizeof(DWORD
) * 2),
178 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
180 DPRINT1("SetFilePointer() failed! %d", GetLastError());
184 RecBuf
= (PEVENTLOGRECORD
) HeapAlloc(MyHeap
, 0, dwRecSize
);
188 DPRINT1("Can't allocate heap!\n");
192 if (!ReadFile(LogFile
->hFile
, RecBuf
, dwRecSize
, &dwRead
, NULL
))
194 DPRINT1("ReadFile() failed! %d\n", GetLastError());
195 HeapFree(MyHeap
, 0, RecBuf
);
199 if (dwRead
!= dwRecSize
)
201 HeapFree(MyHeap
, 0, RecBuf
);
205 pdwRecSize2
= (PDWORD
) (((PBYTE
) RecBuf
) + dwRecSize
- 4);
207 if (*pdwRecSize2
!= dwRecSize
)
209 DPRINT1("Invalid RecordSizeEnd of record %d (%x) in %S\n",
210 dwRecordsNumber
, *pdwRecSize2
, LogFile
->LogName
);
211 HeapFree(MyHeap
, 0, RecBuf
);
217 if (!LogfAddOffsetInformation(LogFile
,
218 RecBuf
->RecordNumber
,
221 DPRINT1("LogfAddOffsetInformation() failed!\n");
222 HeapFree(MyHeap
, 0, RecBuf
);
226 HeapFree(MyHeap
, 0, RecBuf
);
229 LogFile
->Header
.CurrentRecordNumber
= dwRecordsNumber
+ 1;
230 LogFile
->Header
.OldestRecordNumber
= dwRecordsNumber
? 1 : 0; // FIXME
232 /* FIXME: Read MaxSize from registry for this LogFile.
233 But for now limit EventLog size to just under 5K. */
234 LogFile
->Header
.MaxSize
= 5000;
236 if (!SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_CURRENT
) ==
237 INVALID_SET_FILE_POINTER
)
239 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
243 if (!WriteFile(LogFile
->hFile
,
245 sizeof(EVENTLOGHEADER
),
249 DPRINT1("WriteFile failed! %d\n", GetLastError());
253 if (!FlushFileBuffers(LogFile
->hFile
))
255 DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
262 PLOGFILE
LogfCreate(WCHAR
* LogName
, WCHAR
* FileName
)
265 BOOL bResult
, bCreateNew
= FALSE
;
267 LogFile
= (LOGFILE
*) HeapAlloc(MyHeap
, HEAP_ZERO_MEMORY
, sizeof(LOGFILE
));
270 DPRINT1("Can't allocate heap!\n");
274 LogFile
->hFile
= CreateFile(FileName
,
275 GENERIC_READ
| GENERIC_WRITE
,
279 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_RANDOM_ACCESS
,
282 if (LogFile
->hFile
== INVALID_HANDLE_VALUE
)
284 DPRINT1("Can't create file %S.\n", FileName
);
285 HeapFree(MyHeap
, 0, LogFile
);
289 bCreateNew
= (GetLastError() == ERROR_ALREADY_EXISTS
) ? FALSE
: TRUE
;
292 (WCHAR
*) HeapAlloc(MyHeap
,
294 (lstrlenW(LogName
) + 1) * sizeof(WCHAR
));
296 if (LogFile
->LogName
)
297 lstrcpyW(LogFile
->LogName
, LogName
);
300 DPRINT1("Can't allocate heap\n");
301 HeapFree(MyHeap
, 0, LogFile
);
306 (WCHAR
*) HeapAlloc(MyHeap
,
308 (lstrlenW(FileName
) + 1) * sizeof(WCHAR
));
310 if (LogFile
->FileName
)
311 lstrcpyW(LogFile
->FileName
, FileName
);
314 DPRINT1("Can't allocate heap\n");
318 LogFile
->OffsetInfo
=
319 (PEVENT_OFFSET_INFO
) HeapAlloc(MyHeap
,
321 sizeof(EVENT_OFFSET_INFO
) * 64);
323 if (!LogFile
->OffsetInfo
)
325 DPRINT1("Can't allocate heap\n");
329 LogFile
->OffsetInfoSize
= 64;
332 bResult
= LogfInitializeNew(LogFile
);
334 bResult
= LogfInitializeExisting(LogFile
);
339 InitializeCriticalSection(&LogFile
->cs
);
340 LogfListAddItem(LogFile
);
346 if (LogFile
->OffsetInfo
)
347 HeapFree(MyHeap
, 0, LogFile
->OffsetInfo
);
349 if (LogFile
->FileName
)
350 HeapFree(MyHeap
, 0, LogFile
->FileName
);
352 if (LogFile
->LogName
)
353 HeapFree(MyHeap
, 0, LogFile
->LogName
);
355 HeapFree(MyHeap
, 0, LogFile
);
361 VOID
LogfClose(PLOGFILE LogFile
)
366 EnterCriticalSection(&LogFile
->cs
);
368 FlushFileBuffers(LogFile
->hFile
);
369 CloseHandle(LogFile
->hFile
);
370 LogfListRemoveItem(LogFile
);
372 DeleteCriticalSection(&LogFile
->cs
);
374 HeapFree(MyHeap
, 0, LogFile
->LogName
);
375 HeapFree(MyHeap
, 0, LogFile
->FileName
);
376 HeapFree(MyHeap
, 0, LogFile
->OffsetInfo
);
377 HeapFree(MyHeap
, 0, LogFile
);
382 VOID
LogfCloseAll(VOID
)
384 while (!IsListEmpty(&LogFileListHead
))
386 LogfClose(LogfListHead());
389 DeleteCriticalSection(&LogFileListCs
);
392 VOID
LogfListInitialize(VOID
)
394 InitializeCriticalSection(&LogFileListCs
);
395 InitializeListHead(&LogFileListHead
);
398 PLOGFILE
LogfListHead(VOID
)
400 return CONTAINING_RECORD(LogFileListHead
.Flink
, LOGFILE
, ListEntry
);
403 PLOGFILE
LogfListItemByName(WCHAR
* Name
)
405 PLIST_ENTRY CurrentEntry
;
406 PLOGFILE Result
= NULL
;
408 EnterCriticalSection(&LogFileListCs
);
410 CurrentEntry
= LogFileListHead
.Flink
;
411 while (CurrentEntry
!= &LogFileListHead
)
413 PLOGFILE Item
= CONTAINING_RECORD(CurrentEntry
,
417 if (Item
->LogName
&& !lstrcmpi(Item
->LogName
, Name
))
423 CurrentEntry
= CurrentEntry
->Flink
;
426 LeaveCriticalSection(&LogFileListCs
);
430 /* Index starting from 1 */
431 INT
LogfListItemIndexByName(WCHAR
* Name
)
433 PLIST_ENTRY CurrentEntry
;
437 EnterCriticalSection(&LogFileListCs
);
439 CurrentEntry
= LogFileListHead
.Flink
;
440 while (CurrentEntry
!= &LogFileListHead
)
442 PLOGFILE Item
= CONTAINING_RECORD(CurrentEntry
,
446 if (Item
->LogName
&& !lstrcmpi(Item
->LogName
, Name
))
452 CurrentEntry
= CurrentEntry
->Flink
;
456 LeaveCriticalSection(&LogFileListCs
);
460 /* Index starting from 1 */
461 PLOGFILE
LogfListItemByIndex(INT Index
)
463 PLIST_ENTRY CurrentEntry
;
464 PLOGFILE Result
= NULL
;
467 EnterCriticalSection(&LogFileListCs
);
469 CurrentEntry
= LogFileListHead
.Flink
;
470 while (CurrentEntry
!= &LogFileListHead
)
474 Result
= CONTAINING_RECORD(CurrentEntry
, LOGFILE
, ListEntry
);
478 CurrentEntry
= CurrentEntry
->Flink
;
482 LeaveCriticalSection(&LogFileListCs
);
486 INT
LogfListItemCount()
488 PLIST_ENTRY CurrentEntry
;
491 EnterCriticalSection(&LogFileListCs
);
493 CurrentEntry
= LogFileListHead
.Flink
;
494 while (CurrentEntry
!= &LogFileListHead
)
496 CurrentEntry
= CurrentEntry
->Flink
;
500 LeaveCriticalSection(&LogFileListCs
);
504 VOID
LogfListAddItem(PLOGFILE Item
)
506 EnterCriticalSection(&LogFileListCs
);
507 InsertTailList(&LogFileListHead
, &Item
->ListEntry
);
508 LeaveCriticalSection(&LogFileListCs
);
511 VOID
LogfListRemoveItem(PLOGFILE Item
)
513 EnterCriticalSection(&LogFileListCs
);
514 RemoveEntryList(&Item
->ListEntry
);
515 LeaveCriticalSection(&LogFileListCs
);
518 DWORD
LogfReadEvent(PLOGFILE LogFile
,
520 DWORD
* RecordNumber
,
526 DWORD dwOffset
, dwRead
, dwRecSize
;
527 DWORD dwBufferUsage
= 0, dwRecNum
;
529 if (Flags
& EVENTLOG_FORWARDS_READ
&& Flags
& EVENTLOG_BACKWARDS_READ
)
530 return ERROR_INVALID_PARAMETER
;
532 if (!(Flags
& EVENTLOG_FORWARDS_READ
) && !(Flags
& EVENTLOG_BACKWARDS_READ
))
533 return ERROR_INVALID_PARAMETER
;
535 if (!Buffer
|| !BytesRead
|| !BytesNeeded
)
536 return ERROR_INVALID_PARAMETER
;
538 if ((*RecordNumber
==0) && !(EVENTLOG_SEQUENTIAL_READ
))
540 return ERROR_INVALID_PARAMETER
;
543 dwRecNum
= *RecordNumber
;
544 EnterCriticalSection(&LogFile
->cs
);
549 dwOffset
= LogfOffsetByNumber(LogFile
, dwRecNum
);
553 LeaveCriticalSection(&LogFile
->cs
);
554 return ERROR_HANDLE_EOF
;
557 if (SetFilePointer(LogFile
->hFile
, dwOffset
, NULL
, FILE_BEGIN
) ==
558 INVALID_SET_FILE_POINTER
)
560 DPRINT1("SetFilePointer() failed!\n");
564 if (!ReadFile(LogFile
->hFile
, &dwRecSize
, sizeof(DWORD
), &dwRead
, NULL
))
566 DPRINT1("ReadFile() failed!\n");
570 if (dwRecSize
> BufSize
)
572 *BytesNeeded
= dwRecSize
;
573 LeaveCriticalSection(&LogFile
->cs
);
574 return ERROR_INSUFFICIENT_BUFFER
;
577 if (SetFilePointer(LogFile
->hFile
,
578 -((LONG
) sizeof(DWORD
)),
580 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
582 DPRINT1("SetFilePointer() failed!\n");
586 if (!ReadFile(LogFile
->hFile
, Buffer
, dwRecSize
, &dwRead
, NULL
))
588 DPRINT1("ReadFile() failed!\n");
592 dwBufferUsage
+= dwRead
;
594 while (dwBufferUsage
<= BufSize
)
596 if (Flags
& EVENTLOG_FORWARDS_READ
)
601 dwOffset
= LogfOffsetByNumber(LogFile
, dwRecNum
);
605 if (SetFilePointer(LogFile
->hFile
, dwOffset
, NULL
, FILE_BEGIN
) ==
606 INVALID_SET_FILE_POINTER
)
608 DPRINT1("SetFilePointer() failed!\n");
612 if (!ReadFile(LogFile
->hFile
,
618 DPRINT1("ReadFile() failed!\n");
622 if (dwBufferUsage
+ dwRecSize
> BufSize
)
625 if (SetFilePointer(LogFile
->hFile
,
626 -((LONG
) sizeof(DWORD
)),
628 FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
630 DPRINT1("SetFilePointer() failed!\n");
634 if (!ReadFile(LogFile
->hFile
,
635 Buffer
+ dwBufferUsage
,
640 DPRINT1("ReadFile() failed!\n");
644 dwBufferUsage
+= dwRead
;
647 *BytesRead
= dwBufferUsage
;
648 * RecordNumber
= dwRecNum
;
649 LeaveCriticalSection(&LogFile
->cs
);
650 return ERROR_SUCCESS
;
653 DPRINT1("LogfReadEvent failed with %x\n",GetLastError());
654 LeaveCriticalSection(&LogFile
->cs
);
655 return GetLastError();
658 BOOL
LogfWriteData(PLOGFILE LogFile
, DWORD BufSize
, PBYTE Buffer
)
664 PEVENTLOGRECORD RecBuf
;
665 LARGE_INTEGER logFileSize
;
671 SystemTimeToEventTime(&st
, &((PEVENTLOGRECORD
) Buffer
)->TimeWritten
);
673 EnterCriticalSection(&LogFile
->cs
);
675 if (!GetFileSizeEx(LogFile
->hFile
, &logFileSize
))
680 /* If the size of the file is over MaxSize */
681 if ((logFileSize
.QuadPart
+ BufSize
)> LogFile
->Header
.MaxSize
)
683 RecBuf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(EVENTLOGRECORD
));
684 /* Determine how many records need to be overwritten */
687 DPRINT("EventLogFile has reached maximume size\n");
691 DPRINT1("Failed to allocate buffer for OldestRecord!\n");
692 HeapFree(GetProcessHeap(), 0, RecBuf
);
693 LeaveCriticalSection(&LogFile
->cs
);
697 /* Get the oldest record data */
698 RecOffSet
= LogfOffsetByNumber(LogFile
, LogFile
->Header
.OldestRecordNumber
);
699 if (SetFilePointer(LogFile
->hFile
,
702 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
704 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
705 HeapFree(GetProcessHeap(), 0, RecBuf
);
706 LeaveCriticalSection(&LogFile
->cs
);
710 if (!ReadFile(LogFile
->hFile
, RecBuf
, sizeof(EVENTLOGRECORD
), &dwRead
, NULL
))
712 DPRINT1("ReadFile() failed!\n");
713 HeapFree(GetProcessHeap(), 0, RecBuf
);
714 LeaveCriticalSection(&LogFile
->cs
);
718 if (RecBuf
->Reserved
!= LOGFILE_SIGNATURE
)
720 DPRINT1("LogFile corrupt!\n");
724 LogFile
->Header
.OldestRecordNumber
++;
726 /* Check the size of the record as the record adding may be larger */
727 if (RecBuf
->Length
>= BufSize
)
729 DPRINT1("Record will fit\n");
730 LogFile
->Header
.StartOffset
= LogfOffsetByNumber(LogFile
, LogFile
->Header
.OldestRecordNumber
);
735 DPRINT1("Record wont fit\n");
738 HeapFree(GetProcessHeap(), 0, RecBuf
);
741 if (SetFilePointer(LogFile
->hFile
,
742 LogFile
->Header
.EndOffset
,
744 FILE_BEGIN
) == INVALID_SET_FILE_POINTER
)
746 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
747 LeaveCriticalSection(&LogFile
->cs
);
751 if (!WriteFile(LogFile
->hFile
, Buffer
, BufSize
, &dwWritten
, NULL
))
753 DPRINT1("WriteFile() failed! %d\n", GetLastError());
754 LeaveCriticalSection(&LogFile
->cs
);
758 if (!LogfAddOffsetInformation(LogFile
,
759 LogFile
->Header
.CurrentRecordNumber
,
760 LogFile
->Header
.EndOffset
))
762 LeaveCriticalSection(&LogFile
->cs
);
766 LogFile
->Header
.CurrentRecordNumber
++;
767 LogFile
->Header
.EndOffset
+= dwWritten
;
769 if (LogFile
->Header
.OldestRecordNumber
== 0)
770 LogFile
->Header
.OldestRecordNumber
= 1;
772 EofRec
.Ones
= 0x11111111;
773 EofRec
.Twos
= 0x22222222;
774 EofRec
.Threes
= 0x33333333;
775 EofRec
.Fours
= 0x44444444;
776 EofRec
.RecordSizeBeginning
= sizeof(EVENTLOGEOF
);
777 EofRec
.RecordSizeEnd
= sizeof(EVENTLOGEOF
);
778 EofRec
.CurrentRecordNumber
= LogFile
->Header
.CurrentRecordNumber
;
779 EofRec
.OldestRecordNumber
= LogFile
->Header
.OldestRecordNumber
;
780 EofRec
.BeginRecord
= LogFile
->Header
.StartOffset
;
781 EofRec
.EndRecord
= LogFile
->Header
.EndOffset
;
783 if (!WriteFile(LogFile
->hFile
,
789 DPRINT1("WriteFile() failed! %d\n", GetLastError());
790 LeaveCriticalSection(&LogFile
->cs
);
794 if (SetFilePointer(LogFile
->hFile
, 0, NULL
, FILE_BEGIN
) ==
795 INVALID_SET_FILE_POINTER
)
797 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
798 LeaveCriticalSection(&LogFile
->cs
);
802 if (!WriteFile(LogFile
->hFile
,
804 sizeof(EVENTLOGHEADER
),
808 DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
809 LeaveCriticalSection(&LogFile
->cs
);
813 if (!FlushFileBuffers(LogFile
->hFile
))
815 LeaveCriticalSection(&LogFile
->cs
);
816 DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
820 LeaveCriticalSection(&LogFile
->cs
);
824 ULONG
LogfOffsetByNumber(PLOGFILE LogFile
, DWORD RecordNumber
)
826 /* Returns 0 if nothing found. */
830 for (i
= 0; i
< LogFile
->OffsetInfoNext
; i
++)
832 if (LogFile
->OffsetInfo
[i
].EventNumber
== RecordNumber
)
833 return LogFile
->OffsetInfo
[i
].EventOffset
;
838 DWORD
LogfGetOldestRecord(PLOGFILE LogFile
)
840 return LogFile
->Header
.OldestRecordNumber
;
843 DWORD
LogfGetCurrentRecord(PLOGFILE LogFile
)
845 return LogFile
->Header
.CurrentRecordNumber
;
848 BOOL
LogfAddOffsetInformation(PLOGFILE LogFile
, ULONG ulNumber
, ULONG ulOffset
)
850 LPVOID NewOffsetInfo
;
852 if (LogFile
->OffsetInfoNext
== LogFile
->OffsetInfoSize
)
854 NewOffsetInfo
= HeapReAlloc(MyHeap
,
857 (LogFile
->OffsetInfoSize
+ 64) *
858 sizeof(EVENT_OFFSET_INFO
));
862 DPRINT1("Can't reallocate heap.\n");
866 LogFile
->OffsetInfo
= (PEVENT_OFFSET_INFO
) NewOffsetInfo
;
867 LogFile
->OffsetInfoSize
+= 64;
870 LogFile
->OffsetInfo
[LogFile
->OffsetInfoNext
].EventNumber
= ulNumber
;
871 LogFile
->OffsetInfo
[LogFile
->OffsetInfoNext
].EventOffset
= ulOffset
;
872 LogFile
->OffsetInfoNext
++;
877 PBYTE
LogfAllocAndBuildNewRecord(LPDWORD lpRecSize
,
878 DWORD dwRecordNumber
,
883 LPCWSTR ComputerName
,
892 PEVENTLOGRECORD pRec
;
895 UINT i
, pos
, nStrings
;
899 sizeof(EVENTLOGRECORD
) + (lstrlenW(ComputerName
) +
900 lstrlenW(SourceName
) + 2) * sizeof(WCHAR
);
902 if (dwRecSize
% 4 != 0)
903 dwRecSize
+= 4 - (dwRecSize
% 4);
905 dwRecSize
+= dwSidLength
;
907 for (i
= 0, str
= lpStrings
; i
< wNumStrings
; i
++)
909 dwRecSize
+= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
910 str
+= lstrlenW(str
) + 1;
913 dwRecSize
+= dwDataSize
;
914 if (dwRecSize
% 4 != 0)
915 dwRecSize
+= 4 - (dwRecSize
% 4);
919 Buffer
= (BYTE
*) HeapAlloc(MyHeap
, HEAP_ZERO_MEMORY
, dwRecSize
);
923 DPRINT1("Can't allocate heap!\n");
927 pRec
= (PEVENTLOGRECORD
) Buffer
;
928 pRec
->Length
= dwRecSize
;
929 pRec
->Reserved
= LOGFILE_SIGNATURE
;
930 pRec
->RecordNumber
= dwRecordNumber
;
932 GetSystemTime(&SysTime
);
933 SystemTimeToEventTime(&SysTime
, &pRec
->TimeGenerated
);
934 SystemTimeToEventTime(&SysTime
, &pRec
->TimeWritten
);
936 pRec
->EventID
= dwEventId
;
937 pRec
->EventType
= wType
;
938 pRec
->NumStrings
= wNumStrings
;
939 pRec
->EventCategory
= wCategory
;
941 pos
= sizeof(EVENTLOGRECORD
);
943 lstrcpyW((WCHAR
*) (Buffer
+ pos
), SourceName
);
944 pos
+= (lstrlenW(SourceName
) + 1) * sizeof(WCHAR
);
945 lstrcpyW((WCHAR
*) (Buffer
+ pos
), ComputerName
);
946 pos
+= (lstrlenW(ComputerName
) + 1) * sizeof(WCHAR
);
948 pRec
->UserSidOffset
= pos
;
952 pos
+= 4 - (pos
% 4);
953 CopyMemory(Buffer
+ pos
, lpUserSid
, dwSidLength
);
954 pRec
->UserSidLength
= dwSidLength
;
955 pRec
->UserSidOffset
= pos
;
959 pRec
->StringOffset
= pos
;
960 for (i
= 0, str
= lpStrings
, nStrings
= 0; i
< wNumStrings
; i
++)
962 lstrcpyW((WCHAR
*) (Buffer
+ pos
), str
);
963 pos
+= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
964 str
+= lstrlenW(str
) + 1;
967 pRec
->NumStrings
= nStrings
;
969 pRec
->DataOffset
= pos
;
972 pRec
->DataLength
= dwDataSize
;
973 CopyMemory(Buffer
+ pos
, lpRawData
, dwDataSize
);
978 pos
+= 4 - (pos
% 4);
980 *((PDWORD
) (Buffer
+ pos
)) = dwRecSize
;
982 *lpRecSize
= dwRecSize
;