Esempio n. 1
0
        /// <summary>
        /// This function queries the usn journal on the volume.
        /// </summary>
        /// <param name="usnJournalState">the USN_JOURNAL_DATA object that is associated with this volume</param>
        /// <returns>
        /// The success state of the <c>WinApi32.DeviceIoControl</c> call.
        /// </returns>
        private bool QueryUsnJournal(ref Win32Api.USN_JOURNAL_DATA usnJournalState)
        {
            UInt32 cb;

            return(Win32Api.DeviceIoControl(
                       _usnJournalRootHandle,
                       Win32Api.FSCTL_QUERY_USN_JOURNAL,
                       IntPtr.Zero,
                       0,
                       out usnJournalState,
                       Marshal.SizeOf(usnJournalState),
                       out cb,
                       IntPtr.Zero
                       ));
        }
Esempio n. 2
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((Utils.Is64Bit ? pData.ToInt64() : 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((Utils.Is64Bit ? pUsnRecord.ToInt64() : pUsnRecord.ToInt32()) + usnEntry.RecordLength);
                    outBytesReturned -= usnEntry.RecordLength;
                }
                Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
            }

            Marshal.FreeHGlobal(pData);
        }