⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -