c++ - USN中的文件引用号返回空

标签 c++ windows debugging filereference usn

我正在使用此MSDN链接以编程方式读取USN记录。
https://docs.microsoft.com/en-us/windows/win32/fileio/walking-a-buffer-of-change-journal-records

错误:Project1.exe中的0x00007FFD58682666(ucrtbased.dll)引发异常:0xC0000005:访问冲突读取位置0x00000000FFFFFD7F。

#include <Windows.h>
#include <WinIoCtl.h>
#include <stdio.h>

#define BUF_LEN 4096

void main()
{
    HANDLE hVol;
    CHAR Buffer[BUF_LEN];

    USN_JOURNAL_DATA JournalData;
    READ_USN_JOURNAL_DATA_V1 ReadData = { 0, 0xFFFFFFFF, FALSE, 0, 0, 0, 2, 3 };
    PUSN_RECORD UsnRecord;

    DWORD dwBytes;
    DWORD dwRetBytes;
    int I;

    hVol = CreateFile(TEXT("\\\\.\\c:"),
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    if (hVol == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile failed (%d)\n", GetLastError());
        return;
    }

    if (!DeviceIoControl(hVol,
        FSCTL_QUERY_USN_JOURNAL,
        NULL,
        0,
        &JournalData,
        sizeof(JournalData),
        &dwBytes,
        NULL))
    {
        printf("Query journal failed (%d)\n", GetLastError());
        return;
    }

    ReadData.UsnJournalID = JournalData.UsnJournalID;

    printf("Journal ID: %I64x\n", JournalData.UsnJournalID);
    printf("FirstUsn: %I64x\n\n", JournalData.FirstUsn);

    for (I = 0; I <= 10; I++)
    {
        memset(Buffer, 0, BUF_LEN);

        if (!DeviceIoControl(hVol,
            FSCTL_READ_USN_JOURNAL,
            &ReadData,
            sizeof(ReadData),
            &Buffer,
            BUF_LEN,
            &dwBytes,
            NULL))
        {
            printf("Read journal failed (%d)\n", GetLastError());
            return;
        }

        dwRetBytes = dwBytes - sizeof(USN);

        // Find the first record
        UsnRecord = (PUSN_RECORD)(((PUCHAR)Buffer) + sizeof(USN));
        NTFS_FILE_RECORD_OUTPUT_BUFFER * FileRef = (NTFS_FILE_RECORD_OUTPUT_BUFFER *)(UsnRecord);

        printf("****************************************\n");

        // This loop could go on for a long time, given the current buffer size.
        while (dwRetBytes > 0)
        {
            printf("USN: %I64x\n", UsnRecord->Usn);
            printf("File name: %.*S\n",
                UsnRecord->FileNameLength / 2,
                UsnRecord->FileName);
            wprintf(UsnRecord->FileName);
            fputws(UsnRecord->FileName, stdout);
            printf("file record found\n%.*S\n",
                FileRef->FileReferenceNumber);
            //added
            /*rootdir_usn = (USN_RECORD *)buffer;
            show_record(rootdir_usn, FALSE);
            rootdir = rootdir_usn->FileReferenceNumber;*/
            //stopped


            printf("Reason: %x\n", UsnRecord->Reason);
            printf("\n");

            dwRetBytes -= UsnRecord->RecordLength;

            // Find the next record
            UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) +
                UsnRecord->RecordLength);
        }
        // Update starting USN for next call
        ReadData.StartUsn = *(USN *)&Buffer;
    }

    CloseHandle(hVol);

}

最佳答案

在这里看起来好像缺少完整性检查

UsnRecord = (PUSN_RECORD)(((PUCHAR)Buffer) + sizeof(USN));    
NTFS_FILE_RECORD_OUTPUT_BUFFER * FileRef = (NTFS_FILE_RECORD_OUTPUT_BUFFER *)(UsnRecord);
if (!FileRef) {
  printf("This was not the FileRef I was looking for\n");
  return;
}

如果失败,则UsnRecord损坏且错误先前已发生,则可能是
for (I = 0; I <= 10; I++)

错误发生在第11次迭代中。

关于c++ - USN中的文件引用号返回空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61815124/

相关文章:

c++ - 遗留 C/C++ 代码分析工具

windows - docker-compose 错误无法启动服务 mongo : driver failed programming external connectivity on endpoint

c# - Windows 窗体屏幕保护程序预览窗口句柄

c++ - Emacs 和 gdb - 在回溯中显示函数代码

c - 逆向工程——使用调试信息进行编译

java - 如何在调用特定 Java 方法时转储堆栈跟踪?

c++ - 为什么新运算符(operator)会挂起我的程序?

c++ - 如何批量使用同一个线程池

c++ - 递增/递减与赋值?

windows - Docker compose - 共享卷 Nginx