public MpqManager(string mpqFile) { FileInfo info = new FileInfo(mpqFile); string destFileName = Path.Combine(Path.GetTempPath(), info.Name); File.Copy(mpqFile, destFileName, true); this._mpqArchive = new Foole.Mpq.MpqArchive(destFileName); this._mpqArchive.AddListfileFilenames(); }
internal MpqStream(MpqArchive archive, MpqEntry entry) { this._entry = entry; this._stream = archive.BaseStream; this._blockSize = archive.BlockSize; if (this._entry.IsCompressed && !this._entry.IsSingleUnit) { this.LoadBlockPositions(); } }
private byte[] LoadBlock(int blockIndex, int expectedLength) { uint offset; int toread; uint encryptionseed; if (_entry.IsCompressed) { offset = _blockPositions[blockIndex]; toread = (int)(_blockPositions[blockIndex + 1] - offset); } else { offset = (uint)(blockIndex * _blockSize); toread = expectedLength; } offset += _entry.FilePos; byte[] data = new byte[toread]; lock (_stream) { _stream.Seek(offset, SeekOrigin.Begin); int read = _stream.Read(data, 0, toread); if (read != toread) { throw new MpqParserException("Insufficient data or invalid data length"); } } if (_entry.IsEncrypted && _entry.FileSize > 3) { if (_entry.EncryptionSeed == 0) { throw new MpqParserException("Unable to determine encryption key"); } encryptionseed = (uint)(blockIndex + _entry.EncryptionSeed); MpqArchive.DecryptBlock(data, encryptionseed); } if (_entry.IsCompressed && (toread != expectedLength)) { if ((_entry.Flags & MpqFileFlags.CompressedMulti) != 0) { data = DecompressMulti(data, expectedLength); } else { data = PKDecompress(new MemoryStream(data), expectedLength); } } return(data); }
// Compressed files start with an array of offsets to make seeking possible private void LoadBlockPositions() { int blockposcount = (int)((_entry.FileSize + _blockSize - 1) / _blockSize) + 1; // Files with metadata have an extra block containing block checksums if ((_entry.Flags & MpqFileFlags.FileHasMetadata) != 0) { blockposcount++; } _blockPositions = new uint[blockposcount]; lock (_stream) { _stream.Seek(_entry.FilePos, SeekOrigin.Begin); BinaryReader br = new BinaryReader(_stream); for (int i = 0; i < blockposcount; i++) { _blockPositions[i] = br.ReadUInt32(); } } uint blockpossize = (uint)blockposcount * 4; /* * if(_blockPositions[0] != blockpossize) * _entry.Flags |= MpqFileFlags.Encrypted; */ if (_entry.IsEncrypted) { if (_entry.EncryptionSeed == 0) // This should only happen when the file name is not known { _entry.EncryptionSeed = MpqArchive.DetectFileSeed(_blockPositions[0], _blockPositions[1], blockpossize) + 1; if (_entry.EncryptionSeed == 1) { throw new MpqParserException("Unable to determine encyption seed"); } } MpqArchive.DecryptBlock(_blockPositions, _entry.EncryptionSeed - 1); if (_blockPositions[0] != blockpossize) { throw new MpqParserException("Decryption failed"); } if (_blockPositions[1] > _blockSize + blockpossize) { throw new MpqParserException("Decryption failed"); } } }
public MpqManager(string mpqFile) { //FileInfo info = new FileInfo(mpqFile); //string destFileName = Path.Combine(Path.GetTempPath(), info.Name); //File.Copy(mpqFile, destFileName, true); //this._mpqArchive = new Foole.Mpq.MpqArchive(destFileName); if (File.Exists(mpqFile)) { this._mpqArchive = new Foole.Mpq.MpqArchive(mpqFile); this._mpqArchive.AddListfileFilenames(); return; } }
private uint CalculateEncryptionSeed() { if (this.Filename == null) { return(0); } uint num = MpqArchive.HashString(Path.GetFileName(this.Filename), 0x300); if ((this.Flags & MpqFileFlags.BlockOffsetAdjustedKey) == MpqFileFlags.BlockOffsetAdjustedKey) { num = (num + this._fileOffset) ^ this.FileSize; } return(num); }
private uint CalculateEncryptionSeed() { if (Filename == null) { return(0); } uint seed = MpqArchive.HashString(Path.GetFileName(Filename), 0x300); if ((Flags & MpqFileFlags.BlockOffsetAdjustedKey) == MpqFileFlags.BlockOffsetAdjustedKey) { seed = (seed + _fileOffset) ^ FileSize; } return(seed); }
private byte[] LoadBlock(int blockIndex, int expectedLength) { uint num; int num2; if (this._entry.IsCompressed) { num = this._blockPositions[blockIndex]; num2 = (int)(this._blockPositions[blockIndex + 1] - num); } else { num = (uint)(blockIndex * this._blockSize); num2 = expectedLength; } num += this._entry.FilePos; byte[] buffer = new byte[num2]; lock (this._stream) { this._stream.Seek((long)num, SeekOrigin.Begin); if (this._stream.Read(buffer, 0, num2) != num2) { throw new MpqParserException("Insufficient data or invalid data length"); } } if (this._entry.IsEncrypted && (this._entry.FileSize > 3)) { if (this._entry.EncryptionSeed == 0) { throw new MpqParserException("Unable to determine encryption key"); } uint num3 = ((uint)blockIndex) + this._entry.EncryptionSeed; MpqArchive.DecryptBlock(buffer, num3); } if (!this._entry.IsCompressed || (num2 == expectedLength)) { return(buffer); } if ((this._entry.Flags & MpqFileFlags.CompressedMulti) != ((MpqFileFlags)0)) { return(DecompressMulti(buffer, expectedLength)); } return(PKDecompress(new MemoryStream(buffer), expectedLength)); }
private void LoadBlockPositions() { int num = ((int)(((this._entry.FileSize + this._blockSize) - 1) / ((long)this._blockSize))) + 1; if ((this._entry.Flags & MpqFileFlags.FileHasMetadata) != ((MpqFileFlags)0)) { num++; } this._blockPositions = new uint[num]; lock (this._stream) { this._stream.Seek((long)this._entry.FilePos, SeekOrigin.Begin); BinaryReader reader = new BinaryReader(this._stream); for (int i = 0; i < num; i++) { this._blockPositions[i] = reader.ReadUInt32(); } } uint decrypted = (uint)(num * 4); if (this._entry.IsEncrypted) { if (this._entry.EncryptionSeed == 0) { this._entry.EncryptionSeed = MpqArchive.DetectFileSeed(this._blockPositions[0], this._blockPositions[1], decrypted) + 1; if (this._entry.EncryptionSeed == 1) { throw new MpqParserException("Unable to determine encyption seed"); } } MpqArchive.DecryptBlock(this._blockPositions, this._entry.EncryptionSeed - 1); if (this._blockPositions[0] != decrypted) { throw new MpqParserException("Decryption failed"); } if (this._blockPositions[1] > (this._blockSize + decrypted)) { throw new MpqParserException("Decryption failed"); } } }
public void Close() { this._mpqArchive.Dispose(); this._mpqArchive = null; }