diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearchRecord.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearchRecord.cs index 3186ec97f6..cc3a7ba76c 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearchRecord.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearchRecord.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Wox.Infrastructure.MFTSearch +namespace Wox.Plugin.FindFile.MFTSearch { public class MFTSearchRecord { diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcher.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcher.cs index 317468e885..870aef9cd8 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcher.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcher.cs @@ -2,29 +2,24 @@ * Thanks to the https://github.com/yiwenshengmei/MyEverything, we can bring MFT search to Wox * */ + using System; using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.IO; -using System.Linq; using System.Runtime.InteropServices; -using MyEverything; -namespace Wox.Infrastructure.MFTSearch +namespace Wox.Plugin.FindFile.MFTSearch { public class MFTSearcher { private static MFTSearcherCache cache = new MFTSearcherCache(); - public static void IndexVolume(string volume) + private static void IndexVolume(string volume) { - List files; - List folders; - EnumerateVolume(volume, out files, out folders); - cache.AddRecord(volume, files, USNRecordType.File); - cache.AddRecord(volume, folders, USNRecordType.Folder); + cache.CheckHashTableKey(volume); + EnumerateVolume(volume,cache.VolumeRecords[volume]); } public static void IndexAllVolumes() @@ -37,11 +32,7 @@ namespace Wox.Infrastructure.MFTSearch public static long IndexedFileCount { - get { return cache.FileCount; } - } - public static long IndexedFolderCount - { - get { return cache.FolderCount; } + get { return cache.RecordsCount; } } public static List Search(string item) @@ -53,7 +44,7 @@ namespace Wox.Infrastructure.MFTSearch return found.ConvertAll(o => new MFTSearchRecord(o)); } - private static void AddVolumeRootRecord(string volumeName, ref List folders) + private static void AddVolumeRootRecord(string volumeName, Dictionary files) { string rightVolumeName = string.Concat("\\\\.\\", volumeName); rightVolumeName = string.Concat(rightVolumeName, Path.DirectorySeparatorChar); @@ -74,7 +65,7 @@ namespace Wox.Infrastructure.MFTSearch UInt64 fileIndexHigh = (UInt64)fi.FileIndexHigh; UInt64 indexRoot = (fileIndexHigh << 32) | fi.FileIndexLow; - folders.Add(new USNRecord + files.Add(indexRoot,new USNRecord { FRN = indexRoot, Name = volumeName, @@ -96,20 +87,19 @@ namespace Wox.Infrastructure.MFTSearch throw new IOException("Unable to get root frn entry", new Win32Exception(Marshal.GetLastWin32Error())); } } - private static void EnumerateVolume(string volumeName, out List files, out List flds) + + private static void EnumerateVolume(string volumeName, Dictionary files) { - files = new List(); - flds = new List(); IntPtr medBuffer = IntPtr.Zero; IntPtr pVolume = IntPtr.Zero; try { - AddVolumeRootRecord(volumeName, ref flds); + AddVolumeRootRecord(volumeName,files); pVolume = GetVolumeJournalHandle(volumeName); EnableVomuleJournal(pVolume); SetupMFTEnumInBuffer(ref medBuffer, pVolume); - EnumerateFiles(volumeName, pVolume, medBuffer, ref files, ref flds); + EnumerateFiles(volumeName, pVolume, medBuffer, files); } catch (Exception e) { @@ -134,6 +124,7 @@ namespace Wox.Infrastructure.MFTSearch } } } + internal static IntPtr GetVolumeJournalHandle(string volumeName) { string vol = string.Concat("\\\\.\\", volumeName); @@ -210,7 +201,8 @@ namespace Wox.Infrastructure.MFTSearch throw new IOException("DeviceIoControl() returned false", new Win32Exception(Marshal.GetLastWin32Error())); } } - unsafe private static void EnumerateFiles(string volumeName, IntPtr pVolume, IntPtr medBuffer, ref List files, ref List folders) + + unsafe private static void EnumerateFiles(string volumeName, IntPtr pVolume, IntPtr medBuffer, Dictionary files) { IntPtr pData = Marshal.AllocHGlobal(sizeof(UInt64) + 0x10000); PInvokeWin32.ZeroMemory(pData, sizeof(UInt64) + 0x10000); @@ -225,28 +217,14 @@ namespace Wox.Infrastructure.MFTSearch { PInvokeWin32.USN_RECORD usn = new PInvokeWin32.USN_RECORD(pUsnRecord); - if (usn.IsFolder) + files.Add(usn.FRN,new USNRecord { - folders.Add(new USNRecord - { - Name = usn.FileName, - ParentFrn = usn.ParentFRN, - FRN = usn.FRN, - IsFolder = true, - VolumeName = volumeName - }); - } - else - { - files.Add(new USNRecord - { - Name = usn.FileName, - ParentFrn = usn.ParentFRN, - FRN = usn.FRN, - IsFolder = false, - VolumeName = volumeName - }); - } + Name = usn.FileName, + ParentFrn = usn.ParentFRN, + FRN = usn.FRN, + IsFolder = usn.IsFolder, + VolumeName = volumeName + }); pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength); outBytesReturned -= usn.RecordLength; @@ -255,14 +233,16 @@ namespace Wox.Infrastructure.MFTSearch } Marshal.FreeHGlobal(pData); } + internal static void FillPath(string volume, USNRecord record, MFTSearcherCache db) { if (record == null) return; - var fdSource = db.GetFolderSource(volume); + var fdSource = db.GetVolumeRecords(volume); string fullpath = record.Name; FindRecordPath(record, ref fullpath, fdSource); record.FullPath = fullpath; } + private static void FindRecordPath(USNRecord curRecord, ref string fullpath, Dictionary fdSource) { if (curRecord.IsVolumeRoot) return; diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcherCache.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcherCache.cs index 87c04aedde..849279ff48 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcherCache.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/MFTSearcherCache.cs @@ -1,59 +1,45 @@ using System; using System.Collections.Generic; using System.Linq; -using MyEverything; -namespace Wox.Infrastructure.MFTSearch +namespace Wox.Plugin.FindFile.MFTSearch { internal class MFTSearcherCache { - private Dictionary> _volumes_files = new Dictionary>(); - private Dictionary> _volumes_folders = new Dictionary>(); + public Dictionary> VolumeRecords = new Dictionary>(); public MFTSearcherCache() { } public bool ContainsVolume(string volume) { - return _volumes_files.ContainsKey(volume) && _volumes_folders.ContainsKey(volume); + return VolumeRecords.ContainsKey(volume); } - public void AddRecord(string volume, List r, USNRecordType type) + + public void AddRecord(string volume, List r) { - if (type == USNRecordType.File) - { - CheckHashTableKey(_volumes_files, volume); - r.ForEach(x => _volumes_files[volume].Add(x.FRN, x)); - } - else - { - CheckHashTableKey(_volumes_folders, volume); - r.ForEach(x => _volumes_folders[volume].Add(x.FRN, x)); - } + CheckHashTableKey(volume); + r.ForEach(x => VolumeRecords[volume].Add(x.FRN, x)); } - public void AddRecord(string volume, USNRecord record, USNRecordType type) + + public void AddRecord(string volume, USNRecord record) { - if (type == USNRecordType.File) - { - CheckHashTableKey(_volumes_files, volume); - _volumes_files[volume].Add(record.FRN, record); - } - else - { - CheckHashTableKey(_volumes_folders, volume); - _volumes_folders[volume].Add(record.FRN, record); - } + CheckHashTableKey(volume); + VolumeRecords[volume].Add(record.FRN, record); } - private void CheckHashTableKey(Dictionary> hashtable, string key) + + public void CheckHashTableKey(string volume) { - if (!hashtable.ContainsKey(key)) - hashtable.Add(key, new Dictionary()); + if (!VolumeRecords.ContainsKey(volume)) + VolumeRecords.Add(volume, new Dictionary()); } + public bool DeleteRecord(string volume, ulong frn) { bool result = false; - result = DeleteRecordHashTableItem(_volumes_files, volume, frn); - if (!result) result = DeleteRecordHashTableItem(_volumes_folders, volume, frn); + result = DeleteRecordHashTableItem(VolumeRecords, volume, frn); return result; } + private bool DeleteRecordHashTableItem(Dictionary> hashtable, string volume, ulong frn) { if (hashtable.ContainsKey(volume) && hashtable[volume].ContainsKey(frn)) @@ -66,13 +52,12 @@ namespace Wox.Infrastructure.MFTSearch return false; } } - public void UpdateRecord(string volume, USNRecord record, USNRecordType type) + + public void UpdateRecord(string volume, USNRecord record) { - if (type == USNRecordType.File) - RealUpdateRecord(volume, _volumes_files, record); - else - RealUpdateRecord(volume, _volumes_folders, record); + RealUpdateRecord(volume, VolumeRecords, record); } + private bool RealUpdateRecord(string volume, Dictionary> source, USNRecord record) { if (source.ContainsKey(volume) && source[volume].ContainsKey(record.FRN)) @@ -85,48 +70,40 @@ namespace Wox.Infrastructure.MFTSearch return false; } } + public List FindByName(string filename) { filename = filename.ToLower(); - var fileQuery = from filesInVolumeDic in _volumes_files.Values + var fileQuery = from filesInVolumeDic in VolumeRecords.Values from eachFilePair in filesInVolumeDic where eachFilePair.Value.Name.ToLower().Contains(filename) select eachFilePair.Value; - var folderQuery = from fldsInVolumeDic in _volumes_folders.Values - from eachFldPair in fldsInVolumeDic - where eachFldPair.Value.Name.ToLower().Contains(filename) - select eachFldPair.Value; - List result = new List(); result.AddRange(fileQuery); - result.AddRange(folderQuery); return result; } + public USNRecord FindByFrn(string volume, ulong frn) { - if ((!_volumes_files.ContainsKey(volume)) || (!_volumes_folders.ContainsKey(volume))) + if ((!VolumeRecords.ContainsKey(volume))) throw new Exception(string.Format("DB not contain the volume: {0}", volume)); USNRecord result = null; - _volumes_files[volume].TryGetValue(frn, out result); - if (result != null) return result; - _volumes_folders[volume].TryGetValue(frn, out result); + VolumeRecords[volume].TryGetValue(frn, out result); return result; } - public long FileCount + + public long RecordsCount { - get { return _volumes_files.Sum(x => x.Value.Count); } + get { return VolumeRecords.Sum(x => x.Value.Count); } } - public long FolderCount - { - get { return _volumes_folders.Sum(x => x.Value.Count); } - } - public Dictionary GetFolderSource(string volume) + + public Dictionary GetVolumeRecords(string volume) { Dictionary result = null; - _volumes_folders.TryGetValue(volume, out result); + VolumeRecords.TryGetValue(volume, out result); return result; } } diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/PInvokeWin32.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/PInvokeWin32.cs index 6d536c2455..dd5a7735d9 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/PInvokeWin32.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/PInvokeWin32.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace Wox.Infrastructure.MFTSearch { +namespace Wox.Plugin.FindFile.MFTSearch { public class PInvokeWin32 { diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNChangeReason.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/USNChangeReason.cs index 61095a6a57..c550208eb0 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNChangeReason.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/USNChangeReason.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace Wox.Infrastructure.MFTSearch +namespace Wox.Plugin.FindFile.MFTSearch { internal class USNChangeReason { diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecord.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecord.cs index 64c0ee05e7..8fbad7b231 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecord.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecord.cs @@ -1,7 +1,6 @@ using System; -using MyEverything; -namespace Wox.Infrastructure.MFTSearch +namespace Wox.Plugin.FindFile.MFTSearch { public class USNRecord { diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecordType.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecordType.cs deleted file mode 100644 index 41c68076cc..0000000000 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/USNRecordType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Wox.Infrastructure.MFTSearch -{ - internal enum USNRecordType - { - File, - Folder - } -} \ No newline at end of file diff --git a/Plugins/Wox.Plugin.FindFile/MFTSearch/VolumeMonitor.cs b/Plugins/Wox.Plugin.FindFile/MFTSearch/VolumeMonitor.cs index c65cf866d9..a29aa05afa 100644 --- a/Plugins/Wox.Plugin.FindFile/MFTSearch/VolumeMonitor.cs +++ b/Plugins/Wox.Plugin.FindFile/MFTSearch/VolumeMonitor.cs @@ -1,18 +1,13 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; -using System.Diagnostics; -using System.IO; -using Wox.Infrastructure.MFTSearch; -namespace MyEverything +namespace Wox.Plugin.FindFile.MFTSearch { internal class VolumeMonitor { - public Action RecordAddedEvent; public Action RecordDeletedEvent; public Action RecordRenameEvent; @@ -32,7 +27,7 @@ namespace MyEverything IntPtr pMonitorVolume = MFTSearcher.GetVolumeJournalHandle(volume); uint bytesReturned = 0; PInvokeWin32.USN_JOURNAL_DATA ujd = new PInvokeWin32.USN_JOURNAL_DATA(); - Wox.Infrastructure.MFTSearch.MFTSearcher.QueryUSNJournal(pMonitorVolume, out ujd, out bytesReturned); + MFTSearcher.QueryUSNJournal(pMonitorVolume, out ujd, out bytesReturned); // 构建输入参数 PInvokeWin32.READ_USN_JOURNAL_DATA rujd = new PInvokeWin32.READ_USN_JOURNAL_DATA(); @@ -62,7 +57,7 @@ namespace MyEverything Marshal.StructureToPtr(rujd, prujd, true); Debug.WriteLine(string.Format("\nMoniting on {0}......", volume)); - IntPtr pVolume = Wox.Infrastructure.MFTSearch.MFTSearcher.GetVolumeJournalHandle(volume); + IntPtr pVolume = MFTSearcher.GetVolumeJournalHandle(volume); bool fok = PInvokeWin32.DeviceIoControl(pVolume, PInvokeWin32.FSCTL_READ_USN_JOURNAL, @@ -89,7 +84,7 @@ namespace MyEverything private void ProcessUSN(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db) { var dbCached = db.FindByFrn(volume, usn.FRN); - Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, dbCached, db); + MFTSearcher.FillPath(volume, dbCached, db); Debug.WriteLine(string.Format("------USN[frn={0}]------", usn.FRN)); Debug.WriteLine(string.Format("FileName={0}, USNChangeReason={1}", usn.FileName, USNChangeReason.ReasonPrettyFormat(usn.Reason))); Debug.WriteLine(string.Format("FileName[Cached]={0}", dbCached == null ? "NoCache" : dbCached.FullPath)); @@ -111,7 +106,7 @@ namespace MyEverything } else { - Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, cached, db); + MFTSearcher.FillPath(volume, cached, db); var deleteok = db.DeleteRecord(volume, usn.FRN); Debug.WriteLine(string.Format(">>>> File {0} deleted {1}.", cached.FullPath, deleteok ? "successful" : "fail")); if (RecordDeletedEvent != null) @@ -122,14 +117,13 @@ namespace MyEverything { USNRecord newRecord = USNRecord.ParseUSN(volume, usn); //string fullpath = newRecord.Name; - //db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(volume)); + //db.FindRecordPath(newRecord, ref fullpath, db.GetVolumeRecords(volume)); //newRecord.FullPath = fullpath; var oldRecord = db.FindByFrn(volume, usn.FRN); - Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, oldRecord, db); - Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, newRecord, db); + MFTSearcher.FillPath(volume, oldRecord, db); + MFTSearcher.FillPath(volume, newRecord, db); Debug.WriteLine(string.Format(">>>> RenameFile {0} to {1}", oldRecord.FullPath, newRecord.FullPath)); - db.UpdateRecord(volume, newRecord, - usn.IsFolder ? USNRecordType.Folder : USNRecordType.File); + db.UpdateRecord(volume, newRecord); if (RecordRenameEvent != null) RecordRenameEvent(oldRecord, newRecord); if (newRecord.FullPath.Contains("$RECYCLE.BIN")) { @@ -140,10 +134,10 @@ namespace MyEverything { USNRecord record = USNRecord.ParseUSN(volume, usn); //string fullpath = record.Name; - //db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume)); + //db.FindRecordPath(record, ref fullpath, db.GetVolumeRecords(volume)); //record.FullPath = fullpath; - db.AddRecord(volume, record, usn.IsFolder ? USNRecordType.Folder : USNRecordType.File); - Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, record, db); + db.AddRecord(volume, record); + MFTSearcher.FillPath(volume, record, db); Debug.WriteLine(string.Format(">>>> NewFile: {0}", record.FullPath)); if (RecordAddedEvent != null) RecordAddedEvent(record); diff --git a/Plugins/Wox.Plugin.FindFile/Main.cs b/Plugins/Wox.Plugin.FindFile/Main.cs index 5f0518235d..5311191bfc 100644 --- a/Plugins/Wox.Plugin.FindFile/Main.cs +++ b/Plugins/Wox.Plugin.FindFile/Main.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using Wox.Infrastructure; -using Wox.Infrastructure.MFTSearch; +using Wox.Plugin.FindFile.MFTSearch; namespace Wox.Plugin.FindFile { diff --git a/Plugins/Wox.Plugin.FindFile/Wox.Plugin.FindFile.csproj b/Plugins/Wox.Plugin.FindFile/Wox.Plugin.FindFile.csproj index 3cabda2b97..81ecab8d62 100644 --- a/Plugins/Wox.Plugin.FindFile/Wox.Plugin.FindFile.csproj +++ b/Plugins/Wox.Plugin.FindFile/Wox.Plugin.FindFile.csproj @@ -49,7 +49,6 @@ - diff --git a/Wox.Test/MFTSearcherTest.cs b/Wox.Test/MFTSearcherTest.cs index 6008788a6d..dac4e23dee 100644 --- a/Wox.Test/MFTSearcherTest.cs +++ b/Wox.Test/MFTSearcherTest.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; -using Wox.Infrastructure.MFTSearch; +using Wox.Plugin.FindFile.MFTSearch; namespace Wox.Test {