/// <summary> /// Constructs a KIFINT entry with the specified file name, entry data, parent KIFINT archive. /// </summary> /// <param name="fileName"> /// The cached name of the file. Calling <see cref="KifintArchive.KIFENTRY.FileName"/> is wasteful. /// </param> /// <param name="kifEntry">The decrypted data for the entry.</param> /// <param name="kifint">The parent KIFINT arhive.</param> internal KifintEntry(string fileName, KIFENTRY kifEntry, KifintArchive kifint) { Kifint = kifint; FileName = fileName; Offset = kifEntry.Offset; Length = kifEntry.Length; }
private static void DecryptArchiveSave(KIFHDR hdr, List <KIFENTRY> entries, uint tocSeed, uint fileKey, Blowfish blowfish, int keyIndex, Stream inStream, Stream outStream, KifintProgressArgs progress, KifintProgressCallback callback) { BinaryReader reader = new BinaryReader(inStream); BinaryWriter writer = new BinaryWriter(outStream); const int ProgressThreshold = 1; progress.EntryName = null; progress.EntryIndex = 0; progress.EntryCount = entries.Count; // Decrypt the KIFINT entries using the file key for (uint i = 0; i < hdr.EntryCount; i++, progress.EntryIndex++) { if (unchecked ((int)i) == keyIndex) { continue; } KIFENTRY entry = entries[unchecked ((int)i)]; // Give the entry the correct name UnobfuscateFileName(entry.FileNameRaw, unchecked (tocSeed + i)); // Apply the extra offset to be decrypted entry.Offset += i; // Decrypt the entry's length and offset blowfish.Decrypt(ref entry.Info); progress.EntryName = entry.FileName; if (i % ProgressThreshold == 0 || i + 1 == hdr.EntryCount) { callback?.Invoke(progress); } // Goto the entry's decrypted offset, read the buffer, then decrypt it inStream.Position = entry.Offset; byte[] buffer = reader.ReadBytes(entry.Length); blowfish.Decrypt(buffer, entry.Length & ~7); // Move to the entry's offset in the output stream and write the buffer outStream.Position = entry.Offset; writer.Write(buffer); // Make sure to reassign the entry to the list, because // it's not an array and does not return struct references. entries[unchecked ((int)i)] = entry; } entries.RemoveAt(keyIndex); hdr.EntryCount--; outStream.Position = 0; writer.WriteUnmanaged(hdr); writer.WriteUnmanagedArray(entries); }