public static void PrintUsnEntry(IConsole console, UsnJournal usnJournal, UsnEntry usnEntry) { console.WriteLine(); console.WriteLine($"{"USN:",-20}{usnEntry.USN:X}"); console.WriteLine(usnEntry.IsFolder ? $"{"Directory:",-20}{usnEntry.Name}" : $"{"File:",-20}{usnEntry.Name}"); if (usnJournal.TryGetPathFromFileId(usnEntry.ParentFileReferenceNumber, out var path)) { path = $"{usnJournal.VolumeName.TrimEnd('\\')}{path}"; console.WriteLine($"{"Parent:",-20}{path}"); } if (usnEntry.TimeStamp > 0) { console.WriteLine($"{"Timestamp:",-20}{DateTime.FromFileTimeUtc(usnEntry.TimeStamp).ToLocalTime()}"); } console.WriteLine($"{"File ID:",-20}{usnEntry.FileReferenceNumber:X}"); console.WriteLine($"{"Parent File ID:",-20}{usnEntry.ParentFileReferenceNumber:X}"); var reason = ((UsnReason)usnEntry.Reason).ToString().Replace(',', '|'); console.WriteLine($"{"Reason:",-20}{reason}"); var sourceInfo = ((UsnSource)usnEntry.SourceInfo).ToString().Replace(',', '|'); console.WriteLine($"{"Source Info:",-20}{sourceInfo}"); }
public static void PrintEntryPath(IConsole console, UsnJournal usnJournal, UsnEntry usnEntry) { console.WriteLine(); console.WriteLine($"{"Name:",-20}{usnEntry.Name}"); console.WriteLine($"{"IsFolder:",-20}{usnEntry.IsFolder}"); if (usnJournal.TryGetPathFromFileId(usnEntry.ParentFileReferenceNumber, out var path)) { path = $"{usnJournal.VolumeName.TrimEnd('\\')}{path}"; console.WriteLine($"{"Parent:",-20}{path}"); } }
private static void SearchMasterFileTable(IConsole console, UsnJournal journal, string filter, bool?onlyFiles, CancellationToken token) { var usnEntries = journal.EnumerateUsnEntries(filter, onlyFiles); foreach (var entry in usnEntries) { if (token.IsCancellationRequested) { break; } PrintEntryPath(console, journal, entry); } }
private static void MonitorRealTimeUsnJournal(IConsole console, UsnJournal journal, USN_JOURNAL_DATA_V0 usnState, string filter, bool?onlyFiles, CancellationToken token) { while (true) { if (token.IsCancellationRequested) { return; } var usnEntries = journal.GetUsnJournalEntries(usnState, 0xFFFFFFFF, filter, onlyFiles, out usnState); foreach (var entry in usnEntries) { PrintUsnEntry(console, journal, entry); } } }
private static void ReadHistoryUsnJournals(IConsole console, UsnJournal journal, ulong usnJournalId, string filter, bool?onlyFiles, CancellationToken token) { var usnReadState = new USN_JOURNAL_DATA_V0 { NextUsn = 0, UsnJournalID = usnJournalId }; var usnEntries = journal.ReadUsnEntries(usnReadState, 0xFFFFFFFF, filter, onlyFiles); foreach (var entry in usnEntries) { if (token.IsCancellationRequested) { break; } PrintUsnEntry(console, journal, entry); } }
private void OnExecute() { var console = PhysicalConsole.Singleton; var cts = new CancellationTokenSource(); console.CancelKeyPress += (o, e) => { console.WriteLine("Keyboard interrupt, exiting..."); cts.Cancel(); }; if (!OperatingSystem.IsWindows()) { console.PrintError($"This tool only support Windows OS."); return; } if (!HasAdministratorPrivilege()) { console.PrintError($"You must have system administrator privileges to access the change journal of \"{Volume}\"."); return; } bool?onlyFiles; if (FileOnly) { onlyFiles = true; } else if (DirectoryOnly) { onlyFiles = false; } else { onlyFiles = null; } try { var driveInfo = new DriveInfo(Volume); var journal = new UsnJournal(driveInfo); var usnState = new USN_JOURNAL_DATA_V0(); var retCode = journal.GetUsnJournalState(ref usnState); if (retCode != 0) { console.PrintError($"FSCTL_QUERY_USN_JOURNAL failed with {retCode}"); return; } PrintUsnJournalState(console, usnState); if (Read) { MonitorRealTimeUsnJournal(console, journal, usnState, Filter, onlyFiles, cts.Token); } else if (Search) { SearchMasterFileTable(console, journal, Filter, onlyFiles, cts.Token); } else { ReadHistoryUsnJournals(console, journal, usnState.UsnJournalID, Filter, onlyFiles, cts.Token); } } catch (Exception ex) { console.PrintError(ex.Message); } }