Пример #1
0
        public void ChangeDisplay(double top, double left, Win32Api.UsnEntry usnEntry, UsnEntryDetail.EntryDetail entryDetail)
        {
            Top  = top;
            Left = left;

            MainWindow     mainWin    = (MainWindow)Application.Current.MainWindow;
            NtfsUsnJournal usnJournal = mainWin.Journal;
            StringBuilder  sb         = new StringBuilder();

            if (usnEntry.IsFolder)
            {
                sb.AppendFormat("Directory: {0}", usnEntry.Name);
            }
            else if (usnEntry.IsFile)
            {
                sb.AppendFormat("File: {0}", usnEntry.Name);
            }
            _nameLbl.Content = sb.ToString();
            sb = new StringBuilder();
            string path;

            NtfsUsnJournal.UsnJournalReturnCode usnRtnCode = usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path);
            if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != string.Compare(path, "Unavailable", true))
            {
                sb.AppendFormat("  Path:    {0}{1}\\", usnJournal.VolumeName.TrimEnd('\\'), path);
            }
            else
            {
                sb.AppendFormat("  Path:    {0}", path);
            }
            _pathLbl.Content = sb.ToString();
            sb = new StringBuilder();
            sb.AppendFormat("  File Ref No: {0}", usnEntry.FileReferenceNumber);
            sb.AppendFormat("\n  Parent FRN   {0}", usnEntry.ParentFileReferenceNumber);

            if (entryDetail == EntryDetail.UsnEntry)
            {
                sb.AppendFormat("\n  Length:  {0}", usnEntry.RecordLength);
                sb.AppendFormat("\n  USN:     {0}", usnEntry.USN);
                AddReasonData(sb, usnEntry);
            }
            if (usnEntry.IsFile)
            {
                string fullPath = System.IO.Path.Combine(path, usnEntry.Name);
                if (File.Exists(fullPath))
                {
                    FileInfo fi = new FileInfo(fullPath);
                    sb.AppendFormat("\n  File Length:   {0} (bytes)", fi.Length);
                    sb.AppendFormat("\n  Creation Time: {0} - {1}", fi.CreationTime.ToShortDateString(), fi.CreationTime.ToShortTimeString());
                    sb.AppendFormat("\n  Last Modify:   {0} - {1}", fi.LastWriteTime.ToShortDateString(), fi.LastWriteTime.ToShortTimeString());
                    sb.AppendFormat("\n  Last Access:   {0} - {1}", fi.LastAccessTime.ToShortDateString(), fi.LastAccessTime.ToShortTimeString());
                }
            }
            _entryDetailLbl.Content = sb.ToString();
            Visibility = Visibility.Visible;
        }
Пример #2
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);
        }
        /*
         * public FileNameAndParentFrn(string name, UInt64 frn, UInt64 parentFrn)
         * {
         *  if (!string.IsNullOrEmpty(name))
         *  {
         *      _name = name;
         *  }
         *  else
         *  {
         *      throw new ArgumentException("Invalid argument: null or Length = zero", "name");
         *  }
         *  _frn = frn;
         *  _parentFrn = parentFrn;
         * }   // end FileNameAndParentFrn() closing bracket
         */

        public FileNameAndParentFrn(Win32Api.UsnEntry usnEntry)
        {
            if (!string.IsNullOrEmpty(usnEntry.Name))
            {
                _name = usnEntry.Name;
            }
            else
            {
                throw new ArgumentException("Invalid argument: null or Length = zero", "name");
            }
            _frn       = usnEntry.FileReferenceNumber;
            _parentFrn = usnEntry.ParentFileReferenceNumber;
        }   // end FileNameAndParentFrn() closing bracket
Пример #4
0
        private void resultsLb_Selectionchanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox lb = sender as ListBox;

            if (lb.SelectedItem != null)
            {
                if (lb.SelectedItem.GetType() == typeof(Win32Api.UsnEntry))
                {
                    Win32Api.UsnEntry item = (Win32Api.UsnEntry)lb.SelectedItem;
                    _usnEntryDetail.ChangeDisplay(_lbItemY, _lbItemX, item, _entryDetail);
                }
            }
        }
Пример #5
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
                    }
                }
        }
Пример #6
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;
        }
Пример #7
0
        private static string GetActualPath(NtfsUsnJournal journal, Win32Api.UsnEntry item)
        {
            string actualPath = null;

            string rawPath;
            var    usnRtnCode = journal.GetPathFromFileReference(item.ParentFileReferenceNumber, out rawPath);

            if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != String.Compare(rawPath, "Unavailable", StringComparison.OrdinalIgnoreCase))
            {
                actualPath = $"{journal.MountPoint.TrimEnd('\\')}{rawPath.TrimEnd('\\')}\\{item.Name}";
            }
            else
            {
                return(actualPath);
            }
            if (actualPath.ToLowerInvariant().StartsWith($"{journal.MountPoint.TrimEnd('\\')}\\System Volume Information".ToLowerInvariant()))
            {
                return(actualPath);
            }
            return(actualPath);
        }
Пример #8
0
        private void resultsLb_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListBox lb = sender as ListBox;

            if (lb.SelectedItem != null)
            {
                if (lb.SelectedItem.GetType() == typeof(Win32Api.UsnEntry))
                {
                    Win32Api.UsnEntry usnEntry = (Win32Api.UsnEntry)lb.SelectedItem;
                    StringBuilder     sb       = new StringBuilder();
                    string            path;
                    NtfsUsnJournal.UsnJournalReturnCode usnRtnCode = _usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path);
                    if (usnRtnCode == NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && 0 != string.Compare(path, "Unavailable", true))
                    {
                        if (usnEntry.IsFile)
                        {
                            string fullPath = System.IO.Path.Combine(path, usnEntry.Name);
                            if (File.Exists(fullPath))
                            {
                                try
                                {
                                    Process.Start(fullPath);
                                }
                                catch (Exception excptn)
                                {
                                    MessageBox.Show(excptn.Message);
                                }
                            }
                            else
                            {
                                MessageBox.Show(string.Format("File '{0}' not found", fullPath));
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
        private void PopulateFlags(RawUSNEntry dbEntry, Win32Api.UsnEntry entry)
        {
            uint value = entry.Reason & Win32Api.USN_REASON_DATA_OVERWRITE;

            if (0 != value)
            {
                dbEntry.DataOverwrite = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_DATA_EXTEND;
            if (0 != value)
            {
                dbEntry.DataExtend = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_DATA_TRUNCATION;
            if (0 != value)
            {
                dbEntry.DataTruncation = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_OVERWRITE;
            if (0 != value)
            {
                dbEntry.NamedDataOverwrite = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_EXTEND;
            if (0 != value)
            {
                dbEntry.NamedDataExtend = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_NAMED_DATA_TRUNCATION;
            if (0 != value)
            {
                dbEntry.NamedDataTruncation = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_FILE_CREATE;
            if (0 != value)
            {
                dbEntry.FileCreate = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_FILE_DELETE;
            if (0 != value)
            {
                dbEntry.FileDelete = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_EA_CHANGE;
            if (0 != value)
            {
                dbEntry.EaChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_SECURITY_CHANGE;
            if (0 != value)
            {
                dbEntry.SecurityChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_RENAME_OLD_NAME;
            if (0 != value)
            {
                dbEntry.RenameOldName = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_RENAME_NEW_NAME;
            if (0 != value)
            {
                dbEntry.RenameNewName = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_INDEXABLE_CHANGE;
            if (0 != value)
            {
                dbEntry.IndexableChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_BASIC_INFO_CHANGE;
            if (0 != value)
            {
                dbEntry.BasicInfoChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_HARD_LINK_CHANGE;
            if (0 != value)
            {
                dbEntry.HardLinkChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_COMPRESSION_CHANGE;
            if (0 != value)
            {
                dbEntry.CompressionChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_ENCRYPTION_CHANGE;
            if (0 != value)
            {
                dbEntry.EncryptionChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_OBJECT_ID_CHANGE;
            if (0 != value)
            {
                dbEntry.ObjectIdChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_REPARSE_POINT_CHANGE;
            if (0 != value)
            {
                dbEntry.ReparsePointChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_STREAM_CHANGE;
            if (0 != value)
            {
                dbEntry.StreamChange = true;
            }
            value = entry.Reason & Win32Api.USN_REASON_CLOSE;
            if (0 != value)
            {
                dbEntry.Close = true;
            }
        }
        /// <summary>Given a previous state, GetUsnJournalEntries() determines if the USN journal is active and
        /// no USN journal entries have been lost (i.e. USN journal is valid), then
        /// it loads a SortedList<UInt64, Win32Api.UsnEntry> list and returns it as the out parameter 'usnEntries'.
        /// If GetUsnJournalChanges returns anything but USN_JOURNAL_SUCCESS, the usnEntries list will
        /// be empty.
        /// </summary>
        /// <param name="previousUsnState">The USN journal state the last time volume changes were requested.</param>
        /// <param name="reasonMask"></param>
        /// <param name="usnEntries"></param>
        /// <param name="newUsnState"></param>
        /// <returns>
        /// USN_JOURNAL_SUCCESS                 GetUsnJournalChanges() function succeeded.
        /// VOLUME_NOT_NTFS                     volume is not an NTFS volume.
        /// INVALID_HANDLE_VALUE                NtfsUsnJournal object failed initialization.
        /// USN_JOURNAL_NOT_ACTIVE              USN journal is not active on volume.
        /// ERROR_ACCESS_DENIED                 accessing the USN journal requires admin rights, see remarks.
        /// ERROR_INVALID_FUNCTION              error generated by DeviceIoControl() call.
        /// ERROR_FILE_NOT_FOUND                error generated by DeviceIoControl() call.
        /// ERROR_PATH_NOT_FOUND                error generated by DeviceIoControl() call.
        /// ERROR_TOO_MANY_OPEN_FILES           error generated by DeviceIoControl() call.
        /// ERROR_INVALID_HANDLE                error generated by DeviceIoControl() call.
        /// ERROR_INVALID_DATA                  error generated by DeviceIoControl() call.
        /// ERROR_NOT_SUPPORTED                 error generated by DeviceIoControl() call.
        /// ERROR_INVALID_PARAMETER             error generated by DeviceIoControl() call.
        /// ERROR_JOURNAL_DELETE_IN_PROGRESS    USN journal delete is in progress.
        /// ERROR_INVALID_USER_BUFFER           error generated by DeviceIoControl() call.
        /// USN_JOURNAL_ERROR                   unspecified USN journal error.
        /// </returns>
        /// <remarks>
        /// If function returns ERROR_ACCESS_DENIED you need to run application as an Administrator.
        /// </remarks>
        public int GetUsnJournalEntries(Win32Api.USN_JOURNAL_DATA_V0 previousUsnState, uint reasonMask, out List <Win32Api.UsnEntry> usnEntries, out Win32Api.USN_JOURNAL_DATA_V0 newUsnState)
        {
            usnEntries  = new List <Win32Api.UsnEntry>();
            newUsnState = new Win32Api.USN_JOURNAL_DATA_V0();
            var lastError = (int)UsnJournalReturnCode.VOLUME_NOT_NTFS;

            var sw = new Stopwatch();

            sw.Start();

            if (bNtfsVolume)
            {
                if (_usnJournalRootHandle.ToInt64() != Win32Api.INVALID_HANDLE_VALUE)
                {
                    // Get current USN journal state.
                    lastError = QueryUsnJournal(ref newUsnState);
                    if (lastError == (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS)
                    {
                        var bReadMore = true;

                        // Sequentially process the USN journal looking for image file entries.
                        const int pbDataSize = sizeof(ulong) * 16384;
                        var       pbData     = Marshal.AllocHGlobal(pbDataSize);
                        Win32Api.ZeroMemory(pbData, pbDataSize);

                        var rujd = new Win32Api.READ_USN_JOURNAL_DATA_V0
                        {
                            StartUsn          = (ulong)previousUsnState.NextUsn,
                            ReasonMask        = reasonMask,
                            ReturnOnlyOnClose = 0,
                            Timeout           = 0,
                            BytesToWaitFor    = 0,
                            UsnJournalId      = previousUsnState.UsnJournalID
                        };

                        var sizeRujd   = Marshal.SizeOf(rujd);
                        var rujdBuffer = Marshal.AllocHGlobal(sizeRujd);
                        Win32Api.ZeroMemory(rujdBuffer, sizeRujd);
                        Marshal.StructureToPtr(rujd, rujdBuffer, true);

                        // Read USN journal entries.
                        while (bReadMore)
                        {
                            uint outBytesReturned;

                            var bRtn = Win32Api.DeviceIoControl(_usnJournalRootHandle, Win32Api.FSCTL_READ_USN_JOURNAL, rujdBuffer, sizeRujd, pbData, pbDataSize, out outBytesReturned, IntPtr.Zero);
                            if (bRtn)
                            {
                                var pUsnRecord = new IntPtr(pbData.ToInt64() + sizeof(ulong));

                                // While there is at least one entry in the USN journal.
                                while (outBytesReturned > 60)
                                {
                                    var usnEntry = new Win32Api.UsnEntry(pUsnRecord);

                                    // Only read until the current usn points beyond the current state's USN.
                                    if (usnEntry.USN >= newUsnState.NextUsn)
                                    {
                                        bReadMore = false;
                                        break;
                                    }

                                    usnEntries.Add(usnEntry);

                                    pUsnRecord        = new IntPtr(pUsnRecord.ToInt64() + usnEntry.RecordLength);
                                    outBytesReturned -= usnEntry.RecordLength;
                                }
                            }

                            else
                            {
                                var lastWin32Error = Marshal.GetLastWin32Error();
                                if (lastWin32Error == (int)Win32Api.GetLastErrorEnum.ERROR_HANDLE_EOF)
                                {
                                    lastError = (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS;
                                }

                                break;
                            }

                            var nextUsn = Marshal.ReadInt64(pbData, 0);
                            if (nextUsn >= newUsnState.NextUsn)
                            {
                                break;
                            }

                            Marshal.WriteInt64(rujdBuffer, nextUsn);
                        }

                        Marshal.FreeHGlobal(rujdBuffer);
                        Marshal.FreeHGlobal(pbData);
                    }
                }

                else
                {
                    lastError = (int)UsnJournalReturnCode.INVALID_HANDLE_VALUE;
                }
            }

            ElapsedTime = TimeSpan.FromMilliseconds(sw.ElapsedMilliseconds);

            return(lastError);
        }
        /// <summary>Returns an enumerable collection of <see cref="Win32Api.UsnEntry"/> entries that meet specified criteria.</summary>
        /// <param name="onlyFolders"></param>
        /// <param name="filter">The filter.</param>
        private IEnumerable <Win32Api.UsnEntry> EnumerateUsnEntries(bool?onlyFolders, string filter = null)
        {
            var usnState = new Win32Api.USN_JOURNAL_DATA_V0();

            if (QueryUsnJournal(ref usnState) != (int)UsnJournalReturnCode.USN_JOURNAL_SUCCESS)
            {
                throw new Win32Exception("Failed to query the USN journal on the volume.");
            }


            if (string.IsNullOrWhiteSpace(filter) || filter.Equals("*", StringComparison.Ordinal))
            {
                filter = null;
            }

            var fileTypes = null != filter?filter.Split(' ', ',', ';') : null;


            // Set up MFT_ENUM_DATA_V0 structure.
            var mftData = new Win32Api.MFT_ENUM_DATA_V0
            {
                StartFileReferenceNumber = 0,
                LowUsn  = 0,
                HighUsn = usnState.NextUsn
            };

            var mftDataSize   = Marshal.SizeOf(mftData);
            var mftDataBuffer = Marshal.AllocHGlobal(mftDataSize);

            Win32Api.ZeroMemory(mftDataBuffer, mftDataSize);
            Marshal.StructureToPtr(mftData, mftDataBuffer, true);


            // Set up the data buffer which receives the USN_RECORD data.
            const int pDataSize = sizeof(ulong) + 10000;
            var       pData     = Marshal.AllocHGlobal(pDataSize);

            Win32Api.ZeroMemory(pData, pDataSize);


            uint outBytesReturned;

            // Gather up volume's directories.
            while (Win32Api.DeviceIoControl(_usnJournalRootHandle, Win32Api.FSCTL_ENUM_USN_DATA, mftDataBuffer, mftDataSize, pData, pDataSize, out outBytesReturned, IntPtr.Zero))
            {
                var pUsnRecord = new IntPtr(pData.ToInt64() + sizeof(long));

                // While there is at least one entry in the USN journal.
                while (outBytesReturned > 60)
                {
                    var usnEntry = new Win32Api.UsnEntry(pUsnRecord);


                    if (null == onlyFolders)
                    {
                        yield return(usnEntry);
                    }

                    else if (usnEntry.IsFolder)
                    {
                        if ((bool)onlyFolders)
                        {
                            yield return(usnEntry);
                        }
                    }

                    else if (!(bool)onlyFolders)
                    {
                        if (null == filter)
                        {
                            yield return(usnEntry);
                        }

                        else
                        {
                            var extension = Path.GetExtension(usnEntry.Name);

                            if (!string.IsNullOrEmpty(extension))
                            {
                                foreach (var fileType in fileTypes)
                                {
                                    if (fileType.Contains("*"))
                                    {
                                        if (extension.IndexOf(fileType.Trim('*'), StringComparison.OrdinalIgnoreCase) >= 0)
                                        {
                                            yield return(usnEntry);
                                        }
                                    }

                                    else if (extension.Equals("." + fileType.TrimStart('.'), StringComparison.OrdinalIgnoreCase))
                                    {
                                        yield return(usnEntry);
                                    }
                                }
                            }
                        }
                    }


                    pUsnRecord        = new IntPtr(pUsnRecord.ToInt64() + usnEntry.RecordLength);
                    outBytesReturned -= usnEntry.RecordLength;
                }

                Marshal.WriteInt64(mftDataBuffer, Marshal.ReadInt64(pData, 0));
            }

            Marshal.FreeHGlobal(pData);
        }
Пример #12
0
        /// <summary>
        /// GetFileAndDirEntries() reads the Master File Table to find all of the files and
        /// folders on a volume and returns them individually.
        /// </summary>
        /// <param name="dirs">The directories.</param>
        /// <param name="files">The files.</param>
        /// <param name="filter">The filter.</param>
        private void GetFileAndDirEntries(out ConcurrentDictionary<ulong, Win32Api.UsnEntry> dirs, out ConcurrentBag<Win32Api.UsnEntry> files, Regex filter = null)
        {
            dirs  = new ConcurrentDictionary<ulong, Win32Api.UsnEntry>();
            files = new ConcurrentBag<Win32Api.UsnEntry>();

            var usnState = new Win32Api.USN_JOURNAL_DATA();

            if (!QueryUsnJournal(ref usnState))
            {
                throw new Win32Exception("Failed to query the USN journal on the volume.");
            }

            //
            // set up MFT_ENUM_DATA structure
            //
            Win32Api.MFT_ENUM_DATA med;
            med.StartFileReferenceNumber = 0;
            med.LowUsn = 0;
            med.HighUsn = usnState.NextUsn;
            Int32 sizeMftEnumData = Marshal.SizeOf(med);
            IntPtr medBuffer = Marshal.AllocHGlobal(sizeMftEnumData);
            Win32Api.ZeroMemory(medBuffer, sizeMftEnumData);
            Marshal.StructureToPtr(med, medBuffer, true);

            //
            // set up the data buffer which receives the USN_RECORD data
            //
            int pDataSize = sizeof (UInt64) + 10000;
            IntPtr pData = Marshal.AllocHGlobal(pDataSize);
            Win32Api.ZeroMemory(pData, pDataSize);
            uint outBytesReturned = 0;

            //
            // Gather up volume's directories
            //
            while (Win32Api.DeviceIoControl(
                _usnJournalRootHandle,
                Win32Api.FSCTL_ENUM_USN_DATA,
                medBuffer,
                sizeMftEnumData,
                pData,
                pDataSize,
                out outBytesReturned,
                IntPtr.Zero))
            {
                IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof (Int64));
                while (outBytesReturned > 60)
                {
                    var usnEntry = new Win32Api.UsnEntry(pUsnRecord);

                    if (usnEntry.IsFile && (filter == null || filter.IsMatch(usnEntry.Name)))
                    {
                        files.Add(usnEntry);
                    }
                    if (usnEntry.IsFolder)
                    {
                        dirs.TryAdd(usnEntry.FileReferenceNumber, usnEntry);
                    }

                    pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnEntry.RecordLength);
                    outBytesReturned -= usnEntry.RecordLength;
                }
                Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
            }

            Marshal.FreeHGlobal(pData);
        }
Пример #13
0
        private static void AddReasonData(StringBuilder sb, Win32Api.UsnEntry usnEntry)
        {
            sb.AppendFormat("\n  Reason Codes:");
            var value = usnEntry.Reason & Win32Api.USN_REASON_DATA_OVERWRITE;

            if (0 != value)
            {
                sb.AppendFormat("\n     -DATA OVERWRITE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_DATA_EXTEND;
            if (0 != value)
            {
                sb.AppendFormat("\n     -DATA EXTEND");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_DATA_TRUNCATION;
            if (0 != value)
            {
                sb.AppendFormat("\n     -DATA TRUNCATION");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_OVERWRITE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -NAMED DATA OVERWRITE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_EXTEND;
            if (0 != value)
            {
                sb.AppendFormat("\n     -NAMED DATA EXTEND");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_NAMED_DATA_TRUNCATION;
            if (0 != value)
            {
                sb.AppendFormat("\n     -NAMED DATA TRUNCATION");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_FILE_CREATE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -FILE CREATE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_FILE_DELETE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -FILE DELETE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_EA_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -EA CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_SECURITY_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -SECURITY CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_RENAME_OLD_NAME;
            if (0 != value)
            {
                sb.AppendFormat("\n     -RENAME OLD NAME");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_RENAME_NEW_NAME;
            if (0 != value)
            {
                sb.AppendFormat("\n     -RENAME NEW NAME");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_INDEXABLE_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -INDEXABLE CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_BASIC_INFO_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -BASIC INFO CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_HARD_LINK_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -HARD LINK CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_COMPRESSION_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -COMPRESSION CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_ENCRYPTION_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -ENCRYPTION CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_OBJECT_ID_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -OBJECT ID CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_REPARSE_POINT_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -REPARSE POINT CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_STREAM_CHANGE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -STREAM CHANGE");
            }

            value = usnEntry.Reason & Win32Api.USN_REASON_CLOSE;
            if (0 != value)
            {
                sb.AppendFormat("\n     -CLOSE");
            }
        }
Пример #14
0
        public void ChangeDisplay(NtfsUsnJournal usnJournal, double top, double left, Win32Api.UsnEntry usnEntry, EntryDetail entryDetail)
        {
            Top  = top;
            Left = left;

            _nameLbl.Text = string.Format(CultureInfo.InvariantCulture, usnEntry.IsFolder ? "Directory: {0}" : "File: {0}", usnEntry.Name);

            string path;

            var lastError = usnJournal.GetPathFromFileReference(usnEntry.ParentFileReferenceNumber, out path);

            if (lastError == (int)NtfsUsnJournal.UsnJournalReturnCode.USN_JOURNAL_SUCCESS && null != path)
            {
                path = string.Format(CultureInfo.InvariantCulture, "{0}{1}\\", usnJournal.VolumeName.TrimEnd('\\'), path);
            }

            _pathLbl.Text = path;


            var sb = new StringBuilder();

            sb.AppendFormat("  File Ref No: {0}", usnEntry.FileReferenceNumber);
            sb.AppendFormat("\n  Parent FRN   {0}", usnEntry.ParentFileReferenceNumber);

            if (entryDetail == EntryDetail.UsnEntry)
            {
                sb.AppendFormat("\n  Length:  {0}", usnEntry.RecordLength);
                sb.AppendFormat("\n  USN:     {0}", usnEntry.USN);
                AddReasonData(sb, usnEntry);
            }

            if (!usnEntry.IsFolder)
            {
                var fullPath = Path.Combine(_pathLbl.Text, usnEntry.Name);
                if (File.Exists(fullPath))
                {
                    var fi = new FileInfo(fullPath);
                    sb.AppendFormat("\n  File Length:   {0} (bytes)", fi.Length);
                    sb.AppendFormat("\n  Creation Time: {0} - {1}", fi.CreationTime.ToShortDateString(), fi.CreationTime.ToShortTimeString());
                    sb.AppendFormat("\n  Last Modify:   {0} - {1}", fi.LastWriteTime.ToShortDateString(), fi.LastWriteTime.ToShortTimeString());
                    sb.AppendFormat("\n  Last Access:   {0} - {1}", fi.LastAccessTime.ToShortDateString(), fi.LastAccessTime.ToShortTimeString());
                }
            }

            _entryDetailLbl.Content = sb.ToString();
            Visibility = Visibility.Visible;
        }
Пример #15
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
                }
            }
        }
Пример #16
0
 public NTFS_File(Win32Api.UsnEntry u)
 {
     Entry    = u;
     Children = new List <NTFS_File>();
     Parent   = null;
 }