/// <inheritdoc /> public bool TryGetFileInfo(string filePath, out MPQFileInfo fileInfo) { fileInfo = null; if (!ArchiveHashTable.TryFindEntry(filePath, out var hashEntry)) { return(false); } var blockEntry = ArchiveBlockTable.GetEntry((int)hashEntry.GetBlockEntryIndex()); if (HasFileAttributes()) { fileInfo = new MPQFileInfo(filePath, hashEntry, blockEntry); } else { fileInfo = new MPQFileInfo ( filePath, hashEntry, blockEntry, _fileAttributes.FileAttributes[(int)hashEntry.GetBlockEntryIndex()] ); } return(true); }
public bool TryExtractFile(string filePath, [NotNullWhen(true)] out byte[]?data) { ThrowIfDisposed(); data = null; // Reset all positions to be safe _archiveReader.BaseStream.Position = 0; if (!ArchiveHashTable.TryFindEntry(filePath, out var fileHashEntry)) { return(false); } var fileBlockEntry = ArchiveBlockTable.GetEntry((int)fileHashEntry.GetBlockEntryIndex()); // Drop out if the file has been deleted if (fileBlockEntry.IsDeleted()) { return(false); } // Seek to the beginning of the file's sectors long adjustedBlockOffset; if (Header.GetFormat() == MPQFormat.ExtendedV1 && RequiresExtendedFormat()) { var upperOffsetBits = ExtendedBlockTable ![(int)fileHashEntry.GetBlockEntryIndex()];
public byte[] ExtractFile(string filePath) { ThrowIfDisposed(); if (!TryExtractFile(filePath, out var data)) { if (!ArchiveHashTable.TryFindEntry(filePath, out var fileHashEntry)) { throw new FileNotFoundException("No file found at the given path.", filePath); } var fileBlockEntry = ArchiveBlockTable.GetEntry((int)fileHashEntry.GetBlockEntryIndex()); if (fileBlockEntry.IsDeleted()) { throw new FileDeletedException("The given file is deleted.", filePath); } throw new IOException("An unknown failure prevented the file from being extracted."); } return(data); }
public bool TryExtractFile(string filePath, out byte[] data) { ThrowIfDisposed(); data = null; // Reset all positions to be safe _archiveReader.BaseStream.Position = 0; if (!ArchiveHashTable.TryFindEntry(filePath, out var fileHashEntry)) { return(false); } var fileBlockEntry = ArchiveBlockTable.GetEntry((int)fileHashEntry.GetBlockEntryIndex()); // Drop out if the file has been deleted if (fileBlockEntry.IsDeleted()) { return(false); } // Seek to the beginning of the file's sectors long adjustedBlockOffset; if (Header.GetFormat() == MPQFormat.ExtendedV1 && RequiresExtendedFormat()) { var upperOffsetBits = ExtendedBlockTable[(int)fileHashEntry.GetBlockEntryIndex()]; adjustedBlockOffset = (long)fileBlockEntry.GetExtendedBlockOffset(upperOffsetBits); } else { adjustedBlockOffset = fileBlockEntry.GetBlockOffset(); } _archiveReader.BaseStream.Position = adjustedBlockOffset; // Calculate the decryption key if necessary var fileKey = MPQCrypt.CreateFileEncryptionKey ( filePath, fileBlockEntry.ShouldEncryptionKeyBeAdjusted(), adjustedBlockOffset, fileBlockEntry.GetFileSize() ); // Examine the file storage types and extract as necessary if (fileBlockEntry.IsSingleUnit()) { data = ExtractSingleUnitFile(fileBlockEntry, fileKey); return(true); } if (fileBlockEntry.IsCompressed()) { data = ExtractCompressedSectoredFile(fileBlockEntry, fileKey, adjustedBlockOffset); return(true); } data = ExtractUncompressedSectoredFile(fileBlockEntry, fileKey); return(true); }