コード例 #1
0
            private Stream GetIdxStreamWhichContainsTargetedFile(List <Idx.Entry> idxEntries, Stream imgStream, string fileName)
            {
                var idxDictionary = new IdxDictionary {
                    idxEntries
                };

                foreach (var innerIdx in Img.InternalIdxs)
                {
                    if (idxDictionary.TryGetEntry(innerIdx, out var innerIdxEntry))
                    {
                        var innerIdxStream     = OpenIsoSubStream(imgStream, innerIdxEntry.Offset, innerIdxEntry.Length);
                        var innerIdxDictionary = new IdxDictionary
                        {
                            Idx.Read(innerIdxStream)
                        };

                        if (innerIdxDictionary.Exists(fileName))
                        {
                            return(innerIdxStream);
                        }
                    }
                }

                return(null);
            }
コード例 #2
0
ファイル: IdxTests.cs プロジェクト: Fotia13/OpenKh
        public void WriteIdxEntry() => Helpers.AssertStream(CreateMockIdxStream(1, 2, 3, 4, 5), stream =>
        {
            var outStream = new MemoryStream();
            Idx.Write(outStream, Idx.Read(stream));

            return(outStream);
        });
コード例 #3
0
        private static IEnumerable <Idx.Entry> OpenIdx(string fileName)
        {
            using var idxStream = File.OpenRead(fileName);
            if (!Idx.IsValid(idxStream))
            {
                throw new CustomException($"The IDX {fileName} is invalid or not recognized.");
            }

            return(Idx.Read(idxStream));
        }
コード例 #4
0
        private static IEnumerable <EntryViewModel> GetChildren(string idxName, IIdxManager idxManager)
        {
            var idxStream = idxManager.OpenFileFromIdx(idxName);

            if (idxStream == null)
            {
                return(new EntryViewModel[0]);
            }

            using (idxStream)
            {
                return(EntryParserModel.GetChildren(Idx.Read(idxStream), idxManager));
            }
        }
コード例 #5
0
ファイル: Kh2Utilities.cs プロジェクト: xorllc/OpenKh
        public static List <Msg.Entry> ReadMsgFromIdx(Stream idxStream, Stream imgStream)
        {
            var img = new Img(imgStream, Idx.Read(idxStream), false);

            foreach (var language in Constants.Regions)
            {
                var stream = img.FileOpen($"msg/{language}/sys.bar");
                if (stream != null)
                {
                    return(ReadMsgFromBar(stream));
                }
            }

            throw new FileNotFoundException($"Unable to find a 'sys.bar' between the supported languages.");
        }
コード例 #6
0
            protected int OnExecute(CommandLineApplication app)
            {
                const long EsitmatedMaximumImgFileSize             = 4L * 1024 * 1024 * 1024; // 4GB
                const int  EsitmatedMaximumIdxFileSize             = 600 * 1024;              // 600KB
                const int  EstimatedMaximumIdxEntryAmountToBeValid = EsitmatedMaximumIdxFileSize / 0x10 - 4;

                using var isoStream = File.Open(InputIso, FileMode.Open, FileAccess.ReadWrite);


                if (IdxIsoBlock == -1 || ImgIsoBlock == -1)
                {
                    const int needleLength = 0x0B;

                    var imgNeedle = new byte[needleLength] {
                        0x01, 0x09, 0x4B, 0x48, 0x32, 0x2E, 0x49, 0x4D, 0x47, 0x3B, 0x31
                    };
                    var idxNeedle = new byte[needleLength] {
                        0x01, 0x09, 0x4B, 0x48, 0x32, 0x2E, 0x49, 0x44, 0x58, 0x3B, 0x31
                    };

                    const uint basePosition = 0x105 * 0x800;

                    for (int i = 0; i < 0x500; i++)
                    {
                        isoStream.Position = basePosition + i;
                        var hayRead = isoStream.ReadBytes(needleLength);

                        var idxCmp = hayRead.SequenceEqual(idxNeedle);
                        var imgCmp = hayRead.SequenceEqual(imgNeedle);

                        if (imgCmp || idxCmp)
                        {
                            isoStream.Position -= 0x24;

                            var blockStack   = isoStream.ReadBytes(0x04);
                            var blockCorrect = new byte[0x04] {
                                blockStack[3], blockStack[2], blockStack[1], blockStack[0]
                            };

                            if (idxCmp && IdxIsoBlock == -1)
                            {
                                IdxIsoBlock = BitConverter.ToInt32(blockCorrect);
                            }

                            else if (imgCmp && ImgIsoBlock == -1)
                            {
                                ImgIsoBlock = BitConverter.ToInt32(blockCorrect);
                            }
                        }
                    }

                    if (IdxIsoBlock == -1 || ImgIsoBlock == -1)
                    {
                        throw new IOException("Could not determine the LBA Offsets of KH2.IDX or KH2.IMG, is this ISO valid?");
                    }
                }

                var idxStream = OpenIsoSubStream(isoStream, IdxIsoBlock, EsitmatedMaximumIdxFileSize);

                using var imgStream = OpenIsoSubStream(isoStream, ImgIsoBlock, EsitmatedMaximumImgFileSize);

                var idxEntryCount = idxStream.ReadInt32();

                if (idxEntryCount > EstimatedMaximumIdxEntryAmountToBeValid)
                {
                    throw new CustomException("There is a high chance that the IDX block is not valid, therefore the injection will terminate to avoid corruption.");
                }

                var idxEntries = Idx.Read(idxStream.SetPosition(0));
                var entry      = idxEntries.FirstOrDefault(x => x.Hash32 == Idx.GetHash32(FilePath) && x.Hash16 == Idx.GetHash16(FilePath));

                if (entry == null)
                {
                    idxStream = GetIdxStreamWhichContainsTargetedFile(idxEntries, imgStream, FilePath);
                    if (idxStream == null)
                    {
                        throw new CustomException($"The file {FilePath} has not been found inside the KH2.IDX, therefore the injection will terminate.");
                    }

                    idxEntries = Idx.Read(idxStream.SetPosition(0));
                    entry      = idxEntries.FirstOrDefault(x => x.Hash32 == Idx.GetHash32(FilePath) && x.Hash16 == Idx.GetHash16(FilePath));
                }

                var inputData          = File.ReadAllBytes(InputFile);
                var decompressedLength = inputData.Length;

                if (Uncompressed == false)
                {
                    inputData = Img.Compress(inputData);
                }

                var blockCountRequired = (inputData.Length + 0x7ff) / 0x800 - 1;

                if (blockCountRequired > entry.BlockLength)
                {
                    throw new CustomException($"The file to inject is too big: the actual is {inputData.Length} but the maximum allowed is {GetLength(entry.BlockLength)}.");
                }

                imgStream.SetPosition(GetOffset(entry.Offset));
                // Clean completely the content of the previous file to not mess up the decompression
                imgStream.Write(new byte[GetLength(entry.BlockLength)]);

                imgStream.SetPosition(GetOffset(entry.Offset));
                imgStream.Write(inputData);

                entry.IsCompressed = !Uncompressed;
                entry.Length       = decompressedLength;
                // we are intentionally not patching entry.BlockLength because it would not allow to insert back bigger files.

                Idx.Write(idxStream.SetPosition(0), idxEntries);

                return(0);
            }
コード例 #7
0
ファイル: KingdomHearts2.cs プロジェクト: tommadness/OpenKh
                protected int OnExecute(CommandLineApplication app)
                {
                    const long EsitmatedMaximumImgFileSize             = 4L * 1024 * 1024 * 1024; // 4GB
                    const int  EsitmatedMaximumIdxFileSize             = 600 * 1024;              // 600KB
                    const int  EstimatedMaximumIdxEntryAmountToBeValid = EsitmatedMaximumIdxFileSize / 0x10 - 4;

                    using var isoStream = File.Open(InputIso, FileMode.Open, FileAccess.ReadWrite);


                    if (IdxIsoBlock == -1 || ImgIsoBlock == -1)
                    {
                        var bufferedStream = new BufferedStream(isoStream);
                        IdxIsoBlock = IsoUtility.GetFileOffset(bufferedStream, "KH2.IDX;1");
                        ImgIsoBlock = IsoUtility.GetFileOffset(bufferedStream, "KH2.IMG;1");

                        if (IdxIsoBlock == -1 || ImgIsoBlock == -1)
                        {
                            throw new IOException("Could not determine the LBA Offsets of KH2.IDX or KH2.IMG, is this ISO valid?");
                        }
                    }

                    var idxStream = OpenIsoSubStream(isoStream, IdxIsoBlock, EsitmatedMaximumIdxFileSize);

                    using var imgStream = OpenIsoSubStream(isoStream, ImgIsoBlock, EsitmatedMaximumImgFileSize);

                    var idxEntryCount = idxStream.ReadInt32();

                    if (idxEntryCount > EstimatedMaximumIdxEntryAmountToBeValid)
                    {
                        throw new CustomException("There is a high chance that the IDX block is not valid, therefore the injection will terminate to avoid corruption.");
                    }

                    var idxEntries = Idx.Read(idxStream.SetPosition(0));
                    var entry      = idxEntries.FirstOrDefault(x => x.Hash32 == Idx.GetHash32(FilePath) && x.Hash16 == Idx.GetHash16(FilePath));

                    if (entry == null)
                    {
                        idxStream = GetIdxStreamWhichContainsTargetedFile(idxEntries, imgStream, FilePath);
                        if (idxStream == null)
                        {
                            throw new CustomException($"The file {FilePath} has not been found inside the KH2.IDX, therefore the injection will terminate.");
                        }

                        idxEntries = Idx.Read(idxStream.SetPosition(0));
                        entry      = idxEntries.FirstOrDefault(x => x.Hash32 == Idx.GetHash32(FilePath) && x.Hash16 == Idx.GetHash16(FilePath));
                    }

                    var inputData          = File.ReadAllBytes(InputFile);
                    var decompressedLength = inputData.Length;

                    if (Uncompressed == false)
                    {
                        inputData = Img.Compress(inputData);
                    }

                    var blockCountRequired = (inputData.Length + 0x7ff) / 0x800 - 1;

                    if (blockCountRequired > entry.BlockLength)
                    {
                        throw new CustomException($"The file to inject is too big: the actual is {inputData.Length} but the maximum allowed is {GetLength(entry.BlockLength)}.");
                    }

                    imgStream.SetPosition(GetOffset(entry.Offset));
                    // Clean completely the content of the previous file to not mess up the decompression
                    imgStream.Write(new byte[GetLength(entry.BlockLength)]);

                    imgStream.SetPosition(GetOffset(entry.Offset));
                    imgStream.Write(inputData);

                    entry.IsCompressed = !Uncompressed;
                    entry.Length       = decompressedLength;
                    // we are intentionally not patching entry.BlockLength because it would not allow to insert back bigger files.

                    Idx.Write(idxStream.SetPosition(0), idxEntries);

                    return(0);
                }
コード例 #8
0
ファイル: Program.cs プロジェクト: Some1fromthedark/OpenKh
 private static Idx OpenIdx(string fileName)
 {
     using (var idxStream = File.OpenRead(fileName))
         return(Idx.Read(idxStream));
 }
コード例 #9
0
 public IdxDataContent(Stream idxStream, Stream imgStream)
 {
     _idx = Idx.Read(idxStream);
     _img = new Img(imgStream, _idx, false);
 }