public Iso9660PathTableRecord(byte[] pathBytes, bool isLittleEndian) { this.LengthOfDirectoryIdentifier = ParseFile.ParseSimpleOffset(pathBytes, 0, 1)[0]; this.ExtendedAttributeRecordLength = ParseFile.ParseSimpleOffset(pathBytes, 1, 1)[0]; if (isLittleEndian) { this.LocationOfExtent = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(pathBytes, 2, 4), 0); } else { this.LocationOfExtent = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(pathBytes, 2, 4)); } if (isLittleEndian) { this.DirectoryNumberOfParentDirectory = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(pathBytes, 6, 2), 0); } else { this.DirectoryNumberOfParentDirectory = ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(pathBytes, 6, 2)); } this.DirectoryIdentifierBytes = ParseFile.ParseSimpleOffset(pathBytes, 8, this.LengthOfDirectoryIdentifier); this.DirectoryIdentifier = ByteConversion.GetEncodedText(this.DirectoryIdentifierBytes, ByteConversion.GetPredictedCodePageForTags(this.DirectoryIdentifierBytes)); if (this.LengthOfDirectoryIdentifier % 2 == 1) { this.PaddingByte = ParseFile.ParseSimpleOffset(pathBytes, this.LengthOfDirectoryIdentifier + 8, 1)[0]; } }
public virtual void LoadDirectories(FileStream isoStream) { // change name of top level folder this.DirectoryRecordForRootDirectory.FileIdentifierString = String.Empty; // get first path record byte[] rootDirPathBytes = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, this.LocationOfOccurrenceOfTypeMPathTable, this.IsRawDump, this.LogicalBlockSize); rootDirPathBytes = CdRom.GetDataChunkFromSector(rootDirPathBytes, this.IsRawDump); // grab the directory record uint rootDirectoryOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootDirPathBytes, 2, 4)); byte[] rootDirDirectorySector = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, rootDirectoryOffset, this.IsRawDump, this.LogicalBlockSize); rootDirDirectorySector = CdRom.GetDataChunkFromSector(rootDirDirectorySector, this.IsRawDump); byte rootDirectoryRecordSize = rootDirDirectorySector[0]; byte[] rootDirectoryRecord = ParseFile.ParseSimpleOffset(rootDirDirectorySector, 0, rootDirectoryRecordSize); this.DirectoryRecordForRootDirectory = new GreenBookCdiDirectoryRecord(rootDirectoryRecord); // populate this volume's directory structure GreenBookCdiDirectoryStructure rootDirectory = new GreenBookCdiDirectoryStructure(isoStream, isoStream.Name, this.VolumeBaseOffset, this.DirectoryRecordForRootDirectory, this.LogicalBlockSize, this.IsRawDump, this.SectorSize, null); this.DirectoryStructureArray.Add(rootDirectory); }
public NintendoGameCubeDirectoryRecord(byte[] directoryBytes, int OffsetBitShiftValue) { this.NameOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0, 4)); this.FileOffset = (long)ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 4, 4)); this.FileOffset <<= OffsetBitShiftValue; this.FileSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 8, 4)); this.IsDirectory = ((this.NameOffset & 0xFF000000) != 0); this.NameOffset &= 0xFFFFFF; }
public NintendoWiiOpticalDiscDirectoryRecord(byte[] directoryBytes) { this.NameOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0, 4)); this.FileOffset = (long)ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 4, 4)); this.FileOffset <<= 2; this.FileSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 8, 4)); this.IsDirectory = ((this.NameOffset & 0xFF000000) != 0); this.NameOffset &= 0xFFFFFF; }
protected override long GetStartOffset(Stream readStream, long currentOffset) { long startOffset = 0; uint seekOffsets = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(readStream, 0x86, 4)); uint seekCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(readStream, 0x8A, 4)); if (seekOffsets > 0) { startOffset = seekOffsets + (seekCount * 0x0A); } return(startOffset); }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] volumeIdentifierBytes; byte[] imageDateBytes; string imageDateString; this.VolumeBaseOffset = offset; this.IsRawDump = isRawDump; this.VolumeType = VolumeDataType.Data; this.DirectoryStructureArray = new ArrayList(); // get identifier volumeIdentifierBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 0x20, 64); volumeIdentifierBytes = FileUtil.ReplaceNullByteWithSpace(volumeIdentifierBytes); this.VolumeIdentifier = ByteConversion.GetEncodedText(volumeIdentifierBytes, ByteConversion.GetPredictedCodePageForTags(volumeIdentifierBytes)).Trim();; // get date imageDateBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 0x2440, 0xA); imageDateString = ByteConversion.GetAsciiText(imageDateBytes); try { this.ImageCreationTime = new DateTime(int.Parse(imageDateString.Substring(0, 4)), int.Parse(imageDateString.Substring(5, 2)), int.Parse(imageDateString.Substring(8, 2))); } catch (Exception) { this.ImageCreationTime = new DateTime(); } // set bit shift for GC or WII if (this.IsGameCubeDisc(isoStream)) { this.OffsetBitShiftValue = 0; this.FormatDescription = NintendoGameCube.FORMAT_DESCRIPTION_STRING; } else { this.OffsetBitShiftValue = 2; this.FormatDescription = NintendoWiiOpticalDisc.FORMAT_DESCRIPTION_STRING_DECRYPTED; } // get offset of file table this.RootDirectoryOffset = (long)ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 0x424, 4)); this.RootDirectoryOffset <<= this.OffsetBitShiftValue; this.LoadDirectories(isoStream); }
private void ParseComponents(FileStream thpStream) { this.ComponentCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, this.ComponentDataOffset, 4)); byte componentType; long componentDetailsOffset = this.ComponentDataOffset + 4 + 0x10; // load components for (int i = 0; i < this.ComponentCount; i++) { componentType = ParseFile.ParseSimpleOffset(thpStream, this.ComponentDataOffset + 4 + (i * 1), 1)[0]; if (componentType == VIDEO_COMPONENT) { this.Width = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset, 4)); this.Height = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset + 4, 4)); if (this.Version == ThpVersion.Version11) { this.Unknown = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset + 8, 4)); componentDetailsOffset += 0xC; } else { this.Unknown = 0; componentDetailsOffset += 0x8; } } else if (componentType == AUDIO_COMPONENT) { this.NumberOfChannels = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset, 4)); this.Frequency = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset + 4, 4)); this.NumberOfSamples = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset + 8, 4)); if (this.Version == ThpVersion.Version11) { this.NumberOfAudioBlocksPerFrame = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, componentDetailsOffset + 0xC, 4)); componentDetailsOffset += 0x10; } else { this.NumberOfAudioBlocksPerFrame = 1; // 1 audio chunk per frame componentDetailsOffset += 0xC; } } } }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] volumeIdentifierBytes; byte[] imageDateBytes; string imageDateString; this.IsRawDump = isRawDump; this.DirectoryStructureArray = new ArrayList(); this.FormatDescription = NintendoWiiOpticalDisc.FORMAT_DESCRIPTION_STRING; this.VolumeType = VolumeDataType.Data; // get identifier volumeIdentifierBytes = DiscReader.GetBytes(isoStream, this.VolumeBaseOffset, this.DataOffset, 0x20, 64, this.PartitionKey); volumeIdentifierBytes = FileUtil.ReplaceNullByteWithSpace(volumeIdentifierBytes); this.VolumeIdentifier = ByteConversion.GetEncodedText(volumeIdentifierBytes, ByteConversion.GetPredictedCodePageForTags(volumeIdentifierBytes)).Trim();; // get date imageDateBytes = DiscReader.GetBytes(isoStream, this.VolumeBaseOffset, this.DataOffset, 0x2440, 0xA, this.PartitionKey); imageDateString = ByteConversion.GetAsciiText(imageDateBytes); try { this.ImageCreationTime = new DateTime(int.Parse(imageDateString.Substring(0, 4)), int.Parse(imageDateString.Substring(5, 2)), int.Parse(imageDateString.Substring(8, 2))); } catch (Exception) { this.ImageCreationTime = new DateTime(); } // get offset of file table this.RootDirectoryOffset = (long)ByteConversion.GetUInt32BigEndian(DiscReader.GetBytes(isoStream, this.VolumeBaseOffset, this.DataOffset, 0x424, 4, this.PartitionKey)); this.RootDirectoryOffset <<= 2; this.LoadDirectories(isoStream); }
private void ReadHeader(FileStream thpStream, long currentOffset) { byte[] magicBytes = ParseFile.ParseSimpleOffset(thpStream, currentOffset, MAGIC_BYTES.Length); byte[] tempChunk; if (ParseFile.CompareSegment(magicBytes, 0, MAGIC_BYTES)) { tempChunk = ParseFile.ParseSimpleOffset(thpStream, currentOffset + 4, 4); if (ParseFile.CompareSegment(tempChunk, 0, VERSON_10)) { this.Version = ThpVersion.Version10; } else { this.Version = ThpVersion.Version11; } this.MaxBufferSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 8, 4)); this.MaxAudioSamples = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0xC, 4)); this.ContainsAudio = (this.MaxAudioSamples > 0); // public float Fps { set; get; } this.NumberOfFrames = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x14, 4)); this.FirstFrameSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x18, 4)); this.DataSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x1C, 4)); this.ComponentDataOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x20, 4)); this.ComponentTypes = ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x24, 16); this.FirstFrameOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x28, 4)); this.LastFrameOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(thpStream, currentOffset + 0x2C, 4)); } else { throw new FormatException("Magic bytes 'THP\\0' not found."); } }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] rootSector; this.VolumeBaseOffset = offset; this.FormatDescription = Panasonic3do.FORMAT_DESCRIPTION_STRING; this.VolumeType = VolumeDataType.Data; this.IsRawDump = isRawDump; this.DirectoryStructureArray = new ArrayList(); rootSector = CdRom.GetSectorByLba(isoStream, this.VolumeBaseOffset, 0, this.IsRawDump, (int)Panasonic3do.SECTOR_SIZE); rootSector = CdRom.GetDataChunkFromSector(rootSector, this.IsRawDump); this.RootDirectoryCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootSector, 0x60, 4)) + 1; this.RootDirectoryLbas = new uint[this.RootDirectoryCount]; for (uint i = 0; i < this.RootDirectoryCount; i++) { this.RootDirectoryLbas[i] = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(rootSector, (int)(0x64 + (i * 4)), 4)); } this.LoadDirectories(isoStream); }
} // 4 bytes each, for total of SubDirectoryCount LBAs public Panasonic3doDirectoryRecord(byte[] directoryBytes) { this.DirectoryItemTypeBytes = ParseFile.ParseSimpleOffset(directoryBytes, 0, 4); this.Unknown1 = ParseFile.ParseSimpleOffset(directoryBytes, 4, 4); this.DirectoryItemTypeTextFlagBytes = ParseFile.ParseSimpleOffset(directoryBytes, 8, 4); this.DirectoryItemTypeTextFlag = ByteConversion.GetEncodedText(this.DirectoryItemTypeTextFlagBytes, ByteConversion.GetPredictedCodePageForTags(this.DirectoryItemTypeTextFlagBytes)); this.DirectoryItemLogicalBlockSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0xC, 4)); this.DirectoryItemSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0x10, 4)); this.DirectoryItemSizeInSectors = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0x14, 4)); this.Unknown2 = ParseFile.ParseSimpleOffset(directoryBytes, 0x18, 4); this.Unknown3 = ParseFile.ParseSimpleOffset(directoryBytes, 0x1C, 4); this.DirectoryItemNameBytes = ParseFile.ParseSimpleOffset(directoryBytes, 0x20, 0x20); this.DirectoryItemName = ByteConversion.GetEncodedText(FileUtil.ReplaceNullByteWithSpace(this.DirectoryItemNameBytes), ByteConversion.GetPredictedCodePageForTags(this.DirectoryItemNameBytes)).Trim(); this.SubDirectoryCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0x40, 4)) + 1; this.SubDirectoryLbas = new uint[this.SubDirectoryCount]; for (uint i = 0; i < this.SubDirectoryCount; i++) { this.SubDirectoryLbas[i] = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, (int)(0x44 + (i * 4)), 4)); } }
private void parseDirectoryRecord( FileStream isoStream, DateTime creationDateTime, long baseOffset, long directoryLba, uint logicalBlockSize, string parentDirectory, bool isRaw, int nonRawSectorSize) { uint recordSize; byte[] directorySector; byte[] directoryRecordBytes; uint directoryRecordLength; uint bytesRead; uint currentOffset; long currentLba = directoryLba; Panasonic3doDirectoryRecord tempDirectoryRecord; Panasonic3doDirectoryStructure tempDirectory; Panasonic3doFileStructure tempFile; // get the first sector directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); directoryRecordLength = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, 0xC, 4)); bytesRead = 0x14; currentOffset = 0x14; while (bytesRead < directoryRecordLength) { recordSize = 0x48 + (4 * ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, (int)(currentOffset + 0x40), 4))); directoryRecordBytes = ParseFile.ParseSimpleOffset(directorySector, (int)currentOffset, (int)recordSize); tempDirectoryRecord = new Panasonic3doDirectoryRecord(directoryRecordBytes); if (tempDirectoryRecord.DirectoryItemTypeBytes[3] == 0x07) { //for (uint i = 0; i < tempDirectoryRecord.SubDirectoryCount; i++) //{ tempDirectory = new Panasonic3doDirectoryStructure(isoStream, isoStream.Name, creationDateTime, baseOffset, tempDirectoryRecord.SubDirectoryLbas[0], logicalBlockSize, tempDirectoryRecord.DirectoryItemName, parentDirectory, isRaw, nonRawSectorSize); this.SubDirectoryArray.Add(tempDirectory); //} } else { tempFile = new Panasonic3doFileStructure(parentDirectory, this.SourceFilePath, tempDirectoryRecord.DirectoryItemName, baseOffset, tempDirectoryRecord.SubDirectoryLbas[0], tempDirectoryRecord.DirectoryItemSize, isRaw, nonRawSectorSize, creationDateTime); this.FileArray.Add(tempFile); } if (tempDirectoryRecord.DirectoryItemTypeBytes[0] == 0xC0) { break; } else if (tempDirectoryRecord.DirectoryItemTypeBytes[0] == 0x40) { directorySector = CdRom.GetSectorByLba(isoStream, baseOffset, ++currentLba, isRaw, nonRawSectorSize); directorySector = CdRom.GetDataChunkFromSector(directorySector, isRaw); directoryRecordLength = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directorySector, 0xC, 4)); bytesRead = 0x14; currentOffset = 0x14; } else { bytesRead += recordSize; currentOffset += recordSize; } } }
public GreenBookCdiDirectoryRecord(byte[] directoryBytes) { this.LengthOfDirectoryRecord = directoryBytes[0]; if (this.LengthOfDirectoryRecord > 0) { this.ExtendedAttributeRecordLength = directoryBytes[1]; this.LocationOfExtent = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 6, 4)); this.DataLength = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, 0x0E, 4)); this.RecordingDateAndTime = new DateTime(directoryBytes[0x12] + 1900, directoryBytes[0x13], directoryBytes[0x14], directoryBytes[0x15], directoryBytes[0x16], directoryBytes[0x17]); this.FileFlags = directoryBytes[this.LengthOfDirectoryRecord - 6]; ushort cdiItemDetails = ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(directoryBytes, this.LengthOfDirectoryRecord - 6, 2)); if ((cdiItemDetails & CDI_ATTR_DIRECTORY) == CDI_ATTR_DIRECTORY) { this.FlagDirectory = true; } //else if ((cdiItemDetails & CDI_ATTR_MODE2FORM1) == CDI_ATTR_MODE2FORM1) //{ // this.ItemMode = CdSectorType.Mode2Form1; //} //else if ((cdiItemDetails & CDI_ATTR_MODE2FORM2) == CDI_ATTR_MODE2FORM2) //{ // this.ItemMode = CdSectorType.Mode2Form2; // this.DataLength = (uint)(this.DataLength / (uint)CdRom.NON_RAW_SECTOR_SIZE) * (uint)CdRom.RAW_SECTOR_SIZE; //} //else if ((cdiItemDetails & CDI_ATTR_CDDA) == CDI_ATTR_CDDA) //{ // this.ItemMode = CdSectorType.Audio; // this.DataLength = (uint)(this.DataLength / (uint)CdRom.NON_RAW_SECTOR_SIZE) * (uint)CdRom.RAW_SECTOR_SIZE; //} //else //{ // this.ItemMode = CdSectorType.Unknown; //} /* * this.FlagExistance = (this.FileFlags & 0x1) == 0x1 ? true : false; * this.FlagDirectory = (this.FileFlags & 0x2) == 0x2 ? true : false; * this.FlagAssociatedFile = (this.FileFlags & 0x4) == 0x4 ? true : false; * this.FlagRecord = (this.FileFlags & 0x08) == 0x08 ? true : false; * this.FlagProtection = (this.FileFlags & 0x10) == 0x10 ? true : false; * this.FlagMultiExtent = (this.FileFlags & 0x80) == 0x80 ? false : true; */ this.FileUnitSize = directoryBytes[0x1A]; this.InterleaveGapSize = directoryBytes[0x1B]; this.VolumeSequenceNumber = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(directoryBytes, 0x1E, 2), 0); this.LengthOfFileIdentifier = directoryBytes[0x20]; this.FileIdentifier = ParseFile.ParseSimpleOffset(directoryBytes, 0x21, this.LengthOfFileIdentifier); // parse identifier if (this.LengthOfFileIdentifier > 1) { this.FileIdentifierString = ByteConversion.GetEncodedText(this.FileIdentifier, ByteConversion.GetPredictedCodePageForTags(this.FileIdentifier)); } else if (this.FileIdentifier[0] == 0) { this.FileIdentifierString = "."; } else if (this.FileIdentifier[0] == 1) { this.FileIdentifierString = ".."; } /* * * public byte[] PaddingField { set; get; } * public byte[] SystemUse { set; get; } */ } }
public void InitializePartitions(FileStream isoStream) { //byte[] encryptedPartitionCluster; //byte[] decryptedClusterDataSection; //byte[] clusterIV; //byte[] encryptedClusterDataSection; this.CommonKey = null; this.KoreanCommonKey = null; this.Partitions = new Partition[4]; for (int i = 0; i < 4; i++) { this.Partitions[i] = new Partition(); this.Partitions[i].PartitionCount = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.DiscBaseOffset + 0x40000 + (i * 8), 4)); this.Partitions[i].PartitionEntries = new PartitionEntry[this.Partitions[i].PartitionCount]; this.Partitions[i].PartitionTableOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.DiscBaseOffset + 0x40004 + (i * 8), 4)); this.Partitions[i].PartitionTableOffset <<= 2; if (this.Partitions[i].PartitionTableOffset > 0) { // set absolute offset of partition this.Partitions[i].PartitionTableOffset += this.DiscBaseOffset; for (int j = 0; j < this.Partitions[i].PartitionCount; j++) { this.Partitions[i].PartitionEntries[j] = new PartitionEntry(); // get offset to this partition this.Partitions[i].PartitionEntries[j].PartitionOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionTableOffset + (j * 8), 4)); this.Partitions[i].PartitionEntries[j].PartitionOffset <<= 2; this.Partitions[i].PartitionEntries[j].PartitionOffset += this.DiscBaseOffset; // get partition type this.Partitions[i].PartitionEntries[j].PartitionType = ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionTableOffset + 4 + (i * 8), 4); // get relative offset partition's data section this.Partitions[i].PartitionEntries[j].RelativeDataOffset = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionEntries[j].PartitionOffset + 0x02B8, 4)); this.Partitions[i].PartitionEntries[j].RelativeDataOffset <<= 2; this.Partitions[i].PartitionEntries[j].RelativeDataOffset += this.DiscBaseOffset; // get the size of partition's data section this.Partitions[i].PartitionEntries[j].DataSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionEntries[j].PartitionOffset + 0x02BC, 4)); this.Partitions[i].PartitionEntries[j].DataSize <<= 2; //--------------------------- // parse this entry's ticket //--------------------------- this.Partitions[i].PartitionEntries[j].TitleId = new byte[0x10]; Array.Copy( ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionEntries[j].PartitionOffset + 0x01DC, 8), 0, this.Partitions[i].PartitionEntries[j].TitleId, 0, 8); this.Partitions[i].PartitionEntries[j].EncryptedTitleKey = ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionEntries[j].PartitionOffset + 0x01BF, 0x10); this.Partitions[i].PartitionEntries[j].CommonKeyIndex = ParseFile.ParseSimpleOffset(isoStream, this.Partitions[i].PartitionEntries[j].PartitionOffset + 0x01F1, 1)[0]; //--------------------- // decrypt the TitleId //--------------------- switch (this.Partitions[i].PartitionEntries[j].CommonKeyIndex) { case 0: if (this.CommonKey == null) { this.CommonKey = NintendoWiiOpticalDisc.GetKeyFromFile(NintendoWiiOpticalDisc.COMMON_KEY_PATH); } this.Partitions[i].PartitionEntries[j].DecryptedTitleKey = AESEngine.Decrypt(this.Partitions[i].PartitionEntries[j].EncryptedTitleKey, this.CommonKey, this.Partitions[i].PartitionEntries[j].TitleId, CipherMode.CBC, PaddingMode.Zeros); break; case 1: if (this.KoreanCommonKey == null) { this.KoreanCommonKey = NintendoWiiOpticalDisc.GetKeyFromFile(NintendoWiiOpticalDisc.KOREAN_KEY_PATH); } this.Partitions[i].PartitionEntries[j].DecryptedTitleKey = AESEngine.Decrypt(this.Partitions[i].PartitionEntries[j].EncryptedTitleKey, this.KoreanCommonKey, this.Partitions[i].PartitionEntries[j].TitleId, CipherMode.CBC, PaddingMode.Zeros); break; } // switch (this.Partitions[i].PartitionEntries[j].CommonKeyIndex) //string outFile = Path.Combine(Path.GetDirectoryName(isoStream.Name), String.Format("{0}-{1}.bin", i.ToString(), j.ToString())); //long currentOffset = 0; //using (FileStream outStream = File.OpenWrite(outFile)) //{ // while (currentOffset < this.Partitions[i].PartitionEntries[j].DataSize) // { // encryptedPartitionCluster = ParseFile.ParseSimpleOffset(isoStream, // this.Partitions[i].PartitionEntries[j].PartitionOffset + this.Partitions[i].PartitionEntries[j].RelativeDataOffset + currentOffset, // 0x8000); // clusterIV = ParseFile.ParseSimpleOffset(encryptedPartitionCluster, 0x03D0, 0x10); // encryptedClusterDataSection = ParseFile.ParseSimpleOffset(encryptedPartitionCluster, 0x400, 0x7C00); // decryptedClusterDataSection = AESEngine.Decrypt(encryptedClusterDataSection, // this.Partitions[i].PartitionEntries[j].DecryptedTitleKey, clusterIV, // CipherMode.CBC, PaddingMode.Zeros); // outStream.Write(decryptedClusterDataSection, 0, decryptedClusterDataSection.Length); // currentOffset += 0x8000; // } //} } // for (int j = 0; j < this.Partitions[i].PartitionCount; j++) } // if (this.Partitions[i].PartitionTableOffset > 0) } }
public virtual void Initialize(FileStream isoStream, long offset, bool isRawDump) { byte[] sectorBytes; byte[] sectorDataBytes; this.FormatDescription = NullDcGdi.FORMAT_DESCRIPTION_STRING; this.VolumeType = VolumeDataType.Data; this.IsRawDump = isRawDump; this.DirectoryStructureArray = new ArrayList(); this.VolumeBaseOffset = this.IsRawDump ? (offset - Iso9660.EMPTY_HEADER_SIZE_RAW) : (offset - Iso9660.EMPTY_HEADER_SIZE); this.SectorSize = this.IsRawDump ? (int)CdRom.RAW_SECTOR_SIZE : (int)CdRom.NON_RAW_SECTOR_SIZE; // parse inital level sector sectorBytes = ParseFile.ParseSimpleOffset(isoStream, offset, this.SectorSize); sectorDataBytes = CdRom.GetDataChunkFromSector(sectorBytes, this.IsRawDump); // check for CDXA marker this.ContainsCdxaData = ParseFile.CompareSegmentUsingSourceOffset(sectorDataBytes, (int)Iso9660.CDXA_IDENTIFIER_OFFSET, Iso9660.CDXA_IDENTIFIER.Length, Iso9660.CDXA_IDENTIFIER); this.VolumeDescriptorType = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x00, 1)[0]; this.StandardIdentifier = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x01, 5); this.VolumeDescriptorVersion = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x06, 1)[0]; this.UnusedField1 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x07, 1)[0]; this.SystemIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x08, 0x20)).Trim(); this.VolumeIdentifier = ByteConversion.GetAsciiText(FileUtil.ReplaceNullByteWithSpace(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x28, 0x20))).Trim(); this.UnusedField2 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x48, 0x08); this.VolumeSpaceSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x50, 0x04), 0); this.UnusedField3 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x58, 0x20); this.VolumeSetSize = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x78, 0x02), 0); this.VolumeSequenceNumber = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x7C, 0x02), 0); this.LogicalBlockSize = BitConverter.ToUInt16(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x80, 0x02), 0); this.PathTableSize = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x84, 0x04), 0); this.LocationOfOccurrenceOfTypeLPathTable = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x8C, 0x04), 0); this.LocationOfOptionalOccurrenceOfTypeLPathTable = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x90, 0x04), 0); this.LocationOfOccurrenceOfTypeMPathTable = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x94, 0x04)); this.LocationOfOptionalOccurrenceOfTypeMPathTable = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x98, 0x04)); this.DirectoryRecordForRootDirectoryBytes = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x9C, 0x22); this.DirectoryRecordForRootDirectory = new NullDcGdiDirectoryRecord(this.DirectoryRecordForRootDirectoryBytes, this.ContainsCdxaData); this.VolumeSetIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0xBE, 0x80)).Trim(); this.PublisherIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x13E, 0x80)).Trim(); this.DataPreparerIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x1BE, 0x80)).Trim(); this.ApplicationIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x23E, 0x80)).Trim(); this.CopyrightFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x2BE, 0x25)).Trim(); this.AbstractFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x2E3, 0x25)).Trim(); this.BibliographicFileIdentifier = ByteConversion.GetAsciiText(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x308, 0x25)).Trim(); this.VolumeCreationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x32D, 0x11)); this.VolumeModificationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x33E, 0x11)); this.VolumeExpirationDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x34F, 0x11)); this.VolumeEffectiveDateAndTime = Iso9660.GetIsoDateTime(ParseFile.ParseSimpleOffset(sectorDataBytes, 0x360, 0x11)); this.FileStructureVersion = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x371, 1)[0]; this.Reserved1 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x372, 1)[0]; this.ApplicationUse = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x373, 0x200); this.Reserved2 = ParseFile.ParseSimpleOffset(sectorDataBytes, 0x573, 0x28D); this.LoadDirectories(isoStream); }
public void DemultiplexStreams(MpegStream.DemuxOptionsStruct demuxOptions) { long currentOffset = 0; uint frameCount = 1; uint nextFrameSize; byte[] currentFrame; byte[] videoChunkSizeBytes = null; uint videoChunkSize; byte[] audioChunkSizeBytes = null; uint audioChunkSize; long dataStart; byte[] videoChunk; byte[] audioChunk; // bool isAudioHeaderWritten = false; Dictionary <string, bool> isAudioHeaderWritten = new Dictionary <string, bool>(); bool isVideoHeaderWritten = false; byte[] thpHeader; byte[] firstFrameSize; long headerLocation; uint previousFrameSizeVideo = 0; uint previousFrameSizeAudio = 0; uint nextFrameSizeVideo; uint nextFrameSizeAudio; byte[] previousFrameSizeBytes; byte[] nextFrameSizeBytes; uint totalDataSize = 0; byte[] totalDataSizeBytes; byte[] fourEmptyBytes = new byte[] { 0x00, 0x00, 0x00, 0x00 }; long videoFrameOffset = 0; long audioFrameOffset = 0; byte[] lastOffsetBytes; string audioStreamHashKey; byte[] bigEndianOne = new byte[] { 0x00, 0x00, 0x00, 0x01 }; Dictionary <string, FileStream> streamWriters = new Dictionary <string, FileStream>(); try { using (FileStream fs = File.OpenRead(this.FilePath)) { headerLocation = ParseFile.GetNextOffset(fs, currentOffset, MAGIC_BYTES); currentOffset = headerLocation; if (currentOffset > -1) { // read header this.ReadHeader(fs, currentOffset); nextFrameSize = this.FirstFrameSize; // get component info this.ParseComponents(fs); // process frames currentOffset = this.FirstFrameOffset; while (currentOffset <= this.LastFrameOffset) { // read frame currentFrame = ParseFile.ParseSimpleOffset(fs, (long)currentOffset, (int)nextFrameSize); // get size of next frame nextFrameSize = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(currentFrame, 0, 4)); // get size of next audio/video frame (for writing output frame headers) if (frameCount < this.NumberOfFrames) { nextFrameSizeVideo = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, currentOffset + currentFrame.Length + 8, 4)); nextFrameSizeAudio = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, currentOffset + currentFrame.Length + 0xC, 4)); } else { nextFrameSizeVideo = 0; nextFrameSizeAudio = 0; } videoChunkSizeBytes = ParseFile.ParseSimpleOffset(currentFrame, 8, 4); videoChunkSize = ByteConversion.GetUInt32BigEndian(videoChunkSizeBytes); if (this.ContainsAudio) { audioChunkSizeBytes = ParseFile.ParseSimpleOffset(currentFrame, 0xC, 4); audioChunkSize = ByteConversion.GetUInt32BigEndian(audioChunkSizeBytes); dataStart = 0x10; } else { audioChunkSize = 0; dataStart = 0xC; } #region WRITE VIDEO /////////////// // write video /////////////// if (demuxOptions.ExtractVideo) { if (streamWriters.ContainsKey("video")) { videoFrameOffset = streamWriters["video"].Length; } // attach THP header if (!isVideoHeaderWritten) { // get original header thpHeader = ParseFile.ParseSimpleOffset(fs, headerLocation, (int)(fs.Length - this.DataSize)); // clean out audio info thpHeader = this.RemoveAudioInfoFromThpHeader(thpHeader); // update first frame size in header firstFrameSize = ByteConversion.GetBytesBigEndian((uint)(videoChunkSize + 0xC)); Array.Copy(firstFrameSize, 0, thpHeader, 0x18, 4); // write updated header this.writeChunkToStream(thpHeader, "video", streamWriters, this.FileExtensionVideo); isVideoHeaderWritten = true; } // add frame header // write next frame size nextFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(nextFrameSizeVideo + 0xC)); this.writeChunkToStream(nextFrameSizeBytes, "video", streamWriters, this.FileExtensionVideo); // write previous frame size previousFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(previousFrameSizeVideo + 0xC)); this.writeChunkToStream(nextFrameSizeBytes, "video", streamWriters, this.FileExtensionVideo); // write video size this.writeChunkToStream(videoChunkSizeBytes, "video", streamWriters, this.FileExtensionVideo); // write data videoChunk = ParseFile.ParseSimpleOffset(currentFrame, (int)dataStart, (int)videoChunkSize); this.writeChunkToStream(videoChunk, "video", streamWriters, this.FileExtensionVideo); // save previous bytes for next frame previousFrameSizeVideo = videoChunkSize; } #endregion #region WRITE AUDIO /////////////// // write audio /////////////// if (demuxOptions.ExtractAudio && this.ContainsAudio) { //if (this.NumberOfAudioBlocksPerFrame > 1) //{ // int x = 1; //} // add blocks for (int i = 0; i < this.NumberOfAudioBlocksPerFrame; i++) { audioStreamHashKey = String.Format("track_{0}", i.ToString("D2")); // write file header if (streamWriters.ContainsKey(audioStreamHashKey)) { audioFrameOffset = streamWriters[audioStreamHashKey].Position; } // attach THP header if (!isAudioHeaderWritten.ContainsKey(audioStreamHashKey) || isAudioHeaderWritten[audioStreamHashKey] == false) { // get original header thpHeader = ParseFile.ParseSimpleOffset(fs, headerLocation, (int)(fs.Length - this.DataSize)); // clean out video info thpHeader = this.RemoveVideoInfoFromThpHeader(thpHeader); // update first frame size in header firstFrameSize = ByteConversion.GetBytesBigEndian((uint)(audioChunkSize + 0x10)); Array.Copy(firstFrameSize, 0, thpHeader, 0x18, 4); // set NumberOfAudioBlocksPerFrame to 1 Array.Copy(bigEndianOne, 0, thpHeader, 0x50, 4); // write updated header this.writeChunkToStream(thpHeader, audioStreamHashKey, streamWriters, this.FileExtensionAudio); isAudioHeaderWritten.Add(audioStreamHashKey, true); } ////////////////////// // write frame header ////////////////////// // write next frame size nextFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(nextFrameSizeAudio + 0x10)); this.writeChunkToStream(nextFrameSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio); // write previous frame size previousFrameSizeBytes = ByteConversion.GetBytesBigEndian((uint)(previousFrameSizeAudio + 0x10)); this.writeChunkToStream(nextFrameSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio); // write video size (zero) this.writeChunkToStream(fourEmptyBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio); // write audio size for this frame this.writeChunkToStream(audioChunkSizeBytes, audioStreamHashKey, streamWriters, this.FileExtensionAudio); // write chunk audioChunk = ParseFile.ParseSimpleOffset(currentFrame, (int)(dataStart + videoChunkSize + (i * audioChunkSize)), (int)audioChunkSize); this.writeChunkToStream(audioChunk, audioStreamHashKey, streamWriters, this.FileExtensionAudio); // set previous frame size for next frame previousFrameSizeAudio = audioChunkSize; } } #endregion // increment offset and frame counter currentOffset += currentFrame.Length; frameCount++; } // fix headers as needed // data size foreach (string key in streamWriters.Keys) { totalDataSize = (uint)(streamWriters[key].Length - this.FirstFrameOffset); totalDataSizeBytes = ByteConversion.GetBytesBigEndian(totalDataSize); streamWriters[key].Position = 0x1C; streamWriters[key].Write(totalDataSizeBytes, 0, 4); } // frame offsets for (int i = 0; i < this.NumberOfAudioBlocksPerFrame; i++) { audioStreamHashKey = String.Format("audio_{0}", i.ToString("DD")); if (streamWriters.ContainsKey(audioStreamHashKey)) { lastOffsetBytes = ByteConversion.GetBytesBigEndian((uint)audioFrameOffset); streamWriters[audioStreamHashKey].Position = 0x2C; streamWriters[audioStreamHashKey].Write(lastOffsetBytes, 0, 4); } } if (streamWriters.ContainsKey("video")) { lastOffsetBytes = ByteConversion.GetBytesBigEndian((uint)videoFrameOffset); streamWriters["video"].Position = 0x2C; streamWriters["video"].Write(lastOffsetBytes, 0, 4); } } else { throw new FormatException("Cannot find THP header."); } } // using (FileStream fs = File.OpenRead(this.FilePath)) } catch (Exception ex) { throw new Exception(ex.Message, ex); } finally { foreach (string key in streamWriters.Keys) { // close writers if (streamWriters[key] != null && streamWriters[key].CanWrite) { streamWriters[key].Close(); streamWriters[key].Dispose(); } } } }
protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractAdxStruct, DoWorkEventArgs e) { ExtractAdxStruct extractAdxStruct = (ExtractAdxStruct)pExtractAdxStruct; long offset = 0; uint copyrightOffset; byte[] copyrightBytes; uint totalHeaderSize; int encodingType; uint blockSize; uint bitDepth; uint channelCount; uint sampleRate; uint totalSamples; uint fileSize; int fileCount = 0; string outputPath = Path.Combine(Path.GetDirectoryName(pPath), "_cri_adx_ext"); string outputFileName; string outputFilePath; FileInfo fi = new FileInfo(pPath); using (FileStream fs = File.Open(pPath, FileMode.Open, FileAccess.Read)) { outputPath = Path.Combine(Path.GetDirectoryName(pPath), String.Format("{0}_ADXs", Path.GetFileNameWithoutExtension(pPath))); while ((offset = ParseFile.GetNextOffset(fs, offset, ADX_SIG_BYTES)) > -1) { if (!this.CancellationPending) { // get offset to copyright string copyrightOffset = (uint)ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 2, 2)); copyrightBytes = ParseFile.ParseSimpleOffset(fs, offset + copyrightOffset - 2, CRI_COPYRIGHT_BYTES.Length); // check that copyright bytes are present if (ParseFile.CompareSegment(copyrightBytes, 0, CRI_COPYRIGHT_BYTES)) { // verify this is standard ADX encodingType = ParseFile.ParseSimpleOffset(fs, offset + 4, 1)[0]; if (encodingType != 3) { fileSize = 1; } else { // get other info blockSize = (uint)ParseFile.ParseSimpleOffset(fs, offset + 5, 1)[0]; bitDepth = (uint)ParseFile.ParseSimpleOffset(fs, offset + 6, 1)[0]; channelCount = (uint)ParseFile.ParseSimpleOffset(fs, offset + 7, 1)[0]; sampleRate = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 8, 4)); totalSamples = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4)); totalHeaderSize = copyrightOffset + 4; // calculate file size fileSize = (((totalSamples + 0x1F) / (bitDepth * 8)) * channelCount * blockSize) + totalHeaderSize + blockSize; // extract file outputFileName = String.Format("{0}_{1}.adx", Path.GetFileNameWithoutExtension(pPath), fileCount.ToString("X8")); outputFilePath = Path.Combine(outputPath, outputFileName); this.progressStruct.Clear(); this.progressStruct.GenericMessage = String.Format("{0} - offset: 0x{1} size: 0x{2}{3}", outputFileName, offset.ToString("X8"), fileSize.ToString("X8"), Environment.NewLine); ReportProgress(Constants.ProgressMessageOnly, this.progressStruct); ParseFile.ExtractChunkToFile(fs, offset, (int)fileSize, outputFilePath, true, true); fileCount++; } offset += fileSize; } else { offset += 1; } } else { e.Cancel = true; return; } } } }
public static string ExtractAdxStreams(string path, string filePrefix, string outputFolder, out string messages) { string extractedToFolder = String.Empty; StringBuilder messageBuffer = new StringBuilder(); messages = String.Empty; long offset = 0; uint copyrightOffset; byte[] copyrightBytes; uint totalHeaderSize; int encodingType; uint blockSize; uint bitDepth; uint channelCount; uint sampleRate; uint totalSamples; uint fileSize; int fileCount = 0; string outputFileName; string outputFilePath; FileInfo fi = new FileInfo(path); using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read)) { if (!String.IsNullOrEmpty(outputFolder)) { extractedToFolder = outputFolder; } else { extractedToFolder = Path.Combine(Path.GetDirectoryName(path), String.Format("{0}_ADXs", Path.GetFileNameWithoutExtension(path))); } while ((offset = ParseFile.GetNextOffset(fs, offset, ADX_SIG_BYTES)) > -1) { // get offset to copyright string copyrightOffset = (uint)ByteConversion.GetUInt16BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 2, 2)); copyrightBytes = ParseFile.ParseSimpleOffset(fs, offset + copyrightOffset - 2, CRI_COPYRIGHT_BYTES.Length); // check that copyright bytes are present if (ParseFile.CompareSegment(copyrightBytes, 0, CRI_COPYRIGHT_BYTES)) { // verify this is standard ADX encodingType = ParseFile.ParseSimpleOffset(fs, offset + 4, 1)[0]; if (encodingType != 3) { fileSize = 1; } else { // get other info blockSize = (uint)ParseFile.ParseSimpleOffset(fs, offset + 5, 1)[0]; bitDepth = (uint)ParseFile.ParseSimpleOffset(fs, offset + 6, 1)[0]; channelCount = (uint)ParseFile.ParseSimpleOffset(fs, offset + 7, 1)[0]; sampleRate = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 8, 4)); totalSamples = ByteConversion.GetUInt32BigEndian(ParseFile.ParseSimpleOffset(fs, offset + 0xC, 4)); totalHeaderSize = copyrightOffset + 4; // calculate file size fileSize = (((totalSamples + 0x1F) / (bitDepth * 8)) * channelCount * blockSize) + totalHeaderSize + blockSize; // extract file if (!String.IsNullOrEmpty(filePrefix)) { outputFileName = String.Format("{0}_{1}.adx", filePrefix, fileCount.ToString("X8")); } else { outputFileName = String.Format("{0}_{1}.adx", Path.GetFileNameWithoutExtension(path), fileCount.ToString("X8")); } outputFilePath = Path.Combine(extractedToFolder, outputFileName); ParseFile.ExtractChunkToFile(fs, offset, (int)fileSize, outputFilePath, true, true); messageBuffer.AppendFormat("{0} - offset: 0x{1} size: 0x{2}{3}", outputFileName, offset.ToString("X8"), fileSize.ToString("X8"), Environment.NewLine); fileCount++; } offset += fileSize; } else { offset += 1; } } } messages = messageBuffer.ToString(); return(extractedToFolder); }