mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
Revert MFTSearch changes.
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Wox.Plugin.FindFile
|
||||
MFTSearcher.IndexAllVolumes();
|
||||
initial = true;
|
||||
var searchtimeend = DateTime.Now;
|
||||
Debug.WriteLine(string.Format("{0} file, indexed, {1}ms has spent.", MFTSearcher.IndexedRecordsCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds));
|
||||
Debug.WriteLine(string.Format("{0} file, indexed, {1}ms has spent.", MFTSearcher.IndexedFileCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds));
|
||||
}
|
||||
|
||||
private Result ConvertMFTSearch(MFTSearchRecord record, string query)
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using MyEverything;
|
||||
|
||||
namespace Wox.Infrastructure.MFTSearch
|
||||
{
|
||||
@@ -22,8 +23,8 @@ namespace Wox.Infrastructure.MFTSearch
|
||||
List<USNRecord> files;
|
||||
List<USNRecord> folders;
|
||||
EnumerateVolume(volume, out files, out folders);
|
||||
//cache.AddRecord(files);
|
||||
//cache.AddRecord(folders);
|
||||
cache.AddRecord(volume, files, USNRecordType.File);
|
||||
cache.AddRecord(volume, folders, USNRecordType.Folder);
|
||||
}
|
||||
|
||||
public static void IndexAllVolumes()
|
||||
@@ -34,9 +35,13 @@ namespace Wox.Infrastructure.MFTSearch
|
||||
}
|
||||
}
|
||||
|
||||
public static long IndexedRecordsCount
|
||||
public static long IndexedFileCount
|
||||
{
|
||||
get { return cache.RecordsCount; }
|
||||
get { return cache.FileCount; }
|
||||
}
|
||||
public static long IndexedFolderCount
|
||||
{
|
||||
get { return cache.FolderCount; }
|
||||
}
|
||||
|
||||
public static List<MFTSearchRecord> Search(string item)
|
||||
@@ -44,7 +49,7 @@ namespace Wox.Infrastructure.MFTSearch
|
||||
if (string.IsNullOrEmpty(item)) return new List<MFTSearchRecord>();
|
||||
|
||||
List<USNRecord> found = cache.FindByName(item);
|
||||
found.ForEach(x => FillPath(x, cache));
|
||||
found.ForEach(x => FillPath(x.VolumeName, x, cache));
|
||||
return found.ConvertAll(o => new MFTSearchRecord(o));
|
||||
}
|
||||
|
||||
@@ -250,16 +255,14 @@ namespace Wox.Infrastructure.MFTSearch
|
||||
}
|
||||
Marshal.FreeHGlobal(pData);
|
||||
}
|
||||
|
||||
internal static void FillPath(USNRecord record, MFTSearcherCache db)
|
||||
internal static void FillPath(string volume, USNRecord record, MFTSearcherCache db)
|
||||
{
|
||||
if (record == null) return;
|
||||
var fdSource = db.GetAllRecords();
|
||||
var fdSource = db.GetFolderSource(volume);
|
||||
string fullpath = record.Name;
|
||||
FindRecordPath(record, ref fullpath, fdSource);
|
||||
record.FullPath = fullpath;
|
||||
}
|
||||
|
||||
private static void FindRecordPath(USNRecord curRecord, ref string fullpath, Dictionary<ulong, USNRecord> fdSource)
|
||||
{
|
||||
if (curRecord.IsVolumeRoot) return;
|
||||
|
||||
@@ -1,60 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MyEverything;
|
||||
|
||||
namespace Wox.Infrastructure.MFTSearch
|
||||
{
|
||||
internal class MFTSearcherCache
|
||||
{
|
||||
private Dictionary<ulong, USNRecord> records = new Dictionary<ulong, USNRecord>(100000);
|
||||
private Lookup<string, string> recordsLookup;
|
||||
private Dictionary<string, Dictionary<ulong, USNRecord>> _volumes_files = new Dictionary<string, Dictionary<ulong, USNRecord>>();
|
||||
private Dictionary<string, Dictionary<ulong, USNRecord>> _volumes_folders = new Dictionary<string, Dictionary<ulong, USNRecord>>();
|
||||
|
||||
public MFTSearcherCache() { }
|
||||
|
||||
public void AddRecord(List<USNRecord> record)
|
||||
public bool ContainsVolume(string volume)
|
||||
{
|
||||
record.ForEach(AddRecord);
|
||||
return _volumes_files.ContainsKey(volume) && _volumes_folders.ContainsKey(volume);
|
||||
}
|
||||
|
||||
public void AddRecord(USNRecord record)
|
||||
public void AddRecord(string volume, List<USNRecord> r, USNRecordType type)
|
||||
{
|
||||
if(!records.ContainsKey(record.FRN)) records.Add(record.FRN, record);
|
||||
}
|
||||
|
||||
public bool DeleteRecord(ulong frn)
|
||||
{
|
||||
return records.Remove(frn);
|
||||
}
|
||||
|
||||
public void UpdateRecord(USNRecord record)
|
||||
{
|
||||
USNRecord firstOrDefault = records[record.FRN];
|
||||
if (firstOrDefault != null)
|
||||
if (type == USNRecordType.File)
|
||||
{
|
||||
firstOrDefault.Name = record.Name;
|
||||
firstOrDefault.FullPath = record.FullPath;
|
||||
firstOrDefault.VolumeName = record.VolumeName;
|
||||
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));
|
||||
}
|
||||
}
|
||||
public void AddRecord(string volume, USNRecord record, USNRecordType type)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
private void CheckHashTableKey(Dictionary<string, Dictionary<ulong, USNRecord>> hashtable, string key)
|
||||
{
|
||||
if (!hashtable.ContainsKey(key))
|
||||
hashtable.Add(key, new Dictionary<ulong, USNRecord>());
|
||||
}
|
||||
public bool DeleteRecord(string volume, ulong frn)
|
||||
{
|
||||
bool result = false;
|
||||
result = DeleteRecordHashTableItem(_volumes_files, volume, frn);
|
||||
if (!result) result = DeleteRecordHashTableItem(_volumes_folders, volume, frn);
|
||||
return result;
|
||||
}
|
||||
private bool DeleteRecordHashTableItem(Dictionary<string, Dictionary<ulong, USNRecord>> hashtable, string volume, ulong frn)
|
||||
{
|
||||
if (hashtable.ContainsKey(volume) && hashtable[volume].ContainsKey(frn))
|
||||
{
|
||||
hashtable[volume].Remove(frn);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void UpdateRecord(string volume, USNRecord record, USNRecordType type)
|
||||
{
|
||||
if (type == USNRecordType.File)
|
||||
RealUpdateRecord(volume, _volumes_files, record);
|
||||
else
|
||||
RealUpdateRecord(volume, _volumes_folders, record);
|
||||
}
|
||||
private bool RealUpdateRecord(string volume, Dictionary<string, Dictionary<ulong, USNRecord>> source, USNRecord record)
|
||||
{
|
||||
if (source.ContainsKey(volume) && source[volume].ContainsKey(record.FRN))
|
||||
{
|
||||
source[volume][record.FRN] = record;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<USNRecord> FindByName(string filename)
|
||||
{
|
||||
filename = filename.ToLower();
|
||||
var query = from file in records.Values
|
||||
where file.Name.ToLower().Contains(filename)
|
||||
select file;
|
||||
return query.ToList();
|
||||
}
|
||||
var fileQuery = from filesInVolumeDic in _volumes_files.Values
|
||||
from eachFilePair in filesInVolumeDic
|
||||
where eachFilePair.Value.Name.ToLower().Contains(filename)
|
||||
select eachFilePair.Value;
|
||||
|
||||
public long RecordsCount
|
||||
{
|
||||
get { return records.Count; }
|
||||
var folderQuery = from fldsInVolumeDic in _volumes_folders.Values
|
||||
from eachFldPair in fldsInVolumeDic
|
||||
where eachFldPair.Value.Name.ToLower().Contains(filename)
|
||||
select eachFldPair.Value;
|
||||
|
||||
List<USNRecord> result = new List<USNRecord>();
|
||||
|
||||
result.AddRange(fileQuery);
|
||||
result.AddRange(folderQuery);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Dictionary<ulong, USNRecord> GetAllRecords()
|
||||
public USNRecord FindByFrn(string volume, ulong frn)
|
||||
{
|
||||
return records;
|
||||
if ((!_volumes_files.ContainsKey(volume)) || (!_volumes_folders.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);
|
||||
return result;
|
||||
}
|
||||
public long FileCount
|
||||
{
|
||||
get { return _volumes_files.Sum(x => x.Value.Count); }
|
||||
}
|
||||
public long FolderCount
|
||||
{
|
||||
get { return _volumes_folders.Sum(x => x.Value.Count); }
|
||||
}
|
||||
public Dictionary<ulong, USNRecord> GetFolderSource(string volume)
|
||||
{
|
||||
Dictionary<ulong, USNRecord> result = null;
|
||||
_volumes_folders.TryGetValue(volume, out result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using MyEverything;
|
||||
|
||||
namespace Wox.Infrastructure.MFTSearch
|
||||
{
|
||||
|
||||
@@ -1,158 +1,158 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using System.Runtime.InteropServices;
|
||||
//using System.Threading;
|
||||
//using System.Diagnostics;
|
||||
//using System.IO;
|
||||
//using Wox.Infrastructure.MFTSearch;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Wox.Infrastructure.MFTSearch;
|
||||
|
||||
//namespace MyEverything
|
||||
//{
|
||||
// internal class VolumeMonitor
|
||||
// {
|
||||
namespace MyEverything
|
||||
{
|
||||
internal class VolumeMonitor
|
||||
{
|
||||
|
||||
// public Action<USNRecord> RecordAddedEvent;
|
||||
// public Action<USNRecord> RecordDeletedEvent;
|
||||
// public Action<USNRecord, USNRecord> RecordRenameEvent;
|
||||
public Action<USNRecord> RecordAddedEvent;
|
||||
public Action<USNRecord> RecordDeletedEvent;
|
||||
public Action<USNRecord, USNRecord> RecordRenameEvent;
|
||||
|
||||
// public void Monitor(List<string> volumes, MFTSearcherCache db)
|
||||
// {
|
||||
// foreach (var volume in volumes)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(volume)) throw new InvalidOperationException("Volume cant't be null or empty string.");
|
||||
// if (!db.ContainsVolume(volume)) throw new InvalidOperationException(string.Format("Volume {0} must be scaned first."));
|
||||
// Thread th = new Thread(new ParameterizedThreadStart(MonitorThread));
|
||||
// th.Start(new Dictionary<string, object> { { "Volume", volume }, { "MFTSearcherCache", db } });
|
||||
// }
|
||||
// }
|
||||
// private PInvokeWin32.READ_USN_JOURNAL_DATA SetupInputData4JournalRead(string volume, uint reason)
|
||||
// {
|
||||
// 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);
|
||||
public void Monitor(List<string> volumes, MFTSearcherCache db)
|
||||
{
|
||||
foreach (var volume in volumes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(volume)) throw new InvalidOperationException("Volume cant't be null or empty string.");
|
||||
if (!db.ContainsVolume(volume)) throw new InvalidOperationException(string.Format("Volume {0} must be scaned first."));
|
||||
Thread th = new Thread(new ParameterizedThreadStart(MonitorThread));
|
||||
th.Start(new Dictionary<string, object> { { "Volume", volume }, { "MFTSearcherCache", db } });
|
||||
}
|
||||
}
|
||||
private PInvokeWin32.READ_USN_JOURNAL_DATA SetupInputData4JournalRead(string volume, uint reason)
|
||||
{
|
||||
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);
|
||||
|
||||
// // 构建输入参数
|
||||
// PInvokeWin32.READ_USN_JOURNAL_DATA rujd = new PInvokeWin32.READ_USN_JOURNAL_DATA();
|
||||
// rujd.StartUsn = ujd.NextUsn;
|
||||
// rujd.ReasonMask = reason;
|
||||
// rujd.ReturnOnlyOnClose = 1;
|
||||
// rujd.Timeout = 0;
|
||||
// rujd.BytesToWaitFor = 1;
|
||||
// rujd.UsnJournalID = ujd.UsnJournalID;
|
||||
// 构建输入参数
|
||||
PInvokeWin32.READ_USN_JOURNAL_DATA rujd = new PInvokeWin32.READ_USN_JOURNAL_DATA();
|
||||
rujd.StartUsn = ujd.NextUsn;
|
||||
rujd.ReasonMask = reason;
|
||||
rujd.ReturnOnlyOnClose = 1;
|
||||
rujd.Timeout = 0;
|
||||
rujd.BytesToWaitFor = 1;
|
||||
rujd.UsnJournalID = ujd.UsnJournalID;
|
||||
|
||||
// return rujd;
|
||||
// }
|
||||
// private void MonitorThread(object param)
|
||||
// {
|
||||
return rujd;
|
||||
}
|
||||
private void MonitorThread(object param)
|
||||
{
|
||||
|
||||
// MFTSearcherCache db = (param as Dictionary<string, object>)["MFTSearcherCache"] as MFTSearcherCache;
|
||||
// string volume = (param as Dictionary<string, object>)["Volume"] as string;
|
||||
// IntPtr pbuffer = Marshal.AllocHGlobal(0x1000);
|
||||
// PInvokeWin32.READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead(volume, 0xFFFFFFFF);
|
||||
// UInt32 cbRead;
|
||||
// IntPtr prujd;
|
||||
MFTSearcherCache db = (param as Dictionary<string, object>)["MFTSearcherCache"] as MFTSearcherCache;
|
||||
string volume = (param as Dictionary<string, object>)["Volume"] as string;
|
||||
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);
|
||||
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 = Wox.Infrastructure.MFTSearch.MFTSearcher.GetVolumeJournalHandle(volume);
|
||||
Debug.WriteLine(string.Format("\nMoniting on {0}......", volume));
|
||||
IntPtr pVolume = Wox.Infrastructure.MFTSearch.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);
|
||||
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;
|
||||
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;
|
||||
// }
|
||||
// }
|
||||
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);
|
||||
// }
|
||||
// }
|
||||
// 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);
|
||||
// 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));
|
||||
// Debug.WriteLine("--------------------------------------");
|
||||
Marshal.FreeHGlobal(prujd);
|
||||
rujd.StartUsn = Marshal.ReadInt64(pbuffer);
|
||||
}
|
||||
}
|
||||
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);
|
||||
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));
|
||||
Debug.WriteLine("--------------------------------------");
|
||||
|
||||
// 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)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Wox.Infrastructure.MFTSearch.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)
|
||||
// RecordDeletedEvent(cached);
|
||||
// }
|
||||
// }
|
||||
// private void ProcessRenameNewName(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db)
|
||||
// {
|
||||
// USNRecord newRecord = USNRecord.ParseUSN(volume, usn);
|
||||
// //string fullpath = newRecord.Name;
|
||||
// //db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(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);
|
||||
// Debug.WriteLine(string.Format(">>>> RenameFile {0} to {1}", oldRecord.FullPath, newRecord.FullPath));
|
||||
// db.UpdateRecord(volume, newRecord,
|
||||
// usn.IsFolder ? USNRecordType.Folder : USNRecordType.File);
|
||||
// if (RecordRenameEvent != null) RecordRenameEvent(oldRecord, newRecord);
|
||||
// if (newRecord.FullPath.Contains("$RECYCLE.BIN"))
|
||||
// {
|
||||
// Debug.WriteLine(string.Format(">>>> Means {0} moved to recycle.", oldRecord.FullPath));
|
||||
// }
|
||||
// }
|
||||
// private void ProcessFileCreate(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db)
|
||||
// {
|
||||
// USNRecord record = USNRecord.ParseUSN(volume, usn);
|
||||
// //string fullpath = record.Name;
|
||||
// //db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume));
|
||||
// //record.FullPath = fullpath;
|
||||
// db.AddRecord(volume, record, usn.IsFolder ? USNRecordType.Folder : USNRecordType.File);
|
||||
// Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, record, db);
|
||||
// Debug.WriteLine(string.Format(">>>> NewFile: {0}", record.FullPath));
|
||||
// if (RecordAddedEvent != null)
|
||||
// RecordAddedEvent(record);
|
||||
// }
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Wox.Infrastructure.MFTSearch.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)
|
||||
RecordDeletedEvent(cached);
|
||||
}
|
||||
}
|
||||
private void ProcessRenameNewName(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db)
|
||||
{
|
||||
USNRecord newRecord = USNRecord.ParseUSN(volume, usn);
|
||||
//string fullpath = newRecord.Name;
|
||||
//db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(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);
|
||||
Debug.WriteLine(string.Format(">>>> RenameFile {0} to {1}", oldRecord.FullPath, newRecord.FullPath));
|
||||
db.UpdateRecord(volume, newRecord,
|
||||
usn.IsFolder ? USNRecordType.Folder : USNRecordType.File);
|
||||
if (RecordRenameEvent != null) RecordRenameEvent(oldRecord, newRecord);
|
||||
if (newRecord.FullPath.Contains("$RECYCLE.BIN"))
|
||||
{
|
||||
Debug.WriteLine(string.Format(">>>> Means {0} moved to recycle.", oldRecord.FullPath));
|
||||
}
|
||||
}
|
||||
private void ProcessFileCreate(PInvokeWin32.USN_RECORD usn, string volume, MFTSearcherCache db)
|
||||
{
|
||||
USNRecord record = USNRecord.ParseUSN(volume, usn);
|
||||
//string fullpath = record.Name;
|
||||
//db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume));
|
||||
//record.FullPath = fullpath;
|
||||
db.AddRecord(volume, record, usn.IsFolder ? USNRecordType.Folder : USNRecordType.File);
|
||||
Wox.Infrastructure.MFTSearch.MFTSearcher.FillPath(volume, record, db);
|
||||
Debug.WriteLine(string.Format(">>>> NewFile: {0}", record.FullPath));
|
||||
if (RecordAddedEvent != null)
|
||||
RecordAddedEvent(record);
|
||||
}
|
||||
|
||||
|
||||
// private bool MaskEqual(uint target, uint compare)
|
||||
// {
|
||||
// return (target & compare) != 0;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
private bool MaskEqual(uint target, uint compare)
|
||||
{
|
||||
return (target & compare) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Wox.Test
|
||||
var searchtimestart = DateTime.Now;
|
||||
MFTSearcher.IndexAllVolumes();
|
||||
var searchtimeend = DateTime.Now;
|
||||
Console.WriteLine(string.Format("{0} file indexed, {1}ms has spent.", MFTSearcher.IndexedRecordsCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds));
|
||||
Console.WriteLine(string.Format("{0} file indexed, {1}ms has spent.", MFTSearcher.IndexedFileCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds));
|
||||
|
||||
searchtimestart = DateTime.Now;
|
||||
List<MFTSearchRecord> mftSearchRecords = MFTSearcher.Search("q");
|
||||
@@ -34,6 +34,7 @@ namespace Wox.Test
|
||||
{
|
||||
long oldWorkingSet = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
|
||||
MFTSearcher.IndexAllVolumes();
|
||||
GC.Collect();
|
||||
long newWorkingSet = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
|
||||
Console.WriteLine(string.Format("Index: {0}M", (newWorkingSet - oldWorkingSet)/(1024*1024)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user