public void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] volumeIdentifierBytes; this.SourceFileName = isoStream.Name; this.FormatDescription = MicrosoftSTFS.FORMAT_DESCRIPTION_STRING; this.VolumeBaseOffset = offset; this.IsRawDump = isRawDump; this.VolumeType = VolumeDataType.Data; this.FileTableEntryArray = new ArrayList(); this.DirectoryStructureArray = new ArrayList(); // get identifier volumeIdentifierBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 0x1691, 0x80); this.VolumeIdentifier = Encoding.BigEndianUnicode.GetString(volumeIdentifierBytes); this.VolumeIdentifier = this.VolumeIdentifier.Substring(0, this.VolumeIdentifier.IndexOf('\0')); // get header size this.HeaderSize = ParseFile.ReadUintBE(isoStream, this.VolumeBaseOffset + 0x340); // get file table info this.BlockSeparation = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 0x37B); this.FileTableBlockCount = ParseFile.ReadInt16LE(isoStream, this.VolumeBaseOffset + 0x37C); // not sure about endianess, always zero in my samples so far this.FileTableBlockNumber = ParseFile.ReadInt24LE(isoStream, this.VolumeBaseOffset + 0x37E); // parse file table this.ParseFileTable(isoStream); // build directory tree this.BuildDirectoryTree(); }
public void ParseFileTable(FileStream isoStream) { FileTableEntry tableEntry = new FileTableEntry(); long fileTableMinOffset; long fileTableMaxOffset; long fileSize = isoStream.Length; // get offset for blocks fileTableMinOffset = ComputeBlockNumberAndGetOffset(this.FileTableBlockNumber, this.HeaderSize, this.BlockSeparation); fileTableMaxOffset = ComputeBlockNumberAndGetOffset(this.FileTableBlockNumber + this.FileTableBlockCount, this.HeaderSize, this.BlockSeparation); // check offsets if ((fileTableMinOffset >= MicrosoftSTFS.FIRST_BLOCK_OFFSET) && (fileTableMinOffset < fileTableMaxOffset) && (fileTableMaxOffset < fileSize)) { for (long i = fileTableMinOffset; i < fileTableMaxOffset; i += 0x40) { tableEntry.FileName = ParseFile.ReadAsciiString(isoStream, i); if (!String.IsNullOrEmpty(tableEntry.FileName)) { tableEntry.Flags = ParseFile.ReadByte(isoStream, i + 0x28); tableEntry.BlocksForFileLE1 = ParseFile.ReadInt24LE(isoStream, i + 0x29); tableEntry.BlocksForFileLE2 = ParseFile.ReadInt24LE(isoStream, i + 0x2C); tableEntry.StartingBlockForFileLE = ParseFile.ReadInt24LE(isoStream, i + 0x2F); tableEntry.PathIndicator = ParseFile.ReadInt16BE(isoStream, i + 0x32); tableEntry.FileSize = ParseFile.ReadUintBE(isoStream, i + 0x34); tableEntry.UpdateDateTime = ParseFile.ReadInt32BE(isoStream, i + 0x38); tableEntry.AccessDateTime = ParseFile.ReadInt32BE(isoStream, i + 0x3C); FileTableEntryArray.Add(tableEntry); } } } else { throw new IndexOutOfRangeException("File Table block IDs do not make sense."); } }