unsafe private static void EnumerateFiles(string volumeName, IntPtr pVolume, IntPtr medBuffer, Dictionary <ulong, USNRecord> files) { IntPtr pData = Marshal.AllocHGlobal(sizeof(UInt64) + 0x10000); PInvokeWin32.ZeroMemory(pData, sizeof(UInt64) + 0x10000); uint outBytesReturned = 0; while (false != PInvokeWin32.DeviceIoControl(pVolume, PInvokeWin32.FSCTL_ENUM_USN_DATA, medBuffer, sizeof(PInvokeWin32.MFT_ENUM_DATA), pData, sizeof(UInt64) + 0x10000, out outBytesReturned, IntPtr.Zero)) { IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64)); while (outBytesReturned > 60) { PInvokeWin32.USN_RECORD usn = new PInvokeWin32.USN_RECORD(pUsnRecord); files.Add(usn.FRN, new USNRecord { Name = usn.FileName, ParentFrn = usn.ParentFRN, FRN = usn.FRN, IsFolder = usn.IsFolder, VolumeName = volumeName }); pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength); outBytesReturned -= usn.RecordLength; } Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }
private void ProcessFileCreate(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db) { USNRecord record = USNRecord.ParseUSN(volume, usn); db.AddRecord(volume, record); Debug.WriteLine(string.Format(">>>> NewFile: {0}", record.FullPath)); if (RecordAddedEvent != null) { RecordAddedEvent(record); } }
public static USNRecord ParseUSN(string volume, PInvokeWin32.USN_RECORD usn) { return(new USNRecord { FRN = usn.FRN, Name = usn.FileName, ParentFrn = usn.ParentFRN, IsFolder = usn.IsFolder, VolumeName = volume }); }
private void ProcessUSN(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db) { if (MaskEqual(usn.Reason, USNChangeReason.USN_REASONS["USN_REASON_RENAME_NEW_NAME"])) { ProcessRenameNewName(usn, volume, db); } if ((usn.Reason & USNChangeReason.USN_REASONS["USN_REASON_FILE_CREATE"]) != 0) { ProcessFileCreate(usn, volume, db); } if (MaskEqual(usn.Reason, USNChangeReason.USN_REASONS["USN_REASON_FILE_DELETE"])) { ProcessFileDelete(usn, volume, db); } }
private void ProcessFileDelete(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db) { var cached = db.FindByFrn(volume, usn.FRN); if (cached != null) { MFTSearcher.FillPath(volume, cached, db); var deleteok = db.DeleteRecord(volume, usn.FRN); Debug.WriteLine(string.Format(">>>> DeleteFIle {0} {1}.", cached.FullPath, deleteok ? "successful" : "fail")); if (RecordDeletedEvent != null) { RecordDeletedEvent(cached); } } }
private void ProcessRenameNewName(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db) { USNRecord newRecord = USNRecord.ParseUSN(volume, usn); db.UpdateRecord(volume, newRecord); var oldRecord = db.FindByFrn(volume, usn.FRN); if (oldRecord != null) { Debug.WriteLine(string.Format(">>>> RenameFile {0} to {1}", oldRecord.FullPath, newRecord.FullPath)); if (RecordRenameEvent != null) { RecordRenameEvent(oldRecord, newRecord); } } }
private void MonitorThread(string volume, MFTSearcherCache db) { IntPtr pbuffer = Marshal.AllocHGlobal(0x1000); PInvokeWin32.READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead(volume, 0xFFFFFFFF); UInt32 cbRead; IntPtr prujd; while (true) { prujd = Marshal.AllocHGlobal(Marshal.SizeOf(rujd)); PInvokeWin32.ZeroMemory(prujd, Marshal.SizeOf(rujd)); Marshal.StructureToPtr(rujd, prujd, true); IntPtr pVolume = MFTSearcher.GetVolumeJournalHandle(volume); bool fok = PInvokeWin32.DeviceIoControl(pVolume, PInvokeWin32.FSCTL_READ_USN_JOURNAL, prujd, Marshal.SizeOf(typeof(PInvokeWin32.READ_USN_JOURNAL_DATA)), pbuffer, 0x1000, out cbRead, IntPtr.Zero); IntPtr pRealData = new IntPtr(pbuffer.ToInt32() + Marshal.SizeOf(typeof(Int64))); uint offset = 0; if (fok) { while (offset + Marshal.SizeOf(typeof(Int64)) < cbRead) { PInvokeWin32.USN_RECORD usn = new PInvokeWin32.USN_RECORD(new IntPtr(pRealData.ToInt32() + (int)offset)); ProcessUSN(usn, volume, db); offset += usn.RecordLength; } } Marshal.FreeHGlobal(prujd); rujd.StartUsn = Marshal.ReadInt64(pbuffer); } }