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 } } }
/// <summary> /// Unused internal function that can be used to read all USN records /// </summary> /// <param name="lastUsn">The USN number to start from</param> internal List <KeyValuePair <string, Win32USN.USN_RECORD> > GetChangedItems(long lastUsn) { bool more = true; //int usnsize = (int)Marshal.SizeOf(typeof(long)); /* const int ALLOCATED_MEMORY = 64 * 1024; * * IntPtr allocatedMemory = IntPtr.Zero; * List<KeyValuePair<string, Win32USN.USN_RECORD>> records = new List<KeyValuePair<string, Win32USN.USN_RECORD>>(); * * try * { * uint bytesRead = 0; * * allocatedMemory = Marshal.AllocHGlobal(ALLOCATED_MEMORY); * * Win32USN.READ_USN_JOURNAL_DATA startParams = new Win32USN.READ_USN_JOURNAL_DATA(); * * startParams.StartUsn = 0; //lastUsn; * startParams.ReasonMask = Win32USN.USNReason.USN_REASON_ANY; * //startParams.ReturnOnlyOnClose = 0; * //startParams.ReturnOnlyOnClose = false; * startParams.Timeout = 0; * startParams.BytesToWaitFor = 0; * startParams.UsnJournalID = (ulong)m_journal.UsnJournalID; * Console.WriteLine ("GetChangedItems() : before loop");*/ try{ int pbDataSize = sizeof(UInt64) * 0x4000; IntPtr pbData = Marshal.AllocHGlobal(pbDataSize); Win32Api.ZeroMemory(pbData, pbDataSize); uint outBytesReturned = 0; Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA(); rujd.StartUsn = 0; // lastUsn rujd.ReasonMask = Win32Api.USN_REASON_CLOSE | Win32Api.USN_REASON_FILE_DELETE | Win32Api.USN_REASON_RENAME_NEW_NAME | Win32Api.USN_REASON_RENAME_OLD_NAME; rujd.ReturnOnlyOnClose = 0; rujd.Timeout = 0; rujd.bytesToWaitFor = 0; rujd.UsnJournalId = (ulong)m_journal.UsnJournalID; int sizeRujd = Marshal.SizeOf(rujd); IntPtr rujdBuffer = Marshal.AllocHGlobal(sizeRujd); Win32Api.ZeroMemory(rujdBuffer, sizeRujd); Marshal.StructureToPtr(rujd, rujdBuffer, true); //Win32Api.USN_RECORD usn = null; // // read usn journal entries // while (more) { bool bRtn = Win32Api.DeviceIoControl( m_volumeHandle, Win32Api.FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd, pbData, pbDataSize, out outBytesReturned, IntPtr.Zero); if (!bRtn) { /* while (more) * { * * if (!Win32USN.DeviceIoControl(m_volumeHandle, Win32USN.EIOControlCode.FsctlReadUsnJournal, * ref startParams, (uint)Marshal.SizeOf(typeof(Win32USN.READ_USN_JOURNAL_DATA)), * ref allocatedMemory, ALLOCATED_MEMORY, * ref bytesRead, IntPtr.Zero)) * * {*/ int errorCode = Marshal.GetLastWin32Error(); Console.WriteLine("GetChangedItems() : errorcode=" + errorCode + ", bytesRead=" + outBytesReturned); //If we get no error or EOF the enumeration is completed if (errorCode == Win32USN.ERROR_HANDLE_EOF || errorCode == Win32USN.ERROR_SUCCESS) { break; } else { throw new Win32Exception(errorCode); } } Console.WriteLine("GetChangedItems() : EVICEOONTROL5° CALL IS OK"); startParams.StartUsn = ExtractUsnEntries(bytesRead, allocatedMemory, records, out more); } //Records now contains all Usn entries } catch (Exception e) { Console.WriteLine("GetChangedItems() : Error : " + e.ToString()); throw; } finally { if (allocatedMemory != IntPtr.Zero) { Marshal.FreeHGlobal(allocatedMemory); allocatedMemory = IntPtr.Zero; } } return(records); }
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 } } }