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}"); } }
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(); } }