示例#1
0
 /// <summary>Read a file from the ISO</summary>
 /// <param name="entry">IDX entry describing the file</param>
 /// <returns>Byte array of the file</returns>
 /// <exception cref="System.Exception">Thrown when file is too large</exception>
 public byte[] readFile(IDXEntry entry)
 {
     if (entry.size > 0x7FFFFFFF)
     {
         throw new Exception("File too large to read");
     }
     iso.Position = dataOffset + (2048 * entry.LBA);
     return(br.ReadBytes((int)entry.size));
 }
示例#2
0
        /// <summary>Copy file from <c>origISO</c> to <c>iso</c></summary>
        /// <param name="hash">Hash of filename</param>
        /// <exception cref="System.Exception">Thrown when no matching hash is found in <c>origISO</c></exception>
        public void copyFile(UInt32 hash)
        {
            IDXEntry entry = origISO.idxEntries.Find(a => a.hash == hash);

            if (entry == null)
            {
                throw new Exception("Failed to find IDX entry in original ISO");
            }
            copyFile(entry);
        }
示例#3
0
        /// <summary>Relinks one file to another, so they share the same data</summary>
        /// <param name="sHash">Source file; What to relink</param>
        /// <param name="tHash">Target file; What to relink to</param>
        /// <returns>True if the relink is done, False if it was queued</returns>
        public bool addRelink(UInt32 sHash, UInt32 tHash)
        {
            IDXEntry t = idxEntries.Find(a => a.hash == tHash);

            if (t != null)
            {
                idxEntries.Add(new IDXEntry(sHash, t.flags, t.LBA, t.size));
                return(true);
            }
            idxRelinks.Add(sHash, tHash);
            return(false);
        }
示例#4
0
        /// <summary>Copy file from <c>origISO</c> to <c>iso</c></summary>
        /// <param name="entry">IDX entry describing the file in <c>origISO</c></param>
        /// <exception cref="System.ObjectDisposedException">Thrown when ISO has been finalized</exception>
        /// <exception cref="System.Exception">Thrown when <c>origISO</c> isn't set</exception>
        /// <exception cref="System.Exception">Thrown when <c>entry</c> isn't in <c>origISO</c></exception>
        public void copyFile(IDXEntry entry)
        {
            if (finalized)
            {
                throw new ObjectDisposedException("ISO has been finalized");
            }
            if (origISO == null)
            {
                throw new Exception("No original ISO to copy from");
            }
            if (!origISO.idxEntries.Contains(entry))
            {
                throw new Exception("IDX entry not in original ISO");
            }
            long pos     = iso.Position,
                 padding = (entry.size % 2048) == 0 ? 0 : (2048 - (entry.size % 2048));

            idxEntries.Add(new IDXEntry(entry.hash, entry.flags, (UInt32)(pos - dataOffset) / 2048, entry.size));
            copyBytes(entry.size + padding, origISO.dataOffset + entry.LBA * 2048);
            updateISOFileInfo(entry.hash, pos, entry.size);
        }
示例#5
0
 private static void ExtractIDX(KH1ISOReader input, string tfolder = "export/")
 {
     for (int i = 0, idxC = input.idxEntries.Count; i < idxC; ++i)
     {
         IDXEntry entry      = input.idxEntries[i];
         bool     compressed = entry.flags == 1;
         string   name2;
         if (!HashList.pairs.TryGetValue(entry.hash, out name2))
         {
             name2 = String.Format("@noname/{0:x8}.bin", entry.hash);
         }
         if (name2 == "system.cnf")
         {
             continue;
         }
         if (name2 == "SLPS_251.98")
         {
             continue;
         }
         if (name2 == "ioprp250.img")
         {
             continue;
         }
         if (name2 == "sio2man.irx")
         {
             continue;
         }
         if (name2 == "sio2d.irx")
         {
             continue;
         }
         if (name2 == "dbcman.irx")
         {
             continue;
         }
         if (name2 == "ds2o.irx")
         {
             continue;
         }
         if (name2 == "mcman.irx")
         {
             continue;
         }
         if (name2 == "mcserv.irx")
         {
             continue;
         }
         if (name2 == "libsd.irx")
         {
             continue;
         }
         if (name2 == "libssl.irx")
         {
             continue;
         }
         if (name2 == "dev9.irx")
         {
             continue;
         }
         if (name2 == "atad.irx")
         {
             continue;
         }
         if (name2 == "hdd.irx")
         {
             continue;
         }
         if (name2 == "pfs.irx")
         {
             continue;
         }
         if (name2 == "kingdom.idx")
         {
             continue;
         }
         if (name2 == "kingdom.img")
         {
             continue;
         }
         var idxs = new List <Tuple <IDXFile, string> >();
         if (_advanced)
         {
             Console.WriteLine("-----------File {0,4}/{1}, using KINGDOM.IDX\n", i, input.idxEntries.Count - 1);
             Console.WriteLine("Hashed filename: {0}", entry.hash);
             Console.WriteLine("Compression flags: {0}", compressed);
             Console.WriteLine("Size (packed): {0}", entry.size);
             Console.WriteLine("Real name: {0}", name2);
         }
         else
         {
             Console.WriteLine("[KINGDOM: {0,4}/{1}]\tExtracting {2}", i, input.idxEntries.Count - 1, name2);
         }
         string filename = tfolder + "/KINGDOM/" + name2;
         Directory.CreateDirectory(Path.GetDirectoryName(filename));
         bool   adSize = _advanced;
         byte[] file   = input.readFile(entry);
         if (compressed)
         {
             if (entry.size > int.MaxValue)
             {
                 throw new NotSupportedException("File to big to decompress");
             }
             try
             {
                 byte[] decompressed = KH1Compressor.decompress(file, adSize);
                 File.WriteAllBytes(filename, decompressed);
             }
             catch (Exception e)
             {
                 WriteError(" ERROR: Failed to decompress: " + e.Message);
             }
         }
         else
         {
             File.WriteAllBytes(filename, file);
         }
     }
 }
示例#6
0
        private static void PatchISO(KH1ISOReader input, KH1ISOWriter output, PatchManager files, bool ocompress,
                                     string oextHead)
        {
            int number = 1;

            output.writeHeader(oextHead);//Let's copy the header
            //Console.WriteLine("Adding header using {0} source",  ? "external" : "internal");//TODO: Delete this Console.WriteLine
            for (int i = 0, idxC = input.idxEntries.Count; i < idxC; ++i)
            {
                IDXEntry entry = input.idxEntries[i];
                if (entry.hash == 0x0392ebe4)
                {
                    continue;
                } //kingdom.img

                if (entry.hash == 0x0393eba4) //kingdom.idx
                {
                    Console.WriteLine("[KINGDOM: {0}/{1}]\tKINGDOM.IDX", number, input.idxEntries.Count - 1);
                    //-1 'cause of the file KINGDOM.IMG
                    number++;
                    output.writeDummyIDX(idxC);
                    continue;
                }

                //Loading the patch
                UInt32             flags = 0;
                PatchManager.Patch patch;
                Stream             s = null;
                uint h = 0;
                // Could make sure the parents match perfectly, but there's only 1 of every name anyway.
                // So I'll settle for just making sure the file isn't made for the ISO.
                if (Patches.patches.TryGetValue(entry.hash, out patch) && /*patch.Parent == parenthash*/ !patch.IsinISO)
                {
                    s = patch.Stream; h = patch.Hash;
                }
                string name;
                if (!HashList.pairs.TryGetValue(entry.hash, out name))
                {
                    name = String.Format("@noname/{0:x8}.bin", entry.hash);
                }
                if (s == null)
                {
                    flags = entry.flags;//FLAGS NEEDS TO BE OR 0 IF NOTHING, OR 1 IF COMPRESSED, OR THE NAME TO RELINK TO IF IT NEEDS TO

                    if (h != 0)
                    {
                        if (patch.Compressed)
                        {
                            flags = 1;
                        }
                        else if (patch.IsRelink)
                        {
                            flags = patch.Relink;
                        }
                    }

                    if (flags > 1)
                    {
                        Console.WriteLine("[KINGDOM: {0}/{1}]\t{2}\tRelinking...", number, input.idxEntries.Count - 1, name);     //-1 'cause of the file KINGDOM.IMG
                        number++;

                        /*if (!HashList.pairs.TryGetValue(flags, out name))
                         * {
                         *  name = String.Format("@noname/{0:x8}.bin", flags);
                         * }
                         * Console.WriteLine("{0}", name);*///Err...what is this crappy code? No but srsly
                        output.addRelink(entry.hash, flags);
                    }
                    else
                    {
                        Console.WriteLine("[KINGDOM: {0}/{1}]\t{2}", number, input.idxEntries.Count - 1, name);
                        //-1 'cause of the file KINGDOM.IMG
                        number++;
                        output.copyFile(entry);
                    }
                }
                else
                {
                    Console.WriteLine("[KINGDOM: {0}/{1}]\t{2}\tPatching...", number, input.idxEntries.Count - 1, name);     //-1 'cause of the file KINGDOM.IMG
                    number++;
                    output.importFile(s, entry.hash, flags);
                }
            }
            output.finalize();
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("New ISO finished!");
            Console.ResetColor();
        }
示例#7
0
        /// <summary>Write the IDX to the ISO, update a few final ISO 9660 values, and Dispose of self</summary>
        /// <exception cref="System.ObjectDisposedException">Thrown when ISO has already been finalized</exception>
        /// <exception cref="System.NotSupportedException">Thrown when no IDX dummy has been written</exception>
        /// <exception cref="System.NotSupportedException">
        ///     Thrown when there are more IDX entries to write then space was reserved
        ///     for
        /// </exception>
        public void finalize()
        {
            if (finalized)
            {
                throw new ObjectDisposedException("ISO has been finalized");
            }
            else if (idxOffset == 0)
            {
                throw new NotSupportedException("No IDX to finalize");
            }
            else if ((idxEntries.Count + idxRelinks.Count) * 16 > idxSize)
            {
                throw new NotSupportedException("Trying to write more entries then space was allocated for");
            }
            // Add delayed relinks
            foreach (var item in idxRelinks)
            {
                IDXEntry t = idxEntries.Find((IDXEntry a) => a.hash == item.Value);
                if (t.hash == item.Value)
                {
                    idxEntries.Add(new IDXEntry(item.Key, t.flags, t.LBA, t.size));
                }
                else
                {
                    Console.WriteLine("WARNING: Failed to relink {0:X8} to {1:X8}!", item.Key, item.Value);
                }
            }
            idxRelinks.Clear();
            // Sort IDXs by hash
            idxEntries.Sort((a, b) => a.hash < b.hash ? -1 : (a.hash > b.hash ? 1 : 0));
            // Write IDXs
            iso.Position = idxOffset;
            var IMGLen = (UInt32)((headerIMGEnd > 0 ? headerIMGEnd : iso.Length) - headerIMGoffset);

            foreach (IDXEntry entry in idxEntries)
            {
                bw.Write(entry.hash);
                bw.Write(entry.flags);
                bw.Write(entry.LBA);
                if (entry.hash == 0x0392ebe4) //kingdom.img needs length saved
                {
                    bw.Write(IMGLen);
                }
                else
                {
                    bw.Write(entry.size);
                }
            }
            idxEntries.Clear();

            if (updateISOHeaders)
            {
                UInt32 fileLBA = (UInt32)(iso.Length / 2048),
                       UDFLBA  = fileLBA - 263;
                iso.Position = 32848;
                bw.Write(_ISO9660Number(fileLBA)); /*ISO9660 Volume Space*/
                iso.Position = 69824;
                bw.Write(UDFLBA);                  /*UDF Partition size*/
                iso.Position = 102592;
                bw.Write(UDFLBA);                  /*UDF Partition size (Reserve header)*/

                if ((headerFlags & 0x01) != 0)
                {
                    iso.Position = 535568 + 8;
                    bw.Write(_ISO9660Number(IMGLen)); /*IMG Size*/
                }
            }
            Console.Write("Flushing data to disk...");
            bw.Flush();
            if (!NativeMethods.FlushFileBuffers(iso.SafeFileHandle))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(),
                                         "Win32 FlushFileBuffers returned error in KH1ISOWriter");
            }
            Console.WriteLine("    Done!");

            finalized = true;
            Dispose();
        }
示例#8
0
 /// <summary>Copy file from <c>origISO</c> to <c>iso</c></summary>
 /// <param name="entry">IDX entry describing the file in <c>origISO</c></param>
 /// <exception cref="System.ObjectDisposedException">Thrown when ISO has been finalized</exception>
 /// <exception cref="System.Exception">Thrown when <c>origISO</c> isn't set</exception>
 /// <exception cref="System.Exception">Thrown when <c>entry</c> isn't in <c>origISO</c></exception>
 public void copyFile(IDXEntry entry)
 {
     if (finalized)
     {
         throw new ObjectDisposedException("ISO has been finalized");
     }
     if (origISO == null)
     {
         throw new Exception("No original ISO to copy from");
     }
     if (!origISO.idxEntries.Contains(entry))
     {
         throw new Exception("IDX entry not in original ISO");
     }
     long pos = iso.Position,
         padding = (entry.size%2048) == 0 ? 0 : (2048 - (entry.size%2048));
     idxEntries.Add(new IDXEntry(entry.hash, entry.flags, (UInt32) (pos - dataOffset)/2048, entry.size));
     copyBytes(entry.size + padding, origISO.dataOffset + entry.LBA*2048);
     updateISOFileInfo(entry.hash, pos, entry.size);
 }
示例#9
0
 /// <summary>Read a file from the ISO</summary>
 /// <param name="entry">IDX entry describing the file</param>
 /// <returns>Byte array of the file</returns>
 /// <exception cref="System.Exception">Thrown when file is too large</exception>
 public byte[] readFile(IDXEntry entry)
 {
     if (entry.size > 0x7FFFFFFF)
     {
         throw new Exception("File too large to read");
     }
     iso.Position = dataOffset + (2048*entry.LBA);
     return br.ReadBytes((int) entry.size);
 }