bool DecompressFolder() { if (decompressed != null) { decompressed.Close(); } decompressed = new MemoryStream(); Console.WriteLine("Decompressing cabinet into RAM..."); var compType = (folder.typeCompress & 0xFF); if (compType == 3) { Console.WriteLine($"(~{Util.GetBytesReadable(header.cbCabinet)} -> ~{Util.GetBytesReadable(decompressedSize)})"); // LZX decompress it var windowSize = 1 << ((folder.typeCompress >> 8) & 0x1f); var lzx = new LzxDecoder(windowSize, 0x8000); reader.BaseStream.Position = headerPos + folder.coffCabStart; for (int i = 0; i < folder.cCFData; i++) { var data = reader.ReadStruct <CFDATA>(); if (dataReservedSize > 0) { reader.BaseStream.Position += dataReservedSize; } lzx.Decompress(reader.BaseStream, data.cbData, decompressed, data.cbUncomp); } return(true); } else if (compType == 0) { reader.BaseStream.Position = headerPos + folder.coffCabStart; for (int i = 0; i < folder.cCFData; i++) { var data = reader.ReadStruct <CFDATA>(); if (dataReservedSize > 0) { reader.BaseStream.Position += dataReservedSize; } byte[] block = reader.ReadBytes(data.cbData); decompressed.Write(block, 0, block.Length); } return(true); } Console.WriteLine($"Error: cabinet uses unsupported compression type {compType}!"); return(false); }
// Tries extracting file from the recdata stream public void Extract(Stream dataStream, Stream outputStream) { var lzx = new LzxDecoder(_baseFile.WindowSize, LZXDecompressedBlockSize); dataStream.Position = DataOffset; long outStreamPosition = outputStream.Position; foreach (var blockSize in LzxBlocks) { lzx.Decompress(dataStream, blockSize, outputStream, LZXDecompressedBlockSize); } lzx.Decompress(dataStream, FinalBlockCompSize, outputStream, FinalBlockDecSize); // Trim file to size in the entry header outputStream.SetLength(outStreamPosition + DecompressedSize); }