@@ -1,158 +1,158 @@
// using System;
using System ;
// using System.Collections.Generic;
using System.Collections.Generic ;
// using System.Linq;
using System.Linq ;
// using System.Text;
using System.Text ;
// using System.Runtime.InteropServices;
using System.Runtime.InteropServices ;
// using System.Threading;
using System.Threading ;
// using System.Diagnostics;
using System.Diagnostics ;
// using System.IO;
using System.IO ;
// using Wox.Infrastructure.MFTSearch;
using Wox.Infrastructure.MFTSearch ;
// namespace MyEverything
namespace MyEverything
// {
{
// internal class VolumeMonitor
internal class VolumeMonitor
// {
{
// public Action< USNRecord> RecordAddedEvent;
public Action< USNRecord> RecordAddedEvent ;
// public Action< USNRecord> RecordDeletedEvent;
public Action< USNRecord> RecordDeletedEvent ;
// public Action< USNRecord, USNRecord> RecordRenameEvent;
public Action< USNRecord, USNRecord> RecordRenameEvent ;
// public void Monitor(List<string> volumes, MFTSearcherCache db )
public void Monitor( List < string > volumes, MFTSearcherCache db )
// {
{
// foreach (var volume in volumes)
foreach ( var volume in volumes )
// {
{
// if ( string. IsNullOrEmpty( volume)) throw new InvalidOperationException( "Volume cant't be null or empty string.") ;
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.")) ;
if ( ! db . ContainsVolume( volume) ) throw new InvalidOperationException( string. Format( "Volume {0} must be scaned first.") ) ;
// Thread th = new Thread(new ParameterizedThreadStart( MonitorThread)) ;
Thread th = new Thread ( new ParameterizedThreadStart( MonitorThread) ) ;
// th.Start(new Dictionary< string, object> { { "Volume", volume }, { "MFTSearcherCache", db } }) ;
th. Start ( new Dictionary< string, object > { { "Volume" , volume } , { "MFTSearcherCache" , db } } ) ;
// }
}
// }
}
// private PInvokeWin32. READ_USN_JOURNAL_DATA SetupInputData4JournalRead( string volume, uint reason)
private PInvokeWin32. READ_USN_JOURNAL_DATA SetupInputData4JournalRead( string volume, uint reason )
// {
{
// IntPtr pMonitorVolume = MFTSearcher. GetVolumeJournalHandle( volume) ;
IntPtr pMonitorVolume = MFTSearcher. GetVolumeJournalHandle( volume) ;
// uint bytesReturned = 0 ;
uint bytesReturned = 0 ;
// PInvokeWin32. USN_JOURNAL_DATA ujd = new PInvokeWin32. USN_JOURNAL_DATA() ;
PInvokeWin32. USN_JOURNAL_DATA ujd = new PInvokeWin32. USN_JOURNAL_DATA( ) ;
// Wox. Infrastructure. MFTSearch. MFTSearcher. QueryUSNJournal( pMonitorVolume, out ujd, out bytesReturned) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. QueryUSNJournal( pMonitorVolume, out ujd , out bytesReturned) ;
// // 构建输入参数
// 构建输入参数
// PInvokeWin32. READ_USN_JOURNAL_DATA rujd = new PInvokeWin32. READ_USN_JOURNAL_DATA() ;
PInvokeWin32. READ_USN_JOURNAL_DATA rujd = new PInvokeWin32. READ_USN_JOURNAL_DATA( ) ;
// rujd. StartUsn = ujd. NextUsn;
rujd. StartUsn = ujd . NextUsn ;
// rujd. ReasonMask = reason;
rujd. ReasonMask = reason ;
// rujd. ReturnOnlyOnClose = 1 ;
rujd. ReturnOnlyOnClose = 1 ;
// rujd. Timeout = 0 ;
rujd. Timeout = 0 ;
// rujd. BytesToWaitFor = 1 ;
rujd. BytesToWaitFor = 1 ;
// rujd. UsnJournalID = ujd. UsnJournalID;
rujd. UsnJournalID = ujd . UsnJournalID ;
// return rujd;
return rujd ;
// }
}
// private void MonitorThread( object param)
private void MonitorThread( object param )
// {
{
// MFTSearcherCache db = (param as Dictionary< string, object>)[ "MFTSearcherCache"] as MFTSearcherCache;
MFTSearcherCache db = ( param as Dictionary< string, object > ) [ "MFTSearcherCache"] as MFTSearcherCache ;
// string volume = (param as Dictionary< string, object>)["Volume"] as string;
string volume = ( param as Dictionary< string, object > ) [ "Volume" ] as string ;
// IntPtr pbuffer = Marshal. AllocHGlobal( 0x1000) ;
IntPtr pbuffer = Marshal. AllocHGlobal( 0x1000) ;
// PInvokeWin32. READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead( volume, 0xFFFFFFFF) ;
PInvokeWin32. READ_USN_JOURNAL_DATA rujd = SetupInputData4JournalRead( volume, 0xFFFFFFFF) ;
// UInt32 cbRead;
UInt32 cbRead ;
// IntPtr prujd;
IntPtr prujd ;
// while ( true)
while ( true )
// {
{
// prujd = Marshal. AllocHGlobal( Marshal. SizeOf(rujd)) ;
prujd = Marshal. AllocHGlobal( Marshal. SizeOf( rujd ) ) ;
// PInvokeWin32. ZeroMemory(prujd, Marshal. SizeOf(rujd)) ;
PInvokeWin32. ZeroMemory( prujd , Marshal. SizeOf( rujd ) ) ;
// Marshal. StructureToPtr(rujd, prujd, true) ;
Marshal. StructureToPtr( rujd , prujd , true ) ;
// Debug. WriteLine( string. Format( "\nMoniting on {0}......", volume)) ;
Debug. WriteLine( string. Format( "\nMoniting on {0}......", volume ) ) ;
// IntPtr pVolume = Wox. Infrastructure. MFTSearch. MFTSearcher. GetVolumeJournalHandle( volume) ;
IntPtr pVolume = Wox . Infrastructure. MFTSearch. MFTSearcher. GetVolumeJournalHandle( volume) ;
// bool fok = PInvokeWin32. DeviceIoControl( pVolume,
bool fok = PInvokeWin32. DeviceIoControl( pVolume ,
// PInvokeWin32. FSCTL_READ_USN_JOURNAL,
PInvokeWin32. FSCTL_READ_USN_JOURNAL ,
// prujd, Marshal. SizeOf( typeof( PInvokeWin32. READ_USN_JOURNAL_DATA)) ,
prujd, Marshal. SizeOf( typeof( PInvokeWin32. READ_USN_JOURNAL_DATA) ) ,
// pbuffer, 0x1000, out cbRead, IntPtr.Zero) ;
pbuffer, 0x1000 , out cbRead , IntPtr . Zero ) ;
// IntPtr pRealData = new IntPtr( pbuffer. ToInt32() + Marshal. SizeOf( typeof(Int64))) ;
IntPtr pRealData = new IntPtr( pbuffer. ToInt32( ) + Marshal. SizeOf( typeof( Int64 ) ) ) ;
// uint offset = 0 ;
uint offset = 0 ;
// if ( fok)
if ( fok )
// {
{
// while (offset + Marshal. SizeOf( typeof(Int64)) < cbRead)
while ( offset + Marshal. SizeOf( typeof( Int64 ) ) < cbRead )
// {
{
// PInvokeWin32. USN_RECORD usn = new PInvokeWin32. USN_RECORD(new IntPtr( pRealData. ToInt32() + (int)offset)) ;
PInvokeWin32. USN_RECORD usn = new PInvokeWin32. USN_RECORD( new IntPtr( pRealData. ToInt32( ) + ( int ) offset ) ) ;
// ProcessUSN(usn, volume, db) ;
ProcessUSN( usn , volume , db ) ;
// offset += usn. RecordLength;
offset + = usn . RecordLength ;
// }
}
// }
}
// Marshal. FreeHGlobal(prujd) ;
Marshal. FreeHGlobal( prujd ) ;
// rujd. StartUsn = Marshal. ReadInt64( pbuffer) ;
rujd. StartUsn = Marshal. ReadInt64( pbuffer) ;
// }
}
// }
}
// private void ProcessUSN( PInvokeWin32. USN_RECORD usn, string volume, MFTSearcherCache db )
private void ProcessUSN( PInvokeWin32. USN_RECORD usn , string volume, MFTSearcherCache db )
// {
{
// var dbCached = db. FindByFrn( volume, usn.FRN) ;
var dbCached = db . FindByFrn( volume, usn . FRN ) ;
// Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, dbCached, db) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, dbCached, db ) ;
// Debug. WriteLine( string. Format( "------USN[frn={0}]------", usn.FRN)) ;
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={0}, USNChangeReason={1}", usn . FileName, USNChangeReason. ReasonPrettyFormat( usn . Reason ) ) ) ;
// Debug. WriteLine( string. Format( "FileName[Cached]={0}", dbCached == null ? "NoCache" : dbCached. FullPath)) ;
Debug. WriteLine( string. Format( "FileName[Cached]={0}", dbCached = = null ? "NoCache" : dbCached. FullPath) ) ;
// Debug. WriteLine( "--------------------------------------") ;
Debug. WriteLine( "--------------------------------------") ;
// if ( MaskEqual(usn.Reason, USNChangeReason. USN_REASONS[ "USN_REASON_RENAME_NEW_NAME"]) )
if ( MaskEqual( usn . Reason , USNChangeReason. USN_REASONS[ "USN_REASON_RENAME_NEW_NAME"] ) )
// ProcessRenameNewName(usn, volume, db) ;
ProcessRenameNewName( usn , volume , db ) ;
// if ((usn.Reason & USNChangeReason. USN_REASONS[ "USN_REASON_FILE_CREATE"]) != 0 )
if ( ( usn . Reason & USNChangeReason. USN_REASONS[ "USN_REASON_FILE_CREATE"] ) ! = 0 )
// ProcessFileCreate(usn, volume, db) ;
ProcessFileCreate( usn , volume , db ) ;
// if ( MaskEqual(usn.Reason, USNChangeReason. USN_REASONS[ "USN_REASON_FILE_DELETE"]) )
if ( MaskEqual( usn . Reason , USNChangeReason. USN_REASONS[ "USN_REASON_FILE_DELETE"] ) )
// ProcessFileDelete(usn, volume, db) ;
ProcessFileDelete( usn , volume , db ) ;
// }
}
// private void ProcessFileDelete( PInvokeWin32. USN_RECORD usn, string volume, MFTSearcherCache db )
private void ProcessFileDelete( PInvokeWin32. USN_RECORD usn , string volume, MFTSearcherCache db )
// {
{
// var cached = db. FindByFrn( volume, usn.FRN) ;
var cached = db . FindByFrn( volume, usn . FRN ) ;
// if (cached == null)
if ( cached = = null )
// {
{
// return;
return ;
// }
}
// else
else
// {
{
// Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, cached, db) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, cached , db ) ;
// var deleteok = db. DeleteRecord( volume, usn.FRN) ;
var deleteok = db . DeleteRecord( volume, usn . FRN ) ;
// Debug. WriteLine( string. Format( ">>>> File {0} deleted {1}.", cached. FullPath, deleteok ? "successful" : "fail")) ;
Debug. WriteLine( string. Format( ">>>> File {0} deleted {1}.", cached. FullPath, deleteok ? "successful" : "fail" ) ) ;
// if ( RecordDeletedEvent != null)
if ( RecordDeletedEvent ! = null )
// RecordDeletedEvent( cached) ;
RecordDeletedEvent( cached) ;
// }
}
// }
}
// private void ProcessRenameNewName( PInvokeWin32. USN_RECORD usn, string volume, MFTSearcherCache db )
private void ProcessRenameNewName( PInvokeWin32. USN_RECORD usn , string volume, MFTSearcherCache db )
// {
{
// USNRecord newRecord = USNRecord. ParseUSN( volume, usn) ;
USNRecord newRecord = USNRecord. ParseUSN( volume, usn ) ;
// //string fullpath = newRecord.Name;
//string fullpath = newRecord.Name;
// //db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(volume));
//db.FindRecordPath(newRecord, ref fullpath, db.GetFolderSource(volume));
// //newRecord.FullPath = fullpath;
//newRecord.FullPath = fullpath;
// var oldRecord = db. FindByFrn( volume, usn.FRN) ;
var oldRecord = db . FindByFrn( volume, usn . FRN ) ;
// Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, oldRecord, db) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, oldRecord, db ) ;
// Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, newRecord, db) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, newRecord, db ) ;
// Debug. WriteLine( string. Format( ">>>> RenameFile {0} to {1}", oldRecord. FullPath, newRecord. FullPath)) ;
Debug. WriteLine( string. Format( ">>>> RenameFile {0} to {1}", oldRecord. FullPath, newRecord. FullPath) ) ;
// db. UpdateRecord( volume, newRecord,
db. UpdateRecord( volume, newRecord ,
// usn. IsFolder ? USNRecordType. Folder : USNRecordType.File) ;
usn. IsFolder ? USNRecordType. Folder : USNRecordType. File ) ;
// if ( RecordRenameEvent != null) RecordRenameEvent( oldRecord, newRecord) ;
if ( RecordRenameEvent ! = null ) RecordRenameEvent( oldRecord, newRecord) ;
// if ( newRecord. FullPath. Contains( "$RECYCLE.BIN") )
if ( newRecord. FullPath. Contains( "$RECYCLE.BIN") )
// {
{
// Debug. WriteLine( string. Format( ">>>> Means {0} moved to recycle.", oldRecord. FullPath)) ;
Debug. WriteLine( string. Format( ">>>> Means {0} moved to recycle.", oldRecord. FullPath) ) ;
// }
}
// }
}
// private void ProcessFileCreate( PInvokeWin32. USN_RECORD usn, string volume, MFTSearcherCache db )
private void ProcessFileCreate( PInvokeWin32. USN_RECORD usn , string volume, MFTSearcherCache db )
// {
{
// USNRecord record = USNRecord. ParseUSN( volume, usn) ;
USNRecord record = USNRecord. ParseUSN( volume, usn ) ;
// //string fullpath = record.Name;
//string fullpath = record.Name;
// //db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume));
//db.FindRecordPath(record, ref fullpath, db.GetFolderSource(volume));
// //record.FullPath = fullpath;
//record.FullPath = fullpath;
// db. AddRecord( volume, record, usn. IsFolder ? USNRecordType. Folder : USNRecordType.File) ;
db. AddRecord( volume, record , usn . IsFolder ? USNRecordType. Folder : USNRecordType. File ) ;
// Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, record, db) ;
Wox. Infrastructure. MFTSearch. MFTSearcher. FillPath( volume, record , db ) ;
// Debug. WriteLine( string. Format( ">>>> NewFile: {0}", record. FullPath)) ;
Debug. WriteLine( string. Format( ">>>> NewFile: {0}", record. FullPath) ) ;
// if ( RecordAddedEvent != null)
if ( RecordAddedEvent ! = null )
// RecordAddedEvent( record) ;
RecordAddedEvent( record) ;
// }
}
// private bool MaskEqual( uint target, uint compare)
private bool MaskEqual( uint target, uint compare )
// {
{
// return (target & compare) != 0 ;
return ( target & compare ) ! = 0 ;
// }
}
// }
}
// }
}