I think we found the problem by joining forces.
This code fails:
#include <windows.h>
#include <stdio.h>
void testJournaling(const char* driveLetter) {
char volumePath[MAX_PATH];
sprintf_s(volumePath, "\\\\.\\%s:", driveLetter);
HANDLE hVolume = CreateFileA(volumePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hVolume == INVALID_HANDLE_VALUE) {
printf_s("Failed to open volume %s with error code %lu\n", driveLetter, GetLastError());
return;
}
USN_JOURNAL_DATA journalData;
DWORD bytesReturned;
BOOL result = DeviceIoControl(hVolume, FSCTL_QUERY_USN_JOURNAL, NULL, 0,
&journalData, sizeof(journalData), &bytesReturned, NULL);
if (result) {
printf("USN Journal exists on volume %s with ID: %llu\n", driveLetter, journalData.UsnJournalID);
// Now testing reading USN journal data
READ_USN_JOURNAL_DATA readData = { 0 };
readData.UsnJournalID = journalData.UsnJournalID;
readData.StartUsn = 0;
readData.ReasonMask = 0xFFFFFFFF;
readData.ReturnOnlyOnClose = FALSE;
readData.Timeout = 0;
readData.BytesToWaitFor = 0;
char buffer[1024];
result = DeviceIoControl(hVolume, FSCTL_READ_USN_JOURNAL, &readData,
sizeof(readData), &buffer, sizeof(buffer), &bytesReturned, NULL);
if (result) {
printf("Successfully read USN journal entries on volume %s\n", driveLetter);
} else {
printf("Failed to read USN journal entries on volume %s with error code %lu\n", driveLetter, GetLastError());
}
}
else {
printf("Failed to query USN Journal on volume %s with error code %lu\n", driveLetter, GetLastError());
}
CloseHandle(hVolume);
}
int main() {
printf("Testing journaling on drives D: and E:\n");
testJournaling("D");
testJournaling("E");
return 0;
}
Result:
Testing journaling on drives D: and E:
USN Journal exists on volume D with ID: 132848022929451360
Failed to read USN journal entries on volume D with error code 87
USN Journal exists on volume E with ID: 133421739577808746
Failed to read USN journal entries on volume E with error code 87
I think RbMm’s comment may be a hint in the right direction. Since you mentioned that USN_JOURNAL_DATA
translates to USN_JOURNAL_DATA_V1
, and MinMajorVersion
and MaxMajorVersion
are not initialized.
If we initialize them, e.g.:
readData.MinMajorVersion = 2; // Windows 2000 and later
readData.MaxMajorVersion = 3; // Windows 8 and later
It now works:
Testing journaling on drives D: and E:
USN Journal exists on volume D with ID: 132848022929451360
Successfully read USN journal entries on volume D
USN Journal exists on volume E with ID: 133421739577808746
Successfully read USN journal entries on volume E