Пример #1
0
        public static bool Build_Volume_Mapping(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA currentUsnState, Action <Win32Api.UsnEntry> func)
        {
            Debug.WriteLine("Starting Build_Volume_Mapping");

            DateTime startTime = DateTime.Now;

            Win32Api.MFT_ENUM_DATA med;
            med.StartFileReferenceNumber = 0;
            med.LowUsn  = 0;
            med.HighUsn = currentUsnState.NextUsn;

            using (var med_struct = new StructWrapper(med))
                using (var rawdata = new Raw_Array_Wrapper(BUF_LEN))
                {
                    uint outBytesReturned = 0;

                    while (Win32Api.DeviceIoControl(
                               roothandle.DangerousGetHandle(),
                               Win32Api.FSCTL_ENUM_USN_DATA,
                               med_struct.Ptr,
                               med_struct.Size,
                               rawdata.Ptr,
                               rawdata.Size,
                               out outBytesReturned,
                               IntPtr.Zero))
                    {
                        outBytesReturned = outBytesReturned - sizeof(Int64);
                        IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//need to skip 8 bytes because the first 8 bytes are to a usn number, which isnt in the structure
                        while (outBytesReturned > 60)
                        {
                            var usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                            pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);
                            func(usnEntry);

                            if (usnEntry.RecordLength > outBytesReturned)
                            {
                                outBytesReturned = 0;// prevent overflow
                            }
                            else
                            {
                                outBytesReturned -= usnEntry.RecordLength;
                            }
                        }
                        Marshal.WriteInt64(med_struct.Ptr, Marshal.ReadInt64(rawdata.Ptr, 0));//read the usn that we skipped and place it into the nextusn
                    }
                    var possiblerror = Marshal.GetLastWin32Error();
                    if (possiblerror < 0)
                    {
                        throw new Win32Exception(possiblerror);
                    }
                }
            Debug.WriteLine("Time took: " + (DateTime.Now - startTime).TotalMilliseconds + "ms");
            return(true);
        }
Пример #2
0
        public static void GetUsnJournalEntries(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA previousUsnState,
                                                UInt32 reasonMask,
                                                out List <Win32Api.UsnEntry> usnEntries,
                                                out Win32Api.USN_JOURNAL_DATA newUsnState)
        {
            usnEntries  = new List <Win32Api.UsnEntry>();
            newUsnState = new Win32Api.USN_JOURNAL_DATA();

            QueryUsnJournal(roothandle, ref newUsnState);

            Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA();
            rujd.StartUsn          = previousUsnState.NextUsn;
            rujd.ReasonMask        = reasonMask;
            rujd.ReturnOnlyOnClose = 0;
            rujd.Timeout           = 0;
            rujd.bytesToWaitFor    = 0;
            rujd.UsnJournalId      = previousUsnState.UsnJournalID;

            using (var med_struct = new StructWrapper(rujd))
                using (var rawdata = new Raw_Array_Wrapper(BUF_LEN))
                {
                    uint outBytesReturned = 0;
                    var  nextusn          = previousUsnState.NextUsn;
                    while (nextusn < newUsnState.NextUsn && Win32Api.DeviceIoControl(
                               roothandle.DangerousGetHandle(),
                               Win32Api.FSCTL_READ_USN_JOURNAL,
                               med_struct.Ptr,
                               med_struct.Size,
                               rawdata.Ptr,
                               rawdata.Size,
                               out outBytesReturned,
                               IntPtr.Zero))
                    {
                        outBytesReturned = outBytesReturned - sizeof(Int64);
                        IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64)); //point safe arithmetic!~!!
                        while (outBytesReturned > 60)                                      // while there are at least one entry in the usn journal
                        {
                            var usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                            if (usnEntry.USN > newUsnState.NextUsn)
                            {
                                break;
                            }
                            usnEntries.Add(usnEntry);
                            pUsnRecord        = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);//point safe arithmetic!~!!
                            outBytesReturned -= usnEntry.RecordLength;
                        }
                        nextusn = Marshal.ReadInt64(rawdata.Ptr, 0);
                        Marshal.WriteInt64(med_struct.Ptr, nextusn);//read the usn that we skipped and place it into the nextusn
                    }
                }
        }
Пример #3
0
        private static readonly int BUF_LEN = 8192 + 8; //8 bytes for the leading USN

        #endregion Fields

        #region Methods

        public static bool Build_Volume_Mapping(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA currentUsnState, Action<Win32Api.UsnEntry> func)
        {
            Debug.WriteLine("Starting Build_Volume_Mapping");

            DateTime startTime = DateTime.Now;

            Win32Api.MFT_ENUM_DATA med;
            med.StartFileReferenceNumber = 0;
            med.LowUsn = 0;
            med.HighUsn = currentUsnState.NextUsn;

            using(var med_struct = new StructWrapper(med))
            using(var rawdata = new Raw_Array_Wrapper(BUF_LEN))
            {
                uint outBytesReturned = 0;

                while(Win32Api.DeviceIoControl(
                    roothandle.DangerousGetHandle(),
                    Win32Api.FSCTL_ENUM_USN_DATA,
                    med_struct.Ptr,
                    med_struct.Size,
                    rawdata.Ptr,
                    rawdata.Size,
                    out outBytesReturned,
                    IntPtr.Zero))
                {
                    outBytesReturned = outBytesReturned - sizeof(Int64);
                    IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//need to skip 8 bytes because the first 8 bytes are to a usn number, which isnt in the structure
                    while(outBytesReturned > 60)
                    {
                        var usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                        pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);
                        func(usnEntry);

                        if(usnEntry.RecordLength > outBytesReturned)
                            outBytesReturned = 0;// prevent overflow
                        else
                            outBytesReturned -= usnEntry.RecordLength;
                    }
                    Marshal.WriteInt64(med_struct.Ptr, Marshal.ReadInt64(rawdata.Ptr, 0));//read the usn that we skipped and place it into the nextusn
                }
                var possiblerror = Marshal.GetLastWin32Error();
                if(possiblerror < 0)
                    throw new Win32Exception(possiblerror);
            }
            Debug.WriteLine("Time took: " + (DateTime.Now - startTime).TotalMilliseconds + "ms");
            return true;
        }
Пример #4
0
        public static void GetUsnJournalEntries(SafeFileHandle roothandle, Win32Api.USN_JOURNAL_DATA previousUsnState,
            UInt32 reasonMask,
            out List<Win32Api.UsnEntry> usnEntries,
            out Win32Api.USN_JOURNAL_DATA newUsnState)
        {
            usnEntries = new List<Win32Api.UsnEntry>();
            newUsnState = new Win32Api.USN_JOURNAL_DATA();

            QueryUsnJournal(roothandle, ref newUsnState);

            Win32Api.READ_USN_JOURNAL_DATA rujd = new Win32Api.READ_USN_JOURNAL_DATA();
            rujd.StartUsn = previousUsnState.NextUsn;
            rujd.ReasonMask = reasonMask;
            rujd.ReturnOnlyOnClose = 0;
            rujd.Timeout = 0;
            rujd.bytesToWaitFor = 0;
            rujd.UsnJournalId = previousUsnState.UsnJournalID;

            using(var med_struct = new StructWrapper(rujd))
            using(var rawdata = new Raw_Array_Wrapper(BUF_LEN))
            {
                uint outBytesReturned = 0;
                var nextusn = previousUsnState.NextUsn;
                while(nextusn < newUsnState.NextUsn && Win32Api.DeviceIoControl(
                         roothandle.DangerousGetHandle(),
                        Win32Api.FSCTL_READ_USN_JOURNAL,
                        med_struct.Ptr,
                        med_struct.Size,
                        rawdata.Ptr,
                        rawdata.Size,
                        out outBytesReturned,
                        IntPtr.Zero))
                {
                    outBytesReturned = outBytesReturned - sizeof(Int64);
                    IntPtr pUsnRecord = System.IntPtr.Add(rawdata.Ptr, sizeof(Int64));//point safe arithmetic!~!!
                    while(outBytesReturned > 60)   // while there are at least one entry in the usn journal
                    {
                        var usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                        if(usnEntry.USN > newUsnState.NextUsn)
                            break;
                        usnEntries.Add(usnEntry);
                        pUsnRecord = System.IntPtr.Add(pUsnRecord, (int)usnEntry.RecordLength);//point safe arithmetic!~!!
                        outBytesReturned -= usnEntry.RecordLength;
                    }
                    nextusn = Marshal.ReadInt64(rawdata.Ptr, 0);
                    Marshal.WriteInt64(med_struct.Ptr, nextusn);//read the usn that we skipped and place it into the nextusn
                }
            }
        }