-
-
Save pervognsen/bcc610d6a5ae6cbc3b2b4f7aa00d8da9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _CRT_SECURE_NO_WARNINGS | |
#include <windows.h> | |
#include <winioctl.h> | |
#include <stdio.h> | |
void write_usn(const char *filename, USN usn) { | |
FILE *file = fopen(filename, "w"); | |
if (!file) { | |
printf("Failed to open %s for writing.\n", filename); | |
exit(1); | |
} | |
fprintf(file, "%llx", usn); | |
fclose(file); | |
} | |
int main(int argc, char **argv) { | |
if (argc != 3) { | |
printf("Usage: ListFileChanges <volume name> <usn filename>\n"); | |
return 1; | |
} | |
char *volume_name = argv[1]; | |
char *usn_filename = argv[2]; | |
char volume_path[MAX_PATH]; | |
sprintf_s(volume_path, sizeof(volume_path), "\\\\.\\%s", volume_name); | |
HANDLE volume = CreateFileA(volume_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); | |
if (volume == INVALID_HANDLE_VALUE) { | |
printf("Cannot open volume %s.\n", volume_name); | |
return 1; | |
} | |
USN_JOURNAL_DATA journal_data; | |
DWORD num_bytes; | |
if (!DeviceIoControl(volume, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &journal_data, sizeof(journal_data), &num_bytes, NULL)) { | |
printf("FSCTL_QUERY_USN_JOURNAL failed.\n"); | |
return 1; | |
} | |
USN current_usn = journal_data.NextUsn; | |
FILE *usn_file = fopen(usn_filename, "r"); | |
if (!usn_file) { | |
printf("Cannot open %s for reading. Initializing new file with USN 0x%llx.\n", usn_filename, current_usn); | |
write_usn(usn_filename, current_usn); | |
return 0; | |
} | |
USN saved_usn; | |
fscanf(usn_file, "%llx", &saved_usn); | |
fclose(usn_file); | |
USN begin_usn = saved_usn; | |
USN end_usn = current_usn; | |
printf("File changes from 0x%llx to 0x%llx:\n", begin_usn, current_usn); | |
char buffer[1024] = { 0 }; | |
READ_USN_JOURNAL_DATA journal_read_data = { begin_usn, 0xFFFFFFFF, FALSE, 0, 0, journal_data.UsnJournalID }; | |
while (DeviceIoControl(volume, FSCTL_READ_USN_JOURNAL, &journal_read_data, sizeof(journal_read_data), &buffer, sizeof(buffer), &num_bytes, NULL)) { | |
num_bytes -= sizeof(USN); | |
char *buffer_pointer = buffer + sizeof(USN); | |
while (num_bytes > 0) { | |
USN_RECORD *usn_record = (USN_RECORD *)buffer_pointer; | |
if (usn_record->Usn >= end_usn) { | |
goto finished; | |
} | |
printf("[0x%llx] %.*S\n", usn_record->Usn, usn_record->FileNameLength / 2, usn_record->FileName); | |
buffer_pointer += usn_record->RecordLength; | |
num_bytes -= usn_record->RecordLength; | |
} | |
USN next_usn = *(USN *)buffer; | |
if (next_usn >= end_usn) { | |
goto finished; | |
} | |
journal_read_data.StartUsn = next_usn; | |
} | |
finished: | |
write_usn(usn_filename, current_usn); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment