#include "eventlog.h"
+#include <ndk/iofuncs.h>
+
+#define NDEBUG
+#include <debug.h>
+
/* GLOBALS ******************************************************************/
static LIST_ENTRY LogFileListHead;
/* FUNCTIONS ****************************************************************/
-BOOL LogfInitializeNew(PLOGFILE LogFile)
+static NTSTATUS
+LogfInitializeNew(PLOGFILE LogFile)
{
DWORD dwWritten;
EVENTLOGEOF EofRec;
LogFile->Header.MajorVersion = MAJORVER;
LogFile->Header.MinorVersion = MINORVER;
LogFile->Header.CurrentRecordNumber = 1;
+ LogFile->Header.OldestRecordNumber = 1;
/* FIXME: Read MaxSize from registry for this LogFile.
But for now limit EventLog size to just under 5K. */
LogFile->Header.MaxSize = 5000;
NULL))
{
DPRINT1("WriteFile failed:%d!\n", GetLastError());
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
EofRec.Ones = 0x11111111;
NULL))
{
DPRINT1("WriteFile failed:%d!\n", GetLastError());
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
if (!FlushFileBuffers(LogFile->hFile))
{
DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
- return TRUE;
+ return STATUS_SUCCESS;
}
-BOOL LogfInitializeExisting(PLOGFILE LogFile)
+
+static NTSTATUS
+LogfInitializeExisting(PLOGFILE LogFile, BOOL Backup)
{
DWORD dwRead;
DWORD dwRecordsNumber = 0;
INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (!ReadFile(LogFile->hFile,
NULL))
{
DPRINT1("ReadFile failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (dwRead != sizeof(EVENTLOGHEADER))
{
DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
- return LogfInitializeNew(LogFile);
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (LogFile->Header.HeaderSize != sizeof(EVENTLOGHEADER) ||
LogFile->Header.EndHeaderSize != sizeof(EVENTLOGHEADER))
{
DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
- return LogfInitializeNew(LogFile);
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (LogFile->Header.Signature != LOGFILE_SIGNATURE)
{
DPRINT("EventLog: Invalid signature %x in %S.\n",
LogFile->Header.Signature, LogFile->FileName);
- return LogfInitializeNew(LogFile);
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (LogFile->Header.EndOffset > GetFileSize(LogFile->hFile, NULL) + 1)
{
DPRINT("EventLog: Invalid eof offset %x in %S.\n",
LogFile->Header.EndOffset, LogFile->FileName);
- return LogfInitializeNew(LogFile);
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
/* Set the read location to the oldest record */
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
for (;;)
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
/* If the EVENTLOGEOF info has been reached and the oldest record was not immediately after the Header */
NULL))
{
DPRINT1("ReadFile failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (dwRead != sizeof(dwRecSize))
NULL))
{
DPRINT1("ReadFile() failed! %d\n", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (dwRead != sizeof(dwRecSize))
FILE_CURRENT) == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d", GetLastError());
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
-
- if (!RecBuf)
+ if (RecBuf == NULL)
{
DPRINT1("Can't allocate heap!\n");
- return FALSE;
+ return STATUS_NO_MEMORY;
}
if (!ReadFile(LogFile->hFile, RecBuf, dwRecSize, &dwRead, NULL))
{
DPRINT1("ReadFile() failed! %d\n", GetLastError());
HeapFree(MyHeap, 0, RecBuf);
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
if (dwRead != dwRecSize)
{
DPRINT1("LogfAddOffsetInformation() failed!\n");
HeapFree(MyHeap, 0, RecBuf);
- return FALSE;
+ return STATUS_EVENTLOG_FILE_CORRUPT;
}
HeapFree(MyHeap, 0, RecBuf);
But for now limit EventLog size to just under 5K. */
LogFile->Header.MaxSize = 5000;
- if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
- INVALID_SET_FILE_POINTER)
+ if (!Backup)
{
- DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
- return FALSE;
- }
+ if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
+ INVALID_SET_FILE_POINTER)
+ {
+ DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
+ return STATUS_EVENTLOG_FILE_CORRUPT;
+ }
- if (!WriteFile(LogFile->hFile,
- &LogFile->Header,
- sizeof(EVENTLOGHEADER),
- &dwRead,
- NULL))
- {
- DPRINT1("WriteFile failed! %d\n", GetLastError());
- return FALSE;
- }
+ if (!WriteFile(LogFile->hFile,
+ &LogFile->Header,
+ sizeof(EVENTLOGHEADER),
+ &dwRead,
+ NULL))
+ {
+ DPRINT1("WriteFile failed! %d\n", GetLastError());
+ return STATUS_EVENTLOG_FILE_CORRUPT;
+ }
- if (!FlushFileBuffers(LogFile->hFile))
- {
- DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
- return FALSE;
+ if (!FlushFileBuffers(LogFile->hFile))
+ {
+ DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
+ return STATUS_EVENTLOG_FILE_CORRUPT;
+ }
}
- return TRUE;
+ return STATUS_SUCCESS;
}
-PLOGFILE LogfCreate(WCHAR * LogName, WCHAR * FileName)
-{
- PLOGFILE LogFile;
- BOOL bResult, bCreateNew = FALSE;
- LogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
- if (!LogFile)
+NTSTATUS
+LogfCreate(PLOGFILE *LogFile,
+ WCHAR * LogName,
+ PUNICODE_STRING FileName,
+ BOOL Permanent,
+ BOOL Backup)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PLOGFILE pLogFile;
+ BOOL bCreateNew = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ pLogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
+ if (!pLogFile)
{
DPRINT1("Can't allocate heap!\n");
- return NULL;
+ return STATUS_NO_MEMORY;
}
- LogFile->hFile = CreateFile(FileName,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
- NULL);
-
- if (LogFile->hFile == INVALID_HANDLE_VALUE)
+ InitializeObjectAttributes(&ObjectAttributes,
+ FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtCreateFile(&pLogFile->hFile,
+ Backup ? (GENERIC_READ | SYNCHRONIZE) : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE),
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ Backup ? FILE_OPEN : FILE_OPEN_IF,
+ FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("Can't create file %S.\n", FileName);
- HeapFree(MyHeap, 0, LogFile);
- return NULL;
+ DPRINT1("Can't create file %wZ (Status: 0x%08lx)\n", FileName, Status);
+ goto fail;
}
- bCreateNew = (GetLastError() == ERROR_ALREADY_EXISTS) ? FALSE : TRUE;
+ bCreateNew = (IoStatusBlock.Information == FILE_CREATED) ? TRUE: FALSE;
- LogFile->LogName =
+ pLogFile->LogName =
(WCHAR *) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
(lstrlenW(LogName) + 1) * sizeof(WCHAR));
-
- if (LogFile->LogName)
- lstrcpyW(LogFile->LogName, LogName);
- else
+ if (pLogFile->LogName == NULL)
{
DPRINT1("Can't allocate heap\n");
- HeapFree(MyHeap, 0, LogFile);
- return NULL;
+ Status = STATUS_NO_MEMORY;
+ goto fail;
}
- LogFile->FileName =
+ lstrcpyW(pLogFile->LogName, LogName);
+
+ pLogFile->FileName =
(WCHAR *) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
- (lstrlenW(FileName) + 1) * sizeof(WCHAR));
-
- if (LogFile->FileName)
- lstrcpyW(LogFile->FileName, FileName);
- else
+ (lstrlenW(FileName->Buffer) + 1) * sizeof(WCHAR));
+ if (pLogFile->FileName == NULL)
{
DPRINT1("Can't allocate heap\n");
+ Status = STATUS_NO_MEMORY;
goto fail;
}
- LogFile->OffsetInfo =
+ lstrcpyW(pLogFile->FileName, FileName->Buffer);
+
+ pLogFile->OffsetInfo =
(PEVENT_OFFSET_INFO) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
sizeof(EVENT_OFFSET_INFO) * 64);
-
- if (!LogFile->OffsetInfo)
+ if (pLogFile->OffsetInfo == NULL)
{
DPRINT1("Can't allocate heap\n");
+ Status = STATUS_NO_MEMORY;
goto fail;
}
- LogFile->OffsetInfoSize = 64;
+ pLogFile->OffsetInfoSize = 64;
+
+ pLogFile->Permanent = Permanent;
if (bCreateNew)
- bResult = LogfInitializeNew(LogFile);
+ Status = LogfInitializeNew(pLogFile);
else
- bResult = LogfInitializeExisting(LogFile);
+ Status = LogfInitializeExisting(pLogFile, Backup);
- if (!bResult)
+ if (!NT_SUCCESS(Status))
goto fail;
- InitializeCriticalSection(&LogFile->cs);
- LogfListAddItem(LogFile);
- return LogFile;
+ RtlInitializeResource(&pLogFile->Lock);
+
+ LogfListAddItem(pLogFile);
fail:
- if (LogFile)
+ if (!NT_SUCCESS(Status))
{
- if (LogFile->OffsetInfo)
- HeapFree(MyHeap, 0, LogFile->OffsetInfo);
+ if ((pLogFile->hFile != NULL) && (pLogFile->hFile != INVALID_HANDLE_VALUE))
+ CloseHandle(pLogFile->hFile);
+
+ if (pLogFile->OffsetInfo)
+ HeapFree(MyHeap, 0, pLogFile->OffsetInfo);
- if (LogFile->FileName)
- HeapFree(MyHeap, 0, LogFile->FileName);
+ if (pLogFile->FileName)
+ HeapFree(MyHeap, 0, pLogFile->FileName);
- if (LogFile->LogName)
- HeapFree(MyHeap, 0, LogFile->LogName);
+ if (pLogFile->LogName)
+ HeapFree(MyHeap, 0, pLogFile->LogName);
- HeapFree(MyHeap, 0, LogFile);
+ HeapFree(MyHeap, 0, pLogFile);
+ }
+ else
+ {
+ *LogFile = pLogFile;
}
- return NULL;
+ return Status;
}
-VOID LogfClose(PLOGFILE LogFile)
+
+VOID
+LogfClose(PLOGFILE LogFile,
+ BOOL ForceClose)
{
if (LogFile == NULL)
return;
- EnterCriticalSection(&LogFile->cs);
+ if ((ForceClose == FALSE) &&
+ (LogFile->Permanent == TRUE))
+ return;
+
+ RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
FlushFileBuffers(LogFile->hFile);
CloseHandle(LogFile->hFile);
LogfListRemoveItem(LogFile);
- DeleteCriticalSection(&LogFile->cs);
+ RtlDeleteResource(&LogFile->Lock);
HeapFree(MyHeap, 0, LogFile->LogName);
HeapFree(MyHeap, 0, LogFile->FileName);
{
while (!IsListEmpty(&LogFileListHead))
{
- LogfClose(LogfListHead());
+ LogfClose(LogfListHead(), TRUE);
}
DeleteCriticalSection(&LogFileListCs);
}
dwRecNum = *RecordNumber;
- EnterCriticalSection(&LogFile->cs);
+
+ RtlAcquireResourceShared(&LogFile->Lock, TRUE);
*BytesRead = 0;
*BytesNeeded = 0;
if (!dwOffset)
{
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return ERROR_HANDLE_EOF;
}
if (dwRecSize > BufSize)
{
*BytesNeeded = dwRecSize;
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return ERROR_INSUFFICIENT_BUFFER;
}
*BytesRead = dwBufferUsage;
* RecordNumber = dwRecNum;
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return ERROR_SUCCESS;
Done:
DPRINT1("LogfReadEvent failed with %x\n",GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return GetLastError();
}
GetSystemTime(&st);
SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);
- EnterCriticalSection(&LogFile->cs);
+ RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
if (!GetFileSizeEx(LogFile->hFile, &logFileSize))
{
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
{
DPRINT1("Failed to allocate buffer for OldestRecord!\n");
HeapFree(GetProcessHeap(), 0, RecBuf);
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
{
DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
HeapFree(GetProcessHeap(), 0, RecBuf);
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
{
DPRINT1("ReadFile() failed!\n");
HeapFree(GetProcessHeap(), 0, RecBuf);
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
if (RecBuf->Reserved != LOGFILE_SIGNATURE)
{
DPRINT1("LogFile corrupt!\n");
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
/* Check the size of the record as the record adding may be larger */
if (OverWriteLength >= BufSize)
{
- DPRINT("Record will fit. Lenght %d, BufSize %d\n", OverWriteLength, BufSize);
+ DPRINT("Record will fit. Length %d, BufSize %d\n", OverWriteLength, BufSize);
LogFile->Header.StartOffset = LogfOffsetByNumber(LogFile, LogFile->Header.OldestRecordNumber);
break;
}
FILE_BEGIN) == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
if (!WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL))
{
DPRINT1("WriteFile() failed! %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
LogFile->Header.CurrentRecordNumber,
WriteOffSet))
{
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
LogFile->Header.CurrentRecordNumber++;
- if (LogFile->Header.OldestRecordNumber == 0)
- LogFile->Header.OldestRecordNumber = 1;
-
if (WriteOffSet == LogFile->Header.EndOffset)
{
LogFile->Header.EndOffset += dwWritten;
FILE_BEGIN) == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
NULL))
{
DPRINT1("WriteFile() failed! %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
NULL))
{
DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
if (!FlushFileBuffers(LogFile->hFile))
{
- LeaveCriticalSection(&LogFile->cs);
DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
+ RtlReleaseResource(&LogFile->Lock);
return FALSE;
}
- LeaveCriticalSection(&LogFile->cs);
+ RtlReleaseResource(&LogFile->Lock);
return TRUE;
}
+
+NTSTATUS
+LogfClearFile(PLOGFILE LogFile,
+ PUNICODE_STRING BackupFileName)
+{
+ NTSTATUS Status;
+
+ RtlAcquireResourceExclusive(&LogFile->Lock, TRUE);
+
+ if (BackupFileName->Length > 0)
+ {
+ /* Write a backup file */
+ Status = LogfBackupFile(LogFile,
+ BackupFileName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("LogfBackupFile failed (Status: 0x%08lx)\n", Status);
+ return Status;
+ }
+ }
+
+ Status = LogfInitializeNew(LogFile);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("LogfInitializeNew failed (Status: 0x%08lx)\n", Status);
+ }
+
+ RtlReleaseResource(&LogFile->Lock);
+
+ return Status;
+}
+
+
+NTSTATUS
+LogfBackupFile(PLOGFILE LogFile,
+ PUNICODE_STRING BackupFileName)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ EVENTLOGHEADER Header;
+ EVENTLOGEOF EofRec;
+ HANDLE FileHandle = NULL;
+ ULONG i;
+ LARGE_INTEGER FileOffset;
+ NTSTATUS Status;
+ PUCHAR Buffer = NULL;
+
+ DWORD dwOffset, dwRead, dwRecSize;
+
+ DPRINT("LogfBackupFile(%p, %wZ)\n", LogFile, BackupFileName);
+
+ /* Lock the log file shared */
+ RtlAcquireResourceShared(&LogFile->Lock, TRUE);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ BackupFileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtCreateFile(&FileHandle,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_CREATE,
+ FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Can't create backup file %wZ (Status: 0x%08lx)\n", BackupFileName, Status);
+ goto Done;
+ }
+
+ /* Initialize the (dirty) log file header */
+ Header.HeaderSize = sizeof(EVENTLOGHEADER);
+ Header.Signature = LOGFILE_SIGNATURE;
+ Header.MajorVersion = MAJORVER;
+ Header.MinorVersion = MINORVER;
+ Header.StartOffset = sizeof(EVENTLOGHEADER);
+ Header.EndOffset = sizeof(EVENTLOGHEADER);
+ Header.CurrentRecordNumber = 1;
+ Header.OldestRecordNumber = 1;
+ Header.MaxSize = 0;
+ Header.Flags = ELF_LOGFILE_HEADER_DIRTY;
+ Header.Retention = LogFile->Header.Retention;
+ Header.EndHeaderSize = sizeof(EVENTLOGHEADER);
+
+ /* Write the (dirty) log file header */
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ &Header,
+ sizeof(EVENTLOGHEADER),
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to write the log file header (Status: 0x%08lx)\n", Status);
+ goto Done;
+ }
+
+ for (i = LogFile->Header.OldestRecordNumber; i < LogFile->Header.CurrentRecordNumber; i++)
+ {
+ dwOffset = LogfOffsetByNumber(LogFile, i);
+ if (dwOffset == 0)
+ break;
+
+ if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ {
+ DPRINT1("SetFilePointer() failed!\n");
+ goto Done;
+ }
+
+ if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL))
+ {
+ DPRINT1("ReadFile() failed!\n");
+ goto Done;
+ }
+
+ if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ {
+ DPRINT1("SetFilePointer() failed!\n");
+ goto Done;
+ }
+
+ Buffer = HeapAlloc(MyHeap, 0, dwRecSize);
+ if (Buffer == NULL)
+ {
+ DPRINT1("HeapAlloc() failed!\n");
+ goto Done;
+ }
+
+ if (!ReadFile(LogFile->hFile, &Buffer, dwRecSize, &dwRead, NULL))
+ {
+ DPRINT1("ReadFile() failed!\n");
+ goto Done;
+ }
+
+ /* Write the event record */
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ Buffer,
+ dwRecSize,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed!\n");
+ goto Done;
+ }
+
+ /* Update the header information */
+ Header.EndOffset += dwRecSize;
+
+ /* Free the buffer */
+ HeapFree(MyHeap, 0, Buffer);
+ Buffer = NULL;
+ }
+
+ /* Initialize the EOF record */
+ EofRec.RecordSizeBeginning = sizeof(EVENTLOGEOF);
+ EofRec.Ones = 0x11111111;
+ EofRec.Twos = 0x22222222;
+ EofRec.Threes = 0x33333333;
+ EofRec.Fours = 0x44444444;
+ EofRec.BeginRecord = sizeof(EVENTLOGHEADER);
+ EofRec.EndRecord = Header.EndOffset;
+ EofRec.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
+ EofRec.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
+ EofRec.RecordSizeEnd = sizeof(EVENTLOGEOF);
+
+ /* Write the EOF record */
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ &EofRec,
+ sizeof(EVENTLOGEOF),
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed!\n");
+ goto Done;
+ }
+
+ /* Update the header information */
+ Header.CurrentRecordNumber = LogFile->Header.CurrentRecordNumber;
+ Header.OldestRecordNumber = LogFile->Header.OldestRecordNumber;
+ Header.MaxSize = Header.EndOffset + sizeof(EVENTLOGEOF);
+ Header.Flags = 0;
+
+ /* Write the (clean) log file header */
+ FileOffset.QuadPart = 0;
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ &Header,
+ sizeof(EVENTLOGHEADER),
+ &FileOffset,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed!\n");
+ }
+
+Done:
+ /* Free the buffer */
+ if (Buffer != NULL)
+ HeapFree(MyHeap, 0, Buffer);
+
+ /* Close the backup file */
+ if (FileHandle != NULL)
+ NtClose(FileHandle);
+
+ /* Unlock the log file */
+ RtlReleaseResource(&LogFile->Lock);
+
+ return Status;
+}
+
+
/* Returns 0 if nothing found. */
ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)
{