private void ProcessRenameNewName(PInvokeWin32.USN_RECORD usn, string volume, MyEverythingDB db) { // frn 没有改变 // newname = usn.FileName // 根据usn.FRN可以从db中获取oldname // db.update... MyEverythingRecord newRecord = MyEverythingRecord.ParseUSN(usn); string fullpath = newRecord.Name; db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(volume)); newRecord.FullPath = fullpath; var oldRecord = db.FindByFrn(volume, usn.FRN); string newname = newRecord.FullPath; Debug.WriteLine(string.Format(">>>> RenameFile {0} to {1}", oldRecord.FullPath, newname)); db.UpdateRecord(volume, newRecord, usn.IsFolder ? MyEverythingRecordType.Folder : MyEverythingRecordType.File); if (RecordRenameEvent != null) { RecordRenameEvent(oldRecord, newRecord); } if (newname.Contains("$RECYCLE.BIN")) { Debug.WriteLine(string.Format(">>>> Means {0} moved to recycle.", oldRecord.FullPath)); } }
public static MyEverythingRecord ParseUSN(string volume, PInvokeWin32.USN_RECORD usn) { return(new MyEverythingRecord { FRN = usn.FRN, Name = usn.FileName, ParentFrn = usn.ParentFRN, IsFolder = usn.IsFolder, VolumeName = volume }); }
private void ProcessFileCreate(PInvokeWin32.USN_RECORD usn, string volume, MyEverythingDB db) { MyEverythingRecord record = MyEverythingRecord.ParseUSN(usn); string fullpath = record.Name; db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume)); record.FullPath = fullpath; db.AddRecord(volume, record, usn.IsFolder ? MyEverythingRecordType.Folder : MyEverythingRecordType.File); Debug.WriteLine(string.Format(">>>> NewFile: {0}", record.FullPath)); if (RecordAddedEvent != null) { RecordAddedEvent(record); } }
private void ProcessFileDelete(PInvokeWin32.USN_RECORD usn, string volume, MyEverythingDB db) { var cached = db.FindByFrn(volume, usn.FRN); if (cached == null) { return; } else { var isdelete = db.DeleteRecord(volume, usn.FRN); Debug.WriteLine(string.Format(">>>> File {0} deleted {1}.", cached.FullPath, isdelete ? "successful" : "fail")); if (RecordDeletedEvent != null) { RecordDeletedEvent(cached); } } }
unsafe private static void EnumerateFiles(string volumeName, IntPtr pVolume, IntPtr medBuffer, ref List <MyEverythingRecord> files, ref List <MyEverythingRecord> folders) { 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); if (usn.IsFolder) { folders.Add(new MyEverythingRecord { Name = usn.FileName, ParentFrn = usn.ParentFRN, FRN = usn.FRN, IsFolder = true, VolumeName = volumeName }); } else { files.Add(new MyEverythingRecord { Name = usn.FileName, ParentFrn = usn.ParentFRN, FRN = usn.FRN, IsFolder = false, VolumeName = volumeName }); } pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength); outBytesReturned -= usn.RecordLength; } Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }
private void MonitorThread(object param) { MyEverythingDB db = (param as Dictionary <string, object>)["MyEverythingDB"] as MyEverythingDB; string volume = (param as Dictionary <string, object>)["Volume"] as string; IntPtr pbuffer = Marshal.AllocHGlobal(0x1000); // 构建输出参数 PInvokeWin32.READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead(volume, 0xFFFFFFFF); // 对所有类型的reason都监听 UInt32 cbRead; // 用来存储实际输出的字节数 IntPtr prujd; // 指向输入参数结构体的指针 while (true) { // 构建输入参数的指针 prujd = Marshal.AllocHGlobal(Marshal.SizeOf(rujd)); PInvokeWin32.ZeroMemory(prujd, Marshal.SizeOf(rujd)); Marshal.StructureToPtr(rujd, prujd, true); Debug.WriteLine(string.Format("\nMoniting on {0}......", volume)); IntPtr pVolume = MyEverything.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))); // 返回的内存块头上的8个字节是一个usn_id, 从第9个字节开始才是record. uint offset = 0; if (fok) { while (offset + Marshal.SizeOf(typeof(Int64)) < cbRead) // record可能有多个! { 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); // 返回的内存块头上的8个字节就是用来在进行下一次查询的 } }
private void ProcessUSN(PInvokeWin32.USN_RECORD usn, string volume, MyEverythingDB db) { var dbCached = db.FindByFrn(volume, usn.FRN); Debug.WriteLine(string.Format("------USN[frn={0}]------", usn.FRN)); Debug.WriteLine(string.Format("FileName={0}, Reason={1}", usn.FileName, Reason.ReasonPrettyFormat(usn.Reason))); Debug.WriteLine(string.Format("FileName[Cached]={0}", dbCached == null ? "NoCache": dbCached.FullPath)); Debug.WriteLine("--------------------------------------"); if (Util.MaskEqual(usn.Reason, Reason.USN_REASONS["USN_REASON_RENAME_NEW_NAME"])) { ProcessRenameNewName(usn, volume, db); } if ((usn.Reason & Reason.USN_REASONS["USN_REASON_FILE_CREATE"]) != 0) { ProcessFileCreate(usn, volume, db); } if (Util.MaskEqual(usn.Reason, Reason.USN_REASONS["USN_REASON_FILE_DELETE"])) { ProcessFileDelete(usn, volume, db); } }
private void MonitorThread(object param) { MyEverythingDB db = (param as Dictionary<string, object>)["MyEverythingDB"] as MyEverythingDB; string volume = (param as Dictionary<string, object>)["Volume"] as string; IntPtr pbuffer = Marshal.AllocHGlobal(0x1000); // 构建输出参数 PInvokeWin32.READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead(volume, 0xFFFFFFFF); // 对所有类型的reason都监听 UInt32 cbRead; // 用来存储实际输出的字节数 IntPtr prujd; // 指向输入参数结构体的指针 while (true) { // 构建输入参数的指针 prujd = Marshal.AllocHGlobal(Marshal.SizeOf(rujd)); PInvokeWin32.ZeroMemory(prujd, Marshal.SizeOf(rujd)); Marshal.StructureToPtr(rujd, prujd, true); Debug.WriteLine(string.Format("\nMoniting on {0}......", volume)); IntPtr pVolume = MyEverything.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))); // 返回的内存块头上的8个字节是一个usn_id, 从第9个字节开始才是record. uint offset = 0; if (fok) { while (offset + Marshal.SizeOf(typeof(Int64)) < cbRead) { // record可能有多个! 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); // 返回的内存块头上的8个字节就是用来在进行下一次查询的 } }
private static unsafe void EnumerateFiles(string volumeName, IntPtr pVolume, IntPtr medBuffer, ref List<MyEverythingRecord> files, ref List<MyEverythingRecord> folders) { 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); if (usn.IsFolder) { folders.Add(new MyEverythingRecord { Name = usn.FileName, ParentFrn = usn.ParentFRN, FRN = usn.FRN, IsFolder = true, VolumeName = volumeName }); } else { files.Add(new MyEverythingRecord { Name = usn.FileName, ParentFrn = usn.ParentFRN, FRN = usn.FRN, IsFolder = false, VolumeName = volumeName }); } pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength); outBytesReturned -= usn.RecordLength; } Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }
public static MyEverythingRecord ParseUSN(PInvokeWin32.USN_RECORD usn) { return(new MyEverythingRecord { FRN = usn.FRN, Name = usn.FileName, ParentFrn = usn.ParentFRN }); }