Beispiel #1
0
        public Index(File file, string name, BiosParameterBlock bpb, UpperCase upCase)
        {
            _file = file;
            _name = name;
            _bpb = bpb;
            _isFileIndex = name == "$I30";

            _blockCache = new ObjectCache<long, IndexBlock>();

            _root = _file.GetStream(AttributeType.IndexRoot, _name).GetContent<IndexRoot>();
            _comparer = _root.GetCollator(upCase);

            using (Stream s = _file.OpenStream(AttributeType.IndexRoot, _name, FileAccess.Read))
            {
                byte[] buffer = Utilities.ReadFully(s, (int)s.Length);
                _rootNode = new IndexNode(WriteRootNodeToDisk, 0, this, true, buffer, IndexRoot.HeaderOffset);

                // Give the attribute some room to breathe, so long as it doesn't squeeze others out
                // BROKEN, BROKEN, BROKEN - how to figure this out?  Query at the point of adding entries to the root node?
                _rootNode.TotalSpaceAvailable += _file.MftRecordFreeSpace(AttributeType.IndexRoot, _name) - 100;
            }

            if (_file.StreamExists(AttributeType.IndexAllocation, _name))
            {
                _indexStream = _file.OpenStream(AttributeType.IndexAllocation, _name, FileAccess.ReadWrite);
            }

            if (_file.StreamExists(AttributeType.Bitmap, _name))
            {
                _indexBitmap = new Bitmap(_file.OpenStream(AttributeType.Bitmap, _name, FileAccess.ReadWrite), long.MaxValue);
            }
        }
Beispiel #2
0
        public IndexBlock(Index index, bool isRoot, IndexEntry parentEntry, BiosParameterBlock bpb)
            : base("INDX", bpb.BytesPerSector)
        {
            _index = index;
            _isRoot = isRoot;

            Stream stream = index.AllocationStream;
            _streamPosition = parentEntry.ChildrenVirtualCluster * bpb.BytesPerSector * bpb.SectorsPerCluster;
            stream.Position = _streamPosition;
            byte[] buffer = Utilities.ReadFully(stream, (int)index.IndexBufferSize);
            FromBytes(buffer, 0);
        }
Beispiel #3
0
        private IndexBlock(Index index, bool isRoot, long vcn, BiosParameterBlock bpb)
            : base("INDX", bpb.BytesPerSector, bpb.IndexBufferSize)
        {
            _index = index;
            _isRoot = isRoot;

            _indexBlockVcn = (ulong)vcn;

            _streamPosition = vcn * bpb.BytesPerSector * bpb.SectorsPerCluster;

            _node = new IndexNode(WriteToDisk, UpdateSequenceSize, _index, isRoot, (uint)bpb.IndexBufferSize - FieldSize);

            WriteToDisk();
        }
Beispiel #4
0
        private Index(AttributeType attrType, AttributeCollationRule collationRule, File file, string name, BiosParameterBlock bpb, UpperCase upCase)
        {
            _file = file;
            _name = name;
            _bpb = bpb;
            _isFileIndex = name == "$I30";

            _blockCache = new ObjectCache<long, IndexBlock>();

            _file.CreateStream(AttributeType.IndexRoot, _name);

            _root = new IndexRoot()
            {
                AttributeType = (uint)attrType,
                CollationRule = collationRule,
                IndexAllocationSize = (uint)bpb.IndexBufferSize,
                RawClustersPerIndexRecord = bpb.RawIndexBufferSize
            };

            _comparer = _root.GetCollator(upCase);

            _rootNode = new IndexNode(WriteRootNodeToDisk, 0, this, true, 32);
        }
        internal static BiosParameterBlock Initialized(Geometry diskGeometry, int clusterSize, uint partitionStartLba, long partitionSizeLba, int mftRecordSize, int indexBufferSize)
        {
            BiosParameterBlock bpb = new BiosParameterBlock();
            bpb.OemId = "NTFS    ";
            bpb.BytesPerSector = Sizes.Sector;
            bpb.SectorsPerCluster = (byte)(clusterSize / bpb.BytesPerSector);
            bpb.ReservedSectors = 0;
            bpb.NumFats = 0;
            bpb.FatRootEntriesCount = 0;
            bpb.TotalSectors16 = 0;
            bpb.Media = 0xF8;
            bpb.FatSize16 = 0;
            bpb.SectorsPerTrack = (ushort)diskGeometry.SectorsPerTrack;
            bpb.NumHeads = (ushort)diskGeometry.HeadsPerCylinder;
            bpb.HiddenSectors = partitionStartLba;
            bpb.TotalSectors32 = 0;
            bpb.BiosDriveNumber = 0x80;
            bpb.ChkDskFlags = 0;
            bpb.SignatureByte = 0x80;
            bpb.PaddingByte = 0;
            bpb.TotalSectors64 = partitionSizeLba - 1;
            bpb.RawMftRecordSize = bpb.CodeRecordSize(mftRecordSize);
            bpb.RawIndexBufferSize = bpb.CodeRecordSize(indexBufferSize);
            bpb.VolumeSerialNumber = GenSerialNumber();

            return bpb;
        }
        internal static BiosParameterBlock FromBytes(byte[] bytes, int offset)
        {
            BiosParameterBlock bpb = new BiosParameterBlock();
            bpb.OemId = Utilities.BytesToString(bytes, offset + 0x03, 8);
            bpb.BytesPerSector = Utilities.ToUInt16LittleEndian(bytes, offset + 0x0B);
            bpb.SectorsPerCluster = bytes[offset + 0x0D];
            bpb.ReservedSectors = Utilities.ToUInt16LittleEndian(bytes, offset + 0x0E);
            bpb.NumFats = bytes[offset + 0x10];
            bpb.FatRootEntriesCount = Utilities.ToUInt16LittleEndian(bytes, offset + 0x11);
            bpb.TotalSectors16 = Utilities.ToUInt16LittleEndian(bytes, offset + 0x13);
            bpb.Media = bytes[offset + 0x15];
            bpb.FatSize16 = Utilities.ToUInt16LittleEndian(bytes, offset + 0x16);
            bpb.SectorsPerTrack = Utilities.ToUInt16LittleEndian(bytes, offset + 0x18);
            bpb.NumHeads = Utilities.ToUInt16LittleEndian(bytes, offset + 0x1A);
            bpb.HiddenSectors = Utilities.ToUInt32LittleEndian(bytes, offset + 0x1C);
            bpb.TotalSectors32 = Utilities.ToUInt32LittleEndian(bytes, offset + 0x20);
            bpb.BiosDriveNumber = bytes[offset + 0x24];
            bpb.ChkDskFlags = bytes[offset + 0x25];
            bpb.SignatureByte = bytes[offset + 0x26];
            bpb.PaddingByte = bytes[offset + 0x27];
            bpb.TotalSectors64 = Utilities.ToInt64LittleEndian(bytes, offset + 0x28);
            bpb.MftCluster = Utilities.ToInt64LittleEndian(bytes, offset + 0x30);
            bpb.MftMirrorCluster = Utilities.ToInt64LittleEndian(bytes, offset + 0x38);
            bpb.RawMftRecordSize = bytes[offset + 0x40];
            bpb.RawIndexBufferSize = bytes[offset + 0x44];
            bpb.VolumeSerialNumber = Utilities.ToUInt64LittleEndian(bytes, offset + 0x48);

            return bpb;
        }
Beispiel #7
0
 internal static IndexBlock Initialize(Index index, bool isRoot, IndexEntry parentEntry, BiosParameterBlock bpb)
 {
     return new IndexBlock(index, isRoot, parentEntry.ChildrenVirtualCluster, bpb);
 }