Ejemplo n.º 1
0
                protected int OnExecute(CommandLineApplication app)
                {
                    var outputDir = OutputDir ?? Path.Combine(Path.GetDirectoryName(InputIso), "extract");

                    using var stream = File.OpenRead(InputIso);

                    var firstBlock = IsoUtility.GetFileOffset(stream, "SYSTEM.CNF;1");

                    if (firstBlock == -1)
                    {
                        throw new IOException("The file specified seems to not be a valid PlayStation 2 ISO.");
                    }

                    var kingdomIdxBlock = IsoUtility.GetFileOffset(stream, "KINGDOM.IDX;1");

                    if (kingdomIdxBlock == -1)
                    {
                        throw new IOException("The file specified seems to not be a Kingdom Hearts 1 ISO");
                    }

                    var idx = Idx1.Read(stream.SetPosition(kingdomIdxBlock * IsoBlockAlign));
                    var img = new Img1(stream, idx, firstBlock);

                    ExtractIdx(img, outputDir, DoNotExtractAgain);
                    return(0);
                }
Ejemplo n.º 2
0
                protected int OnExecute(CommandLineApplication app)
                {
                    using var stream = File.OpenRead(InputIso);

                    var firstBlock = IsoUtility.GetFileOffset(stream, "SYSTEM.CNF;1");

                    if (firstBlock == -1)
                    {
                        throw new IOException("The file specified seems to not be a valid PlayStation 2 ISO.");
                    }

                    var kingdomIdxBlock = IsoUtility.GetFileOffset(stream, "KINGDOM.IDX;1");

                    if (kingdomIdxBlock == -1)
                    {
                        throw new IOException("The file specified seems to not be a Kingdom Hearts 1 ISO");
                    }

                    var idx = Idx1.Read(stream.SetPosition(kingdomIdxBlock * IsoBlockAlign));

                    foreach (var entry in idx.OrderBy(x => x.IsoBlock))
                    {
                        Console.WriteLine(Idx1Name.Lookup(entry) ?? $"@{entry.Hash:X08}");
                    }

                    return(0);
                }
Ejemplo n.º 3
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)
                    {
                        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);
                }