[NO-PARSE]#define __USE_MINGW_ANSI_STDIO 1
#include <Windows.h>
#include <stdio.h>
#include <assert.h>
#define PAGE_SIZE 4096
#define STRTOKEN(x) #x
#define STR(x) STRTOKEN(x)
#define HAS_FLAG(value, mask) (((value) & (mask)) == mask)
#define ERROR_EXIT(x) ret = (x); goto end
void ListUSNJournalReasons(DWORD reason)
{
if (HAS_FLAG(reason, USN_REASON_BASIC_INFO_CHANGE)) fputs(" - USN_REASON_BASIC_INFO_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_CLOSE)) fputs(" - USN_REASON_CLOSE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_COMPRESSION_CHANGE)) fputs(" - USN_REASON_COMPRESSION_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_DATA_EXTEND)) fputs(" - USN_REASON_DATA_EXTEND\n", stdout);
if (HAS_FLAG(reason, USN_REASON_DATA_OVERWRITE)) fputs(" - USN_REASON_DATA_OVERWRITE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_DATA_TRUNCATION)) fputs(" - USN_REASON_DATA_TRUNCATION\n", stdout);
if (HAS_FLAG(reason, USN_REASON_EA_CHANGE)) fputs(" - USN_REASON_EA_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_ENCRYPTION_CHANGE)) fputs(" - USN_REASON_ENCRYPTION_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_FILE_CREATE)) fputs(" - USN_REASON_FILE_CREATE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_FILE_DELETE)) fputs(" - USN_REASON_FILE_DELETE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_HARD_LINK_CHANGE)) fputs(" - USN_REASON_HARD_LINK_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_INDEXABLE_CHANGE)) fputs(" - USN_REASON_INDEXABLE_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_NAMED_DATA_EXTEND)) fputs(" - USN_REASON_NAMED_DATA_EXTEND\n", stdout);
if (HAS_FLAG(reason, USN_REASON_NAMED_DATA_OVERWRITE)) fputs(" - USN_REASON_NAMED_DATA_OVERWRITE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_NAMED_DATA_TRUNCATION)) fputs(" - USN_REASON_NAMED_DATA_TRUNCATION\n", stdout);
if (HAS_FLAG(reason, USN_REASON_OBJECT_ID_CHANGE)) fputs(" - USN_REASON_OBJECT_ID_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_RENAME_NEW_NAME)) fputs(" - USN_REASON_RENAME_NEW_NAME\n", stdout);
if (HAS_FLAG(reason, USN_REASON_RENAME_OLD_NAME)) fputs(" - USN_REASON_RENAME_OLD_NAME\n", stdout);
if (HAS_FLAG(reason, USN_REASON_REPARSE_POINT_CHANGE)) fputs(" - USN_REASON_REPARSE_POINT_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_SECURITY_CHANGE)) fputs(" - USN_REASON_SECURITY_CHANGE\n", stdout);
if (HAS_FLAG(reason, USN_REASON_STREAM_CHANGE)) fputs(" - USN_REASON_STREAM_CHANGE\n", stdout);
/*if (HAS_FLAG(reason, USN_REASON_INTEGRITY_CHANGE)) fputs(" - USN_REASON_INTEGRITY_CHANGE\n", stdout);*/
/*if (HAS_FLAG(reason, USN_REASON_TRANSACTED_CHANGE)) fputs(" - USN_REASON_TRANSACTED_CHANGE\n", stdout);*/
}
int main(void)
{
DWORD ret;
CHAR szBuf[PAGE_SIZE];
fputs("\nEnter Volume GUID / Drive Letter (Ex: C): ", stdout);
scanf(" %" STR(sizeof(szBuf) - 1) "s", szBuf);
CHAR szFilename[MAX_PATH];
sprintf(szFilename, szBuf[1] ? "\\\\?\\Volume{%s}\\" : "\\\\.\\%s:", szBuf);
printf("[-] Opening handle to: %s\n", szFilename);
HANDLE hVolume = CreateFile(szFilename,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hVolume != INVALID_HANDLE_VALUE)
{
puts("[-] Obtained handle to specified volume.\n");
DWORD nBytes = 0;
USN_JOURNAL_DATA usnJrnl = { 0 };
ret = DeviceIoControl(hVolume,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
(LPVOID)&usnJrnl,
sizeof(usnJrnl),
&nBytes,
NULL);
if (ret)
{
printf("UsnJournalID : 0x%llx\n", usnJrnl.UsnJournalID);
printf("FirstUsn : 0x%llx\n", usnJrnl.FirstUsn);
printf("NextUsn : 0x%llx\n", usnJrnl.NextUsn);
printf("LowestValidUsn : 0x%llx\n", usnJrnl.LowestValidUsn);
printf("MaxUsn : 0x%llx\n", usnJrnl.MaxUsn);
printf("MaximumSize : 0x%llx\n", usnJrnl.MaximumSize);
printf("AllocationDelta : 0x%llx\n", usnJrnl.AllocationDelta);
printf("\n");
DWORD dwUsnReasonMask = USN_REASON_FILE_CREATE;
READ_USN_JOURNAL_DATA readUsnJrnl = { 0 };
readUsnJrnl.StartUsn = usnJrnl.FirstUsn;
readUsnJrnl.ReasonMask = dwUsnReasonMask;
readUsnJrnl.ReturnOnlyOnClose = FALSE;
readUsnJrnl.Timeout = 0;
readUsnJrnl.BytesToWaitFor = 0;
readUsnJrnl.UsnJournalID = usnJrnl.UsnJournalID;
DWORD dwRetBytes;
while (readUsnJrnl.StartUsn < usnJrnl.NextUsn)
{
memset(szBuf, 0, PAGE_SIZE);
ret = DeviceIoControl(hVolume,
FSCTL_READ_USN_JOURNAL,
&readUsnJrnl,
sizeof(readUsnJrnl),
&szBuf,
PAGE_SIZE,
&nBytes,
NULL);
if (ret)
{
dwRetBytes = nBytes - sizeof(USN);
PUSN_RECORD record = (PUSN_RECORD)(((PUCHAR)szBuf) + sizeof(USN));
while (dwRetBytes > 0)
{
printf("USN: 0x%llx\n", record->Usn);
wprintf(L"Filename: %.*S\n", record->FileNameLength / 2, record->FileName);
printf("USN Reason: (0x%llx)\n", record->Usn);
ListUSNJournalReasons(record->Reason);
printf("\n");
dwRetBytes -= record->RecordLength;
record = (PUSN_RECORD)(((PCHAR)record) + record->RecordLength);
}
readUsnJrnl.StartUsn = *(USN *)&szBuf;
}
else
{
fprintf(stderr, "Read journal failed (%lu)\n", GetLastError());
ERROR_EXIT(-1);
}
}
}
else
{
fprintf(stderr, "Query journal failed (%lx)\n", GetLastError());
ERROR_EXIT(-1);
}
}
else
{
fprintf(stderr, "Failed to obtain handle to speciied volume (%lx)\n", GetLastError());
ERROR_EXIT(-1);
}
end:
if (hVolume != INVALID_HANDLE_VALUE) CloseHandle(hVolume);
return ret;
}[/NO-PARSE]