Пример #1
0
        private void InitializeNTFS()
        {
            // Read $BOOT
            if (Provider.MftFileOnly)
            {
                Boot                  = new BootSector();
                Boot.OEMCode          = "NTFS";
                Boot.SectorsPrCluster = 2;                      // Small cluster
                Boot.BytesPrSector    = 512;                    // Smallest possible sector

                // Get FileRecord size (read first record's size)
                byte[] mft_data = new byte[512];
                Provider.ReadBytes(mft_data, 0, 0, mft_data.Length);

                Boot.MFTRecordSizeBytes = FileRecord.ParseAllocatedSize(mft_data, 0);

                mft_data = null;
            }
            else
            {
                byte[] drive_data = new byte[512];
                Provider.ReadBytes(drive_data, 0, 0, 512);
                Boot = BootSector.ParseData(drive_data, 512, 0);

                drive_data = null;

                Debug.Assert(Boot.OEMCode == "NTFS");
            }

            // Get FileRecord size
            BytesPrFileRecord = Boot.MFTRecordSizeBytes;
            _sectorsPrRecord  = BytesPrFileRecord / BytesPrSector;
            Debug.WriteLine($"Updated BytesPrFileRecord, now set to {BytesPrFileRecord}");

            // Prep cache
            MftRawCache = new RawDiskCache(0);

            // Read $MFT file record

            byte[] record_data = ReadMFTRecordData((uint)SpecialMFTFiles.MFT);
            FileMFT     = ParseMFTRecord(record_data);
            record_data = null;


            Debug.Assert(FileMFT != null);

            Debug.Assert(FileMFT.Attributes.Count(s => s.Type == AttributeType.DATA) == 1);
            AttributeData fileMftData = FileMFT.Attributes.OfType <AttributeData>().Single();

            Debug.Assert(fileMftData.NonResidentFlag == ResidentFlag.NonResident);
            Debug.Assert(fileMftData.DataFragments.Length >= 1);

            MftStream = OpenFileRecord(FileMFT);

            // Prep cache
            long maxLength          = MftStream.Length;
            long toAllocateForCache = Math.Min(maxLength, _rawDiskCacheSizeRecords * BytesPrFileRecord);

            MftRawCache = new RawDiskCache((int)toAllocateForCache);

            // Get number of FileRecords
            FileRecordCount = (uint)((fileMftData.DataFragments.Sum(s => (float)s.Clusters)) * (BytesPrCluster * 1f / BytesPrFileRecord));
            FileRecords     = new WeakReference[FileRecordCount];

            FileRecords[0] = new WeakReference(FileMFT);

            // Read $VOLUME file record
            FileRecord fileVolume = ReadMFTRecord(SpecialMFTFiles.Volume);

            // Get version
            Attribute versionAttrib = fileVolume.Attributes.SingleOrDefault(s => s.Type == AttributeType.VOLUME_INFORMATION);

            if (versionAttrib != null)
            {
                AttributeVolumeInformation attrib = (AttributeVolumeInformation)versionAttrib;
                NTFSVersion = new Version(attrib.MajorVersion, attrib.MinorVersion);
            }
        }