我正在使用这个 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);
}