コード例 #1
0
        public void GetEntries(long usn, ulong fileNumber, GetEntriesHandler handler, int count)
        {
            List <UsnEntry> result       = new List <UsnEntry>();
            UsnErrorCode    usnErrorCode = this.QueryUSNJournal();

            if (usnErrorCode == UsnErrorCode.SUCCESS)
            {
                MFT_ENUM_DATA mftEnumData = new MFT_ENUM_DATA();
                mftEnumData.StartFileReferenceNumber = fileNumber;
                mftEnumData.LowUsn  = 0;
                mftEnumData.HighUsn = this.ntfsUsnJournalData.NextUsn;
                int    sizeMftEnumData = Marshal.SizeOf(mftEnumData);
                IntPtr ptrMftEnumData  = GetHeapGlobalPtr(sizeMftEnumData);
                Marshal.StructureToPtr(mftEnumData, ptrMftEnumData, true);
                int    ptrDataSize = sizeof(UInt64) + 10000;
                IntPtr ptrData     = GetHeapGlobalPtr(ptrDataSize);
                uint   outBytesCount;

                while (false != Win32Api.DeviceIoControl(
                           this.DriveRootHandle,
                           UsnControlCode.FSCTL_ENUM_USN_DATA,
                           ptrMftEnumData,
                           sizeMftEnumData,
                           ptrData,
                           ptrDataSize,
                           out outBytesCount,
                           IntPtr.Zero))
                {
                    long   purvalue     = ptrData.ToInt64() + sizeof(long);
                    IntPtr ptrUsnRecord = new IntPtr(purvalue);

                    while (outBytesCount > 60)
                    {
                        var usnRecord = new USN_RECORD_V2(ptrUsnRecord);

                        UsnEntry rec = new UsnEntry(usnRecord);
                        if (rec.FileReferenceNumber > fileNumber || rec.Usn > usn)
                        {
                            result.Add(rec);
                        }

                        ptrUsnRecord   = new IntPtr(ptrUsnRecord.ToInt64() + usnRecord.RecordLength);
                        outBytesCount -= usnRecord.RecordLength;

                        if (result.Count >= count)
                        {
                            handler?.Invoke(Drive, result);
                            result = new List <UsnEntry>();
                        }
                    }
                    Marshal.WriteInt64(ptrMftEnumData, Marshal.ReadInt64(ptrData, 0));
                }

                Marshal.FreeHGlobal(ptrData);
                Marshal.FreeHGlobal(ptrMftEnumData);
            }
            handler?.Invoke(Drive, result);
        }
コード例 #2
0
ファイル: UsnOperator.cs プロジェクト: tomxue/Everything
        public List <UsnEntry> GetEntries()
        {
            var result = new List <UsnEntry>();

            UsnErrorCode usnErrorCode = this.QueryUSNJournal();

            if (usnErrorCode == UsnErrorCode.SUCCESS)
            {
                MFT_ENUM_DATA mftEnumData = new MFT_ENUM_DATA();
                mftEnumData.StartFileReferenceNumber = 0;
                mftEnumData.LowUsn  = 0;
                mftEnumData.HighUsn = this.ntfsUsnJournalData.NextUsn;
                int    sizeMftEnumData = Marshal.SizeOf(mftEnumData);
                IntPtr ptrMftEnumData  = GetHeapGlobalPtr(sizeMftEnumData);
                Marshal.StructureToPtr(mftEnumData, ptrMftEnumData, true);
                int    ptrDataSize = sizeof(UInt64) + 10000;
                IntPtr ptrData     = GetHeapGlobalPtr(ptrDataSize);
                uint   outBytesCount;

                while (false != Win32Api.DeviceIoControl(
                           this.DriveRootHandle,
                           UsnControlCode.FSCTL_ENUM_USN_DATA,
                           ptrMftEnumData,
                           sizeMftEnumData,
                           ptrData,
                           ptrDataSize,
                           out outBytesCount,
                           IntPtr.Zero))
                {
                    // ptrData includes following struct:
                    //typedef struct
                    //{
                    //    USN             LastFileReferenceNumber;
                    //    USN_RECORD_V2   Record[1];
                    //} *PENUM_USN_DATA;

                    long   purvalue     = ptrData.ToInt64() + sizeof(long);
                    IntPtr ptrUsnRecord = new IntPtr(purvalue);

                    while (outBytesCount > 60)
                    {
                        var usnRecord = new USN_RECORD_V2(ptrUsnRecord);
                        result.Add(new UsnEntry(usnRecord));
                        ptrUsnRecord   = new IntPtr(ptrUsnRecord.ToInt64() + usnRecord.RecordLength);
                        outBytesCount -= usnRecord.RecordLength;
                    }
                    Marshal.WriteInt64(ptrMftEnumData, Marshal.ReadInt64(ptrData, 0));
                }

                Marshal.FreeHGlobal(ptrData);
                Marshal.FreeHGlobal(ptrMftEnumData);
            }

            return(result);
        }
コード例 #3
0
ファイル: UsnEntry.cs プロジェクト: ruo2012/everything
 public UsnEntry(USN_RECORD_V2 usnRecord)
 {
     this.RecordLength              = usnRecord.RecordLength;
     this.FileReferenceNumber       = usnRecord.FileReferenceNumber;
     this.ParentFileReferenceNumber = usnRecord.ParentFileReferenceNumber;
     this.Usn            = usnRecord.Usn;
     this.Reason         = usnRecord.Reason;
     this.FileAttributes = usnRecord.FileAttributes;
     this.FileNameLength = usnRecord.FileNameLength;
     this.FileNameOffset = usnRecord.FileNameOffset;
     this.FileName       = usnRecord.FileName;
 }
コード例 #4
0
 /// <summary>
 ///     Copy constructor.
 /// </summary>
 /// <param name="nativeEntry"></param>
 /// <param name="name"></param>
 internal JournalEntry(USN_RECORD_V2 nativeEntry, string name)
 {
     Name                  = name ?? throw new ArgumentNullException(nameof(name));
     Length                = (int)nativeEntry.RecordLength;
     Version               = new Version(nativeEntry.MajorVersion, nativeEntry.MinorVersion);
     ReferenceNumber       = nativeEntry.FileReferenceNumber;
     ParentReferenceNumber = nativeEntry.ParentFileReferenceNumber;
     UniqueSequenceNumber  = nativeEntry.USN;
     TimeStamp             = DateTime.FromFileTimeUtc(nativeEntry.TimeStamp);
     Reason                = (ChangeReason)nativeEntry.Reason;
     Source                = (SourceInformation)nativeEntry.SourceInfo;
     SecurityID            = (int)nativeEntry.SecurityId;
     Attributes            = (FileAttributes)nativeEntry.FileAttributes;
 }
コード例 #5
0
ファイル: UsnOperator.cs プロジェクト: tomxue/Everything
        public bool UsnIsExist(long usn)
        {
            bool         rs           = false;
            UsnErrorCode usnErrorCode = QueryUSNJournal();

            if (ntfsUsnJournalData.NextUsn < usn)
            {
                return(rs);
            }

            if (usnErrorCode == UsnErrorCode.SUCCESS)
            {
                MFT_ENUM_DATA mftEnumData = new MFT_ENUM_DATA();
                mftEnumData.StartFileReferenceNumber = 0;
                mftEnumData.LowUsn  = usn;
                mftEnumData.HighUsn = usn;
                int    sizeMftEnumData = Marshal.SizeOf(mftEnumData);
                IntPtr ptrMftEnumData  = GetHeapGlobalPtr(sizeMftEnumData);
                Marshal.StructureToPtr(mftEnumData, ptrMftEnumData, true);
                int    ptrDataSize = sizeof(UInt64) + 10000;
                IntPtr ptrData     = GetHeapGlobalPtr(ptrDataSize);
                uint   outBytesCount;

                while (false != Win32Api.DeviceIoControl(
                           this.DriveRootHandle,
                           UsnControlCode.FSCTL_ENUM_USN_DATA,
                           ptrMftEnumData,
                           sizeMftEnumData,
                           ptrData,
                           ptrDataSize,
                           out outBytesCount,
                           IntPtr.Zero))
                {
                    IntPtr ptrUsnRecord = new IntPtr(ptrData.ToInt32() + sizeof(Int64));

                    while (outBytesCount > 60)
                    {
                        var usnRecord = new USN_RECORD_V2(ptrUsnRecord);
                        ptrUsnRecord   = new IntPtr(ptrUsnRecord.ToInt32() + usnRecord.RecordLength);
                        outBytesCount -= usnRecord.RecordLength;
                        rs             = true;
                    }
                    Marshal.WriteInt64(ptrMftEnumData, Marshal.ReadInt64(ptrData, 0));
                }

                Marshal.FreeHGlobal(ptrData);
                Marshal.FreeHGlobal(ptrMftEnumData);
            }
            return(rs);
        }
コード例 #6
0
        private static IUSN_RECORD ParseUsnRecord(UnmanagedMemory mem, int dataOffset, out int length)
        {
            // Get record length
            length = Marshal.ReadInt32(mem, dataOffset);
            int majorVersion = Marshal.ReadByte(mem, dataOffset + sizeof(int)) + (Marshal.ReadByte(mem, dataOffset + sizeof(int) + 1) << 8);

            if (length <= 0)
            {
                // No more records
                return(null);
            }

            // Copy out record subset
            switch (majorVersion)
            {
            case 2:
                USN_RECORD_V2 recordv2 = (USN_RECORD_V2)Marshal.PtrToStructure(mem.Handle + dataOffset, typeof(USN_RECORD_V2));

                // Parse string manually, as we cannot rely on the string to be null-terminated.
                recordv2.FileName = Marshal.PtrToStringUni(mem.Handle + dataOffset + recordv2.FileNameOffset, recordv2.FileNameLength / 2);

                return(recordv2);

            case 3:
                USN_RECORD_V3 recordv3 = (USN_RECORD_V3)Marshal.PtrToStructure(mem.Handle + dataOffset, typeof(USN_RECORD_V3));

                // Parse string manually, as we cannot rely on the string to be null-terminated.
                recordv3.FileName = Marshal.PtrToStringUni(mem.Handle + dataOffset + recordv3.FileNameOffset, recordv3.FileNameLength / 2);

                return(recordv3);

            default:
                // Ignore
                Debugger.Break();
                break;
            }

            return(null);
        }
コード例 #7
0
        private static void ExampleFileSystemIO()
        {
            const string drive = @"\\.\C:";

            Console.WriteLine(@"## Exmaple on {0} ##", drive);
            SafeFileHandle volumeHandle = CreateFile(drive, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);

            if (volumeHandle.IsInvalid)
            {
                int lastError = Marshal.GetLastWin32Error();

                Console.WriteLine(@"!! Invalid {0}; Error ({1}): {2}", drive, lastError, new Win32Exception(lastError).Message);
                Console.WriteLine();
                return;
            }

            using (volumeHandle)
            {
                // Extract a complete file list from the target drive
                IUSN_RECORD[] usnData;
                using (UsnDeviceWrapper usnIo = new UsnDeviceWrapper(volumeHandle))
                    usnData = usnIo.FileSystemEnumUsnData();

                Console.WriteLine("Found {0:N0} file/folder records", usnData.Length);

                // Count the unique file names
                int usnNameUniques = new HashSet <string>(usnData.Select(s => s.FileName)).Count;
                Console.WriteLine("Found {0:N0} unique names on records", usnNameUniques);

                // Prepare a dictionary to resolve parents
                Dictionary <ulong, USN_RECORD_V2> usnDic = usnData.OfType <USN_RECORD_V2>().ToDictionary(s => s.FileReferenceNumber);

                const string root = drive + "\\";

                List <string> files   = new List <string>();
                List <string> parents = new List <string>();

                foreach (USN_RECORD_V2 usnRecord in usnData.OfType <USN_RECORD_V2>())
                {
                    parents.Clear();

                    USN_RECORD_V2 current = usnRecord;
                    while (usnDic.ContainsKey(current.ParentFileReferenceNumber))
                    {
                        current = usnDic[current.ParentFileReferenceNumber];
                        parents.Add(current.FileName);
                    }

                    parents.Reverse();

                    string path = Path.Combine(root, Path.Combine(parents.ToArray()), usnRecord.FileName);
                    files.Add(path);
                }

                // Sort all files in lexicographical order
                files.Sort();

                // FS Stats
                FileSystemStats[] fsStats;
                using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle))
                    fsStats = fsIo.FileSystemGetStatistics();

                for (int i = 0; i < fsStats.Length; i++)
                {
                    switch (fsStats[i].Stats.FileSystemType)
                    {
                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_NTFS:
                        NTFS_STATISTICS ntfsStats = (NTFS_STATISTICS)fsStats[i].FSStats;
                        Console.WriteLine("Processor {0}: (NTFS)  MFT Reads/Writes: {1,7:N0} / {2,7:N0}", i, ntfsStats.MftReads, ntfsStats.MftWrites);
                        break;

                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_FAT:
                        FAT_STATISTICS fatStats = (FAT_STATISTICS)fsStats[i].FSStats;
                        Console.WriteLine("Processor {0}: (FAT)   Noncached Disk Reads/Writes: {1,7:N0} / {2,7:N0}", i, fatStats.NonCachedDiskReads, fatStats.NonCachedDiskWrites);
                        break;

                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_EXFAT:
                        EXFAT_STATISTICS exfatStats = (EXFAT_STATISTICS)fsStats[i].FSStats;
                        Console.WriteLine("Processor {0}: (EXFAT) Noncached Disk Reads/Writes: {1,7:N0} / {2,7:N0}", i, exfatStats.NonCachedDiskReads, exfatStats.NonCachedDiskWrites);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                // Bitmap
                VOLUME_BITMAP_BUFFER bitmap;
                using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle))
                    bitmap = fsIo.FileSystemGetVolumeBitmap(0);

                Console.WriteLine("Bitmap: {0:N0} clusters", bitmap.Buffer.Length);

                int trues = 0, falses = 0;
                for (int i = 0; i < bitmap.Buffer.Length; i++)
                {
                    if (bitmap.Buffer[i])
                    {
                        trues++;
                    }
                    else
                    {
                        falses++;
                    }
                }

                Console.WriteLine("Allocated clusters: {0:N0}", trues);
                Console.WriteLine("Unallocated clusters: {0:N0}", falses);

                // NTFS Base LCN (always 0)
                RETRIEVAL_POINTER_BASE basePointer;
                using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle))
                    basePointer = fsIo.FileSystemGetRetrievalPointerBase();
                Console.WriteLine("Base LCN: {0:N0}", basePointer.FileAreaOffset);
            }

            Console.WriteLine();
        }