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 Initialize(Stream pStream, string pFilePath) { this.filePath = pFilePath; this.asciiSignature = ParseFile.ParseSimpleOffset(pStream, SIG_OFFSET, SIG_LENGTH); this.channels = ParseFile.ParseSimpleOffset(pStream, CHANNELS_OFFSET, CHANNELS_LENGTH); this.interleave = ParseFile.ParseSimpleOffset(pStream, INTERLEAVE_OFFSET, INTERLEAVE_LENGTH); this.frequency = ParseFile.ParseSimpleOffset(pStream, FREQUENCY_OFFSET, FREQUENCY_LENGTH); this.loopStart = ParseFile.ParseSimpleOffset(pStream, LOOP_START_OFFSET, LOOP_START_LENGTH); this.loopEnd = ParseFile.ParseSimpleOffset(pStream, LOOP_END_OFFSET, LOOP_END_LENGTH); this.identifier = ParseFile.ParseSimpleOffset(pStream, IDENTIFIER_OFFSET, IDENTIFIER_LENGTH); this.audioStart = ParseFile.ParseSimpleOffset(pStream, AUDIO_START_OFFSET, AUDIO_START_LENGTH); this.headerLength = ParseFile.ParseSimpleOffset(pStream, HEADER_LENGTH_OFFSET, HEADER_LENGTH_LENGTH); this.originalFileName = ParseFile.ParseSimpleOffset(pStream, ORIG_FILENAME_OFFSET, ORIG_FILENAME_LENGTH); this.originalFileSize = ParseFile.ParseSimpleOffset(pStream, ORIG_FILESIZE_OFFSET, ORIG_FILESIZE_LENGTH); this.versionNumber = ParseFile.ParseSimpleOffset(pStream, GENH_VERSION_OFFSET, GENH_VERSION_LENGTH); this.LeftCoef = ParseFile.ParseSimpleOffset(pStream, LEFT_COEF_OFFSET, LEFT_COEF_LENGTH); this.RightCoef = ParseFile.ParseSimpleOffset(pStream, RIGHT_COEF_OFFSET, RIGHT_COEF_LENGTH); this.DspInterleave = ParseFile.ParseSimpleOffset(pStream, DSP_INTERLEAVE_OFFSET, DSP_INTERLEAVE_LENGTH); this.CoefficientType = ParseFile.ParseSimpleOffset(pStream, COEFFICIENT_TYPE_OFFSET, COEFFICIENT_TYPE_LENGTH); this.SplitCoef1 = ParseFile.ParseSimpleOffset(pStream, SPLIT_COEF1_OFFSET, SPLIT_COEF1_LENGTH); this.SplitCoef2 = ParseFile.ParseSimpleOffset(pStream, SPLIT_COEF2_OFFSET, SPLIT_COEF2_LENGTH); this.TotalSamples = ParseFile.ParseSimpleOffset(pStream, TOTAL_SAMPLES_OFFSET, TOTAL_SAMPLES_LENGTH); this.SkipSamples = ParseFile.ParseSimpleOffset(pStream, SKIP_SAMPLES_OFFSET, SKIP_SAMPLES_LENGTH); this.SkipSamplesMode = ParseFile.ReadByte(pStream, SKIP_SAMPLES_MODE_OFFSET); this.Atrac3StereoMode = ParseFile.ReadByte(pStream, ATRAC3_STEREO_MODE_OFFSET); this.XmaStreamMode = ParseFile.ReadByte(pStream, XMA_STREAM_MODE_OFFSET); this.RawStreamSize = ParseFile.ParseSimpleOffset(pStream, RAW_DATA_SIZE_OFFSET, RAW_DATA_SIZE_LENGTH); this.initializeTagHash(); }
/// <summary> /// Parse directory/file nodes. /// </summary> /// <param name="fs">Filestream of U8 file.</param> public void ParseNodes(FileStream fs) { u8Node node = new u8Node(); uint maxNodeId; // read first node node.NodeType = ParseFile.ReadByte(fs, this.RootNodeOffset); node.NameOffset = ParseFile.ReadUint24BE(fs, this.RootNodeOffset + 1); node.DataOffset = ParseFile.ReadUintBE(fs, this.RootNodeOffset + 4); node.DataSize = ParseFile.ReadUintBE(fs, this.RootNodeOffset + 8); this.NodeArray.Add(node); maxNodeId = node.DataSize; // parse each node for (int i = 1; i < maxNodeId; i++) { node = new u8Node(); node.NodeType = ParseFile.ReadByte(fs, this.RootNodeOffset + (i * 0xC)); node.NameOffset = ParseFile.ReadUint24BE(fs, this.RootNodeOffset + (i * 0xC) + 1); node.DataOffset = ParseFile.ReadUintBE(fs, this.RootNodeOffset + (i * 0xC) + 4); node.DataSize = ParseFile.ReadUintBE(fs, this.RootNodeOffset + (i * 0xC) + 8); this.NodeArray.Add(node); } }
public void Initialize(FileStream isoStream, long offset, bool isRawDump) { this.VolumeBaseOffset = offset; this.IsRawDump = isRawDump; this.VolumeType = VolumeDataType.Data; this.DirectoryStructureArray = new ArrayList(); this.FormatDescription = MicrosoftExFatFileSystem.FORMAT_DESCRIPTION_STRING; this.JumpBoot = ParseFile.ReadUint24LE(isoStream, this.VolumeBaseOffset + 0); this.MagicBytes = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 3, 8); this.ZeroChunk = ParseFile.ParseSimpleOffset(isoStream, this.VolumeBaseOffset + 11, 53); this.PartitionOffset = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 64); this.VolumeLength = ParseFile.ReadUlongLE(isoStream, this.VolumeBaseOffset + 72); this.FatOffset = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 80); this.FatLength = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 84); this.ClusterHeapOffset = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 88); this.ClusterCount = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 92); this.RootDirectoryFirstCluster = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 96); this.VolumeSerialNumber = ParseFile.ReadUintLE(isoStream, this.VolumeBaseOffset + 100); this.VolumeIdentifier = this.VolumeSerialNumber.ToString("X2"); this.FileSystemRevision = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 104); this.VolumeFlags = ParseFile.ReadUshortLE(isoStream, this.VolumeBaseOffset + 106); this.BytesPerSector = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 108); this.SectorsPerCluster = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 109); this.NumberOfFats = ParseFile.ReadByte(isoStream, this.VolumeBaseOffset + 110); // caclulate helper values this.SectorSizeInBytes = (uint)(1 << this.BytesPerSector); this.ClusterSizeInBytes = (uint)(1 << (this.SectorsPerCluster + this.BytesPerSector)); this.VolumeLengthInBytes = this.VolumeLength * this.SectorSizeInBytes; this.FatAbsoluteOffset = (ulong)this.VolumeBaseOffset + (this.FatOffset * this.SectorSizeInBytes); this.FatLengthInBytes = this.FatLength * this.SectorSizeInBytes; this.ClusterHeapAbsoluteOffset = (ulong)this.VolumeBaseOffset + (this.ClusterHeapOffset * this.SectorSizeInBytes); this.RootDirectoryAbsoluteOffset = MicrosoftExFatFileSystem.GetOffsetForClusterId(this.ClusterHeapAbsoluteOffset, this.ClusterSizeInBytes, this.RootDirectoryFirstCluster); // this.ClusterHeapAbsoluteOffset + ((this.RootDirectoryFirstCluster - MicrosoftExFatFileSystem.CLUSTER_CORRECTION_OFFSET) * this.ClusterSizeInBytes); if (this.FileSystemRevision == MicrosoftExFatFileSystem.EXFAT_VERSION_0100) { // initialize FAT this.InitializeAndValidateFat(isoStream); // process root directory entry this.GetVolumeLabel(isoStream); // load directories this.LoadDirectories(isoStream); } else { MessageBox.Show(String.Format("Unsupported exFAT version: {0}", this.FileSystemRevision.ToString("X8"))); } }
public SegaSaturnSequence(string sequencePath) { this.FilePath = Path.GetFullPath(sequencePath); using (FileStream fs = File.OpenRead(this.FilePath)) { this.SequenceCount = ParseFile.ReadByte(fs, 1); } }
public NintendoWad(string sourceFile) { // check magic bytes if (NintendoWad.IsWadFile(sourceFile)) { // read header using (FileStream fs = File.OpenRead(sourceFile)) { // set source file this.SourceFileName = sourceFile; // parse header this.HeaderSize = ParseFile.ReadUintBE(fs, 0); this.WadType = ParseFile.ReadUintBE(fs, 4); this.CertificateChainSize = ParseFile.ReadUintBE(fs, 8); this.Reserved = ParseFile.ReadUintBE(fs, 0xC); this.TicketSize = ParseFile.ReadUintBE(fs, 0x10); this.TitleMetaDataSize = ParseFile.ReadUintBE(fs, 0x14); this.DataSize = ParseFile.ReadUintBE(fs, 0x18); this.FooterSize = ParseFile.ReadUintBE(fs, 0x1C); // offsets this.CertificateChainOffset = (uint)this.PadValue(this.HeaderSize, "Certificate Chain Offset"); this.TicketOffset = (uint)this.PadValue(this.CertificateChainOffset + this.CertificateChainSize, "Ticket Offset"); this.TitleMetaDataOffset = (uint)this.PadValue(this.TicketOffset + this.TicketSize, "Title Meta Data Offset"); this.DataOffset = (uint)this.PadValue(this.TitleMetaDataOffset + this.TitleMetaDataSize, "Data Offset"); this.FooterOffset = (uint)this.PadValue(this.DataOffset + this.DataSize, "Footer Offset"); // get important values this.TicketId = ParseFile.ReadUlongBE(fs, this.TicketOffset + 0x1D0); this.TitleId = ParseFile.ReadUlongBE(fs, this.TicketOffset + 0x1DC); this.TitleIdBytes = ParseFile.ParseSimpleOffset(fs, this.TicketOffset + 0x1DC, 8); this.EncryptedTitleKey = ParseFile.ParseSimpleOffset(fs, this.TicketOffset + 0x1BF, 0x10); this.CommonKeyIndex = ParseFile.ReadByte(fs, this.TicketOffset + 0x1F1); // decrypt title key this.DecryptTitleKey(); // get TMD content entries this.NumberOfContents = ParseFile.ReadUshortBE(fs, this.TitleMetaDataOffset + 0x1DE); this.ParseTmdContentEntries(fs); } // using (FileStream fs = File.OpenRead(sourceFile)) } else { throw new FormatException("Nintendo WAD magic bytes not found at offset 0x03."); } }
private void ParseNcsdHeader(FileStream fs, long offset) { // parse NCSD header this.NcsdHash = ParseFile.ParseSimpleOffset(fs, offset, 0x100); this.MagicBytes = ParseFile.ReadUintBE(fs, offset + 0x100); this.ImageSize = ParseFile.ReadUintLE(fs, offset + 0x104); this.MediaId = ParseFile.ReadUlongLE(fs, offset + 0x108); this.PartitionsFsType = ParseFile.ReadUlongLE(fs, offset + 0x110); this.PartitionsEncryptionType = ParseFile.ReadUlongLE(fs, offset + 0x118); this.NcchOffsetInfo = new SimpleOffset[8]; for (int i = 0; i < 8; i++) { this.NcchOffsetInfo[i] = new SimpleOffset( ParseFile.ReadUintLE(fs, offset + 0x120 + (8 * i)), ParseFile.ReadUintLE(fs, offset + 0x120 + ((8 * i) + 4))); } // parse Exheader this.ExHeaderHash = ParseFile.ParseSimpleOffset(fs, offset + 0x160, 0x20); this.AdditionalHeaderSize = ParseFile.ReadUintLE(fs, offset + 0x180); this.SectorZeroOffset = ParseFile.ReadUintLE(fs, offset + 0x184); this.PartitionFlags = ParseFile.ReadUlongLE(fs, offset + 0x188); this.PartitionIds = new ulong[8]; for (int i = 0; i < 8; i++) { this.PartitionIds[i] = ParseFile.ReadUlongLE(fs, offset + 0x190 + (8 * i)); } this.Reserved01 = ParseFile.ParseSimpleOffset(fs, offset + 0x1D0, 0x20); this.Reserved02 = ParseFile.ParseSimpleOffset(fs, offset + 0x1F0, 0xE); this.Unknown01 = ParseFile.ReadByte(fs, 0x1FE); this.Unknown02 = ParseFile.ReadByte(fs, 0x1FF); // parse Card Info this.CardInfoWritableAddress = ParseFile.ReadInt32LE(fs, offset + 0x200); this.CardInfoBitmask = ParseFile.ReadUintLE(fs, offset + 0x204); this.CardInfoReserved01 = ParseFile.ParseSimpleOffset(fs, offset + 0x208, 0xDF8); this.CardInfoMediaId = ParseFile.ReadUlongLE(fs, offset + 0x1000); this.CardInfoReserved02 = ParseFile.ReadUlongLE(fs, offset + 0x1008); this.CardInfoInitialData = ParseFile.ParseSimpleOffset(fs, offset + 0x1010, 0x30); this.CardInfoReserved03 = ParseFile.ParseSimpleOffset(fs, offset + 0x1040, 0xC0); this.CardInfoNcchHeaderCopy = ParseFile.ParseSimpleOffset(fs, offset + 0x1011, 0x100); }
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."); } }
public static uint?GetDspRamNeeded(string dspFile) { uint?dspRamRequired = null; byte ramValue; if (File.Exists(dspFile)) { using (FileStream fs = File.OpenRead(dspFile)) { ramValue = ParseFile.ReadByte(fs, 0x20); switch (ramValue) { case 0: dspRamRequired = 0x4040; break; case 1: dspRamRequired = 0x8040; break; case 2: dspRamRequired = 0x10040; break; case 3: dspRamRequired = 0x20040; break; default: dspRamRequired = null; break; } } } return(dspRamRequired); }
public void InitializeExeFileSystem(FileStream isoStream, long offset, string nextDirectoryName) { string fileName; long fileOffset; uint fileLength; byte[] hash; long hashOffset; Nintendo3dsCtrFile file; // parse file entries for (int i = 0; i < 10; i++) { // check if row has data if (ParseFile.ReadByte(isoStream, offset + (0x10 * i)) != 0) { // read VFS items fileName = ParseFile.ReadAsciiString(isoStream, offset + (0x10 * i)); fileOffset = ParseFile.ReadUintLE(isoStream, offset + (0x10 * i) + 8); fileOffset += offset + 0x200; fileLength = ParseFile.ReadUintLE(isoStream, offset + (0x10 * i) + 0xC); // read SHA256 hash hashOffset = offset + 0x200 - (0x20 * (i + 1)); hash = ParseFile.ParseSimpleOffset(isoStream, hashOffset, 0x20); // build file object file = new Nintendo3dsCtrFile(isoStream, nextDirectoryName, this.SourceFilePath, fileName, fileOffset, fileLength, this.FileSystem, null); file.Sha256Hash = hash; this.FileArray.Add(file); } } }
/* * public CriCpkDirectory GetDirectoryForGtoc(FileStream fs, CriUtfTable cpkUtf, string BaseDirectoryName) * { * CriUtfTocFileInfo fileInfo = new CriUtfTocFileInfo(); * * CriCpkDirectory baseDirectory = new CriCpkDirectory(this.SourceFileName, BaseDirectoryName, String.Empty); * CriCpkDirectory newDirectory; * CriCpkDirectory currentDirectory; * int indexOfNewDirectory; * * // get Gdata UTF table (Directories) * uint glink = (uint)CriUtfTable.GetOffsetForUtfFieldForRow(this.GtocUtf, 0, "Glink"); * * ulong gDataOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(this.GtocUtf, 0, "Gdata"); * CriUtfTable gData = new CriUtfTable(); * gData.Initialize(fs, (long)gDataOffset); * * // get directories * int currentIndex = 0; * currentDirectory = GetGtocDirectory(gData, currentIndex, this.SourceFileName, String.Empty); * int next = (int)CriUtfTable.GetUtfFieldForRow(gData, currentIndex, "Next"); * baseDirectory.SubDirectoryArray.Add(currentDirectory); * * while (next != -1) * { * * } * * * * * * long trueTocBaseOffset; * ulong contentOffset = (ulong)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "ContentOffset"); * ushort align = (ushort)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "Align"); * * char[] separators = new char[] { '/', '\\' }; * ArrayList allDirectories = new ArrayList(); * * * * CriCpkFile tempFile; * Dictionary<string, ArrayList> fileListDictionary = new Dictionary<string, ArrayList>(); * string parentName; * * // loop over files to get unique dirs * for (int i = 0; i < this.TocUtf.Rows.GetLength(0); i++) * { * fileInfo = GetUtfTocFileInfo(this.TocUtf, i); * * if (fileInfo.FileName != null) * { * //--------------- * // get directory * //--------------- * if (!fileListDictionary.ContainsKey(fileInfo.DirName)) * { * fileListDictionary.Add(fileInfo.DirName, new ArrayList()); * } * * //-------------- * // create file * //-------------- * // set true base offset, since UTF header starts at 0x10 of a container type * trueTocBaseOffset = this.TocUtf.BaseOffset - 0x10; * * // get absolute offset * if (contentOffset < (ulong)trueTocBaseOffset) * { * fileInfo.FileOffset += contentOffset; * } * else * { * fileInfo.FileOffset += (ulong)trueTocBaseOffset; * } * * if (fileInfo.FileOffset % align != 0) * { * fileInfo.FileOffset = MathUtil.RoundUpToByteAlignment(fileInfo.FileOffset, align); * } * * parentName = BaseDirectoryName + Path.DirectorySeparatorChar + fileInfo.DirName; * parentName = parentName.Replace('/', Path.DirectorySeparatorChar); * * tempFile = new CriCpkFile(parentName, this.SourceFileName, fileInfo.FileName, (long)fileInfo.FileOffset, this.VolumeBaseOffset, * (long)fileInfo.FileOffset, fileInfo.FileSize, fileInfo.ExtractSize); * * // add to Dictionary * fileListDictionary[fileInfo.DirName].Add(tempFile); * } * } * * foreach (var path in fileListDictionary.Keys) * { * currentDirectory = baseDirectory; * var pathItems = path.Split(separators); * * parentName = BaseDirectoryName; * * for (int i = 0; i < pathItems.Count(); i++) * { * var item = pathItems[i]; * * var tmp = currentDirectory.SubDirectoryArray.Cast<CriCpkDirectory>().Where(x => x.DirectoryName.Equals(item)); * * if (tmp.Count() > 0) * { * currentDirectory = tmp.Single(); * } * else * { * newDirectory = new CriCpkDirectory(this.SourceFileName, item, parentName); * indexOfNewDirectory = currentDirectory.SubDirectoryArray.Add(newDirectory); * currentDirectory = (CriCpkDirectory)currentDirectory.SubDirectoryArray[indexOfNewDirectory]; * } * * if (i == pathItems.GetUpperBound(0)) * { * foreach (CriCpkFile f in fileListDictionary[path]) * { * currentDirectory.FileArray.Add(f); * } * } * * parentName += Path.DirectorySeparatorChar + item; * } * } * * return baseDirectory; * } */ private static ushort get_next_bits(Stream inFile, ref long offset, ref byte bit_pool, ref int bits_left, int bit_count) { ushort out_bits = 0; int num_bits_produced = 0; while (num_bits_produced < bit_count) { if (bits_left == 0) { bit_pool = ParseFile.ReadByte(inFile, offset); bits_left = 8; offset--; } int bits_this_round; if (bits_left > (bit_count - num_bits_produced)) { bits_this_round = bit_count - num_bits_produced; } else { bits_this_round = bits_left; } out_bits <<= bits_this_round; out_bits |= (ushort)((ushort)(bit_pool >> (bits_left - bits_this_round)) & ((1 << bits_this_round) - 1)); bits_left -= bits_this_round; num_bits_produced += bits_this_round; } return(out_bits); }
public void ParseHeader(FileStream inStream, long offsetToHeader) { long frameOffsetOffset; long audioIdOffet; int fullHeaderSize; byte versionId; this.MagicBytes = ParseFile.ParseSimpleOffset(inStream, offsetToHeader, 3); if (ParseFile.CompareSegment(this.MagicBytes, 0, BINK01_HEADER)) { this.BinkVersion = BinkType.Version01; } else if (ParseFile.CompareSegment(this.MagicBytes, 0, BINK02_HEADER)) { versionId = ParseFile.ReadByte(inStream, offsetToHeader + 3); if (versionId < 0x69) // version "i" { this.BinkVersion = BinkType.Version01; } else // version "a" through "h" { this.BinkVersion = BinkType.Version02; } } else { throw new FormatException("Unrecognized Magic Bytes for Bink."); } this.FrameCount = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(inStream, offsetToHeader + 8, 4), 0); this.AudioTrackCount = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(inStream, offsetToHeader + 0x28, 4), 0); // get Audio Track Ids this.AudioTrackIds = new uint[this.AudioTrackCount]; for (uint i = 0; i < this.AudioTrackCount; i++) { audioIdOffet = offsetToHeader + 0x2C + (this.AudioTrackCount * 8) + (i * 4); if (this.BinkVersion == BinkType.Version02) { audioIdOffet += 4; } this.AudioTrackIds[i] = BitConverter.ToUInt32(ParseFile.ParseSimpleOffset(inStream, audioIdOffet, 4), 0); } // get frame offsets this.FrameOffsetList = new FrameOffsetStruct[this.FrameCount]; for (uint i = 0; i < this.FrameCount; i++) { frameOffsetOffset = offsetToHeader + 0x2C + (this.AudioTrackCount * 0xC) + (i * 4); if (this.BinkVersion == BinkType.Version02) { frameOffsetOffset += 4; } this.FrameOffsetList[i].FrameOffset = ParseFile.ReadUintLE(inStream, frameOffsetOffset); if ((this.FrameOffsetList[i].FrameOffset & 1) == 1) { this.FrameOffsetList[i].IsKeyFrame = true; this.FrameOffsetList[i].FrameOffset &= 0xFFFFFFFE; // mask off bit 0 } } // get full header fullHeaderSize = (int)(offsetToHeader + 0x2C + (this.AudioTrackCount * 0xC) + (this.FrameCount * 4) + 4); if (this.BinkVersion == BinkType.Version02) { fullHeaderSize += 4; } this.FullHeader = ParseFile.ParseSimpleOffset(inStream, offsetToHeader, fullHeaderSize); }
protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pExtractAdxStruct, DoWorkEventArgs e) { ExtractHcaStruct extractAdxStruct = (ExtractHcaStruct)pExtractAdxStruct; long offset = 0; byte revisionMajor; byte revisionMinor; ushort dataOffset; long fmtChunkOffset; uint blockCount; ushort blockSize; long fileSize; int fileCount = 0; string outputPath = Path.Combine(Path.GetDirectoryName(pPath), "_cri_hca_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}_HCAs", Path.GetFileNameWithoutExtension(pPath))); while ((offset = ParseFile.GetNextOffsetMasked(fs, offset, HCA_SIG_BYTES, MASK_BYTES)) > -1) { if (!this.CancellationPending) { // get version revisionMajor = ParseFile.ReadByte(fs, offset + 4); revisionMinor = ParseFile.ReadByte(fs, offset + 5); // get data offset dataOffset = ParseFile.ReadUshortBE(fs, offset + 6); // get 'fmt' chunk offset fmtChunkOffset = ParseFile.GetNextOffsetMasked(fs, offset, FMT_CHUNK_BYTES, MASK_BYTES); if (fmtChunkOffset > -1) { // get block count blockCount = ParseFile.ReadUintBE(fs, fmtChunkOffset + 8); // get block size blockSize = this.getBlockSize(fs, offset); // calculate file size fileSize = dataOffset + (blockCount * blockSize); // extract file outputFileName = String.Format("{0}_{1}.hca", 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, fileSize, outputFilePath, true, true); // increment counter fileCount++; // move pointer offset += fileSize; } else { throw new FormatException(String.Format("'fmt' chunk not found for HCA starting at 0x{0}", offset.ToString("X8"))); } } else { e.Cancel = true; return; } } } }
private void initializeUtfSchema(FileStream SourceFs, FileStream UtfTableFs, long schemaOffset) { long nameOffset; long constantOffset; long dataOffset; long dataSize; long rowDataOffset; long rowDataSize; long currentOffset = schemaOffset; long currentRowBase; long currentRowOffset = 0; CriField field; for (uint i = 0; i < this.NumberOfRows; i++) { //if (i == 0x1a2a) //{ // int yuuuu = 1; //} //try //{ currentOffset = schemaOffset; currentRowBase = this.RowOffset + (this.RowSize * i); currentRowOffset = 0; this.Rows[i] = new Dictionary <string, CriField>(); // parse fields for (ushort j = 0; j < this.NumberOfFields; j++) { field = new CriField(); field.Type = ParseFile.ReadByte(UtfTableFs, currentOffset); nameOffset = ParseFile.ReadUintBE(UtfTableFs, currentOffset + 1); field.Name = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + nameOffset); // each row will have a constant if (((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT) || ((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT2)) { // capture offset of constant constantOffset = currentOffset + 5; // read the constant depending on the type switch (field.Type & COLUMN_TYPE_MASK) { case COLUMN_TYPE_STRING: dataOffset = ParseFile.ReadUintBE(UtfTableFs, constantOffset); field.Value = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + dataOffset); currentOffset += 4; break; case COLUMN_TYPE_8BYTE: field.Value = ParseFile.ReadUlongBE(UtfTableFs, constantOffset); currentOffset += 8; break; case COLUMN_TYPE_DATA: dataOffset = ParseFile.ReadUintBE(UtfTableFs, constantOffset); dataSize = ParseFile.ReadUintBE(UtfTableFs, constantOffset + 4); field.Offset = (ulong)(this.BaseOffset + this.DataOffset + dataOffset); field.Size = (ulong)dataSize; // don't think this is encrypted, need to check field.Value = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)dataSize); currentOffset += 8; break; case COLUMN_TYPE_FLOAT: field.Value = ParseFile.ReadFloatBE(UtfTableFs, constantOffset); currentOffset += 4; break; case COLUMN_TYPE_4BYTE2: field.Value = ParseFile.ReadInt32BE(UtfTableFs, constantOffset); currentOffset += 4; break; case COLUMN_TYPE_4BYTE: field.Value = ParseFile.ReadUintBE(UtfTableFs, constantOffset); currentOffset += 4; break; case COLUMN_TYPE_2BYTE2: field.Value = ParseFile.ReadInt16BE(UtfTableFs, constantOffset); currentOffset += 2; break; case COLUMN_TYPE_2BYTE: field.Value = ParseFile.ReadUshortBE(UtfTableFs, constantOffset); currentOffset += 2; break; case COLUMN_TYPE_1BYTE2: field.Value = ParseFile.ReadSByte(UtfTableFs, constantOffset); currentOffset += 1; break; case COLUMN_TYPE_1BYTE: field.Value = ParseFile.ReadByte(UtfTableFs, constantOffset); currentOffset += 1; break; default: throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8"))); } // switch (field.Type & COLUMN_TYPE_MASK) } else if ((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_PERROW) { // read the constant depending on the type switch (field.Type & COLUMN_TYPE_MASK) { case COLUMN_TYPE_STRING: rowDataOffset = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset); field.Value = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + rowDataOffset); currentRowOffset += 4; break; case COLUMN_TYPE_8BYTE: field.Value = ParseFile.ReadUlongBE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 8; break; case COLUMN_TYPE_DATA: rowDataOffset = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset); rowDataSize = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset + 4); field.Offset = (ulong)(this.BaseOffset + this.DataOffset + rowDataOffset); field.Size = (ulong)rowDataSize; // don't think this is encrypted field.Value = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)rowDataSize); currentRowOffset += 8; break; case COLUMN_TYPE_FLOAT: field.Value = ParseFile.ReadFloatBE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 4; break; case COLUMN_TYPE_4BYTE2: field.Value = ParseFile.ReadInt32BE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 4; break; case COLUMN_TYPE_4BYTE: field.Value = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 4; break; case COLUMN_TYPE_2BYTE2: field.Value = ParseFile.ReadInt16BE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 2; break; case COLUMN_TYPE_2BYTE: field.Value = ParseFile.ReadUshortBE(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 2; break; case COLUMN_TYPE_1BYTE2: field.Value = ParseFile.ReadSByte(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 1; break; case COLUMN_TYPE_1BYTE: field.Value = ParseFile.ReadByte(UtfTableFs, currentRowBase + currentRowOffset); currentRowOffset += 1; break; default: throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8"))); } // switch (field.Type & COLUMN_TYPE_MASK) } // if ((fields[i].Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT) // add field to dictionary this.Rows[i].Add(field.Name, field); // move to next field currentOffset += 5; // sizeof(CriField.Type + CriField.NameOffset) } // for (ushort j = 0; j < this.NumberOfFields; j++) //} //catch (Exception ex) //{ // int xxxx = 1; //} } // for (uint i = 0; i < this.NumberOfRows; i++) }
public void ParseHeader(Stream inStream, long currentOffset) { this.HeaderSize = ParseFile.ReadUintBE(inStream, currentOffset + 0x10); // 0x10-0x13 this.BodySize = ParseFile.ReadUintBE(inStream, currentOffset + 0x14); // 0x14-0x17 this.Blocks = ParseFile.ReadUintBE(inStream, currentOffset + 0x18); // 0x18-0x1B this.AudioFrames = ParseFile.ReadUintBE(inStream, currentOffset + 0x1C); // 0x1C-0x1F this.VideoFrames = ParseFile.ReadUintBE(inStream, currentOffset + 0x20); // 0x20-0x23 this.Unk24 = ParseFile.ReadUintBE(inStream, currentOffset + 0x24); // 0x24-0x27 (0x8257,0x8256) this.Duration = ParseFile.ReadUintBE(inStream, currentOffset + 0x28); // 0x28-0x2B this.Unk2C = ParseFile.ReadUintBE(inStream, currentOffset + 0x2C); // 0x2C-0x2F (0) this.AudioFrameSize = ParseFile.ReadUintBE(inStream, currentOffset + 0x30); // 0x30-0x33 this.Hres = ParseFile.ReadUshortBE(inStream, currentOffset + 0x34); // 0x34-0x35 this.Vres = ParseFile.ReadUshortBE(inStream, currentOffset + 0x36); // 0x36-0x37 this.Unk38 = ParseFile.ReadUshortBE(inStream, currentOffset + 0x38); // 0x38-0x3B (0x0202) this.Unk3A = ParseFile.ReadByte(inStream, currentOffset + 0x3A); // 0x3A (0 or 0x12) this.Unk3B = ParseFile.ReadByte(inStream, currentOffset + 0x3B); // 0x3B (0) this.AudioChannels = ParseFile.ReadByte(inStream, currentOffset + 0x3C); // 0x3C this.AudioBitdepth = ParseFile.ReadByte(inStream, currentOffset + 0x3D); // 0x3D this.Pad = ParseFile.ReadUshortBE(inStream, currentOffset + 0x3E); // 0x3E-0x3F (0) this.AudioSampleRate = ParseFile.ReadUintBE(inStream, currentOffset + 0x40); // 0x40-0x43 // save off original header this.FullHeader = ParseFile.ParseSimpleOffset(inStream, currentOffset, (int)this.HeaderSize); #region AUDIO/VIDEO features checks // set video present flags if (this.VideoFrames == 0) { if (this.Hres == 0) { throw new Exception("Video frame count greater than 0, but horizontal resolution equals zero."); } else if (this.Vres == 0) { throw new Exception("Video frame count greater than 0, but vertical resolution equals zero."); } else { this.IsVideoPresent = true; } } // set audio present flags if (this.AudioFrames > 0) { if (this.AudioFrameSize == 0) { throw new Exception("Audio frame count greater than 0, but audio frame size equals zero."); } else if (this.AudioChannels == 0) { throw new Exception("Audio frame count greater than 0, but audio channel count equals zero."); } else if (this.AudioBitdepth == 0) { throw new Exception("Audio frame count greater than 0, but audio bit depth equals zero."); } else if (this.AudioSampleRate == 0) { throw new Exception("Audio frame count greater than 0, but audio sample rate equals zero."); } else { this.IsAudioPresent = true; } } #endregion }