Merge branch 'V1.1.0' of https://github.com/qianlifeng/Wox into V1.1.0

This commit is contained in:
qianlifeng
2014-10-27 17:16:24 +08:00
5 changed files with 147 additions and 143 deletions

View File

@@ -9,6 +9,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using MyEverything;
namespace Wox.Infrastructure.MFTSearch
{

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MyEverything;
namespace Wox.Infrastructure.MFTSearch
{

View File

@@ -1,4 +1,5 @@
using System;
using MyEverything;
namespace Wox.Infrastructure.MFTSearch
{

View File

@@ -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;
}
}
}