Silence compiler warnings (8/11).
[reactos.git] / reactos / base / services / eventlog / file.c
1 /*
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
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "eventlog.h"
12
13 /* GLOBALS ******************************************************************/
14
15 static LIST_ENTRY LogFileListHead;
16 static CRITICAL_SECTION LogFileListCs;
17 extern HANDLE MyHeap;
18
19 /* FUNCTIONS ****************************************************************/
20
21 BOOL LogfInitializeNew(PLOGFILE LogFile)
22 {
23 DWORD dwWritten;
24 EOF_RECORD EofRec;
25
26 ZeroMemory(&LogFile->Header, sizeof(FILE_HEADER));
27 SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
28 SetEndOfFile(LogFile->hFile);
29
30 LogFile->Header.SizeOfHeader = sizeof(FILE_HEADER);
31 LogFile->Header.SizeOfHeader2 = sizeof(FILE_HEADER);
32 LogFile->Header.FirstRecordOffset = sizeof(FILE_HEADER);
33 LogFile->Header.EofOffset = sizeof(FILE_HEADER);
34 LogFile->Header.MajorVersion = MAJORVER;
35 LogFile->Header.MinorVersion = MINORVER;
36 LogFile->Header.NextRecord = 1;
37
38 LogFile->Header.Signature = LOGFILE_SIGNATURE;
39 if (!WriteFile(LogFile->hFile,
40 &LogFile->Header,
41 sizeof(FILE_HEADER),
42 &dwWritten,
43 NULL))
44 {
45 DPRINT1("WriteFile failed:%d!\n", GetLastError());
46 return FALSE;
47 }
48
49 EofRec.Ones = 0x11111111;
50 EofRec.Twos = 0x22222222;
51 EofRec.Threes = 0x33333333;
52 EofRec.Fours = 0x44444444;
53 EofRec.Size1 = sizeof(EOF_RECORD);
54 EofRec.Size2 = sizeof(EOF_RECORD);
55 EofRec.NextRecordNumber = LogFile->Header.NextRecord;
56 EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
57 EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
58 EofRec.EndOffset = LogFile->Header.EofOffset;
59
60 if (!WriteFile(LogFile->hFile,
61 &EofRec,
62 sizeof(EOF_RECORD),
63 &dwWritten,
64 NULL))
65 {
66 DPRINT1("WriteFile failed:%d!\n", GetLastError());
67 return FALSE;
68 }
69
70 if (!FlushFileBuffers(LogFile->hFile))
71 {
72 DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
73 return FALSE;
74 }
75
76 return TRUE;
77 }
78
79 BOOL LogfInitializeExisting(PLOGFILE LogFile)
80 {
81 DWORD dwRead;
82 DWORD dwRecordsNumber = 0;
83 DWORD dwRecSize, dwRecSign, dwFilePointer;
84 PDWORD pdwRecSize2;
85 PEVENTLOGRECORD RecBuf;
86
87 if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
88 INVALID_SET_FILE_POINTER)
89 {
90 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
91 return FALSE;
92 }
93
94 if (!ReadFile(LogFile->hFile,
95 &LogFile->Header,
96 sizeof(FILE_HEADER),
97 &dwRead,
98 NULL))
99 {
100 DPRINT1("ReadFile failed! %d\n", GetLastError());
101 return FALSE;
102 }
103
104 if (dwRead != sizeof(FILE_HEADER))
105 {
106 DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
107 return LogfInitializeNew(LogFile);
108 }
109
110 if (LogFile->Header.SizeOfHeader != sizeof(FILE_HEADER) ||
111 LogFile->Header.SizeOfHeader2 != sizeof(FILE_HEADER))
112 {
113 DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
114 return LogfInitializeNew(LogFile);
115 }
116
117 if (LogFile->Header.Signature != LOGFILE_SIGNATURE)
118 {
119 DPRINT("EventLog: Invalid signature %x in %S.\n",
120 LogFile->Header.Signature, LogFile->FileName);
121 return LogfInitializeNew(LogFile);
122 }
123
124 if (LogFile->Header.EofOffset > GetFileSize(LogFile->hFile, NULL) + 1)
125 {
126 DPRINT("EventLog: Invalid eof offset %x in %S.\n",
127 LogFile->Header.EofOffset, LogFile->FileName);
128 return LogfInitializeNew(LogFile);
129 }
130
131 for (;;)
132 {
133 dwFilePointer = SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT);
134
135 if (dwFilePointer == INVALID_SET_FILE_POINTER)
136 {
137 DPRINT1("SetFilePointer failed! %d\n", GetLastError());
138 return FALSE;
139 }
140
141 if (!ReadFile(LogFile->hFile,
142 &dwRecSize,
143 sizeof(dwRecSize),
144 &dwRead,
145 NULL))
146 {
147 DPRINT1("ReadFile failed! %d\n", GetLastError());
148 return FALSE;
149 }
150
151 if (dwRead != sizeof(dwRecSize))
152 break;
153
154 if (!ReadFile(LogFile->hFile,
155 &dwRecSign,
156 sizeof(dwRecSign),
157 &dwRead,
158 NULL))
159 {
160 DPRINT1("ReadFile() failed! %d\n", GetLastError());
161 return FALSE;
162 }
163
164 if (dwRead != sizeof(dwRecSize))
165 break;
166
167 if (dwRecSign != LOGFILE_SIGNATURE ||
168 dwRecSize + dwFilePointer > GetFileSize(LogFile->hFile, NULL) + 1 ||
169 dwRecSize < sizeof(EVENTLOGRECORD))
170 {
171 break;
172 }
173
174 if (SetFilePointer(LogFile->hFile,
175 -((LONG) sizeof(DWORD) * 2),
176 NULL,
177 FILE_CURRENT) == INVALID_SET_FILE_POINTER)
178 {
179 DPRINT1("SetFilePointer() failed! %d", GetLastError());
180 return FALSE;
181 }
182
183 RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
184
185 if (!RecBuf)
186 {
187 DPRINT1("Can't allocate heap!\n");
188 return FALSE;
189 }
190
191 if (!ReadFile(LogFile->hFile, RecBuf, dwRecSize, &dwRead, NULL))
192 {
193 DPRINT1("ReadFile() failed! %d\n", GetLastError());
194 HeapFree(MyHeap, 0, RecBuf);
195 return FALSE;
196 }
197
198 if (dwRead != dwRecSize)
199 {
200 HeapFree(MyHeap, 0, RecBuf);
201 break;
202 }
203
204 pdwRecSize2 = (PDWORD) (((PBYTE) RecBuf) + dwRecSize - 4);
205
206 if (*pdwRecSize2 != dwRecSize)
207 {
208 DPRINT1("Invalid size2 of record %d (%x) in %S\n",
209 dwRecordsNumber, *pdwRecSize2, LogFile->LogName);
210 HeapFree(MyHeap, 0, RecBuf);
211 break;
212 }
213
214 dwRecordsNumber++;
215
216 if (!LogfAddOffsetInformation(LogFile,
217 RecBuf->RecordNumber,
218 dwFilePointer))
219 {
220 DPRINT1("LogfAddOffsetInformation() failed!\n");
221 HeapFree(MyHeap, 0, RecBuf);
222 return FALSE;
223 }
224
225 HeapFree(MyHeap, 0, RecBuf);
226 } // for(;;)
227
228 LogFile->Header.NextRecord = dwRecordsNumber + 1;
229 LogFile->Header.OldestRecord = dwRecordsNumber ? 1 : 0; // FIXME
230
231 if (!SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT) ==
232 INVALID_SET_FILE_POINTER)
233 {
234 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
235 return FALSE;
236 }
237
238 if (!WriteFile(LogFile->hFile,
239 &LogFile->Header,
240 sizeof(FILE_HEADER),
241 &dwRead,
242 NULL))
243 {
244 DPRINT1("WriteFile failed! %d\n", GetLastError());
245 return FALSE;
246 }
247
248 if (!FlushFileBuffers(LogFile->hFile))
249 {
250 DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
251 return FALSE;
252 }
253
254 return TRUE;
255 }
256
257 PLOGFILE LogfCreate(WCHAR * LogName, WCHAR * FileName)
258 {
259 PLOGFILE LogFile;
260 BOOL bResult, bCreateNew = FALSE;
261
262 LogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
263 if (!LogFile)
264 {
265 DPRINT1("Can't allocate heap!\n");
266 return NULL;
267 }
268
269 LogFile->hFile = CreateFile(FileName,
270 GENERIC_READ | GENERIC_WRITE,
271 FILE_SHARE_READ,
272 NULL,
273 OPEN_ALWAYS,
274 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
275 NULL);
276
277 if (LogFile->hFile == INVALID_HANDLE_VALUE)
278 {
279 DPRINT1("Can't create file %S.\n", FileName);
280 HeapFree(MyHeap, 0, LogFile);
281 return NULL;
282 }
283
284 bCreateNew = (GetLastError() == ERROR_ALREADY_EXISTS) ? FALSE : TRUE;
285
286 LogFile->LogName =
287 (WCHAR *) HeapAlloc(MyHeap,
288 HEAP_ZERO_MEMORY,
289 (lstrlenW(LogName) + 1) * sizeof(WCHAR));
290
291 if (LogFile->LogName)
292 lstrcpyW(LogFile->LogName, LogName);
293 else
294 {
295 DPRINT1("Can't allocate heap\n");
296 HeapFree(MyHeap, 0, LogFile);
297 return NULL;
298 }
299
300 LogFile->FileName =
301 (WCHAR *) HeapAlloc(MyHeap,
302 HEAP_ZERO_MEMORY,
303 (lstrlenW(FileName) + 1) * sizeof(WCHAR));
304
305 if (LogFile->FileName)
306 lstrcpyW(LogFile->FileName, FileName);
307 else
308 {
309 DPRINT1("Can't allocate heap\n");
310 goto fail;
311 }
312
313 LogFile->OffsetInfo =
314 (PEVENT_OFFSET_INFO) HeapAlloc(MyHeap,
315 HEAP_ZERO_MEMORY,
316 sizeof(EVENT_OFFSET_INFO) * 64);
317
318 if (!LogFile->OffsetInfo)
319 {
320 DPRINT1("Can't allocate heap\n");
321 goto fail;
322 }
323
324 LogFile->OffsetInfoSize = 64;
325
326 if (bCreateNew)
327 bResult = LogfInitializeNew(LogFile);
328 else
329 bResult = LogfInitializeExisting(LogFile);
330
331 if (!bResult)
332 goto fail;
333
334 InitializeCriticalSection(&LogFile->cs);
335 LogfListAddItem(LogFile);
336 return LogFile;
337
338 fail:
339 if (LogFile)
340 {
341 if (LogFile->OffsetInfo)
342 HeapFree(MyHeap, 0, LogFile->OffsetInfo);
343
344 if (LogFile->FileName)
345 HeapFree(MyHeap, 0, LogFile->FileName);
346
347 if (LogFile->LogName)
348 HeapFree(MyHeap, 0, LogFile->LogName);
349
350 HeapFree(MyHeap, 0, LogFile);
351 }
352
353 return NULL;
354 }
355
356 VOID LogfClose(PLOGFILE LogFile)
357 {
358 if (LogFile == NULL)
359 return;
360
361 EnterCriticalSection(&LogFile->cs);
362
363 FlushFileBuffers(LogFile->hFile);
364 CloseHandle(LogFile->hFile);
365 LogfListRemoveItem(LogFile);
366
367 DeleteCriticalSection(&LogFile->cs);
368
369 HeapFree(MyHeap, 0, LogFile->LogName);
370 HeapFree(MyHeap, 0, LogFile->FileName);
371 HeapFree(MyHeap, 0, LogFile->OffsetInfo);
372 HeapFree(MyHeap, 0, LogFile);
373
374 return;
375 }
376
377 VOID LogfCloseAll(VOID)
378 {
379 while (!IsListEmpty(&LogFileListHead))
380 {
381 LogfClose(LogfListHead());
382 }
383
384 DeleteCriticalSection(&LogFileListCs);
385 }
386
387 VOID LogfListInitialize(VOID)
388 {
389 InitializeCriticalSection(&LogFileListCs);
390 InitializeListHead(&LogFileListHead);
391 }
392
393 PLOGFILE LogfListHead(VOID)
394 {
395 return CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry);
396 }
397
398 PLOGFILE LogfListItemByName(WCHAR * Name)
399 {
400 PLIST_ENTRY CurrentEntry;
401 PLOGFILE Result = NULL;
402
403 EnterCriticalSection(&LogFileListCs);
404
405 CurrentEntry = LogFileListHead.Flink;
406 while (CurrentEntry != &LogFileListHead)
407 {
408 PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
409 LOGFILE,
410 ListEntry);
411
412 if (Item->LogName && !lstrcmpi(Item->LogName, Name))
413 {
414 Result = Item;
415 break;
416 }
417
418 CurrentEntry = CurrentEntry->Flink;
419 }
420
421 LeaveCriticalSection(&LogFileListCs);
422 return Result;
423 }
424
425 /* Index starting from 1 */
426 INT LogfListItemIndexByName(WCHAR * Name)
427 {
428 PLIST_ENTRY CurrentEntry;
429 INT Result = 0;
430 INT i = 1;
431
432 EnterCriticalSection(&LogFileListCs);
433
434 CurrentEntry = LogFileListHead.Flink;
435 while (CurrentEntry != &LogFileListHead)
436 {
437 PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
438 LOGFILE,
439 ListEntry);
440
441 if (Item->LogName && !lstrcmpi(Item->LogName, Name))
442 {
443 Result = i;
444 break;
445 }
446
447 CurrentEntry = CurrentEntry->Flink;
448 i++;
449 }
450
451 LeaveCriticalSection(&LogFileListCs);
452 return Result;
453 }
454
455 /* Index starting from 1 */
456 PLOGFILE LogfListItemByIndex(INT Index)
457 {
458 PLIST_ENTRY CurrentEntry;
459 PLOGFILE Result = NULL;
460 INT i = 1;
461
462 EnterCriticalSection(&LogFileListCs);
463
464 CurrentEntry = LogFileListHead.Flink;
465 while (CurrentEntry != &LogFileListHead)
466 {
467 if (i == Index)
468 {
469 Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
470 break;
471 }
472
473 CurrentEntry = CurrentEntry->Flink;
474 i++;
475 }
476
477 LeaveCriticalSection(&LogFileListCs);
478 return Result;
479 }
480
481 INT LogfListItemCount()
482 {
483 PLIST_ENTRY CurrentEntry;
484 INT i = 0;
485
486 EnterCriticalSection(&LogFileListCs);
487
488 CurrentEntry = LogFileListHead.Flink;
489 while (CurrentEntry != &LogFileListHead)
490 {
491 CurrentEntry = CurrentEntry->Flink;
492 i++;
493 }
494
495 LeaveCriticalSection(&LogFileListCs);
496 return i;
497 }
498
499 VOID LogfListAddItem(PLOGFILE Item)
500 {
501 EnterCriticalSection(&LogFileListCs);
502 InsertTailList(&LogFileListHead, &Item->ListEntry);
503 LeaveCriticalSection(&LogFileListCs);
504 }
505
506 VOID LogfListRemoveItem(PLOGFILE Item)
507 {
508 EnterCriticalSection(&LogFileListCs);
509 RemoveEntryList(&Item->ListEntry);
510 LeaveCriticalSection(&LogFileListCs);
511 }
512
513 BOOL LogfReadEvent(PLOGFILE LogFile,
514 DWORD Flags,
515 DWORD RecordNumber,
516 DWORD BufSize,
517 PBYTE Buffer,
518 DWORD * BytesRead,
519 DWORD * BytesNeeded)
520 {
521 DWORD dwOffset, dwRead, dwRecSize;
522 DWORD dwBufferUsage = 0, dwRecNum;
523
524 if (Flags & EVENTLOG_FORWARDS_READ && Flags & EVENTLOG_BACKWARDS_READ)
525 return FALSE;
526
527 if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ))
528 return FALSE;
529
530 if (!Buffer || !BytesRead || !BytesNeeded)
531 return FALSE;
532
533 dwRecNum = RecordNumber;
534 EnterCriticalSection(&LogFile->cs);
535 dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
536
537 if (!dwOffset)
538 {
539 LeaveCriticalSection(&LogFile->cs);
540 return FALSE;
541 }
542
543 if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
544 INVALID_SET_FILE_POINTER)
545 {
546 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
547 LeaveCriticalSection(&LogFile->cs);
548 return FALSE;
549 }
550
551 if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL))
552 {
553 DPRINT1("ReadFile() failed! %d\n", GetLastError());
554 LeaveCriticalSection(&LogFile->cs);
555 return FALSE;
556 }
557
558 if (dwRecSize > BufSize)
559 {
560 *BytesRead = 0;
561 *BytesNeeded = dwRecSize;
562 SetLastError(ERROR_INSUFFICIENT_BUFFER);
563 LeaveCriticalSection(&LogFile->cs);
564 return FALSE;
565 }
566
567 if (SetFilePointer(LogFile->hFile,
568 -((LONG) sizeof(DWORD)),
569 NULL,
570 FILE_CURRENT) == INVALID_SET_FILE_POINTER)
571 {
572 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
573 LeaveCriticalSection(&LogFile->cs);
574 return FALSE;
575 }
576
577 if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL))
578 {
579 DPRINT1("ReadFile() failed! %d\n", GetLastError());
580 LeaveCriticalSection(&LogFile->cs);
581 return FALSE;
582 }
583
584 dwBufferUsage += dwRead;
585
586 while (dwBufferUsage < BufSize)
587 {
588 if (Flags & EVENTLOG_FORWARDS_READ)
589 dwRecNum++;
590 else
591 dwRecNum--;
592
593 dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
594 if (!dwOffset)
595 break;
596
597 if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
598 INVALID_SET_FILE_POINTER)
599 {
600 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
601 LeaveCriticalSection(&LogFile->cs);
602 return FALSE;
603 }
604
605 if (!ReadFile(LogFile->hFile,
606 &dwRecSize,
607 sizeof(DWORD),
608 &dwRead,
609 NULL))
610 {
611 DPRINT1("ReadFile() failed! %d\n", GetLastError());
612 LeaveCriticalSection(&LogFile->cs);
613 return FALSE;
614 }
615
616 if (dwBufferUsage + dwRecSize > BufSize)
617 break;
618
619 if (SetFilePointer(LogFile->hFile,
620 -((LONG) sizeof(DWORD)),
621 NULL,
622 FILE_CURRENT) == INVALID_SET_FILE_POINTER)
623 {
624 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
625 LeaveCriticalSection(&LogFile->cs);
626 return FALSE;
627 }
628
629 if (!ReadFile(LogFile->hFile,
630 Buffer + dwBufferUsage,
631 dwRecSize,
632 &dwRead,
633 NULL))
634 {
635 DPRINT1("ReadFile() failed! %d\n", GetLastError());
636 LeaveCriticalSection(&LogFile->cs);
637 return FALSE;
638 }
639
640 dwBufferUsage += dwRead;
641 }
642
643 *BytesRead = dwBufferUsage;
644 LeaveCriticalSection(&LogFile->cs);
645 return TRUE;
646 }
647
648 BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
649 {
650 DWORD dwWritten;
651 SYSTEMTIME st;
652 EOF_RECORD EofRec;
653
654 if (!Buffer)
655 return FALSE;
656
657 GetSystemTime(&st);
658 SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
659
660 EnterCriticalSection(&LogFile->cs);
661
662 if (SetFilePointer(LogFile->hFile,
663 LogFile->Header.EofOffset,
664 NULL,
665 FILE_BEGIN) == INVALID_SET_FILE_POINTER)
666 {
667 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
668 LeaveCriticalSection(&LogFile->cs);
669 return FALSE;
670 }
671
672 if (!WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL))
673 {
674 DPRINT1("WriteFile() failed! %d\n", GetLastError());
675 LeaveCriticalSection(&LogFile->cs);
676 return FALSE;
677 }
678
679 if (!LogfAddOffsetInformation(LogFile,
680 LogFile->Header.NextRecord,
681 LogFile->Header.EofOffset))
682 {
683 LeaveCriticalSection(&LogFile->cs);
684 return FALSE;
685 }
686
687 LogFile->Header.NextRecord++;
688 LogFile->Header.EofOffset += dwWritten;
689
690 if (LogFile->Header.OldestRecord == 0)
691 LogFile->Header.OldestRecord = 1;
692
693 EofRec.Ones = 0x11111111;
694 EofRec.Twos = 0x22222222;
695 EofRec.Threes = 0x33333333;
696 EofRec.Fours = 0x44444444;
697 EofRec.Size1 = sizeof(EOF_RECORD);
698 EofRec.Size2 = sizeof(EOF_RECORD);
699 EofRec.NextRecordNumber = LogFile->Header.NextRecord;
700 EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
701 EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
702 EofRec.EndOffset = LogFile->Header.EofOffset;
703
704 if (!WriteFile(LogFile->hFile,
705 &EofRec,
706 sizeof(EOF_RECORD),
707 &dwWritten,
708 NULL))
709 {
710 DPRINT1("WriteFile() failed! %d\n", GetLastError());
711 LeaveCriticalSection(&LogFile->cs);
712 return FALSE;
713 }
714
715 if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
716 INVALID_SET_FILE_POINTER)
717 {
718 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
719 LeaveCriticalSection(&LogFile->cs);
720 return FALSE;
721 }
722
723 if (!WriteFile(LogFile->hFile,
724 &LogFile->Header,
725 sizeof(FILE_HEADER),
726 &dwWritten,
727 NULL))
728 {
729 DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
730 LeaveCriticalSection(&LogFile->cs);
731 return FALSE;
732 }
733
734 if (!FlushFileBuffers(LogFile->hFile))
735 {
736 LeaveCriticalSection(&LogFile->cs);
737 DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
738 return FALSE;
739 }
740
741 LeaveCriticalSection(&LogFile->cs);
742 return TRUE;
743 }
744
745 ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
746
747 /* Returns 0 if nothing found. */
748 {
749 DWORD i;
750
751 for (i = 0; i < LogFile->OffsetInfoNext; i++)
752 {
753 if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
754 return LogFile->OffsetInfo[i].EventOffset;
755 }
756 return 0;
757 }
758
759 DWORD LogfGetOldestRecord(PLOGFILE LogFile)
760 {
761 return LogFile->Header.OldestRecord;
762 }
763
764 BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
765 {
766 LPVOID NewOffsetInfo;
767
768 if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
769 {
770 NewOffsetInfo = HeapReAlloc(MyHeap,
771 HEAP_ZERO_MEMORY,
772 LogFile->OffsetInfo,
773 (LogFile->OffsetInfoSize + 64) *
774 sizeof(EVENT_OFFSET_INFO));
775
776 if (!NewOffsetInfo)
777 {
778 DPRINT1("Can't reallocate heap.\n");
779 return FALSE;
780 }
781
782 LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) NewOffsetInfo;
783 LogFile->OffsetInfoSize += 64;
784 }
785
786 LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
787 LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
788 LogFile->OffsetInfoNext++;
789
790 return TRUE;
791 }
792
793 PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
794 DWORD dwRecordNumber,
795 WORD wType,
796 WORD wCategory,
797 DWORD dwEventId,
798 LPCWSTR SourceName,
799 LPCWSTR ComputerName,
800 DWORD dwSidLength,
801 PSID lpUserSid,
802 WORD wNumStrings,
803 WCHAR * lpStrings,
804 DWORD dwDataSize,
805 LPVOID lpRawData)
806 {
807 DWORD dwRecSize;
808 PEVENTLOGRECORD pRec;
809 SYSTEMTIME SysTime;
810 WCHAR *str;
811 UINT i, pos, nStrings;
812 PBYTE Buffer;
813
814 dwRecSize =
815 sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
816 lstrlenW(SourceName) + 2) * sizeof(WCHAR);
817
818 if (dwRecSize % 4 != 0)
819 dwRecSize += 4 - (dwRecSize % 4);
820
821 dwRecSize += dwSidLength;
822
823 for (i = 0, str = lpStrings; i < wNumStrings; i++)
824 {
825 dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
826 str += lstrlenW(str) + 1;
827 }
828
829 dwRecSize += dwDataSize;
830 if (dwRecSize % 4 != 0)
831 dwRecSize += 4 - (dwRecSize % 4);
832
833 dwRecSize += 4;
834
835 Buffer = (BYTE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);
836
837 if (!Buffer)
838 {
839 DPRINT1("Can't allocate heap!\n");
840 return NULL;
841 }
842
843 pRec = (PEVENTLOGRECORD) Buffer;
844 pRec->Length = dwRecSize;
845 pRec->Reserved = LOGFILE_SIGNATURE;
846 pRec->RecordNumber = dwRecordNumber;
847
848 GetSystemTime(&SysTime);
849 SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
850 SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
851
852 pRec->EventID = dwEventId;
853 pRec->EventType = wType;
854 pRec->NumStrings = wNumStrings;
855 pRec->EventCategory = wCategory;
856
857 pos = sizeof(EVENTLOGRECORD);
858
859 lstrcpyW((WCHAR *) (Buffer + pos), SourceName);
860 pos += (lstrlenW(SourceName) + 1) * sizeof(WCHAR);
861 lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
862 pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
863
864 pRec->UserSidOffset = pos;
865 if (dwSidLength)
866 {
867 if (pos % 4 != 0)
868 pos += 4 - (pos % 4);
869 CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
870 pRec->UserSidLength = dwSidLength;
871 pRec->UserSidOffset = pos;
872 pos += dwSidLength;
873 }
874
875 pRec->StringOffset = pos;
876 for (i = 0, str = lpStrings, nStrings = 0; i < wNumStrings; i++)
877 {
878 lstrcpyW((WCHAR *) (Buffer + pos), str);
879 pos += (lstrlenW(str) + 1) * sizeof(WCHAR);
880 str += lstrlenW(str) + 1;
881 nStrings++;
882 }
883 pRec->NumStrings = nStrings;
884
885 pRec->DataOffset = pos;
886 if (dwDataSize)
887 {
888 pRec->DataLength = dwDataSize;
889 CopyMemory(Buffer + pos, lpRawData, dwDataSize);
890 pos += dwDataSize;
891 }
892
893 if (pos % 4 != 0)
894 pos += 4 - (pos % 4);
895
896 *((PDWORD) (Buffer + pos)) = dwRecSize;
897
898 *lpRecSize = dwRecSize;
899 return Buffer;
900 }
901
902 __inline void LogfFreeRecord(LPVOID Rec)
903 {
904 HeapFree(MyHeap, 0, Rec);
905 }