Esempio n. 1
0
            public FileStructureExtraData(Stream stream, CustomBinaryReader reader, int extra_length)
            {
                var end = stream.Position + extra_length;

                _UnknownID = reader.ReadInt16();
                StructureSizeAfterHeader = reader.ReadInt16();

                UncompressedFileLength = reader.ReadInt32();
                _UnknownD            = reader.ReadInt32();
                CompressedFileLength = reader.ReadInt32();
                _UnknownF            = reader.ReadInt32();

                var data_offset_ldword = (Int64)reader.ReadUInt32();
                var data_offset_hdword = (Int64)reader.ReadUInt32();

                DataOffset = data_offset_ldword + (data_offset_hdword << 32);

                _UnknownG = reader.ReadInt32();
                _Timestamp_Maybe_But_Not_Sure = reader.ReadInt32();

                // here be demons and lots of padding
                // make sure we read this to ensure the stream position is correct

                var padding_length = end - stream.Position;
                var data           = reader.ReadBytes((int)padding_length);

                if (stream.Position % 0x1000 != 0)
                {
                    throw new Exception("File Data Section Alignment Error (End Extra Read)");
                }

                FileDataOffset = stream.Position;
            }
Esempio n. 2
0
        void PopulateDirectory(FileStream stream, CustomBinaryReader reader, CentralDirectoryLocator central_directory_locator)
        {
            long central_directory_base_offset = central_directory_locator.ContentDirectoryOffset;

            stream.Position = central_directory_base_offset;
            byte[] central_directory_data = reader.ReadBytes(central_directory_locator.ContentDictionarySize);
            using (MemoryStream central_directory_stream = new MemoryStream(central_directory_data))
                using (CustomBinaryReader central_directory_reader = new CustomBinaryReader(central_directory_stream))
                {
                    // rebase current offset to 0 because we've copied data to a relative stream
                    long central_directory_current_offset = 0;

                    content_dictionary_count = central_directory_locator.DontentDictionaryCount;
                    for (int i = 0; i < central_directory_locator.DontentDictionaryCount; i++)
                    {
                        var central_directory = ReadPK(central_directory_stream, central_directory_reader, central_directory_current_offset) as CentralDirectory;
                        central_directory_current_offset = central_directory_stream.Position;

                        //TODO async query
                        //var file_structure = ReadPK(stream, reader, central_directory.extra.data_offset) as FileStructure;

                        Files[central_directory.Filename] = new P4KFile(this, central_directory);

                        //var file_data = ReadDataFromFileSection(stream, reader, file_offset.extra.file_data_offset, file_offset.extra.file_data_length);

                        /*if(PopulateDirectoryCallbackFunc != null)
                         * {
                         *  PopulateDirectoryCallbackFunc(i, central_directory_locator.content_dictionary_count);
                         * }*/

                        current_index = i;
                    }
                }
        }
Esempio n. 3
0
        public static byte[] ReadDataFromFileSection(FileStream stream, CustomBinaryReader reader, Int64 offset, int size)
        {
            stream.Position = offset;

            if (offset % 0x1000 != 0)
            {
                throw new Exception("File data alignment error");
            }

            return(reader.ReadBytes(size));
        }
Esempio n. 4
0
        static long FindEndCentralDirectoryOffset(FileStream stream, CustomBinaryReader reader)
        {
            // last PK must be within 0x1000 alignment, worst case scenario
            long length = Math.Min(stream.Length, 0x2000L);

            stream.Position = stream.Length - length;

            byte[] data = reader.ReadBytes((int)length);


            byte[] end_central_directory_magic =
            {
                0x50, 0x4B, 0x05, 0x06, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF
            };


            long current_offset = length - end_central_directory_magic.LongLength;
            bool found          = true;

            for (; current_offset > 0; current_offset--)
            {
                found = true;
                for (long magic_index = 0; magic_index < end_central_directory_magic.LongLength; magic_index++)
                {
                    if (data[current_offset + magic_index] != end_central_directory_magic[magic_index])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }

            if (!found)
            {
                throw new Exception("Couldn't find CentralDirectoryEnd");
            }

            long offset_from_eof = length - current_offset;

            stream.Position = stream.Length - offset_from_eof;

            return(stream.Position);
        }