Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfile.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
1.7.6.1
|