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 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; }
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 } } }