コード例 #1
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;
                    }
                }
        }
コード例 #2
0
        public void Initialize(string filename, bool readOnly, bool logging = false)
        {
            Filename = filename;
            Logging  = logging;

            mutex = new Mutex();

            if (readOnly)
            {
                ReadOnly   = true;
                fileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            else
            {
                try
                {
                    ReadOnly   = false;
                    fileStream = File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                }
                catch (IOException)
                {
                    ReadOnly   = true;
                    fileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
            }

            try
            {
                mutex.WaitOne();

                customBinaryReader = new CustomBinaryReader(fileStream);
                customBinaryWriter = ReadOnly ? null : new CustomBinaryWriter(fileStream);

                var offset_central_directory_end = FindEndCentralDirectoryOffset(fileStream, customBinaryReader);
                central_directory_end = ReadPK(fileStream, customBinaryReader, offset_central_directory_end) as CentralDirectoryEnd;

                var offset_central_directory_locator_offset = offset_central_directory_end - 0x14;
                central_directory_locator_offset = ReadPK(fileStream, customBinaryReader, offset_central_directory_locator_offset) as CentralDirectoryLocatorOffset;

                var offset_central_directory_locator = central_directory_locator_offset.DirectoryLocatorOffset;
                central_directory_locator = ReadPK(fileStream, customBinaryReader, offset_central_directory_locator) as CentralDirectoryLocator;

                PopulateDirectory(fileStream, customBinaryReader, central_directory_locator);
            }
            finally
            {
                mutex.ReleaseMutex();
            }

            if (Logging)
            {
                Console.WriteLine($"Finished loading {filename}");
            }
        }
コード例 #3
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();
            }
        }