예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }