public void ChangeDisplay(double top, double left, Win32Api.UsnEntry usnEntry, UsnEntryDetail.EntryDetail entryDetail) { Top = top; Left = left; MainWindow mainWin = (MainWindow)Application.Current.MainWindow; NtfsUsnJournal usnJournal = mainWin.Journal; StringBuilder sb = new StringBuilder(); if (usnEntry.IsFolder) { sb.AppendFormat("Directory: {0}", usnEntry.Name); } else if (usnEntry.IsFile) { sb.AppendFormat("File: {0}", usnEntry.Name); } _nameLbl.Content = sb.ToString(); sb = new StringBuilder(); string path; NtfsUsnJournal.UsnJournalReturnCode usnRtnCode = usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path); if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != string.Compare(path, "Unavailable", true)) { sb.AppendFormat(" Path: {0}{1}\\", usnJournal.VolumeName.TrimEnd('\\'), path); } else { sb.AppendFormat(" Path: {0}", path); } _pathLbl.Content = sb.ToString(); sb = new StringBuilder(); sb.AppendFormat(" File Ref No: {0}", usnEntry.FileReferenceNumber); sb.AppendFormat("\n Parent FRN {0}", usnEntry.ParentFileReferenceNumber); if (entryDetail == EntryDetail.UsnEntry) { sb.AppendFormat("\n Length: {0}", usnEntry.RecordLength); sb.AppendFormat("\n USN: {0}", usnEntry.USN); AddReasonData(sb, usnEntry); } if (usnEntry.IsFile) { string fullPath = System.IO.Path.Combine(path, usnEntry.Name); if (File.Exists(fullPath)) { FileInfo fi = new FileInfo(fullPath); sb.AppendFormat("\n File Length: {0} (bytes)", fi.Length); sb.AppendFormat("\n Creation Time: {0} - {1}", fi.CreationTime.ToShortDateString(), fi.CreationTime.ToShortTimeString()); sb.AppendFormat("\n Last Modify: {0} - {1}", fi.LastWriteTime.ToShortDateString(), fi.LastWriteTime.ToShortTimeString()); sb.AppendFormat("\n Last Access: {0} - {1}", fi.LastAccessTime.ToShortDateString(), fi.LastAccessTime.ToShortTimeString()); } } _entryDetailLbl.Content = sb.ToString(); Visibility = Visibility.Visible; }
public static bool Build_Volume_Mapping(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA currentUsnState, Action <Win32Api.UsnEntry> func) { Debug.WriteLine("Starting Build_Volume_Mapping"); DateTime startTime = DateTime.Now; Win32Api.MFT_ENUM_DATA med; med.StartFileReferenceNumber = 0; med.LowUsn = 0; med.HighUsn = currentUsnState.NextUsn; using (var med_struct = new StructWrapper(med)) using (var rawdata = new Raw_Array_Wrapper(BUF_LEN)) { uint outBytesReturned = 0; while (Win32Api.DeviceIoControl( roothandle.DangerousGetHandle(), Win32Api.FSCTL_ENUM_USN_DATA, med_struct.Ptr, med_struct.Size, rawdata.Ptr, rawdata.Size, out outBytesReturned, IntPtr.Zero)) { outBytesReturned = outBytesReturned - sizeof(Int64); IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//need to skip 8 bytes because the first 8 bytes are to a usn number, which isnt in the structure while (outBytesReturned > 60) { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength); func(usnEntry); if (usnEntry.RecordLength > outBytesReturned) { outBytesReturned = 0;// prevent overflow } else { outBytesReturned -= usnEntry.RecordLength; } } Marshal.WriteInt64(med_struct.Ptr, Marshal.ReadInt64(rawdata.Ptr, 0));//read the usn that we skipped and place it into the nextusn } var possiblerror = Marshal.GetLastWin32Error(); if (possiblerror < 0) { throw new Win32Exception(possiblerror); } } Debug.WriteLine("Time took: " + (DateTime.Now - startTime).TotalMilliseconds + "ms"); return(true); }
/* * public FileNameAndParentFrn(string name, UInt64 frn, UInt64 parentFrn) * { * if (!string.IsNullOrEmpty(name)) * { * _name = name; * } * else * { * throw new ArgumentException("Invalid argument: null or Length = zero", "name"); * } * _frn = frn; * _parentFrn = parentFrn; * } // end FileNameAndParentFrn() closing bracket */ public FileNameAndParentFrn(Win32Api.UsnEntry usnEntry) { if (!string.IsNullOrEmpty(usnEntry.Name)) { _name = usnEntry.Name; } else { throw new ArgumentException("Invalid argument: null or Length = zero", "name"); } _frn = usnEntry.FileReferenceNumber; _parentFrn = usnEntry.ParentFileReferenceNumber; } // end FileNameAndParentFrn() closing bracket
private void resultsLb_Selectionchanged(object sender, SelectionChangedEventArgs e) { ListBox lb = sender as ListBox; if (lb.SelectedItem != null) { if (lb.SelectedItem.GetType() == typeof(Win32Api.UsnEntry)) { Win32Api.UsnEntry item = (Win32Api.UsnEntry)lb.SelectedItem; _usnEntryDetail.ChangeDisplay(_lbItemY, _lbItemX, item, _entryDetail); } } }
public static void GetUsnJournalEntries(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA previousUsnState, UInt32 reasonMask, out List <Win32Api.UsnEntry> usnEntries, out Win32Api.USN_JOURNAL_DATA newUsnState) { usnEntries = new List <Win32Api.UsnEntry>(); newUsnState = new Win32Api.USN_JOURNAL_DATA(); QueryUsnJournal(roothandle, ref newUsnState); Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA(); rujd.StartUsn = previousUsnState.NextUsn; rujd.ReasonMask = reasonMask; rujd.ReturnOnlyOnClose = 0; rujd.Timeout = 0; rujd.bytesToWaitFor = 0; rujd.UsnJournalId = previousUsnState.UsnJournalID; using (var med_struct = new StructWrapper(rujd)) using (var rawdata = new Raw_Array_Wrapper(BUF_LEN)) { uint outBytesReturned = 0; var nextusn = previousUsnState.NextUsn; while (nextusn < newUsnState.NextUsn && Win32Api.DeviceIoControl( roothandle.DangerousGetHandle(), Win32Api.FSCTL_READ_USN_JOURNAL, med_struct.Ptr, med_struct.Size, rawdata.Ptr, rawdata.Size, out outBytesReturned, IntPtr.Zero)) { outBytesReturned = outBytesReturned - sizeof(Int64); IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64)); //point safe arithmetic!~!! while (outBytesReturned > 60) // while there are at least one entry in the usn journal { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); if (usnEntry.USN > newUsnState.NextUsn) { break; } usnEntries.Add(usnEntry); pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);//point safe arithmetic!~!! outBytesReturned -= usnEntry.RecordLength; } nextusn = Marshal.ReadInt64(rawdata.Ptr, 0); Marshal.WriteInt64(med_struct.Ptr, nextusn);//read the usn that we skipped and place it into the nextusn } } }
private static readonly int BUF_LEN = 8192 + 8; //8 bytes for the leading USN #endregion Fields #region Methods public static bool Build_Volume_Mapping(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA currentUsnState, Action<Win32Api.UsnEntry> func) { Debug.WriteLine("Starting Build_Volume_Mapping"); DateTime startTime = DateTime.Now; Win32Api.MFT_ENUM_DATA med; med.StartFileReferenceNumber = 0; med.LowUsn = 0; med.HighUsn = currentUsnState.NextUsn; using(var med_struct = new StructWrapper(med)) using(var rawdata = new Raw_Array_Wrapper(BUF_LEN)) { uint outBytesReturned = 0; while(Win32Api.DeviceIoControl( roothandle.DangerousGetHandle(), Win32Api.FSCTL_ENUM_USN_DATA, med_struct.Ptr, med_struct.Size, rawdata.Ptr, rawdata.Size, out outBytesReturned, IntPtr.Zero)) { outBytesReturned = outBytesReturned - sizeof(Int64); IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//need to skip 8 bytes because the first 8 bytes are to a usn number, which isnt in the structure while(outBytesReturned > 60) { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength); func(usnEntry); if(usnEntry.RecordLength > outBytesReturned) outBytesReturned = 0;// prevent overflow else outBytesReturned -= usnEntry.RecordLength; } Marshal.WriteInt64(med_struct.Ptr, Marshal.ReadInt64(rawdata.Ptr, 0));//read the usn that we skipped and place it into the nextusn } var possiblerror = Marshal.GetLastWin32Error(); if(possiblerror < 0) throw new Win32Exception(possiblerror); } Debug.WriteLine("Time took: " + (DateTime.Now - startTime).TotalMilliseconds + "ms"); return true; }
private static string GetActualPath(NtfsUsnJournal journal, Win32Api.UsnEntry item) { string actualPath = null; string rawPath; var usnRtnCode = journal.GetPathFromFileReference(item.ParentFileReferenceNumber, out rawPath); if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != String.Compare(rawPath, "Unavailable", StringComparison.OrdinalIgnoreCase)) { actualPath = $"{journal.MountPoint.TrimEnd('\\')}{rawPath.TrimEnd('\\')}\\{item.Name}"; } else { return(actualPath); } if (actualPath.ToLowerInvariant().StartsWith($"{journal.MountPoint.TrimEnd('\\')}\\System Volume Information".ToLowerInvariant())) { return(actualPath); } return(actualPath); }
private void resultsLb_MouseDoubleClick(object sender, MouseButtonEventArgs e) { ListBox lb = sender as ListBox; if (lb.SelectedItem != null) { if (lb.SelectedItem.GetType() == typeof(Win32Api.UsnEntry)) { Win32Api.UsnEntry usnEntry = (Win32Api.UsnEntry)lb.SelectedItem; StringBuilder sb = new StringBuilder(); string path; NtfsUsnJournal.UsnJournalReturnCode usnRtnCode = _usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path); if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != string.Compare(path, "Unavailable", true)) { if (usnEntry.IsFile) { string fullPath = System.IO.Path.Combine(path, usnEntry.Name); if (File.Exists(fullPath)) { try { Process.Start(fullPath); } catch (Exception excptn) { MessageBox.Show(excptn.Message); } } else { MessageBox.Show(string.Format("File '{0}' not found", fullPath)); } } } } } }
private void PopulateFlags(RawUSNEntry dbEntry, Win32Api.UsnEntry entry) { uint value = entry.Reason & Win32Api.USN_REASON_DATA_OVERWRITE; if (0 != value) { dbEntry.DataOverwrite = true; } value = entry.Reason & Win32Api.USN_REASON_DATA_EXTEND; if (0 != value) { dbEntry.DataExtend = true; } value = entry.Reason & Win32Api.USN_REASON_DATA_TRUNCATION; if (0 != value) { dbEntry.DataTruncation = true; } value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_OVERWRITE; if (0 != value) { dbEntry.NamedDataOverwrite = true; } value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_EXTEND; if (0 != value) { dbEntry.NamedDataExtend = true; } value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_TRUNCATION; if (0 != value) { dbEntry.NamedDataTruncation = true; } value = entry.Reason & Win32Api.USN_REASON_FILE_CREATE; if (0 != value) { dbEntry.FileCreate = true; } value = entry.Reason & Win32Api.USN_REASON_FILE_DELETE; if (0 != value) { dbEntry.FileDelete = true; } value = entry.Reason & Win32Api.USN_REASON_EA_CHANGE; if (0 != value) { dbEntry.EaChange = true; } value = entry.Reason & Win32Api.USN_REASON_SECURITY_CHANGE; if (0 != value) { dbEntry.SecurityChange = true; } value = entry.Reason & Win32Api.USN_REASON_RENAME_OLD_NAME; if (0 != value) { dbEntry.RenameOldName = true; } value = entry.Reason & Win32Api.USN_REASON_RENAME_NEW_NAME; if (0 != value) { dbEntry.RenameNewName = true; } value = entry.Reason & Win32Api.USN_REASON_INDEXABLE_CHANGE; if (0 != value) { dbEntry.IndexableChange = true; } value = entry.Reason & Win32Api.USN_REASON_BASIC_INFO_CHANGE; if (0 != value) { dbEntry.BasicInfoChange = true; } value = entry.Reason & Win32Api.USN_REASON_HARD_LINK_CHANGE; if (0 != value) { dbEntry.HardLinkChange = true; } value = entry.Reason & Win32Api.USN_REASON_COMPRESSION_CHANGE; if (0 != value) { dbEntry.CompressionChange = true; } value = entry.Reason & Win32Api.USN_REASON_ENCRYPTION_CHANGE; if (0 != value) { dbEntry.EncryptionChange = true; } value = entry.Reason & Win32Api.USN_REASON_OBJECT_ID_CHANGE; if (0 != value) { dbEntry.ObjectIdChange = true; } value = entry.Reason & Win32Api.USN_REASON_REPARSE_POINT_CHANGE; if (0 != value) { dbEntry.ReparsePointChange = true; } value = entry.Reason & Win32Api.USN_REASON_STREAM_CHANGE; if (0 != value) { dbEntry.StreamChange = true; } value = entry.Reason & Win32Api.USN_REASON_CLOSE; if (0 != value) { dbEntry.Close = true; } }
/// <summary>Given a previous state, GetUsnJournalEntries() determines if the USN journal is active and /// no USN journal entries have been lost (i.e. USN journal is valid), then /// it loads a SortedList<UInt64, Win32Api.UsnEntry> list and returns it as the out parameter 'usnEntries'. /// If GetUsnJournalChanges returns anything but USN_JOURNAL_SUCCESS, the usnEntries list will /// be empty. /// </summary> /// <param name="previousUsnState">The USN journal state the last time volume changes were requested.</param> /// <param name="reasonMask"></param> /// <param name="usnEntries"></param> /// <param name="newUsnState"></param> /// <returns> /// USN_JOURNAL_SUCCESS GetUsnJournalChanges() function succeeded. /// VOLUME_NOT_NTFS volume is not an NTFS volume. /// INVALID_HANDLE_VALUE NtfsUsnJournal object failed initialization. /// USN_JOURNAL_NOT_ACTIVE USN journal is not active on volume. /// ERROR_ACCESS_DENIED accessing the USN journal requires admin rights, see remarks. /// ERROR_INVALID_FUNCTION error generated by DeviceIoControl() call. /// ERROR_FILE_NOT_FOUND error generated by DeviceIoControl() call. /// ERROR_PATH_NOT_FOUND error generated by DeviceIoControl() call. /// ERROR_TOO_MANY_OPEN_FILES error generated by DeviceIoControl() call. /// ERROR_INVALID_HANDLE error generated by DeviceIoControl() call. /// ERROR_INVALID_DATA error generated by DeviceIoControl() call. /// ERROR_NOT_SUPPORTED error generated by DeviceIoControl() call. /// ERROR_INVALID_PARAMETER error generated by DeviceIoControl() call. /// ERROR_JOURNAL_DELETE_IN_PROGRESS USN journal delete is in progress. /// ERROR_INVALID_USER_BUFFER error generated by DeviceIoControl() call. /// USN_JOURNAL_ERROR unspecified USN journal error. /// </returns> /// <remarks> /// If function returns ERROR_ACCESS_DENIED you need to run application as an Administrator. /// </remarks> public int GetUsnJournalEntries(Win32Api.USN_JOURNAL_DATA_V0 previousUsnState, uint reasonMask, out List <Win32Api.UsnEntry> usnEntries, out Win32Api.USN_JOURNAL_DATA_V0 newUsnState) { usnEntries = new List <Win32Api.UsnEntry>(); newUsnState = new Win32Api.USN_JOURNAL_DATA_V0(); var lastError = (int)UsnJournalReturnCode.VOLUME_NOT_NTFS; var sw = new Stopwatch(); sw.Start(); if (bNtfsVolume) { if (_usnJournalRootHandle.ToInt64() != Win32Api.INVALID_HANDLE_VALUE) { // Get current USN journal state. lastError = QueryUsnJournal(ref newUsnState); if (lastError == (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS) { var bReadMore = true; // Sequentially process the USN journal looking for image file entries. const int pbDataSize = sizeof(ulong) * 16384; var pbData = Marshal.AllocHGlobal(pbDataSize); Win32Api.ZeroMemory(pbData, pbDataSize); var rujd = new Win32Api.READ_USN_JOURNAL_DATA_V0 { StartUsn = (ulong)previousUsnState.NextUsn, ReasonMask = reasonMask, ReturnOnlyOnClose = 0, Timeout = 0, BytesToWaitFor = 0, UsnJournalId = previousUsnState.UsnJournalID }; var sizeRujd = Marshal.SizeOf(rujd); var rujdBuffer = Marshal.AllocHGlobal(sizeRujd); Win32Api.ZeroMemory(rujdBuffer, sizeRujd); Marshal.StructureToPtr(rujd, rujdBuffer, true); // Read USN journal entries. while (bReadMore) { uint outBytesReturned; var bRtn = Win32Api.DeviceIoControl(_usnJournalRootHandle, Win32Api.FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd, pbData, pbDataSize, out outBytesReturned, IntPtr.Zero); if (bRtn) { var pUsnRecord = new IntPtr(pbData.ToInt64() + sizeof(ulong)); // While there is at least one entry in the USN journal. while (outBytesReturned > 60) { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); // Only read until the current usn points beyond the current state's USN. if (usnEntry.USN >= newUsnState.NextUsn) { bReadMore = false; break; } usnEntries.Add(usnEntry); pUsnRecord = new IntPtr(pUsnRecord.ToInt64() + usnEntry.RecordLength); outBytesReturned -= usnEntry.RecordLength; } } else { var lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error == (int)Win32Api.GetLastErrorEnum.ERROR_HANDLE_EOF) { lastError = (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS; } break; } var nextUsn = Marshal.ReadInt64(pbData, 0); if (nextUsn >= newUsnState.NextUsn) { break; } Marshal.WriteInt64(rujdBuffer, nextUsn); } Marshal.FreeHGlobal(rujdBuffer); Marshal.FreeHGlobal(pbData); } } else { lastError = (int)UsnJournalReturnCode.INVALID_HANDLE_VALUE; } } ElapsedTime = TimeSpan.FromMilliseconds(sw.ElapsedMilliseconds); return(lastError); }
/// <summary>Returns an enumerable collection of <see cref="Win32Api.UsnEntry"/> entries that meet specified criteria.</summary> /// <param name="onlyFolders"></param> /// <param name="filter">The filter.</param> private IEnumerable <Win32Api.UsnEntry> EnumerateUsnEntries(bool?onlyFolders, string filter = null) { var usnState = new Win32Api.USN_JOURNAL_DATA_V0(); if (QueryUsnJournal(ref usnState) != (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS) { throw new Win32Exception("Failed to query the USN journal on the volume."); } if (string.IsNullOrWhiteSpace(filter) || filter.Equals("*", StringComparison.Ordinal)) { filter = null; } var fileTypes = null != filter?filter.Split(' ', ',', ';') : null; // Set up MFT_ENUM_DATA_V0 structure. var mftData = new Win32Api.MFT_ENUM_DATA_V0 { StartFileReferenceNumber = 0, LowUsn = 0, HighUsn = usnState.NextUsn }; var mftDataSize = Marshal.SizeOf(mftData); var mftDataBuffer = Marshal.AllocHGlobal(mftDataSize); Win32Api.ZeroMemory(mftDataBuffer, mftDataSize); Marshal.StructureToPtr(mftData, mftDataBuffer, true); // Set up the data buffer which receives the USN_RECORD data. const int pDataSize = sizeof(ulong) + 10000; var pData = Marshal.AllocHGlobal(pDataSize); Win32Api.ZeroMemory(pData, pDataSize); uint outBytesReturned; // Gather up volume's directories. while (Win32Api.DeviceIoControl(_usnJournalRootHandle, Win32Api.FSCTL_ENUM_USN_DATA, mftDataBuffer, mftDataSize, pData, pDataSize, out outBytesReturned, IntPtr.Zero)) { var pUsnRecord = new IntPtr(pData.ToInt64() + sizeof(long)); // While there is at least one entry in the USN journal. while (outBytesReturned > 60) { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); if (null == onlyFolders) { yield return(usnEntry); } else if (usnEntry.IsFolder) { if ((bool)onlyFolders) { yield return(usnEntry); } } else if (!(bool)onlyFolders) { if (null == filter) { yield return(usnEntry); } else { var extension = Path.GetExtension(usnEntry.Name); if (!string.IsNullOrEmpty(extension)) { foreach (var fileType in fileTypes) { if (fileType.Contains("*")) { if (extension.IndexOf(fileType.Trim('*'), StringComparison.OrdinalIgnoreCase) >= 0) { yield return(usnEntry); } } else if (extension.Equals("." + fileType.TrimStart('.'), StringComparison.OrdinalIgnoreCase)) { yield return(usnEntry); } } } } } pUsnRecord = new IntPtr(pUsnRecord.ToInt64() + usnEntry.RecordLength); outBytesReturned -= usnEntry.RecordLength; } Marshal.WriteInt64(mftDataBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }
/// <summary> /// GetFileAndDirEntries() reads the Master File Table to find all of the files and /// folders on a volume and returns them individually. /// </summary> /// <param name="dirs">The directories.</param> /// <param name="files">The files.</param> /// <param name="filter">The filter.</param> private void GetFileAndDirEntries(out ConcurrentDictionary<ulong, Win32Api.UsnEntry> dirs, out ConcurrentBag<Win32Api.UsnEntry> files, Regex filter = null) { dirs = new ConcurrentDictionary<ulong, Win32Api.UsnEntry>(); files = new ConcurrentBag<Win32Api.UsnEntry>(); var usnState = new Win32Api.USN_JOURNAL_DATA(); if (!QueryUsnJournal(ref usnState)) { throw new Win32Exception("Failed to query the USN journal on the volume."); } // // set up MFT_ENUM_DATA structure // Win32Api.MFT_ENUM_DATA med; med.StartFileReferenceNumber = 0; med.LowUsn = 0; med.HighUsn = usnState.NextUsn; Int32 sizeMftEnumData = Marshal.SizeOf(med); IntPtr medBuffer = Marshal.AllocHGlobal(sizeMftEnumData); Win32Api.ZeroMemory(medBuffer, sizeMftEnumData); Marshal.StructureToPtr(med, medBuffer, true); // // set up the data buffer which receives the USN_RECORD data // int pDataSize = sizeof (UInt64) + 10000; IntPtr pData = Marshal.AllocHGlobal(pDataSize); Win32Api.ZeroMemory(pData, pDataSize); uint outBytesReturned = 0; // // Gather up volume's directories // while (Win32Api.DeviceIoControl( _usnJournalRootHandle, Win32Api.FSCTL_ENUM_USN_DATA, medBuffer, sizeMftEnumData, pData, pDataSize, out outBytesReturned, IntPtr.Zero)) { IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof (Int64)); while (outBytesReturned > 60) { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); if (usnEntry.IsFile && (filter == null || filter.IsMatch(usnEntry.Name))) { files.Add(usnEntry); } if (usnEntry.IsFolder) { dirs.TryAdd(usnEntry.FileReferenceNumber, usnEntry); } pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnEntry.RecordLength); outBytesReturned -= usnEntry.RecordLength; } Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }
private static void AddReasonData(StringBuilder sb, Win32Api.UsnEntry usnEntry) { sb.AppendFormat("\n Reason Codes:"); var value = usnEntry.Reason & Win32Api.USN_REASON_DATA_OVERWRITE; if (0 != value) { sb.AppendFormat("\n -DATA OVERWRITE"); } value = usnEntry.Reason & Win32Api.USN_REASON_DATA_EXTEND; if (0 != value) { sb.AppendFormat("\n -DATA EXTEND"); } value = usnEntry.Reason & Win32Api.USN_REASON_DATA_TRUNCATION; if (0 != value) { sb.AppendFormat("\n -DATA TRUNCATION"); } value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_OVERWRITE; if (0 != value) { sb.AppendFormat("\n -NAMED DATA OVERWRITE"); } value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_EXTEND; if (0 != value) { sb.AppendFormat("\n -NAMED DATA EXTEND"); } value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_TRUNCATION; if (0 != value) { sb.AppendFormat("\n -NAMED DATA TRUNCATION"); } value = usnEntry.Reason & Win32Api.USN_REASON_FILE_CREATE; if (0 != value) { sb.AppendFormat("\n -FILE CREATE"); } value = usnEntry.Reason & Win32Api.USN_REASON_FILE_DELETE; if (0 != value) { sb.AppendFormat("\n -FILE DELETE"); } value = usnEntry.Reason & Win32Api.USN_REASON_EA_CHANGE; if (0 != value) { sb.AppendFormat("\n -EA CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_SECURITY_CHANGE; if (0 != value) { sb.AppendFormat("\n -SECURITY CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_RENAME_OLD_NAME; if (0 != value) { sb.AppendFormat("\n -RENAME OLD NAME"); } value = usnEntry.Reason & Win32Api.USN_REASON_RENAME_NEW_NAME; if (0 != value) { sb.AppendFormat("\n -RENAME NEW NAME"); } value = usnEntry.Reason & Win32Api.USN_REASON_INDEXABLE_CHANGE; if (0 != value) { sb.AppendFormat("\n -INDEXABLE CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_BASIC_INFO_CHANGE; if (0 != value) { sb.AppendFormat("\n -BASIC INFO CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_HARD_LINK_CHANGE; if (0 != value) { sb.AppendFormat("\n -HARD LINK CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_COMPRESSION_CHANGE; if (0 != value) { sb.AppendFormat("\n -COMPRESSION CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_ENCRYPTION_CHANGE; if (0 != value) { sb.AppendFormat("\n -ENCRYPTION CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_OBJECT_ID_CHANGE; if (0 != value) { sb.AppendFormat("\n -OBJECT ID CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_REPARSE_POINT_CHANGE; if (0 != value) { sb.AppendFormat("\n -REPARSE POINT CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_STREAM_CHANGE; if (0 != value) { sb.AppendFormat("\n -STREAM CHANGE"); } value = usnEntry.Reason & Win32Api.USN_REASON_CLOSE; if (0 != value) { sb.AppendFormat("\n -CLOSE"); } }
public void ChangeDisplay(NtfsUsnJournal usnJournal, double top, double left, Win32Api.UsnEntry usnEntry, EntryDetail entryDetail) { Top = top; Left = left; _nameLbl.Text = string.Format(CultureInfo.InvariantCulture, usnEntry.IsFolder ? "Directory: {0}" : "File: {0}", usnEntry.Name); string path; var lastError = usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path); if (lastError == (int)NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && null != path) { path = string.Format(CultureInfo.InvariantCulture, "{0}{1}\\", usnJournal.VolumeName.TrimEnd('\\'), path); } _pathLbl.Text = path; var sb = new StringBuilder(); sb.AppendFormat(" File Ref No: {0}", usnEntry.FileReferenceNumber); sb.AppendFormat("\n Parent FRN {0}", usnEntry.ParentFileReferenceNumber); if (entryDetail == EntryDetail.UsnEntry) { sb.AppendFormat("\n Length: {0}", usnEntry.RecordLength); sb.AppendFormat("\n USN: {0}", usnEntry.USN); AddReasonData(sb, usnEntry); } if (!usnEntry.IsFolder) { var fullPath = Path.Combine(_pathLbl.Text, usnEntry.Name); if (File.Exists(fullPath)) { var fi = new FileInfo(fullPath); sb.AppendFormat("\n File Length: {0} (bytes)", fi.Length); sb.AppendFormat("\n Creation Time: {0} - {1}", fi.CreationTime.ToShortDateString(), fi.CreationTime.ToShortTimeString()); sb.AppendFormat("\n Last Modify: {0} - {1}", fi.LastWriteTime.ToShortDateString(), fi.LastWriteTime.ToShortTimeString()); sb.AppendFormat("\n Last Access: {0} - {1}", fi.LastAccessTime.ToShortDateString(), fi.LastAccessTime.ToShortTimeString()); } } _entryDetailLbl.Content = sb.ToString(); Visibility = Visibility.Visible; }
public static void GetUsnJournalEntries(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA previousUsnState, UInt32 reasonMask, out List<Win32Api.UsnEntry> usnEntries, out Win32Api.USN_JOURNAL_DATA newUsnState) { usnEntries = new List<Win32Api.UsnEntry>(); newUsnState = new Win32Api.USN_JOURNAL_DATA(); QueryUsnJournal(roothandle, ref newUsnState); Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA(); rujd.StartUsn = previousUsnState.NextUsn; rujd.ReasonMask = reasonMask; rujd.ReturnOnlyOnClose = 0; rujd.Timeout = 0; rujd.bytesToWaitFor = 0; rujd.UsnJournalId = previousUsnState.UsnJournalID; using(var med_struct = new StructWrapper(rujd)) using(var rawdata = new Raw_Array_Wrapper(BUF_LEN)) { uint outBytesReturned = 0; var nextusn = previousUsnState.NextUsn; while(nextusn < newUsnState.NextUsn && Win32Api.DeviceIoControl( roothandle.DangerousGetHandle(), Win32Api.FSCTL_READ_USN_JOURNAL, med_struct.Ptr, med_struct.Size, rawdata.Ptr, rawdata.Size, out outBytesReturned, IntPtr.Zero)) { outBytesReturned = outBytesReturned - sizeof(Int64); IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//point safe arithmetic!~!! while(outBytesReturned > 60) // while there are at least one entry in the usn journal { var usnEntry = new Win32Api.UsnEntry(pUsnRecord); if(usnEntry.USN > newUsnState.NextUsn) break; usnEntries.Add(usnEntry); pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);//point safe arithmetic!~!! outBytesReturned -= usnEntry.RecordLength; } nextusn = Marshal.ReadInt64(rawdata.Ptr, 0); Marshal.WriteInt64(med_struct.Ptr, nextusn);//read the usn that we skipped and place it into the nextusn } } }
public NTFS_File(Win32Api.UsnEntry u) { Entry = u; Children = new List <NTFS_File>(); Parent = null; }