Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;------------------------------------------------------------------------------
- ; CDCompressMem - Compress data in memory with one of the Cabinet compression
- ; algorithms. Stores a header signature at the first dword indicating the
- ; compression algorithm used to compress the data.
- ;
- ; Returns: pointer to Compressed data if succesful or NULL otherwise.
- ; User should free memory when no longer required with call to GlobalFree
- ; Variable pointed to by lpdwCompressedDataLength will contain the size of the
- ; compressed data or 0 if a failure occured.
- ;------------------------------------------------------------------------------
- CDCompressMem PROC USES EBX lpUncompressedData:DWORD, dwUncompressedDataLength:DWORD, dwCompressionAlgorithm:DWORD, lpdwCompressedDataLength:DWORD
- LOCAL CompressorHandle:DWORD
- LOCAL CompressedBuffer:DWORD
- LOCAL CompressedBufferSize:DWORD
- LOCAL CompressedDataSize:DWORD
- LOCAL CompressionAlgorithm:DWORD
- LOCAL pData:DWORD
- IFDEF DEBUG32
- PrintText 'CDCompressMem'
- ;PrintDec lpUncompressedData
- ;PrintDec dwUncompressedDataLength
- ENDIF
- .IF lpUncompressedData == NULL || dwUncompressedDataLength == 0
- IFDEF DEBUG32
- PrintText 'CDCompressMem lpUncompressedData == NULL || dwUncompressedDataLength == 0'
- ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- mov eax, dwCompressionAlgorithm
- .IF eax != COMPRESS_ALGORITHM_MSZIP && eax != COMPRESS_ALGORITHM_XPRESS && eax != COMPRESS_ALGORITHM_XPRESS_HUFF && eax != COMPRESS_ALGORITHM_LZMS
- IFDEF DEBUG32
- PrintText 'CDCompressMem dwCompressionAlgorithm Not Valid'
- ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Create compressor
- ;--------------------------------------------------------------------------
- Invoke CreateCompressor, dwCompressionAlgorithm, NULL, Addr CompressorHandle
- .IF eax == FALSE
- IFDEF DEBUG32
- PrintText 'CDCompressMem CreateCompressor Failed'
- ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Get size required first
- ;--------------------------------------------------------------------------
- Invoke Compress, CompressorHandle, lpUncompressedData, dwUncompressedDataLength, NULL, 0, Addr CompressedBufferSize
- .IF eax == FALSE
- Invoke GetLastError
- .IF eax == ERROR_INSUFFICIENT_BUFFER
- .ELSE
- IFDEF DEBUG32
- PrintText 'CDCompressMem Compress Get Size Failed'
- ENDIF
- .IF CompressorHandle != 0
- Invoke CloseCompressor, CompressorHandle
- .ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Alloc buffer required
- ;--------------------------------------------------------------------------
- ;PrintDec CompressedBufferSize
- mov eax, CompressedBufferSize
- add eax, SIZEOF DWORD ; room for header signature
- Invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax
- .IF eax == NULL
- IFDEF DEBUG32
- PrintText 'CDCompressMem GlobalAlloc Failed'
- ENDIF
- .IF CompressorHandle != 0
- Invoke CloseCompressor, CompressorHandle
- .ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- mov CompressedBuffer, eax
- mov pData, eax
- add pData, SIZEOF DWORD ; skip past header signature
- ;--------------------------------------------------------------------------
- ; Add header signature
- ;--------------------------------------------------------------------------
- mov ebx, CompressedBuffer
- mov eax, dwCompressionAlgorithm
- .IF eax == COMPRESS_ALGORITHM_MSZIP
- mov eax, HEADER_MSZIP
- mov [ebx], eax
- .ELSEIF eax == COMPRESS_ALGORITHM_XPRESS
- mov eax, HEADER_XPRESS
- mov [ebx], eax
- .ELSEIF eax == COMPRESS_ALGORITHM_XPRESS_HUFF
- mov eax, HEADER_HUFF
- mov [ebx], eax
- .ELSEIF eax == COMPRESS_ALGORITHM_LZMS
- mov eax, HEADER_LZMS
- mov [ebx], eax
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Do actual compression now
- ;--------------------------------------------------------------------------
- Invoke Compress, CompressorHandle, lpUncompressedData, dwUncompressedDataLength, pData, CompressedBufferSize, Addr CompressedDataSize
- .IF eax == FALSE
- IFDEF DEBUG32
- PrintText 'CDCompressMem Compress Failed'
- ENDIF
- .IF CompressedBuffer != 0
- Invoke GlobalFree, CompressedBuffer
- .ENDIF
- .IF CompressorHandle != 0
- Invoke CloseCompressor, CompressorHandle
- .ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, 0
- mov [ebx], eax
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Cleanup
- ;--------------------------------------------------------------------------
- .IF CompressorHandle != 0
- Invoke CloseCompressor, CompressorHandle
- .ENDIF
- .IF lpdwCompressedDataLength != 0
- mov ebx, lpdwCompressedDataLength
- mov eax, CompressedDataSize
- add eax, SIZEOF DWORD ; to account for compression header we add
- mov [ebx], eax
- .ENDIF
- mov eax, CompressedBuffer
- ret
- CDCompressMem ENDP
- ;------------------------------------------------------------------------------
- ; CDDecompressMem - Decompress memory that was previously compressed with one
- ; of the Cabinet compression algorithms. Checks for header signature first to
- ; verify that there is a compressed data and what algorithm to use.
- ;
- ; Returns: pointer to decompressed data if succesful or NULL otherwise.
- ; User should free memory when no longer required with call to GlobalFree
- ;------------------------------------------------------------------------------
- CDDecompressMem PROC USES EBX lpCompressedData:DWORD, dwCompressedDataLength:DWORD
- LOCAL DecompressorHandle:DWORD
- LOCAL DecompressedBuffer:DWORD
- LOCAL DecompressedBufferSize:DWORD
- LOCAL DecompressedDataSize:DWORD
- LOCAL DecompressionAlgorithm:DWORD
- LOCAL pData:DWORD
- LOCAL nDataLength:DWORD
- IFDEF DEBUG32
- PrintText 'CDDecompressMem'
- ENDIF
- .IF lpCompressedData == NULL || dwCompressedDataLength == 0
- mov eax, NULL
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Check for header signature and adjust pointer and length
- ;--------------------------------------------------------------------------
- mov ebx, lpCompressedData
- mov eax, [ebx]
- .IF eax == HEADER_MSZIP || eax == HEADER_XPRESS || eax == HEADER_HUFF || eax == HEADER_LZMS
- .IF eax == HEADER_MSZIP
- mov DecompressionAlgorithm, COMPRESS_ALGORITHM_MSZIP
- .ELSEIF eax == HEADER_XPRESS
- mov DecompressionAlgorithm, COMPRESS_ALGORITHM_XPRESS
- .ELSEIF eax == HEADER_HUFF
- mov DecompressionAlgorithm, COMPRESS_ALGORITHM_XPRESS_HUFF
- .ELSEIF eax == HEADER_LZMS
- mov DecompressionAlgorithm, COMPRESS_ALGORITHM_LZMS
- .ENDIF
- .ELSE
- mov eax, NULL
- ret
- .ENDIF
- mov eax, lpCompressedData
- add eax, 4 ; skip past header signature
- mov pData, eax
- mov eax, dwCompressedDataLength
- sub eax, 4 ; we need 4 less coz of signature
- .IF sdword ptr eax < 0 ; check size again
- mov eax, NULL
- ret
- .ENDIF
- mov nDataLength, eax
- ;--------------------------------------------------------------------------
- ; Create decompressor
- ;--------------------------------------------------------------------------
- Invoke CreateDecompressor, DecompressionAlgorithm, NULL, Addr DecompressorHandle
- .IF eax == FALSE
- IFDEF DEBUG32
- PrintText 'CDDecompressMem CreateDecompressor Failed'
- ENDIF
- mov eax, FALSE
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Get size required
- ;--------------------------------------------------------------------------
- Invoke Decompress, DecompressorHandle, pData, nDataLength, NULL, 0, Addr DecompressedBufferSize
- .IF eax == FALSE
- Invoke GetLastError
- .IF eax == ERROR_INSUFFICIENT_BUFFER
- ;
- .ELSE
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Get Size Failed'
- ENDIF
- .IF DecompressorHandle != 0
- Invoke CloseDecompressor, DecompressorHandle
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Alloc buffer required
- ;--------------------------------------------------------------------------
- mov eax, DecompressedBufferSize
- add eax, 4 ; we add four extra to give us 4 null bytes in case compressed
- ; data is an ansi or unicode string or something that requires null endings
- Invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, eax ;DecompressedBufferSize
- .IF eax == NULL
- IFDEF DEBUG32
- PrintText 'CDDecompressMem GlobalAlloc Failed'
- ENDIF
- .IF DecompressorHandle != 0
- Invoke CloseDecompressor, DecompressorHandle
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- mov DecompressedBuffer, eax
- ;--------------------------------------------------------------------------
- ; Do the actual decompression now
- ;--------------------------------------------------------------------------
- Invoke Decompress, DecompressorHandle, pData, nDataLength, DecompressedBuffer, DecompressedBufferSize, Addr DecompressedDataSize
- .IF eax == FALSE
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Failed'
- ENDIF
- Invoke GetLastError
- .IF eax == ERROR_BAD_COMPRESSION_BUFFER
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Failed ERROR_BAD_COMPRESSION_BUFFER'
- ENDIF
- .ELSEIF eax == ERROR_INSUFFICIENT_BUFFER
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Failed ERROR_INSUFFICIENT_BUFFER'
- PrintDec DecompressedBufferSize
- PrintDec nDataLength
- PrintDec DecompressedBuffer
- PrintDec pData
- ENDIF
- .ELSEIF eax == ERROR_FUNCTION_FAILED
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Failed ERROR_FUNCTION_FAILED'
- ENDIF
- .ELSEIF eax == ERROR_INVALID_HANDLE
- IFDEF DEBUG32
- PrintText 'CDDecompressMem Decompress Failed ERROR_INVALID_HANDLE'
- ENDIF
- .ENDIF
- .IF DecompressedBuffer != 0
- Invoke GlobalFree, DecompressedBuffer
- .ENDIF
- .IF DecompressorHandle != 0
- Invoke CloseDecompressor, DecompressorHandle
- .ENDIF
- mov eax, NULL
- ret
- .ENDIF
- ;--------------------------------------------------------------------------
- ; Cleanup and return pointer to decompressed data
- ;--------------------------------------------------------------------------
- .IF DecompressorHandle != 0
- Invoke CloseDecompressor, DecompressorHandle
- .ENDIF
- mov eax, DecompressedBuffer
- ret
- CDDecompressMem ENDP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement