📄 file.c
字号:
/*
* PROJECT: ReactOS kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: services/eventlog/file.c
* PURPOSE: Event logging service
* COPYRIGHT: Copyright 2005 Saveliy Tretiakov
*/
/* INCLUDES *****************************************************************/
#include "eventlog.h"
/* GLOBALS ******************************************************************/
static LIST_ENTRY LogFileListHead;
static CRITICAL_SECTION LogFileListCs;
extern HANDLE MyHeap;
/* FUNCTIONS ****************************************************************/
BOOL LogfInitializeNew(PLOGFILE LogFile)
{
DWORD dwWritten;
EOF_RECORD EofRec;
ZeroMemory(&LogFile->Header, sizeof(FILE_HEADER));
SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN);
SetEndOfFile(LogFile->hFile);
LogFile->Header.SizeOfHeader = sizeof(FILE_HEADER);
LogFile->Header.SizeOfHeader2 = sizeof(FILE_HEADER);
LogFile->Header.FirstRecordOffset = sizeof(FILE_HEADER);
LogFile->Header.EofOffset = sizeof(FILE_HEADER);
LogFile->Header.MajorVersion = MAJORVER;
LogFile->Header.MinorVersion = MINORVER;
LogFile->Header.NextRecord = 1;
LogFile->Header.Signature = LOGFILE_SIGNATURE;
if (!WriteFile(LogFile->hFile,
&LogFile->Header,
sizeof(FILE_HEADER),
&dwWritten,
NULL))
{
DPRINT1("WriteFile failed:%d!\n", GetLastError());
return FALSE;
}
EofRec.Ones = 0x11111111;
EofRec.Twos = 0x22222222;
EofRec.Threes = 0x33333333;
EofRec.Fours = 0x44444444;
EofRec.Size1 = sizeof(EOF_RECORD);
EofRec.Size2 = sizeof(EOF_RECORD);
EofRec.NextRecordNumber = LogFile->Header.NextRecord;
EofRec.OldestRecordNumber = LogFile->Header.OldestRecord;
EofRec.StartOffset = LogFile->Header.FirstRecordOffset;
EofRec.EndOffset = LogFile->Header.EofOffset;
if (!WriteFile(LogFile->hFile,
&EofRec,
sizeof(EOF_RECORD),
&dwWritten,
NULL))
{
DPRINT1("WriteFile failed:%d!\n", GetLastError());
return FALSE;
}
if (!FlushFileBuffers(LogFile->hFile))
{
DPRINT1("FlushFileBuffers failed:%d!\n", GetLastError());
return FALSE;
}
return TRUE;
}
BOOL LogfInitializeExisting(PLOGFILE LogFile)
{
DWORD dwRead;
DWORD dwRecordsNumber = 0;
DWORD dwRecSize, dwRecSign, dwFilePointer;
PDWORD pdwRecSize2;
PEVENTLOGRECORD RecBuf;
if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer failed! %d\n", GetLastError());
return FALSE;
}
if (!ReadFile(LogFile->hFile,
&LogFile->Header,
sizeof(FILE_HEADER),
&dwRead,
NULL))
{
DPRINT1("ReadFile failed! %d\n", GetLastError());
return FALSE;
}
if (dwRead != sizeof(FILE_HEADER))
{
DPRINT("EventLog: Invalid file %S.\n", LogFile->FileName);
return LogfInitializeNew(LogFile);
}
if (LogFile->Header.SizeOfHeader != sizeof(FILE_HEADER) ||
LogFile->Header.SizeOfHeader2 != sizeof(FILE_HEADER))
{
DPRINT("EventLog: Invalid header size in %S.\n", LogFile->FileName);
return LogfInitializeNew(LogFile);
}
if (LogFile->Header.Signature != LOGFILE_SIGNATURE)
{
DPRINT("EventLog: Invalid signature %x in %S.\n",
LogFile->Header.Signature, LogFile->FileName);
return LogfInitializeNew(LogFile);
}
if (LogFile->Header.EofOffset > GetFileSize(LogFile->hFile, NULL) + 1)
{
DPRINT("EventLog: Invalid eof offset %x in %S.\n",
LogFile->Header.EofOffset, LogFile->FileName);
return LogfInitializeNew(LogFile);
}
for (;;)
{
dwFilePointer = SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT);
if (dwFilePointer == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer failed! %d\n", GetLastError());
return FALSE;
}
if (!ReadFile(LogFile->hFile,
&dwRecSize,
sizeof(dwRecSize),
&dwRead,
NULL))
{
DPRINT1("ReadFile failed! %d\n", GetLastError());
return FALSE;
}
if (dwRead != sizeof(dwRecSize))
break;
if (!ReadFile(LogFile->hFile,
&dwRecSign,
sizeof(dwRecSign),
&dwRead,
NULL))
{
DPRINT1("ReadFile() failed! %d\n", GetLastError());
return FALSE;
}
if (dwRead != sizeof(dwRecSize))
break;
if (dwRecSign != LOGFILE_SIGNATURE ||
dwRecSize + dwFilePointer > GetFileSize(LogFile->hFile, NULL) + 1 ||
dwRecSize < sizeof(EVENTLOGRECORD))
{
break;
}
if (SetFilePointer(LogFile->hFile,
-((LONG) sizeof(DWORD) * 2),
NULL,
FILE_CURRENT) == INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d", GetLastError());
return FALSE;
}
RecBuf = (PEVENTLOGRECORD) HeapAlloc(MyHeap, 0, dwRecSize);
if (!RecBuf)
{
DPRINT1("Can't allocate heap!\n");
return FALSE;
}
if (!ReadFile(LogFile->hFile, RecBuf, dwRecSize, &dwRead, NULL))
{
DPRINT1("ReadFile() failed! %d\n", GetLastError());
HeapFree(MyHeap, 0, RecBuf);
return FALSE;
}
if (dwRead != dwRecSize)
{
HeapFree(MyHeap, 0, RecBuf);
break;
}
pdwRecSize2 = (PDWORD) (((PBYTE) RecBuf) + dwRecSize - 4);
if (*pdwRecSize2 != dwRecSize)
{
DPRINT1("Invalid size2 of record %d (%x) in %s\n",
dwRecordsNumber, *pdwRecSize2, LogFile->LogName);
HeapFree(MyHeap, 0, RecBuf);
break;
}
dwRecordsNumber++;
if (!LogfAddOffsetInformation(LogFile,
RecBuf->RecordNumber,
dwFilePointer))
{
DPRINT1("LogfAddOffsetInformation() failed!\n");
HeapFree(MyHeap, 0, RecBuf);
return FALSE;
}
HeapFree(MyHeap, 0, RecBuf);
} // for(;;)
LogFile->Header.NextRecord = dwRecordsNumber + 1;
LogFile->Header.OldestRecord = dwRecordsNumber ? 1 : 0; // FIXME
if (!SetFilePointer(LogFile->hFile, 0, NULL, FILE_CURRENT) ==
INVALID_SET_FILE_POINTER)
{
DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
return FALSE;
}
if (!WriteFile(LogFile->hFile,
&LogFile->Header,
sizeof(FILE_HEADER),
&dwRead,
NULL))
{
DPRINT1("WriteFile failed! %d\n", GetLastError());
return FALSE;
}
if (!FlushFileBuffers(LogFile->hFile))
{
DPRINT1("FlushFileBuffers failed! %d\n", GetLastError());
return FALSE;
}
return TRUE;
}
PLOGFILE LogfCreate(WCHAR * LogName, WCHAR * FileName)
{
PLOGFILE LogFile;
BOOL bResult, bCreateNew = FALSE;
LogFile = (LOGFILE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, sizeof(LOGFILE));
if (!LogFile)
{
DPRINT1("Can't allocate heap!\n");
return NULL;
}
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)
{
DPRINT1("Can't create file %S.\n", FileName);
HeapFree(MyHeap, 0, LogFile);
return NULL;
}
bCreateNew = (GetLastError() == ERROR_ALREADY_EXISTS) ? FALSE : TRUE;
LogFile->LogName =
(WCHAR *) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
(lstrlenW(LogName) + 1) * sizeof(WCHAR));
if (LogFile->LogName)
lstrcpyW(LogFile->LogName, LogName);
else
{
DPRINT1("Can't allocate heap\n");
HeapFree(MyHeap, 0, LogFile);
return NULL;
}
LogFile->FileName =
(WCHAR *) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
(lstrlenW(FileName) + 1) * sizeof(WCHAR));
if (LogFile->FileName)
lstrcpyW(LogFile->FileName, FileName);
else
{
DPRINT1("Can't allocate heap\n");
goto fail;
}
LogFile->OffsetInfo =
(PEVENT_OFFSET_INFO) HeapAlloc(MyHeap,
HEAP_ZERO_MEMORY,
sizeof(EVENT_OFFSET_INFO) * 64);
if (!LogFile->OffsetInfo)
{
DPRINT1("Can't allocate heap\n");
goto fail;
}
LogFile->OffsetInfoSize = 64;
if (bCreateNew)
bResult = LogfInitializeNew(LogFile);
else
bResult = LogfInitializeExisting(LogFile);
if (!bResult)
goto fail;
InitializeCriticalSection(&LogFile->cs);
LogfListAddItem(LogFile);
return LogFile;
fail:
if (LogFile)
{
if (LogFile->OffsetInfo)
HeapFree(MyHeap, 0, LogFile->OffsetInfo);
if (LogFile->FileName)
HeapFree(MyHeap, 0, LogFile->FileName);
if (LogFile->LogName)
HeapFree(MyHeap, 0, LogFile->LogName);
HeapFree(MyHeap, 0, LogFile);
}
return NULL;
}
VOID LogfClose(PLOGFILE LogFile)
{
if (LogFile == NULL)
return;
EnterCriticalSection(&LogFile->cs);
FlushFileBuffers(LogFile->hFile);
CloseHandle(LogFile->hFile);
LogfListRemoveItem(LogFile);
DeleteCriticalSection(&LogFile->cs);
HeapFree(MyHeap, 0, LogFile->LogName);
HeapFree(MyHeap, 0, LogFile->FileName);
HeapFree(MyHeap, 0, LogFile->OffsetInfo);
HeapFree(MyHeap, 0, LogFile);
return;
}
VOID LogfCloseAll(VOID)
{
while (!IsListEmpty(&LogFileListHead))
{
LogfClose(LogfListHead());
}
DeleteCriticalSection(&LogFileListCs);
}
VOID LogfListInitialize(VOID)
{
InitializeCriticalSection(&LogFileListCs);
InitializeListHead(&LogFileListHead);
}
PLOGFILE LogfListHead(VOID)
{
return CONTAINING_RECORD(LogFileListHead.Flink, LOGFILE, ListEntry);
}
PLOGFILE LogfListItemByName(WCHAR * Name)
{
PLIST_ENTRY CurrentEntry;
PLOGFILE Result = NULL;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = Item;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
/* Index starting from 1 */
INT LogfListItemIndexByName(WCHAR * Name)
{
PLIST_ENTRY CurrentEntry;
INT Result = 0;
INT i = 1;
EnterCriticalSection(&LogFileListCs);
CurrentEntry = LogFileListHead.Flink;
while (CurrentEntry != &LogFileListHead)
{
PLOGFILE Item = CONTAINING_RECORD(CurrentEntry,
LOGFILE,
ListEntry);
if (Item->LogName && !lstrcmpi(Item->LogName, Name))
{
Result = i;
break;
}
CurrentEntry = CurrentEntry->Flink;
i++;
}
LeaveCriticalSection(&LogFileListCs);
return Result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -