ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

file.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:          ReactOS kernel
00003  * LICENSE:          GPL - See COPYING in the top level directory
00004  * FILE:             services/eventlog/file.c
00005  * PURPOSE:          Event logging service
00006  * COPYRIGHT:        Copyright 2005 Saveliy Tretiakov
00007                      Michael Martin
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include "eventlog.h"
00013 
00014 /* GLOBALS ******************************************************************/
00015 
00016 static LIST_ENTRY LogFileListHead;
00017 static CRITICAL_SECTION LogFileListCs;
00018 
00019 /* FUNCTIONS ****************************************************************/
00020 
00021 static NTSTATUS
00022 LogfInitializeNew(PLOGFILE LogFile)
00023 {
00024     DWORD dwWritten;
00025     EVENTLOGEOF EofRec;
00026 
00027     ZeroMemory(&LogFile->Header, sizeof(EVENTLOGHEADER));
00028     SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
00029     SetEndOfFile(LogFile->hFile);
00030 
00031     LogFile->Header.HeaderSize = sizeof(EVENTLOGHEADER);
00032     LogFile->Header.EndHeaderSize = sizeof(EVENTLOGHEADER);
00033     LogFile->Header.StartOffset = sizeof(EVENTLOGHEADER);
00034     LogFile->Header.EndOffset = sizeof(EVENTLOGHEADER);
00035     LogFile->Header.MajorVersion = MAJORVER;
00036     LogFile->Header.MinorVersion = MINORVER;
00037     LogFile->Header.CurrentRecordNumber = 1;
00038     LogFile->Header.OldestRecordNumber = 1;
00039     /* FIXME: Read MaxSize from registry for this LogFile.
00040        But for now limit EventLog size to just under 5K. */
00041     LogFile->Header.MaxSize = 5000;
00042     LogFile->Header.Signature = LOGFILE_SIGNATURE;
00043     if (!WriteFile(LogFile->hFile,
00044                    &LogFile->Header,
00045                    sizeof(EVENTLOGHEADER),
00046                    &dwWritten,
00047                    NULL))
00048     {
00049         DPRINT1("WriteFile failed:%d!\n", GetLastError());
00050         return STATUS_UNSUCCESSFUL;
00051     }
00052 
00053     EofRec.Ones = 0x11111111;
00054     EofRec.Twos = 0x22222222;
00055     EofRec.Threes = 0x33333333;
00056     EofRec.Fours = 0x44444444;
00057     EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
00058     EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
00059     EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
00060     EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
00061     EofRec.BeginRecord = LogFile->Header.StartOffset;
00062     EofRec.EndRecord = LogFile->Header.EndOffset;
00063 
00064     if (!WriteFile(LogFile->hFile,
00065                    &EofRec,
00066                    sizeof(EVENTLOGEOF),
00067                    &dwWritten,
00068                    NULL))
00069     {
00070         DPRINT1("WriteFile failed:%d!\n", GetLastError());
00071         return STATUS_UNSUCCESSFUL;
00072     }
00073 
00074     if (!FlushFileBuffers(LogFile->hFile))
00075     {
00076         DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
00077         return STATUS_UNSUCCESSFUL;
00078     }
00079 
00080     return STATUS_SUCCESS;
00081 }
00082 
00083 
00084 static NTSTATUS
00085 LogfInitializeExisting(PLOGFILE LogFile)
00086 {
00087     DWORD dwRead;
00088     DWORD dwRecordsNumber = 0;
00089     DWORD dwRecSize, dwRecSign, dwFilePointer;
00090     PDWORD pdwRecSize2;
00091     PEVENTLOGRECORD RecBuf;
00092     BOOL OvewrWrittenRecords = FALSE;
00093 
00094     DPRINT("Initializing LogFile %S\n",LogFile->LogName);
00095 
00096     if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
00097         INVALID_SET_FILE_POINTER)
00098     {
00099         DPRINT1("SetFilePointer failed! %d\n", GetLastError());
00100         return STATUS_EVENTLOG_FILE_CORRUPT;
00101     }
00102 
00103     if (!ReadFile(LogFile->hFile,
00104                   &LogFile->Header,
00105                   sizeof(EVENTLOGHEADER),
00106                   &dwRead,
00107                   NULL))
00108     {
00109         DPRINT1("ReadFile failed! %d\n", GetLastError());
00110         return STATUS_EVENTLOG_FILE_CORRUPT;
00111     }
00112 
00113     if (dwRead != sizeof(EVENTLOGHEADER))
00114     {
00115         DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
00116         return STATUS_EVENTLOG_FILE_CORRUPT;
00117     }
00118 
00119     if (LogFile->Header.HeaderSize != sizeof(EVENTLOGHEADER) ||
00120         LogFile->Header.EndHeaderSize != sizeof(EVENTLOGHEADER))
00121     {
00122         DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
00123         return STATUS_EVENTLOG_FILE_CORRUPT;
00124     }
00125 
00126     if (LogFile->Header.Signature != LOGFILE_SIGNATURE)
00127     {
00128         DPRINT("EventLog: Invalid signature %x in %S.\n",
00129                LogFile->Header.Signature, LogFile->FileName);
00130         return STATUS_EVENTLOG_FILE_CORRUPT;
00131     }
00132 
00133     if (LogFile->Header.EndOffset > GetFileSize(LogFile->hFile, NULL) + 1)
00134     {
00135         DPRINT("EventLog: Invalid eof offset %x in %S.\n",
00136                LogFile->Header.EndOffset, LogFile->FileName);
00137         return STATUS_EVENTLOG_FILE_CORRUPT;
00138     }
00139 
00140     /* Set the read location to the oldest record */
00141     dwFilePointer = SetFilePointer(LogFile->hFile, LogFile->Header.StartOffset, NULL, FILE_BEGIN);
00142     if (dwFilePointer == INVALID_SET_FILE_POINTER)
00143     {
00144         DPRINT1("SetFilePointer failed! %d\n", GetLastError());
00145         return STATUS_EVENTLOG_FILE_CORRUPT;
00146     }
00147 
00148     for (;;)
00149     {
00150         dwFilePointer = SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT);
00151 
00152         if (dwFilePointer == INVALID_SET_FILE_POINTER)
00153         {
00154             DPRINT1("SetFilePointer failed! %d\n", GetLastError());
00155             return STATUS_EVENTLOG_FILE_CORRUPT;
00156         }
00157 
00158         /* If the EVENTLOGEOF info has been reached and the oldest record was not immediately after the Header */
00159         if ((dwFilePointer == LogFile->Header.EndOffset) && (LogFile->Header.StartOffset != sizeof(EVENTLOGHEADER)))
00160         {
00161             OvewrWrittenRecords = TRUE;
00162             /* The file has records that overwrote old ones so read them */
00163             dwFilePointer = SetFilePointer(LogFile->hFile, sizeof(EVENTLOGHEADER), NULL, FILE_BEGIN);
00164         }
00165 
00166         if (!ReadFile(LogFile->hFile,
00167                       &dwRecSize,
00168                       sizeof(dwRecSize),
00169                       &dwRead,
00170                       NULL))
00171         {
00172             DPRINT1("ReadFile failed! %d\n", GetLastError());
00173             return STATUS_EVENTLOG_FILE_CORRUPT;
00174         }
00175 
00176         if (dwRead != sizeof(dwRecSize))
00177             break;
00178 
00179         if (!ReadFile(LogFile->hFile,
00180                       &dwRecSign,
00181                       sizeof(dwRecSign),
00182                       &dwRead,
00183                       NULL))
00184         {
00185             DPRINT1("ReadFile() failed! %d\n", GetLastError());
00186             return STATUS_EVENTLOG_FILE_CORRUPT;
00187         }
00188 
00189         if (dwRead != sizeof(dwRecSize))
00190             break;
00191 
00192         if (dwRecSign != LOGFILE_SIGNATURE ||
00193             dwRecSize + dwFilePointer > GetFileSize(LogFile->hFile, NULL) + 1 ||
00194             dwRecSize < sizeof(EVENTLOGRECORD))
00195         {
00196             break;
00197         }
00198 
00199         if (SetFilePointer(LogFile->hFile,
00200                            -((LONG) sizeof(DWORD) * 2),
00201                            NULL,
00202                            FILE_CURRENT) == INVALID_SET_FILE_POINTER)
00203         {
00204             DPRINT1("SetFilePointer() failed! %d", GetLastError());
00205             return STATUS_EVENTLOG_FILE_CORRUPT;
00206         }
00207 
00208         RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
00209         if (RecBuf == NULL)
00210         {
00211             DPRINT1("Can't allocate heap!\n");
00212             return STATUS_NO_MEMORY;
00213         }
00214 
00215         if (!ReadFile(LogFile->hFile, RecBuf, dwRecSize, &dwRead, NULL))
00216         {
00217             DPRINT1("ReadFile() failed! %d\n", GetLastError());
00218             HeapFree(MyHeap, 0, RecBuf);
00219             return STATUS_EVENTLOG_FILE_CORRUPT;
00220         }
00221 
00222         if (dwRead != dwRecSize)
00223         {
00224             HeapFree(MyHeap, 0, RecBuf);
00225             break;
00226         }
00227 
00228         /* if OvewrWrittenRecords is TRUE and this record has already been read */
00229         if ((OvewrWrittenRecords == TRUE) && (RecBuf->RecordNumber == LogFile->Header.OldestRecordNumber))
00230         {
00231             HeapFree(MyHeap, 0, RecBuf);
00232             break;
00233         }
00234 
00235         pdwRecSize2 = (PDWORD) (((PBYTE) RecBuf) + dwRecSize - 4);
00236 
00237         if (*pdwRecSize2 != dwRecSize)
00238         {
00239             DPRINT1("Invalid RecordSizeEnd of record %d (%x) in %S\n",
00240                     dwRecordsNumber, *pdwRecSize2, LogFile->LogName);
00241             HeapFree(MyHeap, 0, RecBuf);
00242             break;
00243         }
00244 
00245         dwRecordsNumber++;
00246 
00247         if (!LogfAddOffsetInformation(LogFile,
00248                                       RecBuf->RecordNumber,
00249                                       dwFilePointer))
00250         {
00251             DPRINT1("LogfAddOffsetInformation() failed!\n");
00252             HeapFree(MyHeap, 0, RecBuf);
00253             return STATUS_EVENTLOG_FILE_CORRUPT;
00254         }
00255 
00256         HeapFree(MyHeap, 0, RecBuf);
00257     }
00258 
00259     LogFile->Header.CurrentRecordNumber = dwRecordsNumber + LogFile->Header.OldestRecordNumber;
00260     if (LogFile->Header.CurrentRecordNumber == 0)
00261         LogFile->Header.CurrentRecordNumber = 1;
00262 
00263     /* FIXME: Read MaxSize from registry for this LogFile.
00264        But for now limit EventLog size to just under 5K. */
00265     LogFile->Header.MaxSize = 5000;
00266 
00267     if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
00268         INVALID_SET_FILE_POINTER)
00269     {
00270         DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
00271         return STATUS_EVENTLOG_FILE_CORRUPT;
00272     }
00273 
00274     if (!WriteFile(LogFile->hFile,
00275                    &LogFile->Header,
00276                    sizeof(EVENTLOGHEADER),
00277                    &dwRead,
00278                    NULL))
00279     {
00280         DPRINT1("WriteFile failed! %d\n", GetLastError());
00281         return STATUS_EVENTLOG_FILE_CORRUPT;
00282     }
00283 
00284     if (!FlushFileBuffers(LogFile->hFile))
00285     {
00286         DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
00287         return STATUS_EVENTLOG_FILE_CORRUPT;
00288     }
00289 
00290     return STATUS_SUCCESS;
00291 }
00292 
00293 
00294 NTSTATUS
00295 LogfCreate(PLOGFILE *LogFile,
00296            WCHAR * LogName,
00297            PUNICODE_STRING FileName,
00298            BOOL Permanent,
00299            BOOL Backup)
00300 {
00301     OBJECT_ATTRIBUTES ObjectAttributes;
00302     IO_STATUS_BLOCK IoStatusBlock;
00303     PLOGFILE pLogFile;
00304     BOOL bCreateNew = FALSE;
00305     NTSTATUS Status = STATUS_SUCCESS;
00306 
00307     pLogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
00308     if (!pLogFile)
00309     {
00310         DPRINT1("Can't allocate heap!\n");
00311         return STATUS_NO_MEMORY;
00312     }
00313 
00314     InitializeObjectAttributes(&ObjectAttributes,
00315                                FileName,
00316                                OBJ_CASE_INSENSITIVE,
00317                                NULL,
00318                                NULL);
00319 
00320     Status = NtCreateFile(&pLogFile->hFile,
00321                           Backup ? (GENERIC_READ | SYNCHRONIZE) : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE),
00322                           &ObjectAttributes,
00323                           &IoStatusBlock,
00324                           NULL,
00325                           FILE_ATTRIBUTE_NORMAL,
00326                           FILE_SHARE_READ,
00327                           Backup ? FILE_OPEN : FILE_OPEN_IF,
00328                           FILE_SYNCHRONOUS_IO_NONALERT,
00329                           NULL,
00330                           0);
00331     if (!NT_SUCCESS(Status))
00332     {
00333         DPRINT1("Can't create file %wZ (Status: 0x%08lx)\n", FileName, Status);
00334         goto fail;
00335     }
00336 
00337     bCreateNew = (IoStatusBlock.Information == FILE_CREATED) ? TRUE: FALSE;
00338 
00339     pLogFile->LogName =
00340         (WCHAR *) HeapAlloc(MyHeap,
00341                             HEAP_ZERO_MEMORY,
00342                             (lstrlenW(LogName) + 1) * sizeof(WCHAR));
00343     if (pLogFile->LogName == NULL)
00344     {
00345         DPRINT1("Can't allocate heap\n");
00346         Status = STATUS_NO_MEMORY;
00347         goto fail;
00348     }
00349 
00350     lstrcpyW(pLogFile->LogName, LogName);
00351 
00352     pLogFile->FileName =
00353         (WCHAR *) HeapAlloc(MyHeap,
00354                             HEAP_ZERO_MEMORY,
00355                             (lstrlenW(FileName->Buffer) + 1) * sizeof(WCHAR));
00356     if (pLogFile->FileName == NULL)
00357     {
00358         DPRINT1("Can't allocate heap\n");
00359         Status = STATUS_NO_MEMORY;
00360         goto fail;
00361     }
00362 
00363     lstrcpyW(pLogFile->FileName, FileName->Buffer);
00364 
00365     pLogFile->OffsetInfo =
00366         (PEVENT_OFFSET_INFO) HeapAlloc(MyHeap,
00367                                        HEAP_ZERO_MEMORY,
00368                                        sizeof(EVENT_OFFSET_INFO) * 64);
00369     if (pLogFile->OffsetInfo == NULL)
00370     {
00371         DPRINT1("Can't allocate heap\n");
00372         Status = STATUS_NO_MEMORY;
00373         goto fail;
00374     }
00375 
00376     pLogFile->OffsetInfoSize = 64;
00377 
00378     pLogFile->Permanent = Permanent;
00379 
00380     if (bCreateNew)
00381         Status = LogfInitializeNew(pLogFile);
00382     else
00383         Status = LogfInitializeExisting(pLogFile);
00384 
00385     if (!NT_SUCCESS(Status))
00386         goto fail;
00387 
00388     RtlInitializeResource(&pLogFile->Lock);
00389 
00390     LogfListAddItem(pLogFile);
00391 
00392   fail:
00393     if (!NT_SUCCESS(Status))
00394     {
00395         if ((pLogFile->hFile != NULL) && (pLogFile->hFile != INVALID_HANDLE_VALUE))
00396             CloseHandle(pLogFile->hFile);
00397 
00398         if (pLogFile->OffsetInfo)
00399             HeapFree(MyHeap, 0, pLogFile->OffsetInfo);
00400 
00401         if (pLogFile->FileName)
00402             HeapFree(MyHeap, 0, pLogFile->FileName);
00403 
00404         if (pLogFile->LogName)
00405             HeapFree(MyHeap, 0, pLogFile->LogName);
00406 
00407         HeapFree(MyHeap, 0, pLogFile);
00408     }
00409     else
00410     {
00411         *LogFile = pLogFile;
00412     }
00413 
00414     return Status;
00415 }
00416 
00417 
00418 VOID
00419 LogfClose(PLOGFILE LogFile,
00420           BOOL ForceClose)
00421 {
00422     if (LogFile == NULL)
00423         return;
00424 
00425     if ((ForceClose == FALSE) &&
00426         (LogFile->Permanent == TRUE))
00427         return;
00428 
00429     RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
00430 
00431     FlushFileBuffers(LogFile->hFile);
00432     CloseHandle(LogFile->hFile);
00433     LogfListRemoveItem(LogFile);
00434 
00435     RtlDeleteResource(&LogFile->Lock);
00436 
00437     HeapFree(MyHeap, 0, LogFile->LogName);
00438     HeapFree(MyHeap, 0, LogFile->FileName);
00439     HeapFree(MyHeap, 0, LogFile->OffsetInfo);
00440     HeapFree(MyHeap, 0, LogFile);
00441 
00442     return;
00443 }
00444 
00445 VOID LogfCloseAll(VOID)
00446 {
00447     while (!IsListEmpty(&LogFileListHead))
00448     {
00449         LogfClose(LogfListHead(), TRUE);
00450     }
00451 
00452     DeleteCriticalSection(&LogFileListCs);
00453 }
00454 
00455 VOID LogfListInitialize(VOID)
00456 {
00457     InitializeCriticalSection(&LogFileListCs);
00458     InitializeListHead(&LogFileListHead);
00459 }
00460 
00461 PLOGFILE LogfListHead(VOID)
00462 {
00463     return CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry);
00464 }
00465 
00466 PLOGFILE LogfListItemByName(WCHAR * Name)
00467 {
00468     PLIST_ENTRY CurrentEntry;
00469     PLOGFILE Result = NULL;
00470 
00471     EnterCriticalSection(&LogFileListCs);
00472 
00473     CurrentEntry = LogFileListHead.Flink;
00474     while (CurrentEntry != &LogFileListHead)
00475     {
00476         PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
00477                                           LOGFILE,
00478                                           ListEntry);
00479 
00480         if (Item->LogName && !lstrcmpi(Item->LogName, Name))
00481         {
00482             Result = Item;
00483             break;
00484         }
00485 
00486         CurrentEntry = CurrentEntry->Flink;
00487     }
00488 
00489     LeaveCriticalSection(&LogFileListCs);
00490     return Result;
00491 }
00492 
00493 /* Index starting from 1 */
00494 INT LogfListItemIndexByName(WCHAR * Name)
00495 {
00496     PLIST_ENTRY CurrentEntry;
00497     INT Result = 0;
00498     INT i = 1;
00499 
00500     EnterCriticalSection(&LogFileListCs);
00501 
00502     CurrentEntry = LogFileListHead.Flink;
00503     while (CurrentEntry != &LogFileListHead)
00504     {
00505         PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
00506                                           LOGFILE,
00507                                           ListEntry);
00508 
00509         if (Item->LogName && !lstrcmpi(Item->LogName, Name))
00510         {
00511             Result = i;
00512             break;
00513         }
00514 
00515         CurrentEntry = CurrentEntry->Flink;
00516         i++;
00517     }
00518 
00519     LeaveCriticalSection(&LogFileListCs);
00520     return Result;
00521 }
00522 
00523 /* Index starting from 1 */
00524 PLOGFILE LogfListItemByIndex(INT Index)
00525 {
00526     PLIST_ENTRY CurrentEntry;
00527     PLOGFILE Result = NULL;
00528     INT i = 1;
00529 
00530     EnterCriticalSection(&LogFileListCs);
00531 
00532     CurrentEntry = LogFileListHead.Flink;
00533     while (CurrentEntry != &LogFileListHead)
00534     {
00535         if (i == Index)
00536         {
00537             Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
00538             break;
00539         }
00540 
00541         CurrentEntry = CurrentEntry->Flink;
00542         i++;
00543     }
00544 
00545     LeaveCriticalSection(&LogFileListCs);
00546     return Result;
00547 }
00548 
00549 INT LogfListItemCount(VOID)
00550 {
00551     PLIST_ENTRY CurrentEntry;
00552     INT i = 0;
00553 
00554     EnterCriticalSection(&LogFileListCs);
00555 
00556     CurrentEntry = LogFileListHead.Flink;
00557     while (CurrentEntry != &LogFileListHead)
00558     {
00559         CurrentEntry = CurrentEntry->Flink;
00560         i++;
00561     }
00562 
00563     LeaveCriticalSection(&LogFileListCs);
00564     return i;
00565 }
00566 
00567 VOID LogfListAddItem(PLOGFILE Item)
00568 {
00569     EnterCriticalSection(&LogFileListCs);
00570     InsertTailList(&LogFileListHead, &Item->ListEntry);
00571     LeaveCriticalSection(&LogFileListCs);
00572 }
00573 
00574 VOID LogfListRemoveItem(PLOGFILE Item)
00575 {
00576     EnterCriticalSection(&LogFileListCs);
00577     RemoveEntryList(&Item->ListEntry);
00578     LeaveCriticalSection(&LogFileListCs);
00579 }
00580 
00581 static BOOL
00582 ReadAnsiLogEntry(HANDLE hFile,
00583                  LPVOID lpBuffer,
00584                  DWORD nNumberOfBytesToRead,
00585                  LPDWORD lpNumberOfBytesRead)
00586 {
00587     PEVENTLOGRECORD Dst;
00588     PEVENTLOGRECORD Src;
00589     ANSI_STRING StringA;
00590     UNICODE_STRING StringW;
00591     LPWSTR SrcPtr;
00592     LPSTR DstPtr;
00593     LPWSTR SrcString;
00594     LPSTR DstString;
00595     LPVOID lpUnicodeBuffer = NULL;
00596     DWORD dwRead = 0;
00597     DWORD i;
00598     DWORD dwPadding;
00599     DWORD dwEntryLength;
00600     PDWORD pLength;
00601     NTSTATUS Status;
00602     BOOL ret = TRUE;
00603 
00604     *lpNumberOfBytesRead = 0;
00605 
00606     lpUnicodeBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nNumberOfBytesToRead);
00607     if (lpUnicodeBuffer == NULL)
00608     {
00609         DPRINT1("Alloc failed!\n");
00610         return FALSE;
00611     }
00612 
00613     if (!ReadFile(hFile, lpUnicodeBuffer, nNumberOfBytesToRead, &dwRead, NULL))
00614     {
00615         DPRINT1("Read failed!\n");
00616         ret = FALSE;
00617         goto done;
00618     }
00619 
00620     Dst = (PEVENTLOGRECORD)lpBuffer;
00621     Src = (PEVENTLOGRECORD)lpUnicodeBuffer;
00622 
00623     Dst->TimeGenerated = Src->TimeGenerated;
00624     Dst->Reserved = Src->Reserved;
00625     Dst->RecordNumber = Src->RecordNumber;
00626     Dst->TimeWritten = Src->TimeWritten;
00627     Dst->EventID = Src->EventID;
00628     Dst->EventType = Src->EventType;
00629     Dst->EventCategory = Src->EventCategory;
00630     Dst->NumStrings = Src->NumStrings;
00631     Dst->UserSidLength = Src->UserSidLength;
00632     Dst->DataLength = Src->DataLength;
00633 
00634     SrcPtr = (LPWSTR)((DWORD_PTR)Src + sizeof(EVENTLOGRECORD));
00635     DstPtr = (LPSTR)((DWORD_PTR)Dst + sizeof(EVENTLOGRECORD));
00636 
00637     /* Convert the module name */
00638     RtlInitUnicodeString(&StringW, SrcPtr);
00639     Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
00640     if (NT_SUCCESS(Status))
00641     {
00642         RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
00643 
00644         DstPtr = (PVOID)((DWORD_PTR)DstPtr + StringA.MaximumLength);
00645 
00646         RtlFreeAnsiString(&StringA);
00647     }
00648 
00649     /* Convert the computer name */
00650     if (NT_SUCCESS(Status))
00651     {
00652         SrcPtr = (PWSTR)((DWORD_PTR)SrcPtr + StringW.MaximumLength);
00653 
00654         RtlInitUnicodeString(&StringW, SrcPtr);
00655         Status = RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
00656         if (NT_SUCCESS(Status))
00657         {
00658             RtlCopyMemory(DstPtr, StringA.Buffer, StringA.MaximumLength);
00659 
00660             DstPtr = (PVOID)((DWORD_PTR)DstPtr + StringA.MaximumLength);
00661 
00662             RtlFreeAnsiString(&StringA);
00663         }
00664     }
00665 
00666     /* Add the padding and the User SID*/
00667     if (NT_SUCCESS(Status))
00668     {
00669         dwPadding = sizeof(DWORD) - (((DWORD_PTR)DstPtr - (DWORD_PTR)Dst) % sizeof(DWORD));
00670         RtlZeroMemory(DstPtr, dwPadding);
00671 
00672         DstPtr = (LPSTR)((DWORD_PTR)DstPtr + dwPadding);
00673         RtlCopyMemory(DstPtr,
00674                       (PVOID)((DWORD_PTR)Src + Src->UserSidOffset),
00675                       Src->UserSidLength);
00676 
00677         Dst->UserSidOffset = (DWORD)((DWORD_PTR)DstPtr - (DWORD_PTR)Dst);
00678     }
00679 
00680 
00681     /* Convert the strings */
00682     if (NT_SUCCESS(Status))
00683     {
00684         DstPtr = (PVOID)((DWORD_PTR)DstPtr + Src->UserSidLength);
00685 
00686         SrcString = (LPWSTR)((DWORD_PTR)Src + (DWORD)Src->StringOffset);
00687         DstString = (LPSTR)DstPtr;
00688 
00689         for (i = 0; i < Dst->NumStrings; i++)
00690         {
00691             RtlInitUnicodeString(&StringW, SrcString);
00692 
00693             RtlUnicodeStringToAnsiString(&StringA, &StringW, TRUE);
00694 
00695             RtlCopyMemory(DstString, StringA.Buffer, StringA.MaximumLength);
00696 
00697             SrcString = (LPWSTR)((DWORD_PTR)SrcString +
00698                                  (DWORD)StringW.MaximumLength);
00699 
00700             DstString = (LPSTR)((DWORD_PTR)DstString +
00701                                 (DWORD)StringA.MaximumLength);
00702 
00703             RtlFreeAnsiString(&StringA);
00704         }
00705 
00706         Dst->StringOffset = (DWORD)((DWORD_PTR)DstPtr - (DWORD_PTR)Dst);
00707 
00708 
00709         /* Copy the binary data */
00710         DstPtr = (PVOID)DstString;
00711         Dst->DataOffset = (DWORD_PTR)DstPtr - (DWORD_PTR)Dst;
00712 
00713         RtlCopyMemory(DstPtr, (PVOID)((DWORD_PTR)Src + Src->DataOffset), Src->DataLength);
00714 
00715         /* Add the padding */
00716         DstPtr = (PVOID)((DWORD_PTR)DstPtr + Src->DataLength);
00717         dwPadding = sizeof(DWORD) - (((DWORD_PTR)DstPtr-(DWORD_PTR)Dst) % sizeof(DWORD));
00718         RtlZeroMemory(DstPtr, dwPadding);
00719 
00720         dwEntryLength = (DWORD)((DWORD_PTR)DstPtr + dwPadding + sizeof(DWORD) - (DWORD_PTR)Dst);
00721 
00722         /* Set the entry length at the end of the entry*/
00723         pLength = (PDWORD)((DWORD_PTR)DstPtr + dwPadding);
00724         *pLength = dwEntryLength;
00725         Dst->Length = dwEntryLength;
00726 
00727         *lpNumberOfBytesRead = dwEntryLength;
00728     }
00729 
00730 done:
00731     if (lpUnicodeBuffer != NULL)
00732         HeapFree(GetProcessHeap(), 0, lpUnicodeBuffer);
00733 
00734     return ret;
00735 }
00736 
00737 
00738 DWORD LogfReadEvent(PLOGFILE LogFile,
00739                    DWORD Flags,
00740                    DWORD * RecordNumber,
00741                    DWORD BufSize,
00742                    PBYTE Buffer,
00743                    DWORD * BytesRead,
00744                    DWORD * BytesNeeded,
00745                    BOOL Ansi)
00746 {
00747     DWORD dwOffset, dwRead, dwRecSize;
00748     DWORD dwBufferUsage = 0, dwRecNum;
00749 
00750     if (Flags & EVENTLOG_FORWARDS_READ && Flags & EVENTLOG_BACKWARDS_READ)
00751         return ERROR_INVALID_PARAMETER;
00752 
00753     if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ))
00754         return ERROR_INVALID_PARAMETER;
00755 
00756     if (!Buffer || !BytesRead || !BytesNeeded)
00757         return ERROR_INVALID_PARAMETER;
00758 
00759     if ((*RecordNumber==0) && !(EVENTLOG_SEQUENTIAL_READ))
00760     {
00761         return ERROR_INVALID_PARAMETER;
00762     }
00763 
00764     dwRecNum = *RecordNumber;
00765 
00766     RtlAcquireResourceShared(&LogFile->Lock, TRUE);
00767 
00768     *BytesRead = 0;
00769     *BytesNeeded = 0;
00770 
00771     dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
00772 
00773     if (!dwOffset)
00774     {
00775         RtlReleaseResource(&LogFile->Lock);
00776         return ERROR_HANDLE_EOF;
00777     }
00778 
00779     if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
00780         INVALID_SET_FILE_POINTER)
00781     {
00782         DPRINT1("SetFilePointer() failed!\n");
00783         goto Done;
00784     }
00785 
00786     if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL))
00787     {
00788         DPRINT1("ReadFile() failed!\n");
00789         goto Done;
00790     }
00791 
00792     if (dwRecSize > BufSize)
00793     {
00794         *BytesNeeded = dwRecSize;
00795         RtlReleaseResource(&LogFile->Lock);
00796         return ERROR_INSUFFICIENT_BUFFER;
00797     }
00798 
00799     if (SetFilePointer(LogFile->hFile,
00800                        -((LONG) sizeof(DWORD)),
00801                        NULL,
00802                        FILE_CURRENT) == INVALID_SET_FILE_POINTER)
00803     {
00804         DPRINT1("SetFilePointer() failed!\n");
00805         goto Done;
00806     }
00807 
00808     if (Ansi == TRUE)
00809     {
00810         if (!ReadAnsiLogEntry(LogFile->hFile, Buffer, dwRecSize, &dwRead))
00811         {
00812             DPRINT1("ReadAnsiLogEntry() failed!\n");
00813             goto Done;
00814         }
00815     }
00816     else
00817     {
00818         if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL))
00819         {
00820             DPRINT1("ReadFile() failed!\n");
00821             goto Done;
00822         }
00823     }
00824 
00825     dwBufferUsage += dwRead;
00826 
00827     while (dwBufferUsage <= BufSize)
00828     {
00829         if (Flags & EVENTLOG_FORWARDS_READ)
00830             dwRecNum++;
00831         else
00832             dwRecNum--;
00833 
00834         dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
00835         if (!dwOffset)
00836             break;
00837 
00838         if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
00839             INVALID_SET_FILE_POINTER)
00840         {
00841             DPRINT1("SetFilePointer() failed!\n");
00842             goto Done;
00843         }
00844 
00845         if (!ReadFile(LogFile->hFile,
00846                       &dwRecSize,
00847                       sizeof(DWORD),
00848                       &dwRead,
00849                       NULL))
00850         {
00851             DPRINT1("ReadFile() failed!\n");
00852             goto Done;
00853         }
00854 
00855         if (dwBufferUsage + dwRecSize > BufSize)
00856             break;
00857 
00858         if (SetFilePointer(LogFile->hFile,
00859                            -((LONG) sizeof(DWORD)),
00860                            NULL,
00861                            FILE_CURRENT) == INVALID_SET_FILE_POINTER)
00862         {
00863             DPRINT1("SetFilePointer() failed!\n");
00864             goto Done;
00865         }
00866 
00867         if (Ansi == TRUE)
00868         {
00869             if (!ReadAnsiLogEntry(LogFile->hFile,
00870                                   Buffer + dwBufferUsage,
00871                                   dwRecSize,
00872                                   &dwRead))
00873             {
00874                 DPRINT1("ReadAnsiLogEntry() failed!\n");
00875                 goto Done;
00876             }
00877         }
00878         else
00879         {
00880             if (!ReadFile(LogFile->hFile,
00881                           Buffer + dwBufferUsage,
00882                           dwRecSize,
00883                           &dwRead,
00884                           NULL))
00885             {
00886                 DPRINT1("ReadFile() failed!\n");
00887                 goto Done;
00888             }
00889         }
00890 
00891         dwBufferUsage += dwRead;
00892     }
00893 
00894     *BytesRead = dwBufferUsage;
00895     * RecordNumber = dwRecNum;
00896     RtlReleaseResource(&LogFile->Lock);
00897     return ERROR_SUCCESS;
00898 
00899 Done:
00900     DPRINT1("LogfReadEvent failed with %x\n",GetLastError());
00901     RtlReleaseResource(&LogFile->Lock);
00902     return GetLastError();
00903 }
00904 
00905 BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
00906 {
00907     DWORD dwWritten;
00908     DWORD dwRead;
00909     SYSTEMTIME st;
00910     EVENTLOGEOF EofRec;
00911     PEVENTLOGRECORD RecBuf;
00912     LARGE_INTEGER logFileSize;
00913     ULONG RecOffSet;
00914     ULONG WriteOffSet;
00915 
00916     if (!Buffer)
00917         return FALSE;
00918 
00919     GetSystemTime(&st);
00920     SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
00921 
00922     RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
00923 
00924     if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
00925     {
00926         RtlReleaseResource(&LogFile->Lock);
00927         return FALSE;
00928     }
00929 
00930     /* If the size of the file is over MaxSize */
00931     if ((logFileSize.QuadPart + BufSize)> LogFile->Header.MaxSize)
00932     {
00933         ULONG OverWriteLength = 0;
00934         WriteOffSet = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
00935         RecBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(EVENTLOGRECORD));
00936         /* Determine how many records need to be overwritten */
00937         while (TRUE)
00938         {
00939             DPRINT("EventLogFile has reached maximume size\n");
00940 
00941             if (!RecBuf)
00942             {
00943                 DPRINT1("Failed to allocate buffer for OldestRecord!\n");
00944                 HeapFree(GetProcessHeap(), 0, RecBuf);
00945                 RtlReleaseResource(&LogFile->Lock);
00946                 return FALSE;
00947             }
00948 
00949             /* Get the oldest record data */
00950             RecOffSet = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
00951 
00952             if (SetFilePointer(LogFile->hFile,
00953                                RecOffSet,
00954                                NULL,
00955                                FILE_BEGIN) == INVALID_SET_FILE_POINTER)
00956             {
00957                 DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
00958                 HeapFree(GetProcessHeap(), 0, RecBuf);
00959                 RtlReleaseResource(&LogFile->Lock);
00960                 return FALSE;
00961             }
00962 
00963             if (!ReadFile(LogFile->hFile, RecBuf, sizeof(EVENTLOGRECORD), &dwRead, NULL))
00964             {
00965                 DPRINT1("ReadFile() failed!\n");
00966                 HeapFree(GetProcessHeap(), 0, RecBuf);
00967                 RtlReleaseResource(&LogFile->Lock);
00968                 return FALSE;
00969             }
00970 
00971             if (RecBuf->Reserved != LOGFILE_SIGNATURE)
00972             {
00973                 DPRINT1("LogFile corrupt!\n");
00974                 RtlReleaseResource(&LogFile->Lock);
00975                 return FALSE;
00976             }
00977 
00978             LogfDeleteOffsetInformation(LogFile,LogFile->Header.OldestRecordNumber);
00979 
00980             LogFile->Header.OldestRecordNumber++;
00981 
00982             OverWriteLength += RecBuf->Length;
00983             /* Check the size of the record as the record adding may be larger */
00984             if (OverWriteLength >= BufSize)
00985             {
00986                 DPRINT("Record will fit. Lenght %d, BufSize %d\n", OverWriteLength, BufSize);
00987                 LogFile->Header.StartOffset = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
00988                 break;
00989             }
00990         }
00991         HeapFree(GetProcessHeap(), 0, RecBuf);
00992     }
00993     else
00994         WriteOffSet = LogFile->Header.EndOffset;
00995 
00996     if (SetFilePointer(LogFile->hFile,
00997                        WriteOffSet,
00998                        NULL,
00999                        FILE_BEGIN) == INVALID_SET_FILE_POINTER)
01000     {
01001         DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
01002         RtlReleaseResource(&LogFile->Lock);
01003         return FALSE;
01004     }
01005 
01006     if (!WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL))
01007     {
01008         DPRINT1("WriteFile() failed! %d\n", GetLastError());
01009         RtlReleaseResource(&LogFile->Lock);
01010         return FALSE;
01011     }
01012 
01013     if (!LogfAddOffsetInformation(LogFile,
01014                                   LogFile->Header.CurrentRecordNumber,
01015                                   WriteOffSet))
01016     {
01017         RtlReleaseResource(&LogFile->Lock);
01018         return FALSE;
01019     }
01020 
01021     LogFile->Header.CurrentRecordNumber++;
01022 
01023     if (WriteOffSet == LogFile->Header.EndOffset)
01024     {
01025         LogFile->Header.EndOffset += dwWritten;
01026     }
01027     if (SetFilePointer(LogFile->hFile,
01028                        LogFile->Header.EndOffset,
01029                        NULL,
01030                        FILE_BEGIN) == INVALID_SET_FILE_POINTER)
01031     {
01032         DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
01033         RtlReleaseResource(&LogFile->Lock);
01034         return FALSE;
01035     }
01036 
01037     EofRec.Ones = 0x11111111;
01038     EofRec.Twos = 0x22222222;
01039     EofRec.Threes = 0x33333333;
01040     EofRec.Fours = 0x44444444;
01041     EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
01042     EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
01043     EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
01044     EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
01045     EofRec.BeginRecord = LogFile->Header.StartOffset;
01046     EofRec.EndRecord = LogFile->Header.EndOffset;
01047 
01048     if (!WriteFile(LogFile->hFile,
01049                    &EofRec,
01050                    sizeof(EVENTLOGEOF),
01051                    &dwWritten,
01052                    NULL))
01053     {
01054         DPRINT1("WriteFile() failed! %d\n", GetLastError());
01055         RtlReleaseResource(&LogFile->Lock);
01056         return FALSE;
01057     }
01058 
01059     if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
01060         INVALID_SET_FILE_POINTER)
01061     {
01062         DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
01063         RtlReleaseResource(&LogFile->Lock);
01064         return FALSE;
01065     }
01066 
01067     if (!WriteFile(LogFile->hFile,
01068                    &LogFile->Header,
01069                    sizeof(EVENTLOGHEADER),
01070                    &dwWritten,
01071                    NULL))
01072     {
01073         DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
01074         RtlReleaseResource(&LogFile->Lock);
01075         return FALSE;
01076     }
01077 
01078     if (!FlushFileBuffers(LogFile->hFile))
01079     {
01080         DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
01081         RtlReleaseResource(&LogFile->Lock);
01082         return FALSE;
01083     }
01084 
01085     RtlReleaseResource(&LogFile->Lock);
01086     return TRUE;
01087 }
01088 
01089 
01090 NTSTATUS
01091 LogfClearFile(PLOGFILE LogFile,
01092               PUNICODE_STRING BackupFileName)
01093 {
01094     RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
01095 
01096     if (BackupFileName->Length > 0)
01097     {
01098         /* FIXME: Write a backup file */
01099     }
01100 
01101     LogfInitializeNew(LogFile);
01102 
01103     RtlReleaseResource(&LogFile->Lock);
01104 
01105     return STATUS_SUCCESS;
01106 }
01107 
01108 
01109 NTSTATUS
01110 LogfBackupFile(PLOGFILE LogFile,
01111                PUNICODE_STRING BackupFileName)
01112 {
01113     OBJECT_ATTRIBUTES ObjectAttributes;
01114     IO_STATUS_BLOCK IoStatusBlock;
01115     EVENTLOGHEADER Header;
01116     EVENTLOGEOF EofRec;
01117     HANDLE FileHandle = NULL;
01118     ULONG i;
01119     LARGE_INTEGER FileOffset;
01120     NTSTATUS Status;
01121     PUCHAR Buffer = NULL;
01122 
01123     DWORD dwOffset, dwRead, dwRecSize;
01124 
01125     DPRINT("LogfBackupFile(%p, %wZ)\n", LogFile, BackupFileName);
01126 
01127     /* Lock the log file shared */
01128     RtlAcquireResourceShared(&LogFile->Lock, TRUE);
01129 
01130     InitializeObjectAttributes(&ObjectAttributes,
01131                                BackupFileName,
01132                                OBJ_CASE_INSENSITIVE,
01133                                NULL,
01134                                NULL);
01135 
01136     Status = NtCreateFile(&FileHandle,
01137                           GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
01138                           &ObjectAttributes,
01139                           &IoStatusBlock,
01140                           NULL,
01141                           FILE_ATTRIBUTE_NORMAL,
01142                           FILE_SHARE_READ,
01143                           FILE_CREATE,
01144                           FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
01145                           NULL,
01146                           0);
01147     if (!NT_SUCCESS(Status))
01148     {
01149         DPRINT("Can't create backup file %wZ (Status: 0x%08lx)\n", BackupFileName, Status);
01150         goto Done;
01151     }
01152 
01153     /* Initialize the (dirty) log file header */
01154     Header.HeaderSize = sizeof(EVENTLOGHEADER);
01155     Header.Signature = LOGFILE_SIGNATURE;
01156     Header.MajorVersion = MAJORVER;
01157     Header.MinorVersion = MINORVER;
01158     Header.StartOffset = sizeof(EVENTLOGHEADER);
01159     Header.EndOffset = sizeof(EVENTLOGHEADER);
01160     Header.CurrentRecordNumber = 1;
01161     Header.OldestRecordNumber = 1;
01162     Header.MaxSize = 0;
01163     Header.Flags = ELF_LOGFILE_HEADER_DIRTY;
01164     Header.Retention = LogFile->Header.Retention;
01165     Header.EndHeaderSize = sizeof(EVENTLOGHEADER);
01166 
01167     /* Write the (dirty) log file header */
01168     Status = NtWriteFile(FileHandle,
01169                          NULL,
01170                          NULL,
01171                          NULL,
01172                          &IoStatusBlock,
01173                          &Header,
01174                          sizeof(EVENTLOGHEADER),
01175                          NULL,
01176                          NULL);
01177     if (!NT_SUCCESS(Status))
01178     {
01179         DPRINT1("Failed to write the log file header (Status: 0x%08lx)\n", Status);
01180         goto Done;
01181     }
01182 
01183     for (i = LogFile->Header.OldestRecordNumber; i < LogFile->Header.CurrentRecordNumber; i++)
01184     {
01185         dwOffset = LogfOffsetByNumber(LogFile, i);
01186         if (dwOffset == 0)
01187             break;
01188 
01189         if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
01190         {
01191             DPRINT1("SetFilePointer() failed!\n");
01192             goto Done;
01193         }
01194 
01195         if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL))
01196         {
01197             DPRINT1("ReadFile() failed!\n");
01198             goto Done;
01199         }
01200 
01201         if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
01202         {
01203             DPRINT1("SetFilePointer() failed!\n");
01204             goto Done;
01205         }
01206 
01207         Buffer = HeapAlloc(MyHeap, 0, dwRecSize);
01208         if (Buffer == NULL)
01209         {
01210             DPRINT1("HeapAlloc() failed!\n");
01211             goto Done;
01212         }
01213 
01214         if (!ReadFile(LogFile->hFile, &Buffer, dwRecSize, &dwRead, NULL))
01215         {
01216             DPRINT1("ReadFile() failed!\n");
01217             goto Done;
01218         }
01219 
01220         /* Write the event record */
01221         Status = NtWriteFile(FileHandle,
01222                              NULL,
01223                              NULL,
01224                              NULL,
01225                              &IoStatusBlock,
01226                              Buffer,
01227                              dwRecSize,
01228                              NULL,
01229                              NULL);
01230         if (!NT_SUCCESS(Status))
01231         {
01232             DPRINT1("NtWriteFile() failed!\n");
01233             goto Done;
01234         }
01235 
01236         /* Update the header information */
01237         Header.EndOffset += dwRecSize;
01238 
01239         /* Free the buffer */
01240         HeapFree(MyHeap, 0, Buffer);
01241         Buffer = NULL;
01242     }
01243 
01244     /* Initialize the EOF record */
01245     EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
01246     EofRec.Ones = 0x11111111;
01247     EofRec.Twos = 0x22222222;
01248     EofRec.Threes = 0x33333333;
01249     EofRec.Fours = 0x44444444;
01250     EofRec.BeginRecord = sizeof(EVENTLOGHEADER);
01251     EofRec.EndRecord = Header.EndOffset;
01252     EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
01253     EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
01254     EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
01255 
01256     /* Write the EOF record */
01257     Status = NtWriteFile(FileHandle,
01258                          NULL,
01259                          NULL,
01260                          NULL,
01261                          &IoStatusBlock,
01262                          &EofRec,
01263                          sizeof(EVENTLOGEOF),
01264                          NULL,
01265                          NULL);
01266     if (!NT_SUCCESS(Status))
01267     {
01268         DPRINT1("NtWriteFile() failed!\n");
01269         goto Done;
01270     }
01271 
01272     /* Update the header information */
01273     Header.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
01274     Header.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
01275     Header.MaxSize = Header.EndOffset + sizeof(EVENTLOGEOF);
01276     Header.Flags = 0;
01277 
01278     /* Write the (clean) log file header */
01279     FileOffset.QuadPart = 0;
01280     Status = NtWriteFile(FileHandle,
01281                          NULL,
01282                          NULL,
01283                          NULL,
01284                          &IoStatusBlock,
01285                          &Header,
01286                          sizeof(EVENTLOGHEADER),
01287                          &FileOffset,
01288                          NULL);
01289     if (!NT_SUCCESS(Status))
01290     {
01291         DPRINT1("NtWriteFile() failed!\n");
01292     }
01293 
01294 Done:
01295     /* Free the buffer */
01296     if (Buffer != NULL)
01297         HeapFree(MyHeap, 0, Buffer);
01298 
01299     /* Close the backup file */
01300     if (FileHandle != NULL)
01301         NtClose(FileHandle);
01302 
01303     /* Unlock the log file */
01304     RtlReleaseResource(&LogFile->Lock);
01305 
01306     return Status;
01307 }
01308 
01309 
01310 /* Returns 0 if nothing found. */
01311 ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
01312 {
01313     DWORD i;
01314 
01315     for (i = 0; i < LogFile->OffsetInfoNext; i++)
01316     {
01317         if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
01318             return LogFile->OffsetInfo[i].EventOffset;
01319     }
01320     return 0;
01321 }
01322 
01323 DWORD LogfGetOldestRecord(PLOGFILE LogFile)
01324 {
01325     return LogFile->Header.OldestRecordNumber;
01326 }
01327 
01328 DWORD LogfGetCurrentRecord(PLOGFILE LogFile)
01329 {
01330     return LogFile->Header.CurrentRecordNumber;
01331 }
01332 
01333 BOOL LogfDeleteOffsetInformation(PLOGFILE LogFile, ULONG ulNumber)
01334 {
01335     DWORD i;
01336 
01337     if (ulNumber != LogFile->OffsetInfo[0].EventNumber)
01338     {
01339         return FALSE;
01340     }
01341 
01342     for (i = 0; i < LogFile->OffsetInfoNext - 1; i++)
01343     {
01344         LogFile->OffsetInfo[i].EventNumber = LogFile->OffsetInfo[i + 1].EventNumber;
01345         LogFile->OffsetInfo[i].EventOffset = LogFile->OffsetInfo[i + 1].EventOffset;
01346     }
01347     LogFile->OffsetInfoNext--;
01348     return TRUE;
01349 }
01350 
01351 BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
01352 {
01353     LPVOID NewOffsetInfo;
01354 
01355     if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
01356     {
01357         NewOffsetInfo = HeapReAlloc(MyHeap,
01358                                     HEAP_ZERO_MEMORY,
01359                                     LogFile->OffsetInfo,
01360                                     (LogFile->OffsetInfoSize + 64) *
01361                                         sizeof(EVENT_OFFSET_INFO));
01362 
01363         if (!NewOffsetInfo)
01364         {
01365             DPRINT1("Can't reallocate heap.\n");
01366             return FALSE;
01367         }
01368 
01369         LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) NewOffsetInfo;
01370         LogFile->OffsetInfoSize += 64;
01371     }
01372 
01373     LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
01374     LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
01375     LogFile->OffsetInfoNext++;
01376 
01377     return TRUE;
01378 }
01379 
01380 PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
01381                                  DWORD   dwRecordNumber,
01382                                  WORD    wType,
01383                                  WORD    wCategory,
01384                                  DWORD   dwEventId,
01385                                  LPCWSTR SourceName,
01386                                  LPCWSTR ComputerName,
01387                                  DWORD   dwSidLength,
01388                                  PSID    lpUserSid,
01389                                  WORD    wNumStrings,
01390                                  WCHAR   * lpStrings,
01391                                  DWORD   dwDataSize,
01392                                  LPVOID  lpRawData)
01393 {
01394     DWORD dwRecSize;
01395     PEVENTLOGRECORD pRec;
01396     SYSTEMTIME SysTime;
01397     WCHAR *str;
01398     UINT i, pos;
01399     PBYTE Buffer;
01400 
01401     dwRecSize =
01402         sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
01403                                   lstrlenW(SourceName) + 2) * sizeof(WCHAR);
01404 
01405     if (dwRecSize % 4 != 0)
01406         dwRecSize += 4 - (dwRecSize % 4);
01407 
01408     dwRecSize += dwSidLength;
01409 
01410     for (i = 0, str = lpStrings; i < wNumStrings; i++)
01411     {
01412         dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
01413         str += lstrlenW(str) + 1;
01414     }
01415 
01416     dwRecSize += dwDataSize;
01417     if (dwRecSize % 4 != 0)
01418         dwRecSize += 4 - (dwRecSize % 4);
01419 
01420     dwRecSize += 4;
01421 
01422     Buffer = HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);
01423 
01424     if (!Buffer)
01425     {
01426         DPRINT1("Can't allocate heap!\n");
01427         return NULL;
01428     }
01429 
01430     pRec = (PEVENTLOGRECORD) Buffer;
01431     pRec->Length = dwRecSize;
01432     pRec->Reserved = LOGFILE_SIGNATURE;
01433     pRec->RecordNumber = dwRecordNumber;
01434 
01435     GetSystemTime(&SysTime);
01436     SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
01437     SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);
01438 
01439     pRec->EventID = dwEventId;
01440     pRec->EventType = wType;
01441     pRec->EventCategory = wCategory;
01442 
01443     pos = sizeof(EVENTLOGRECORD);
01444 
01445     lstrcpyW((WCHAR *) (Buffer + pos), SourceName);
01446     pos += (lstrlenW(SourceName) + 1) * sizeof(WCHAR);
01447     lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
01448     pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);
01449 
01450     pRec->UserSidOffset = pos;
01451 
01452     if (pos % 4 != 0)
01453         pos += 4 - (pos % 4);
01454 
01455     if (dwSidLength)
01456     {
01457         CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
01458         pRec->UserSidLength = dwSidLength;
01459         pRec->UserSidOffset = pos;
01460         pos += dwSidLength;
01461     }
01462 
01463     pRec->StringOffset = pos;
01464     for (i = 0, str = lpStrings; i < wNumStrings; i++)
01465     {
01466         lstrcpyW((WCHAR *) (Buffer + pos), str);
01467         pos += (lstrlenW(str) + 1) * sizeof(WCHAR);
01468         str += lstrlenW(str) + 1;
01469     }
01470     pRec->NumStrings = wNumStrings;
01471 
01472     pRec->DataOffset = pos;
01473     if (dwDataSize)
01474     {
01475         pRec->DataLength = dwDataSize;
01476         CopyMemory(Buffer + pos, lpRawData, dwDataSize);
01477         pos += dwDataSize;
01478     }
01479 
01480     if (pos % 4 != 0)
01481         pos += 4 - (pos % 4);
01482 
01483     *((PDWORD) (Buffer + pos)) = dwRecSize;
01484 
01485     *lpRecSize = dwRecSize;
01486     return Buffer;
01487 }
01488 
01489 
01490 VOID
01491 LogfReportEvent(WORD wType,
01492                 WORD wCategory,
01493                 DWORD dwEventId,
01494                 WORD wNumStrings,
01495                 WCHAR *lpStrings,
01496                 DWORD dwDataSize,
01497                 LPVOID lpRawData)
01498 {
01499     WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
01500     DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
01501     PEVENTSOURCE pEventSource = NULL;
01502     PBYTE logBuffer;
01503     DWORD lastRec;
01504     DWORD recSize;
01505     DWORD dwError;
01506 
01507     if (!GetComputerNameW(szComputerName, &dwComputerNameLength))
01508     {
01509         szComputerName[0] = 0;
01510     }
01511 
01512     pEventSource = GetEventSourceByName(L"EventLog");
01513     if (pEventSource == NULL)
01514     {
01515         return;
01516     }
01517 
01518     lastRec = LogfGetCurrentRecord(pEventSource->LogFile);
01519 
01520     logBuffer = LogfAllocAndBuildNewRecord(&recSize,
01521                                            lastRec,
01522                                            wType,
01523                                            wCategory,
01524                                            dwEventId,
01525                                            pEventSource->szName,
01526                                            (LPCWSTR)szComputerName,
01527                                            0,
01528                                            NULL,
01529                                            wNumStrings,
01530                                            lpStrings,
01531                                            dwDataSize,
01532                                            lpRawData);
01533 
01534     dwError = LogfWriteData(pEventSource->LogFile, recSize, logBuffer);
01535     if (!dwError)
01536     {
01537         DPRINT1("ERROR WRITING TO EventLog %S\n", pEventSource->LogFile->FileName);
01538     }
01539 
01540     LogfFreeRecord(logBuffer);
01541 }

Generated on Fri May 25 2012 04:16:00 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.