public void AddP4KFile(P4KFile file, string filename, byte[] data, ref CentralDirectory central_directory, ref FileStructure file_structure) { if (!Files.ContainsValue(file)) { file.centralDirectory = new CentralDirectory(filename, data); file.FileStructure = new FileStructure(filename, data); // Add this first otherwise the Locator count wont be correct Files[file.Filepath] = file; AllocateFilesystemChunk( data.Length + 0x1000, // add an extra chunk in for the fileinfo out long allocation_offset, out long total_allocated_size, false ); file.centralDirectory.Extra.data_offset = allocation_offset; var crypt = new SHA256Managed(); file.centralDirectory.Extra.sha256_hash = crypt.ComputeHash(data); var mutex = this.GetStream(out FileStream stream, out CustomBinaryReader reader, out CustomBinaryWriter writer); // these are the same for some reason... weird file.FileStructure.Extra.DataOffset = file.centralDirectory.Extra.data_offset; // write fileinfo stream.Position = allocation_offset; file.FileStructure.WriteBinaryToStream(stream, writer, true); // not actually part of the structure, just a useful helper to get the data as its // immediately after this structure file.FileStructure.Extra.FileDataOffset = stream.Position; file.centralDirectory.Extra.compressed_file_length = file.FileStructure.Extra.CompressedFileLength; file.centralDirectory.Extra.uncompressed_file_length = file.FileStructure.Extra.UncompressedFileLength; writer.Write(data); WriteContentDirectoryChunk(stream, reader, writer); mutex.ReleaseMutex(); } }
public object ReadPK(Stream stream, CustomBinaryReader reader, Int64 offset) { stream.Seek(offset, SeekOrigin.Begin); var magic = reader.ReadInt16(); if (magic != 0x4B50) { throw new Exception("Invalid PK offset"); } Signature signature = (Signature)reader.ReadInt16(); switch (signature) { case Signature.CentralDirectory: CentralDirectory centralDirectory = new CentralDirectory(stream, reader); if (Logging) { Console.WriteLine($"Found CentralDirectory {centralDirectory.Filename}"); } if (Logging) { Console.WriteLine($"Searching for FileStructure @{centralDirectory.Extra.data_offset.ToString("X")}"); } return(centralDirectory); case Signature.FileStructure: FileStructure fileStructure = new FileStructure(stream, reader); if (Logging) { Console.WriteLine($"Found FileStructure {fileStructure.Filename}"); } return(fileStructure); case Signature.CentralDirectoryLocator: CentralDirectoryLocator centralDirectoryLocator = new CentralDirectoryLocator(stream, reader); if (Logging) { Console.WriteLine($"Found CentralDirectoryLocator @{offset}"); } return(centralDirectoryLocator); case Signature.CentralDirectoryLocatorOffset: CentralDirectoryLocatorOffset centralDirectoryLocatorOffset = new CentralDirectoryLocatorOffset(stream, reader); if (Logging) { Console.WriteLine($"Found CentralDirectoryLocatorOffset @{offset}"); } return(centralDirectoryLocatorOffset); case Signature.CentralDirectoryEnd: CentralDirectoryEnd centralDirectoryEnd = new CentralDirectoryEnd(stream, reader); if (Logging) { Console.WriteLine($"Found CentralDirectoryEnd @{offset}"); } return(centralDirectoryEnd); default: throw new NotImplementedException(); } }