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); } }
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); }
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(); }
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; }
internal static IndexBlock Initialize(Index index, bool isRoot, IndexEntry parentEntry, BiosParameterBlock bpb) { return new IndexBlock(index, isRoot, parentEntry.ChildrenVirtualCluster, bpb); }