Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Last active June 5, 2020 17:20
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pervognsen/bcc610d6a5ae6cbc3b2b4f7aa00d8da9 to your computer and use it in GitHub Desktop.
Save pervognsen/bcc610d6a5ae6cbc3b2b4f7aa00d8da9 to your computer and use it in GitHub Desktop.
#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