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();
        }
示例#2
0
        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();
        }
示例#3
0
        /// <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);
            }
        }
示例#4
0
        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")));
            }
        }
示例#5
0
        public SegaSaturnSequence(string sequencePath)
        {
            this.FilePath = Path.GetFullPath(sequencePath);

            using (FileStream fs = File.OpenRead(this.FilePath))
            {
                this.SequenceCount = ParseFile.ReadByte(fs, 1);
            }
        }
示例#6
0
        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.");
            }
        }
示例#7
0
        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.");
            }
        }
示例#9
0
        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);
        }
示例#10
0
        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);
                }
            }
        }
示例#11
0
        /*
         * 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);
        }
示例#12
0
        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);
        }
示例#13
0
        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;
                    }
                }
            }
        }
示例#14
0
        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++)
        }
示例#15
0
        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
        }