예제 #1
0
        protected void InitializeCueNameToWaveformMap(FileStream fs, bool includeCueIdInFileName)
        {
            ushort cueIndex;
            string cueName;

            CriUtfTable cueNameTableUtf = new CriUtfTable();

            cueNameTableUtf.Initialize(fs, (long)this.CueNameTableOffset);

            for (int i = 0; i < cueNameTableUtf.NumberOfRows; i++)
            {
                cueIndex = (ushort)CriUtfTable.GetUtfFieldForRow(cueNameTableUtf, i, "CueIndex");

                // skip cues with unidentified waveforms (see 'vc05_0140.acb, vc10_0372.acb' in Kidou_Senshi_Gundam_AGE_Universe_Accel (PSP))
                if (this.CueList[cueIndex].IsWaveformIdentified)
                {
                    cueName = (string)CriUtfTable.GetUtfFieldForRow(cueNameTableUtf, i, "CueName");

                    this.CueList[cueIndex].CueName  = cueName;
                    this.CueList[cueIndex].CueName += CriAcbFile.GetFileExtensionForEncodeType(this.CueList[cueIndex].EncodeType);

                    if (includeCueIdInFileName)
                    {
                        this.CueList[cueIndex].CueName = String.Format("{0}_{1}",
                                                                       this.CueList[cueIndex].CueId.ToString("D5"), this.CueList[cueIndex].CueName);
                    }

                    this.CueNamesToWaveforms.Add(this.CueList[cueIndex].CueName, this.CueList[cueIndex].WaveformId);
                }
            }
        }
예제 #2
0
        public static ushort GetWaveformRowIndexForWaveformId(CriUtfTable utfTable, ushort waveformId, bool isStreamed)
        {
            ushort ret = ushort.MaxValue;

            for (int i = 0; i < utfTable.NumberOfRows; i++)
            {
                var tempId = CriUtfTable.GetUtfFieldForRow(utfTable, i, "Id");

                // newer archives use different labels
                if (tempId == null)
                {
                    if (isStreamed)
                    {
                        tempId = CriUtfTable.GetUtfFieldForRow(utfTable, i, "StreamAwbId");
                    }
                    else
                    {
                        tempId = CriUtfTable.GetUtfFieldForRow(utfTable, i, "MemoryAwbId");
                    }
                }

                if ((ushort)tempId == waveformId)
                {
                    ret = (ushort)i;
                }
            }

            return(ret);
        }
예제 #3
0
        // @TODO: Need to update this for Internal/External CPK
        protected void ExtractAwbWithCueNames(string destinationFolder, AwbToExtract whichAwb)
        {
            CriUtfTable waveformTableUtf;
            byte        encodeType;
            string      rawFileName;

            CriAfs2Archive awb;
            string         rawFileFormat = "{0}_{1}{2}";

            if (whichAwb == AwbToExtract.Internal)
            {
                awb = this.InternalAwb;
            }
            else
            {
                awb = this.ExternalAwb;
            }

            using (FileStream fs = File.Open(awb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // use files names for internal AWB
                foreach (string key in this.CueNamesToWaveforms.Keys)
                {
                    // extract file
                    ParseFile.ExtractChunkToFile64(fs,
                                                   (ulong)awb.Files[this.CueNamesToWaveforms[key]].FileOffsetByteAligned,
                                                   (ulong)awb.Files[this.CueNamesToWaveforms[key]].FileLength,
                                                   Path.Combine(destinationFolder, FileUtil.CleanFileName(key)), false, false);
                }

                //-------------------------------------
                // extract any items without a CueName
                //-------------------------------------
                using (FileStream acbStream = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    waveformTableUtf = new CriUtfTable();
                    waveformTableUtf.Initialize(acbStream, (long)this.WaveformTableOffset);
                }

                // get list of unextracted files
                var unextractedFiles = awb.Files.Keys.Where(x => !this.CueNamesToWaveforms.ContainsValue(x));
                foreach (ushort key in unextractedFiles)
                {
                    encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, key, "EncodeType");

                    rawFileName = String.Format(rawFileFormat,
                                                Path.GetFileNameWithoutExtension(awb.SourceFile), key.ToString("D5"),
                                                CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                    // extract file
                    ParseFile.ExtractChunkToFile64(fs,
                                                   (ulong)awb.Files[key].FileOffsetByteAligned,
                                                   (ulong)awb.Files[key].FileLength,
                                                   Path.Combine(destinationFolder, rawFileName), false, false);
                }
            }
        }
예제 #4
0
        public static bool IsUtfTable(FileStream fs, long offset,
                                      bool useIncomingKeys = false,
                                      Dictionary <string, byte> incomingLcgEncryptionKeys = null)
        {
            bool        ret = false;
            CriUtfTable utf = new CriUtfTable();

            utf.SourceFile = fs.Name;
            utf.BaseOffset = offset;

            try
            {
                utf.MagicBytes = ParseFile.ParseSimpleOffset(fs, utf.BaseOffset, 4);

                // check if file is decrypted and get decryption keys if needed
                utf.checkEncryption(fs, useIncomingKeys, incomingLcgEncryptionKeys);

                if (utf.IsEncrypted)
                {
                    // write (decrypted) utf header to file
                    utf.UtfTableFile = utf.WriteTableToTempFile(fs, offset, 4);

                    using (FileStream checkFs = File.Open(utf.UtfTableFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        utf.MagicBytes = ParseFile.ParseSimpleOffset(checkFs, utf.BaseOffset, 4);
                    }


                    //utf.IsEncrypted = false; // since we've decrypted to a temp file
                    // utf.UtfReader.IsEncrypted = false;
                }

                if (ParseFile.CompareSegment(utf.MagicBytes, 0, SIGNATURE_BYTES))
                {
                    ret = true;
                }
                else
                {
                    ret = false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (!String.IsNullOrEmpty(utf.UtfTableFile))
                {
                    File.Delete(utf.UtfTableFile);
                }
            }

            return(ret);
        }
예제 #5
0
        public static CriUtfTable InitializeToc(FileStream fs, CriUtfTable cpkUtf, string tocIdentifierString)
        {
            CriUtfTable toc = null;

            if (cpkUtf.Rows[0].ContainsKey(tocIdentifierString) &&
                cpkUtf.Rows[0][tocIdentifierString].Value != null)
            {
                toc = new CriUtfTable();
                toc.Initialize(fs, (long)((ulong)cpkUtf.BaseOffset + (ulong)cpkUtf.Rows[0][tocIdentifierString].Value));
            }

            return(toc);
        }
예제 #6
0
        public static ulong GetSizeForUtfFieldForRow(CriUtfTable utfTable, int rowIndex, string key)
        {
            ulong ret = 0;

            if (utfTable.Rows.GetLength(0) > rowIndex)
            {
                if (utfTable.Rows[rowIndex].ContainsKey(key))
                {
                    ret = utfTable.Rows[rowIndex][key].Size;
                }
            }

            return(ret);
        }
예제 #7
0
        public static object GetUtfFieldForRow(CriUtfTable utfTable, int rowIndex, string key)
        {
            object ret = null;

            if (utfTable.Rows.GetLength(0) > rowIndex)
            {
                if (utfTable.Rows[rowIndex].ContainsKey(key))
                {
                    ret = utfTable.Rows[rowIndex][key].Value;
                }
            }

            return(ret);
        }
예제 #8
0
        public static CriUtfTocFileInfo GetUtfItocFileInfo(CriUtfTable dataUtf, int rowIndex)
        {
            CriUtfTocFileInfo fileInfo = new CriUtfTocFileInfo();
            object            temp;

            temp = CriUtfTable.GetUtfFieldForRow(dataUtf, rowIndex, "ID");
            fileInfo.FileName = temp != null ? ((ushort)temp).ToString("D5") : null;

            temp = CriUtfTable.GetUtfFieldForRow(dataUtf, rowIndex, "FileSize");
            fileInfo.FileSize = temp != null?Convert.ToUInt32(temp) : uint.MaxValue;

            temp = CriUtfTable.GetUtfFieldForRow(dataUtf, rowIndex, "ExtractSize");
            fileInfo.ExtractSize = temp != null?Convert.ToUInt32(temp) : uint.MaxValue;

            return(fileInfo);
        }
예제 #9
0
        public static CriCpkDirectory GetGtocDirectory(CriUtfTable dataUtf, int rowIndex, string sourceFile,
                                                       string parentDirectory)
        {
            CriCpkDirectory gtocDirectory;
            object          temp;

            temp          = CriUtfTable.GetUtfFieldForRow(dataUtf, rowIndex, "Gname");
            gtocDirectory = new CriCpkDirectory(sourceFile, (string)temp, parentDirectory);

            temp = CriUtfTable.GetUtfFieldForRow(dataUtf, rowIndex, "Child");

            if ((short)temp != -1)
            {
                // add files
            }

            return(gtocDirectory);
        }
예제 #10
0
        public static CriUtfTocFileInfo GetUtfTocFileInfo(CriUtfTable tocUtf, int rowIndex)
        {
            CriUtfTocFileInfo fileInfo = new CriUtfTocFileInfo();
            object            temp;

            temp             = CriUtfTable.GetUtfFieldForRow(tocUtf, rowIndex, "DirName");
            fileInfo.DirName = temp != null ? (string)temp : null;
            fileInfo.DirName = fileInfo.DirName.Equals(CriCpkArchive.NULL_FILENAME) ? String.Empty : fileInfo.DirName;

            temp = CriUtfTable.GetUtfFieldForRow(tocUtf, rowIndex, "FileName");
            fileInfo.FileName = temp != null ? (string)temp : null;
            fileInfo.FileName = fileInfo.FileName.Equals(CriCpkArchive.NULL_FILENAME) ? String.Format("{0}.bin", rowIndex.ToString("D5")) : fileInfo.FileName;

            temp = CriUtfTable.GetUtfFieldForRow(tocUtf, rowIndex, "FileOffset");
            fileInfo.FileOffset = temp != null ? (ulong)temp : ulong.MaxValue;

            temp = CriUtfTable.GetUtfFieldForRow(tocUtf, rowIndex, "FileSize");
            fileInfo.FileSize = temp != null ? (uint)temp : uint.MaxValue;

            temp = CriUtfTable.GetUtfFieldForRow(tocUtf, rowIndex, "ExtractSize");
            fileInfo.ExtractSize = temp != null ? (uint)temp : uint.MaxValue;

            return(fileInfo);
        }
예제 #11
0
        public void Initialize(FileStream fs, long offset, bool isRawDump)
        {
            FormatDescription = FORMAT_DESCRIPTION_STRING;

            VolumeBaseOffset        = offset;
            IsRawDump               = isRawDump;
            VolumeType              = VolumeDataType.Data;
            DirectoryStructureArray = new ArrayList();

            SourceFileName = fs.Name;

            var cpkUtf = new CriUtfTable();

            cpkUtf.Initialize(fs, VolumeBaseOffset + 0x10);

            VolumeIdentifier = cpkUtf.TableName;

            ItocFiles = new Dictionary <ushort, CriAfs2File>();

            TocUtf = InitializeToc(fs, cpkUtf, "TocOffset");
            // this.EtocUtf = InitializeToc(fs, cpkUtf, "EtocOffset");
            ItocUtf = InitializeToc(fs, cpkUtf, "ItocOffset");
            // this.GtocUtf = InitializeToc(fs, cpkUtf, "GtocOffset");


            var dummy = new CriCpkDirectory(SourceFileName, string.Empty, string.Empty);

            if (TocUtf != null)
            {
                var tocDir = GetDirectoryForToc(fs, cpkUtf, "TOC", VolumeBaseOffset);

                if (tocDir.FileArray.Count > 0 || tocDir.SubDirectoryArray.Count > 0)
                {
                    dummy.SubDirectoryArray.Add(tocDir);
                }
            }

            /*
             * if (etocUtf != null)
             * {
             *  CriCpkDirectory etocDir = this.GetDirectoryForToc(fs, cpkUtf, etocUtf, "ETOC");
             *
             *  if ((etocDir.FileArray.Count > 0) || (etocDir.SubDirectoryArray.Count > 0))
             *  {
             *      dummy.SubDirectoryArray.Add(etocDir);
             *  }
             * }
             */

            if (ItocUtf != null)
            {
                var itocDir = GetDirectoryForItoc(fs, cpkUtf, "ITOC", VolumeBaseOffset);

                if (itocDir.FileArray.Count > 0 || itocDir.SubDirectoryArray.Count > 0)
                {
                    dummy.SubDirectoryArray.Add(itocDir);
                }
            }


            //if (this.GtocUtf != null)
            //{
            //    CriCpkDirectory gtocDir = this.GetDirectoryForGtoc(fs, cpkUtf, "GTOC");

            //    if ((gtocDir.FileArray.Count > 0) || (gtocDir.SubDirectoryArray.Count > 0))
            //    {
            //        dummy.SubDirectoryArray.Add(gtocDir);
            //    }
            //}


            DirectoryStructureArray.Add(dummy);
        }
예제 #12
0
        protected void ExtractAllUsingCueList(string destinationFolder)
        {
            CriUtfTable waveformTableUtf;
            ushort      waveformIndex;
            byte        encodeType;
            string      rawFileName;
            string      rawFileFormat = "{0}.{1}{2}";

            FileStream internalFs = null;
            FileStream externalFs = null;

            ArrayList internalIdsExtracted = new ArrayList();
            ArrayList externalIdsExtracted = new ArrayList();

            string acbAwbDestinationFolder = Path.Combine(destinationFolder, ACB_AWB_EXTRACTION_FOLDER);
            string extAwbDestinationFolder = Path.Combine(destinationFolder, EXT_AWB_EXTRACTION_FOLDER);
            string acbCpkDestinationFolder = Path.Combine(destinationFolder, ACB_CPK_EXTRACTION_FOLDER);
            string extCpkDestinationFolder = Path.Combine(destinationFolder, EXT_CPK_EXTRACTION_FOLDER);

            try
            {
                // open streams
                if (this.InternalAwb != null)
                {
                    internalFs = File.Open(this.InternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                else if (this.InternalCpk != null)
                {
                    internalFs = File.Open(this.InternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                }

                if (this.ExternalAwb != null)
                {
                    externalFs = File.Open(this.ExternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
                else if (this.ExternalCpk != null)
                {
                    externalFs = File.Open(this.ExternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                }

                // loop through cues and extract
                for (int i = 0; i < CueList.Length; i++)
                {
                    CriAcbCueRecord cue = CueList[i];

                    if (cue.IsWaveformIdentified)
                    {
                        if (cue.IsStreaming) // external AWB file
                        {
                            if (this.ExternalAwb != null)
                            {
                                ParseFile.ExtractChunkToFile64(externalFs,
                                                               (ulong)this.ExternalAwb.Files[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.ExternalAwb.Files[cue.WaveformId].FileLength,
                                                               Path.Combine(extAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }
                            else if (this.ExternalCpk != null)
                            {
                                ParseFile.ExtractChunkToFile64(externalFs,
                                                               (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileLength,
                                                               Path.Combine(extCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }

                            externalIdsExtracted.Add(cue.WaveformId);
                        }
                        else // internal AWB file (inside ACB)
                        {
                            if (this.InternalAwb != null)
                            {
                                ParseFile.ExtractChunkToFile64(internalFs,
                                                               (ulong)this.InternalAwb.Files[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.InternalAwb.Files[cue.WaveformId].FileLength,
                                                               Path.Combine(acbAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }
                            else if (this.InternalCpk != null)
                            {
                                ParseFile.ExtractChunkToFile64(internalFs,
                                                               (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned,
                                                               (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileLength,
                                                               Path.Combine(acbCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false);
                            }

                            internalIdsExtracted.Add(cue.WaveformId);
                        }
                    } // if (cue.IsWaveformIdentified)
                }

                // extract leftovers
                using (FileStream acbStream = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    waveformTableUtf = new CriUtfTable();
                    waveformTableUtf.Initialize(acbStream, (long)this.WaveformTableOffset);
                }

                if (this.ExternalAwb != null)
                {
                    var unextractedExternalFiles = this.ExternalAwb.Files.Keys.Where(x => !externalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedExternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.ExternalAwb.SourceFile), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(externalFs,
                                                       (ulong)this.ExternalAwb.Files[key].FileOffsetByteAligned,
                                                       (ulong)this.ExternalAwb.Files[key].FileLength,
                                                       Path.Combine(extAwbDestinationFolder, rawFileName), false, false);
                    }
                }
                else if (this.ExternalCpk != null)
                {
                    var unextractedExternalFiles = this.ExternalCpk.ItocFiles.Keys.Where(x => !externalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedExternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.ExternalCpk.SourceFileName), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(externalFs,
                                                       (ulong)this.ExternalCpk.ItocFiles[key].FileOffsetByteAligned,
                                                       (ulong)this.ExternalCpk.ItocFiles[key].FileLength,
                                                       Path.Combine(extCpkDestinationFolder, rawFileName), false, false);
                    }
                }

                if (this.InternalAwb != null)
                {
                    var unextractedInternalFiles = this.InternalAwb.Files.Keys.Where(x => !internalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedInternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.InternalAwb.SourceFile), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(internalFs,
                                                       (ulong)this.InternalAwb.Files[key].FileOffsetByteAligned,
                                                       (ulong)this.InternalAwb.Files[key].FileLength,
                                                       Path.Combine(acbAwbDestinationFolder, rawFileName), false, false);
                    }
                }
                else if (this.InternalCpk != null)
                {
                    var unextractedInternalFiles = this.InternalCpk.ItocFiles.Keys.Where(x => !internalIdsExtracted.Contains(x));
                    foreach (ushort key in unextractedInternalFiles)
                    {
                        waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false);

                        encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType");

                        rawFileName = String.Format(rawFileFormat,
                                                    Path.GetFileName(this.InternalCpk.SourceFileName), key.ToString("D5"),
                                                    CriAcbFile.GetFileExtensionForEncodeType(encodeType));

                        // extract file
                        ParseFile.ExtractChunkToFile64(internalFs,
                                                       (ulong)this.InternalCpk.ItocFiles[key].FileOffsetByteAligned,
                                                       (ulong)this.InternalCpk.ItocFiles[key].FileLength,
                                                       Path.Combine(acbCpkDestinationFolder, rawFileName), false, false);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (internalFs != null)
                {
                    internalFs.Close();
                    internalFs.Dispose();
                }

                if (externalFs != null)
                {
                    externalFs.Close();
                    externalFs.Dispose();
                }
            }
        }
예제 #13
0
        protected void InitializeCueList(FileStream fs)
        {
            this.CueNamesToWaveforms = new Dictionary <string, ushort>();

            ulong referenceItemsOffset = 0;
            ulong referenceItemsSize   = 0;
            ulong referenceCorrection  = 0;

            object dummy;
            byte   isStreaming = 0;

            CriUtfTable cueTableUtf = new CriUtfTable();

            cueTableUtf.Initialize(fs, (long)this.CueTableOffset);

            CriUtfTable waveformTableUtf = new CriUtfTable();

            waveformTableUtf.Initialize(fs, (long)this.WaveformTableOffset);

            CriUtfTable synthTableUtf = new CriUtfTable();

            synthTableUtf.Initialize(fs, (long)this.SynthTableOffset);

            this.CueList = new CriAcbCueRecord[cueTableUtf.NumberOfRows];

            for (int i = 0; i < cueTableUtf.NumberOfRows; i++)
            {
                this.CueList[i] = new CriAcbCueRecord();
                this.CueList[i].IsWaveformIdentified = false;

                this.CueList[i].CueId          = (uint)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "CueId");
                this.CueList[i].ReferenceType  = (byte)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceType");
                this.CueList[i].ReferenceIndex = (ushort)CriUtfTable.GetUtfFieldForRow(cueTableUtf, i, "ReferenceIndex");

                switch (this.CueList[i].ReferenceType)
                {
                case 2:
                    referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                    referenceCorrection  = referenceItemsSize + 2;
                    break;

                case 3:
                case 8:
                    if (i == 0)
                    {
                        referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceItemsSize   = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, 0, "ReferenceItems");
                        referenceCorrection  = referenceItemsSize - 2;    // samples found have only had a '01 00' record => Always Waveform[0]?.
                    }
                    else
                    {
                        referenceCorrection += 4;     // relative to previous offset, do not lookup
                                                      // @TODO: Should this do a referenceItemsSize - 2 for the ReferenceIndex?  Need to find
                                                      //    one where size > 4.
                        //referenceItemsOffset = (ulong)CriUtfTable.GetOffsetForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceItemsSize = CriUtfTable.GetSizeForUtfFieldForRow(synthTableUtf, this.CueList[i].ReferenceIndex, "ReferenceItems");
                        //referenceCorrection = referenceItemsSize - 2;
                    }
                    break;

                default:
                    throw new FormatException(String.Format("  Unexpected ReferenceType: '{0}' for CueIndex: '{1}.'  Please report to VGMToolbox thread at hcs64.com forums, see link in 'Other' menu item.", this.CueList[i].ReferenceType.ToString("D"), i.ToString("D")));
                }

                if (referenceItemsSize != 0)
                {
                    // get wave form info
                    this.CueList[i].WaveformIndex = ParseFile.ReadUshortBE(fs, (long)(referenceItemsOffset + referenceCorrection));

                    // get Streaming flag, 0 = in ACB files, 1 = in AWB file
                    dummy = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Streaming");

                    if (dummy != null) // check to see if this Id actually exists in the WaveformIndex
                    {
                        isStreaming = (byte)dummy;
                        this.CueList[i].IsStreaming = isStreaming == 0 ? false : true;

                        // get waveform id and encode type from corresponding waveform
                        var waveformId = CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "Id");

                        if (waveformId != null)
                        {
                            // early revisions of ACB spec used "Id"
                            this.CueList[i].WaveformId = (ushort)waveformId;
                        }
                        else
                        {
                            // later versions using "MemoryAwbId" and  "StreamingAwbId"
                            if (this.CueList[i].IsStreaming)
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "StreamAwbId");
                            }
                            else
                            {
                                this.CueList[i].WaveformId = (ushort)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "MemoryAwbId");
                            }
                        }

                        this.CueList[i].EncodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, this.CueList[i].WaveformIndex, "EncodeType");


                        // update flag
                        this.CueList[i].IsWaveformIdentified = true;
                    } // if (dummy != null)
                }
            }
        }
예제 #14
0
        public string GetStringValue(int currentIdent,
                                     FileStream utfStream = null,
                                     bool useIncomingKeys = false,
                                     Dictionary <string, byte> lcgEncryptionKeys = null)
        {
            ulong  numericValue;
            long   signedNumericValue;
            byte   maskedType  = (byte)(this.Type & CriUtfTable.COLUMN_TYPE_MASK);
            string stringValue = String.Empty;

            string frontPad = new string(' ', currentIdent);
            string formattedString;

            switch (maskedType)
            {
            case CriUtfTable.COLUMN_TYPE_DATA:
                if (utfStream == null)
                {
                    stringValue = this.Value.ToString();
                }
                else if (CriUtfTable.IsUtfTable(utfStream, (long)this.Offset, useIncomingKeys, lcgEncryptionKeys))
                {
                    CriUtfTable newUtf = new CriUtfTable();
                    newUtf.Initialize(utfStream, (long)this.Offset);
                    stringValue = newUtf.GetTableAsString((currentIdent + 4), true);
                }
                else
                {
                    stringValue = FileUtil.GetStringFromFileChunk(utfStream, this.Offset, this.Size);

                    if (stringValue.Length > 0x20)
                    {
                        formattedString = Regex.Replace(stringValue, ".{8}(?!$)", "$0 ");
                        stringValue     = Environment.NewLine + formattedString;
                    }
                }

                break;

            case CriUtfTable.COLUMN_TYPE_STRING:
                stringValue = (string)this.Value;
                break;

            case CriUtfTable.COLUMN_TYPE_FLOAT:
                stringValue = Convert.ToSingle(this.Value).ToString();
                break;

            case CriUtfTable.COLUMN_TYPE_8BYTE:
            case CriUtfTable.COLUMN_TYPE_4BYTE:
            case CriUtfTable.COLUMN_TYPE_2BYTE:
            case CriUtfTable.COLUMN_TYPE_1BYTE:
                numericValue = Convert.ToUInt64(this.Value);
                stringValue  = String.Format("0x{0} ({1})", numericValue.ToString("X8"), numericValue.ToString());
                break;

            case CriUtfTable.COLUMN_TYPE_4BYTE2:
            case CriUtfTable.COLUMN_TYPE_2BYTE2:
            case CriUtfTable.COLUMN_TYPE_1BYTE2:
                signedNumericValue = Convert.ToInt64(this.Value);
                stringValue        = String.Format("0x{0} ({1})", signedNumericValue.ToString("X8"), signedNumericValue.ToString());
                break;
            }

            return(stringValue);
        }
예제 #15
0
        public void Initialize(FileStream fs, long offset, bool isRawDump)
        {
            this.FormatDescription = CriCpkArchive.FORMAT_DESCRIPTION_STRING;

            this.VolumeBaseOffset        = offset;
            this.IsRawDump               = isRawDump;
            this.VolumeType              = VolumeDataType.Data;
            this.DirectoryStructureArray = new ArrayList();

            this.SourceFileName = fs.Name;

            CriUtfTable cpkUtf = new CriUtfTable();

            cpkUtf.Initialize(fs, this.VolumeBaseOffset + 0x10);

            this.VolumeIdentifier = cpkUtf.TableName;

            this.ItocFiles = new Dictionary <ushort, CriAfs2File>();

            this.TocUtf = InitializeToc(fs, cpkUtf, "TocOffset");
            // this.EtocUtf = InitializeToc(fs, cpkUtf, "EtocOffset");
            this.ItocUtf = InitializeToc(fs, cpkUtf, "ItocOffset");
            // this.GtocUtf = InitializeToc(fs, cpkUtf, "GtocOffset");



            CriCpkDirectory dummy = new CriCpkDirectory(this.SourceFileName, String.Empty, String.Empty);

            if (this.TocUtf != null)
            {
                CriCpkDirectory tocDir = this.GetDirectoryForToc(fs, cpkUtf, "TOC", this.VolumeBaseOffset);

                if ((tocDir.FileArray.Count > 0) || (tocDir.SubDirectoryArray.Count > 0))
                {
                    dummy.SubDirectoryArray.Add(tocDir);
                }
            }

            /*
             * if (etocUtf != null)
             * {
             *  CriCpkDirectory etocDir = this.GetDirectoryForToc(fs, cpkUtf, etocUtf, "ETOC");
             *
             *  if ((etocDir.FileArray.Count > 0) || (etocDir.SubDirectoryArray.Count > 0))
             *  {
             *      dummy.SubDirectoryArray.Add(etocDir);
             *  }
             * }
             */

            if (this.ItocUtf != null)
            {
                CriCpkDirectory itocDir = this.GetDirectoryForItoc(fs, cpkUtf, "ITOC", this.VolumeBaseOffset);

                if ((itocDir.FileArray.Count > 0) || (itocDir.SubDirectoryArray.Count > 0))
                {
                    dummy.SubDirectoryArray.Add(itocDir);
                }
            }


            //if (this.GtocUtf != null)
            //{
            //    CriCpkDirectory gtocDir = this.GetDirectoryForGtoc(fs, cpkUtf, "GTOC");

            //    if ((gtocDir.FileArray.Count > 0) || (gtocDir.SubDirectoryArray.Count > 0))
            //    {
            //        dummy.SubDirectoryArray.Add(gtocDir);
            //    }
            //}


            this.DirectoryStructureArray.Add(dummy);
        }
예제 #16
0
        public CriCpkDirectory GetDirectoryForItoc(FileStream fs, CriUtfTable cpkUtf, string BaseDirectoryName, long volumeBaseOffset)
        {
            ulong             currentOffset = 0;
            CriUtfTocFileInfo fileInfo      = new CriUtfTocFileInfo();
            CriAfs2File       afs2File      = new CriAfs2File();

            // get content offset and align
            ulong  contentOffset = (ulong)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "ContentOffset");
            ushort align         = (ushort)CriUtfTable.GetUtfFieldForRow(cpkUtf, 0, "Align");

            // build direcory path
            CriCpkDirectory baseDirectory = new CriCpkDirectory(this.SourceFileName, BaseDirectoryName, String.Empty);
            CriCpkFile      tempFile;

            // read file groups
            uint   filesH    = 0;
            uint   filesL    = 0;
            object filesHObj = CriUtfTable.GetUtfFieldForRow(this.ItocUtf, 0, "FilesH"); //count of files in DataH
            object filesLObj = CriUtfTable.GetUtfFieldForRow(this.ItocUtf, 0, "FilesL"); // count of files in DataL

            if (filesHObj != null)
            {
                filesH = (uint)filesHObj;
            }

            if (filesHObj != null)
            {
                filesL = (uint)filesLObj;
            }

            if ((filesH > 0) || (filesL > 0))
            {
                Dictionary <string, CriUtfTocFileInfo> fileList = new Dictionary <string, CriUtfTocFileInfo>();

                if (filesH > 0)
                {
                    // read DataH group
                    CriUtfTable dataH = new CriUtfTable();
                    dataH.Initialize(fs, (long)CriUtfTable.GetOffsetForUtfFieldForRow(this.ItocUtf, 0, "DataH"));

                    for (int i = 0; i < dataH.Rows.GetLength(0); i++)
                    {
                        fileInfo = GetUtfItocFileInfo(dataH, i);
                        fileList.Add(fileInfo.FileName, fileInfo);
                    }
                }

                if (filesL > 0)
                {
                    // read DataL group
                    CriUtfTable dataL = new CriUtfTable();
                    dataL.Initialize(fs, (long)CriUtfTable.GetOffsetForUtfFieldForRow(this.ItocUtf, 0, "DataL"));

                    for (int i = 0; i < dataL.Rows.GetLength(0); i++)
                    {
                        fileInfo = GetUtfItocFileInfo(dataL, i);
                        fileList.Add(fileInfo.FileName, fileInfo);
                    }
                }

                // initialize current offset
                currentOffset = contentOffset;

                // populate offsets for files
                var keys = fileList.Keys.ToList();
                keys.Sort();

                foreach (string key in keys)
                {
                    // afs2 file for ACB extraction
                    afs2File               = new CriAfs2File();
                    afs2File.CueId         = Convert.ToUInt16(fileList[key].FileName); // ??? @TODO maybe key is enough?  need to check.
                    afs2File.FileOffsetRaw = volumeBaseOffset + (long)currentOffset;

                    // align offset
                    if (currentOffset % align != 0)
                    {
                        currentOffset = MathUtil.RoundUpToByteAlignment(currentOffset, align);
                    }

                    // update file info
                    fileList[key].FileOffset = (ulong)volumeBaseOffset + currentOffset;
                    fileList[key].FileName  += ".bin";

                    // afs2 file for ACB extraction
                    afs2File.FileOffsetByteAligned = (long)fileList[key].FileOffset;
                    afs2File.FileLength            = fileList[key].FileSize;

                    // increment current offset
                    currentOffset += fileList[key].FileSize;

                    // create file and add to base directory
                    tempFile = new CriCpkFile(BaseDirectoryName, this.SourceFileName, fileList[key].FileName,
                                              (long)fileList[key].FileOffset, this.VolumeBaseOffset, (long)fileList[key].FileOffset,
                                              fileList[key].FileSize, fileList[key].ExtractSize);

                    baseDirectory.FileArray.Add(tempFile);

                    // add afs2 file to ItocFiles for ACB extraction
                    this.ItocFiles.Add(afs2File.CueId, afs2File);
                } // foreach (string key in keys)
            }     // if ((filesH > 0) || (filesL > 0))


            return(baseDirectory);
        }
예제 #17
0
        public CriCpkDirectory GetDirectoryForToc(FileStream fs, CriUtfTable cpkUtf, string BaseDirectoryName, long volumeBaseOffset)
        {
            CriUtfTocFileInfo fileInfo = new CriUtfTocFileInfo();

            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();

            CriCpkDirectory baseDirectory = new CriCpkDirectory(this.SourceFileName, BaseDirectoryName, String.Empty);
            CriCpkDirectory newDirectory;
            CriCpkDirectory currentDirectory;
            int             indexOfNewDirectory;

            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);
        }