Ejemplo n.º 1
0
 public static void FillPath(string volume, MyEverythingRecord record, MyEverythingDB db)
 {
     if (record == null) return;
     var fdSource = db.GetFolderSource(volume);
     string fullpath = record.Name;
     FindRecordPath(record, ref fullpath, fdSource);
     record.FullPath = fullpath;
 }
Ejemplo n.º 2
0
 public void Monitor(List<string> volumes, MyEverythingDB 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 }, { "MyEverythingDB", db } });
     }
 }
Ejemplo n.º 3
0
 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);
 }
Ejemplo n.º 4
0
        public static void FillPath(string volume, MyEverythingRecord record, MyEverythingDB db)
        {
            if (record == null)
            {
                return;
            }
            var    fdSource = db.GetFolderSource(volume);
            string fullpath = record.Name;

            FindRecordPath(record, ref fullpath, fdSource);
            record.FullPath = fullpath;
        }
Ejemplo n.º 5
0
 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);
     }
 }
Ejemplo n.º 6
0
        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);
            }
        }
Ejemplo n.º 7
0
 public void Monitor(List <string> volumes, MyEverythingDB 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 }, { "MyEverythingDB", db }
         });
     }
 }
Ejemplo n.º 8
0
        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);
                }
            }
        }
Ejemplo n.º 9
0
        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个字节就是用来在进行下一次查询的
            }
        }
Ejemplo n.º 10
0
        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);
            }
        }
Ejemplo n.º 11
0
        static void Main(string[] args)
        {
            Console.Write("Volumes for Scan (eg: C: D: E:): ");
            List <string> volumes = Console.ReadLine().ToUpper().Split(new char[] { ' ' }).ToList();

            MyEverythingDB db = new MyEverythingDB();

            // ----------------遍历 mft,找到指定 volume 上的所有文件和文件夹----------------
            Console.WriteLine("Note: If this is your first time run, it will take some time to open the NTFS Journal System.");
            var enumFilesTimeStart = DateTime.Now;

            foreach (string volume in volumes)
            {
                List <MyEverythingRecord> files;
                List <MyEverythingRecord> folders;
                Console.WriteLine("Scanning {0}...", volume);
                EnumerateVolume(volume, out files, out folders);

                db.AddRecord(volume, files, MyEverythingRecordType.File);
                db.AddRecord(volume, folders, MyEverythingRecordType.Folder);
            }
            Console.WriteLine("{0}s file and {1} folder indexed, {2}ms has spent.",
                              db.FileCount, db.FolderCount, DateTime.Now.Subtract(enumFilesTimeStart).TotalMilliseconds);
            // -----------------------------------------------------------------------------



            // ---------------------------命令模式------------------------------
            Console.WriteLine("\nMyEverything version 0.0.1");
            Console.WriteLine("Type ? for help.");
            while (true)
            {
                Console.Write("MyEverything> ");
                string[] cmd = Console.ReadLine().Split(' ');
                long     fileFoundCnt;
                long     folderFoundCnt;
                List <MyEverythingRecord> found;

                switch (cmd[0].ToLower())
                {
                case "s":
                    if (!string.IsNullOrEmpty(cmd[1]))
                    {
                        var searchtimestart = DateTime.Now;
                        found = db.FindByName(cmd[1], out fileFoundCnt, out folderFoundCnt);
                        found.ForEach(x => FillPath(x.VolumeName, x, db));
                        var searchtimeend = DateTime.Now;
                        if (cmd.Length == 3 && !string.IsNullOrEmpty(cmd[2]))
                        {
                            using (StreamWriter sw = new StreamWriter(cmd[2], false)) {
                                found.ForEach(x => sw.WriteLine(string.IsNullOrEmpty(x.FullPath) ? x.Name : x.FullPath));
                            }
                            Console.WriteLine("{0} has written.", cmd[2]);
                        }
                        else
                        {
                            found.ForEach(x => Console.WriteLine(string.IsNullOrEmpty(x.FullPath) ? x.Name : x.FullPath));
                        }
                        Console.WriteLine("{0}s file and {1}s folder matched, {2}ms has spent.",
                                          fileFoundCnt, folderFoundCnt, searchtimeend.Subtract(searchtimestart).TotalMilliseconds);
                    }
                    break;

                case "?":
                    Console.WriteLine("s filename [logfile]\tSearch files and folders, \n\t\t\tif logfile specified, the result \n\t\t\twill be written to the logfile, \n\t\t\teg: s .txt");
                    Console.WriteLine("mo volume [debug]\tMonitor the volume, eg: mo E: debug\n\t\t\tIf debug param is specified, some debug msg\n\t\t\twill be print to screen.\n\t\t\tNote: multiple volume monitor is not stable now.");
                    Console.WriteLine("x\t\t\tExit this app.");
                    break;

                case "x":
                    Environment.Exit(0);
                    break;

                case "mo":
                    bool          pridebug = (cmd.Length == 3) && (cmd[2] == "debug");
                    VolumeMonitor monitor  = new VolumeMonitor();
                    monitor.RecordAddedEvent += delegate(MyEverythingRecord record) {
                        if (pridebug)
                        {
                            Console.WriteLine(">>>> New file {0} added.", record.FullPath);
                        }
                    };
                    monitor.RecordDeletedEvent += delegate(MyEverythingRecord record) {
                        if (pridebug)
                        {
                            Console.WriteLine(">>>> File {0} deleted.", record.FullPath);
                        }
                    };
                    monitor.RecordRenameEvent += delegate(MyEverythingRecord oldRecord, MyEverythingRecord newRecord) {
                        if (pridebug)
                        {
                            Console.WriteLine(">>>> File {0} renamed to {1}.", oldRecord.FullPath, newRecord.FullPath);
                        }
                    };
                    monitor.Monitor(cmd[1].ToUpper().Split(' ').ToList(), db);
                    Console.WriteLine("Moniting on {0}......", cmd[1].ToUpper());
                    break;
                }
            }
        }
Ejemplo n.º 12
0
        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));
            }
        }
Ejemplo n.º 13
0
        static void Main(string[] args)
        {
            Console.Write("Volumes for Scan (eg: C: D: E:): ");
            List<string> volumes = Console.ReadLine().ToUpper().Split(new char[] {' '}).ToList();

            MyEverythingDB db = new MyEverythingDB();

            // ----------------遍历 mft,找到指定 volume 上的所有文件和文件夹----------------
            Console.WriteLine("Note: If this is your first time run, it will take some time to open the NTFS Journal System.");
            var enumFilesTimeStart = DateTime.Now;
            foreach (string volume in volumes) {
                List<MyEverythingRecord> files;
                List<MyEverythingRecord> folders;
                Console.WriteLine("Scanning {0}...", volume);
                EnumerateVolume(volume, out files, out folders);

                db.AddRecord(volume, files, MyEverythingRecordType.File);
                db.AddRecord(volume, folders, MyEverythingRecordType.Folder);

            }
            Console.WriteLine("{0}s file and {1} folder indexed, {2}ms has spent.",
                db.FileCount, db.FolderCount, DateTime.Now.Subtract(enumFilesTimeStart).TotalMilliseconds);
            // -----------------------------------------------------------------------------

            // ---------------------------命令模式------------------------------
            Console.WriteLine("\nMyEverything version 0.0.1");
            Console.WriteLine("Type ? for help.");
            while (true) {
                Console.Write("MyEverything> ");
                string[] cmd = Console.ReadLine().Split(' ');
                long fileFoundCnt;
                long folderFoundCnt;
                List<MyEverythingRecord> found;

                switch (cmd[0].ToLower()) {
                    case "s":
                        if (!string.IsNullOrEmpty(cmd[1])) {
                            var searchtimestart = DateTime.Now;
                            found = db.FindByName(cmd[1], out fileFoundCnt, out folderFoundCnt);
                            found.ForEach(x => FillPath(x.VolumeName, x, db));
                            var searchtimeend = DateTime.Now;
                            if (cmd.Length == 3 && !string.IsNullOrEmpty(cmd[2])) {
                                using (StreamWriter sw = new StreamWriter(cmd[2], false)) {
                                    found.ForEach(x => sw.WriteLine(string.IsNullOrEmpty(x.FullPath) ? x.Name : x.FullPath));
                                }
                                Console.WriteLine("{0} has written.", cmd[2]);
                            } else {
                                found.ForEach(x => Console.WriteLine(string.IsNullOrEmpty(x.FullPath) ? x.Name : x.FullPath));
                            }
                            Console.WriteLine("{0}s file and {1}s folder matched, {2}ms has spent.",
                                fileFoundCnt, folderFoundCnt, searchtimeend.Subtract(searchtimestart).TotalMilliseconds);
                        }
                        break;
                    case "?":
                        Console.WriteLine("s filename [logfile]\tSearch files and folders, \n\t\t\tif logfile specified, the result \n\t\t\twill be written to the logfile, \n\t\t\teg: s .txt");
                        Console.WriteLine("mo volume [debug]\tMonitor the volume, eg: mo E: debug\n\t\t\tIf debug param is specified, some debug msg\n\t\t\twill be print to screen.\n\t\t\tNote: multiple volume monitor is not stable now.");
                        Console.WriteLine("x\t\t\tExit this app.");
                        break;
                    case "x":
                        Environment.Exit(0);
                        break;
                    case "mo":
                        bool pridebug = (cmd.Length == 3) && (cmd[2] == "debug");
                        VolumeMonitor monitor = new VolumeMonitor();
                        monitor.RecordAddedEvent += delegate(MyEverythingRecord record) {
                            if (pridebug) Console.WriteLine(">>>> New file {0} added.", record.FullPath);
                        };
                        monitor.RecordDeletedEvent += delegate(MyEverythingRecord record) {
                            if (pridebug) Console.WriteLine(">>>> File {0} deleted.", record.FullPath);
                        };
                        monitor.RecordRenameEvent += delegate(MyEverythingRecord oldRecord, MyEverythingRecord newRecord) {
                            if (pridebug) Console.WriteLine(">>>> File {0} renamed to {1}.", oldRecord.FullPath, newRecord.FullPath);
                        };
                        monitor.Monitor(cmd[1].ToUpper().Split(' ').ToList(), db);
                        Console.WriteLine("Moniting on {0}......", cmd[1].ToUpper());
                        break;
                }
            }
        }
Ejemplo n.º 14
0
 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));
     }
 }
Ejemplo n.º 15
0
        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);
        }