Ссылочный номер файла в USN возвращается пустым
Я использую эту ссылку MSDN для программного чтения записей USN.https://docs.microsoft.com/en-us/windows/win32/fileio/walking-a-buffer-of-change-journal-records
Ошибка: исключение 0x00007FFD58682666 (ucrtbased.dll) в Project1.exe: 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);
}
1 ответ
Здесь похоже, что отсутствует проверка работоспособности
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 итерации.