Exemple #1
0
        private PInvokeWin32.READ_USN_JOURNAL_DATA SetupInputData4JournalRead(string volume, uint reason)
        {
            IntPtr pMonitorVolume = MyEverything.GetVolumeJournalHandle(volume);
            uint   bytesReturned  = 0;

            PInvokeWin32.USN_JOURNAL_DATA ujd = new PInvokeWin32.USN_JOURNAL_DATA();
            MyEverything.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;

            return(rujd);
        }
Exemple #2
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个字节就是用来在进行下一次查询的
            }
        }