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

📄 file.c

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

/* Index starting from 1 */
PLOGFILE LogfListItemByIndex(INT Index)
{
    PLIST_ENTRY CurrentEntry;
    PLOGFILE Result = NULL;
    INT i = 1;

    EnterCriticalSection(&LogFileListCs);

    CurrentEntry = LogFileListHead.Flink;
    while (CurrentEntry != &LogFileListHead)
    {
        if (i == Index)
        {
            Result = CONTAINING_RECORD(CurrentEntry, LOGFILE, ListEntry);
            break;
        }

        CurrentEntry = CurrentEntry->Flink;
        i++;
    }

    LeaveCriticalSection(&LogFileListCs);
    return Result;
}

INT LogfListItemCount()
{
    PLIST_ENTRY CurrentEntry;
    INT i = 0;

    EnterCriticalSection(&LogFileListCs);

    CurrentEntry = LogFileListHead.Flink;
    while (CurrentEntry != &LogFileListHead)
    {
        CurrentEntry = CurrentEntry->Flink;
        i++;
    }

    LeaveCriticalSection(&LogFileListCs);
    return i;
}

VOID LogfListAddItem(PLOGFILE Item)
{
    EnterCriticalSection(&LogFileListCs);
    InsertTailList(&LogFileListHead, &Item->ListEntry);
    LeaveCriticalSection(&LogFileListCs);
}

VOID LogfListRemoveItem(PLOGFILE Item)
{
    EnterCriticalSection(&LogFileListCs);
    RemoveEntryList(&Item->ListEntry);
    LeaveCriticalSection(&LogFileListCs);
}

BOOL LogfReadEvent(PLOGFILE LogFile,
                   DWORD Flags,
                   DWORD RecordNumber,
                   DWORD BufSize,
                   PBYTE Buffer,
                   DWORD * BytesRead,
                   DWORD * BytesNeeded)
{
    DWORD dwOffset, dwRead, dwRecSize;
    DWORD dwBufferUsage = 0, dwRecNum;

    if (Flags & EVENTLOG_FORWARDS_READ && Flags & EVENTLOG_BACKWARDS_READ)
        return FALSE;

    if (!(Flags & EVENTLOG_FORWARDS_READ) && !(Flags & EVENTLOG_BACKWARDS_READ))
        return FALSE;

    if (!Buffer || !BytesRead || !BytesNeeded)
        return FALSE;

    dwRecNum = RecordNumber;
    EnterCriticalSection(&LogFile->cs);
    dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);

    if (!dwOffset)
    {
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
        INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!ReadFile(LogFile->hFile, &dwRecSize, sizeof(DWORD), &dwRead, NULL))
    {
        DPRINT1("ReadFile() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (dwRecSize > BufSize)
    {
        *BytesRead = 0;
        *BytesNeeded = dwRecSize;
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (SetFilePointer(LogFile->hFile,
                       -((LONG) sizeof(DWORD)),
                       NULL,
                       FILE_CURRENT) == INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!ReadFile(LogFile->hFile, Buffer, dwRecSize, &dwRead, NULL))
    {
        DPRINT1("ReadFile() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    dwBufferUsage += dwRead;

    while (dwBufferUsage < BufSize)
    {
        if (Flags & EVENTLOG_FORWARDS_READ)
            dwRecNum++;
        else
            dwRecNum--;

        dwOffset = LogfOffsetByNumber(LogFile, dwRecNum);
        if (!dwOffset)
            break;

        if (SetFilePointer(LogFile->hFile, dwOffset, NULL, FILE_BEGIN) ==
            INVALID_SET_FILE_POINTER)
        {
            DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
            LeaveCriticalSection(&LogFile->cs);
            return FALSE;
        }

        if (!ReadFile(LogFile->hFile,
                      &dwRecSize,
                      sizeof(DWORD),
                      &dwRead,
                      NULL))
        {
            DPRINT1("ReadFile() failed! %d\n", GetLastError());
            LeaveCriticalSection(&LogFile->cs);
            return FALSE;
        }

        if (dwBufferUsage + dwRecSize > BufSize)
            break;

        if (SetFilePointer(LogFile->hFile,
                           -((LONG) sizeof(DWORD)),
                           NULL,
                           FILE_CURRENT) == INVALID_SET_FILE_POINTER)
        {
            DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
            LeaveCriticalSection(&LogFile->cs);
            return FALSE;
        }

        if (!ReadFile(LogFile->hFile,
                      Buffer + dwBufferUsage,
                      dwRecSize,
                      &dwRead,
                      NULL))
        {
            DPRINT1("ReadFile() failed! %d\n", GetLastError());
            LeaveCriticalSection(&LogFile->cs);
            return FALSE;
        }

        dwBufferUsage += dwRead;
    }

    *BytesRead = dwBufferUsage;
    LeaveCriticalSection(&LogFile->cs);
    return TRUE;
}

BOOL LogfWriteData(PLOGFILE LogFile, DWORD BufSize, PBYTE Buffer)
{
    DWORD dwWritten;
    SYSTEMTIME st;
    EOF_RECORD EofRec;

    if (!Buffer)
        return FALSE;

    GetSystemTime(&st);
    SystemTimeToEventTime(&st, &((PEVENTLOGRECORD) Buffer)->TimeWritten);

    EnterCriticalSection(&LogFile->cs);

    if (SetFilePointer(LogFile->hFile,
                       LogFile->Header.EofOffset,
                       NULL,
                       FILE_BEGIN) == INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!WriteFile(LogFile->hFile, Buffer, BufSize, &dwWritten, NULL))
    {
        DPRINT1("WriteFile() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!LogfAddOffsetInformation(LogFile,
                                  LogFile->Header.NextRecord,
                                  LogFile->Header.EofOffset))
    {
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    LogFile->Header.NextRecord++;
    LogFile->Header.EofOffset += dwWritten;

    if (LogFile->Header.OldestRecord == 0)
        LogFile->Header.OldestRecord = 1;

    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());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (SetFilePointer(LogFile->hFile, 0, NULL, FILE_BEGIN) ==
        INVALID_SET_FILE_POINTER)
    {
        DPRINT1("SetFilePointer() failed! %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!WriteFile(LogFile->hFile,
                   &LogFile->Header,
                   sizeof(FILE_HEADER),
                   &dwWritten,
                   NULL))
    {
        DPRINT1("WriteFile failed! LastError = %d\n", GetLastError());
        LeaveCriticalSection(&LogFile->cs);
        return FALSE;
    }

    if (!FlushFileBuffers(LogFile->hFile))
    {
        LeaveCriticalSection(&LogFile->cs);
        DPRINT1("FlushFileBuffers() failed! %d\n", GetLastError());
        return FALSE;
    }

    LeaveCriticalSection(&LogFile->cs);
    return TRUE;
}

ULONG LogfOffsetByNumber(PLOGFILE LogFile, DWORD RecordNumber)

/* Returns 0 if nothing found. */
{
    DWORD i;

    for (i = 0; i < LogFile->OffsetInfoNext; i++)
    {
        if (LogFile->OffsetInfo[i].EventNumber == RecordNumber)
            return LogFile->OffsetInfo[i].EventOffset;
    }
    return 0;
}

DWORD LogfGetOldestRecord(PLOGFILE LogFile)
{
    return LogFile->Header.OldestRecord;
}

BOOL LogfAddOffsetInformation(PLOGFILE LogFile, ULONG ulNumber, ULONG ulOffset)
{
    LPVOID NewOffsetInfo;

    if (LogFile->OffsetInfoNext == LogFile->OffsetInfoSize)
    {
        NewOffsetInfo = HeapReAlloc(MyHeap,
                                    HEAP_ZERO_MEMORY,
                                    LogFile->OffsetInfo,
                                    (LogFile->OffsetInfoSize + 64) *
                                        sizeof(EVENT_OFFSET_INFO));

        if (!NewOffsetInfo)
        {
            DPRINT1("Can't reallocate heap.\n");
            return FALSE;
        }

        LogFile->OffsetInfo = (PEVENT_OFFSET_INFO) NewOffsetInfo;
        LogFile->OffsetInfoSize += 64;
    }

    LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventNumber = ulNumber;
    LogFile->OffsetInfo[LogFile->OffsetInfoNext].EventOffset = ulOffset;
    LogFile->OffsetInfoNext++;

    return TRUE;
}

PBYTE LogfAllocAndBuildNewRecord(LPDWORD lpRecSize,
                                 DWORD   dwRecordNumber,
                                 WORD    wType,
                                 WORD    wCategory,
                                 DWORD   dwEventId,
                                 LPCWSTR SourceName,
                                 LPCWSTR ComputerName,
                                 DWORD   dwSidLength,
                                 PSID    lpUserSid,
                                 WORD    wNumStrings,
                                 WCHAR   * lpStrings,
                                 DWORD   dwDataSize,
                                 LPVOID  lpRawData)
{
    DWORD dwRecSize;
    PEVENTLOGRECORD pRec;
    SYSTEMTIME SysTime;
    WCHAR *str;
    UINT i, pos, nStrings;
    PBYTE Buffer;

    dwRecSize =
        sizeof(EVENTLOGRECORD) + (lstrlenW(ComputerName) +
                                  lstrlenW(SourceName) + 2) * sizeof(WCHAR);

    if (dwRecSize % 4 != 0)
        dwRecSize += 4 - (dwRecSize % 4);

    dwRecSize += dwSidLength;

    for (i = 0, str = lpStrings; i < wNumStrings; i++)
    {
        dwRecSize += (lstrlenW(str) + 1) * sizeof(WCHAR);
        str += lstrlenW(str) + 1;
    }

    dwRecSize += dwDataSize;
    if (dwRecSize % 4 != 0)
        dwRecSize += 4 - (dwRecSize % 4);

    dwRecSize += 4;

    Buffer = (BYTE *) HeapAlloc(MyHeap, HEAP_ZERO_MEMORY, dwRecSize);

    if (!Buffer)
    {
        DPRINT1("Can't allocate heap!\n");
        return NULL;
    }

    pRec = (PEVENTLOGRECORD) Buffer;
    pRec->Length = dwRecSize;
    pRec->Reserved = LOGFILE_SIGNATURE;
    pRec->RecordNumber = dwRecordNumber;

    GetSystemTime(&SysTime);
    SystemTimeToEventTime(&SysTime, &pRec->TimeGenerated);
    SystemTimeToEventTime(&SysTime, &pRec->TimeWritten);

    pRec->EventID = dwEventId;
    pRec->EventType = wType;
    pRec->NumStrings = wNumStrings;
    pRec->EventCategory = wCategory;

    pos = sizeof(EVENTLOGRECORD);

    lstrcpyW((WCHAR *) (Buffer + pos), SourceName);
    pos += (lstrlenW(SourceName) + 1) * sizeof(WCHAR);
    lstrcpyW((WCHAR *) (Buffer + pos), ComputerName);
    pos += (lstrlenW(ComputerName) + 1) * sizeof(WCHAR);

    pRec->UserSidOffset = pos;
    if (dwSidLength)
    {
        if (pos % 4 != 0)
            pos += 4 - (pos % 4);
        CopyMemory(Buffer + pos, lpUserSid, dwSidLength);
        pRec->UserSidLength = dwSidLength;
        pRec->UserSidOffset = pos;
        pos += dwSidLength;
    }

    pRec->StringOffset = pos;
    for (i = 0, str = lpStrings, nStrings = 0; i < wNumStrings; i++)
    {
        lstrcpyW((WCHAR *) (Buffer + pos), str);
        pos += (lstrlenW(str) + 1) * sizeof(WCHAR);
        str += lstrlenW(str) + 1;
        nStrings++;
    }
    pRec->NumStrings = nStrings;

    pRec->DataOffset = pos;
    if (dwDataSize)
    {
        pRec->DataLength = dwDataSize;
        CopyMemory(Buffer + pos, lpRawData, dwDataSize);
        pos += dwDataSize;
    }

    if (pos % 4 != 0)
        pos += 4 - (pos % 4);

    *((PDWORD) (Buffer + pos)) = dwRecSize;

    *lpRecSize = dwRecSize;
    return Buffer;
}

void __inline LogfFreeRecord(LPVOID Rec)
{
    HeapFree(MyHeap, 0, Rec);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -