简述
在 Windows 环境下,使用 Windows API 可以进行文件的压缩和解压操作。这提供了一种有效的方式来
处理文件,减小存储空间,并在需要时快速解压。以下是一个使用 Windows API 进行压缩与解压的简单
示例,使用了 ntdll.dll 中的 RtlCompressBuffer 和 RtlDecompressBuffer 函数。
# include <iostream> # include <windows.h> using namespace std; # define STATUS_SUCCESS ( ( NTSTATUS) 0x00000000UL ) # define STATUS_BUFFER_ALL_ZEROS ( ( NTSTATUS) 0x00000117UL ) # define STATUS_INVALID_PARAMETER ( ( NTSTATUS) 0xC000000DUL ) # define STATUS_UNSUPPORTED_COMPRESSION ( ( NTSTATUS) 0xC000025FUL ) # define STATUS_NOT_SUPPORTED_ON_SBS ( ( NTSTATUS) 0xC0000300UL ) # define STATUS_BUFFER_TOO_SMALL ( ( NTSTATUS) 0xC0000023UL ) # define STATUS_BAD_COMPRESSION_BUFFER ( ( NTSTATUS) 0xC0000242UL )
HMODULE ntdll = GetModuleHandleA ( "ntdll.dll" ) ; typedef NTSTATUS ( __stdcall* _RtlCompressBuffer) (
USHORT CompressionFormatAndEngine,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
ULONG UncompressedChunkSize,
PULONG FinalCompressedSize,
PVOID WorkSpace
) ; typedef NTSTATUS ( __stdcall* _RtlDecompressBuffer) (
USHORT CompressionFormat,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize
) ; typedef NTSTATUS ( __stdcall* _RtlGetCompressionWorkSpaceSize) (
USHORT CompressionFormatAndEngine,
PULONG CompressBufferWorkSpaceSize,
PULONG CompressFragmentWorkSpaceSize
) ; char * ReadFileWs ( const char * FilePath, DWORD& bufferLen) {
HANDLE File = CreateFileA ( FilePath, GENERIC_READ, FILE_SHARE_READ, NULL , OPEN_EXISTING, 0 , NULL ) ; if ( File == INVALID_HANDLE_VALUE) { return NULL ; }
DWORD _size = GetFileSize ( File, 0 ) ; char * Buffer = new char [ _size + 1 ] ; bool result = ReadFile ( File, Buffer, _size, & bufferLen, 0 ) ; CloseHandle ( File) ; if ( result) return Buffer; else return NULL ; } bool WriteFileWs ( const char * FilePath, char * Buffer, DWORD bufferLen, DWORD& numberBytesRead) {
HANDLE File = CreateFileA ( FilePath, GENERIC_WRITE, FILE_SHARE_WRITE, 0 , CREATE_ALWAYS, 0 , 0 ) ; if ( File == INVALID_HANDLE_VALUE) { return false ; } bool result = WriteFile ( File, Buffer, bufferLen, & numberBytesRead, NULL ) ; CloseHandle ( File) ; return result; }
UCHAR* compress_buffer ( const char * buffer, const ULONG bufferLen, ULONG compBufferLen, ULONG* compBufferSize) {
_RtlCompressBuffer RtlCompressBuffer = ( _RtlCompressBuffer) GetProcAddress ( ntdll, "RtlCompressBuffer" ) ;
_RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = ( _RtlGetCompressionWorkSpaceSize) GetProcAddress ( ntdll, "RtlGetCompressionWorkSpaceSize" ) ;
ULONG bufWorkspaceSize;
ULONG fragWorkspaceSize;
NTSTATUS ret = RtlGetCompressionWorkSpaceSize (
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, & bufWorkspaceSize, & fragWorkspaceSize ) ; if ( ret != STATUS_SUCCESS) return 0 ;
VOID* workspace = ( VOID* ) LocalAlloc ( LMEM_FIXED, bufWorkspaceSize) ; if ( workspace == NULL ) return 0 ;
UCHAR* compBuffer = new UCHAR[ compBufferLen] ;
NTSTATUS result = RtlCompressBuffer (
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, ( UCHAR* ) buffer,
bufferLen,
compBuffer,
compBufferLen, 4096 ,
compBufferSize,
workspace ) ; LocalFree ( workspace) ; if ( result != STATUS_SUCCESS) { return 0 ; } return compBuffer; }
UCHAR* decompress_buffer ( const char * buffer, const int bufferLen, const int uncompBufferLen, ULONG* uncompBufferSize) {
_RtlDecompressBuffer RtlDecompressBuffer = ( _RtlDecompressBuffer) GetProcAddress ( ntdll, "RtlDecompressBuffer" ) ;
UCHAR* uncompBuffer = new UCHAR[ uncompBufferLen] ;
NTSTATUS result = RtlDecompressBuffer (
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD,
uncompBuffer,
uncompBufferLen, ( UCHAR* ) buffer,
bufferLen,
uncompBufferSize ) ; if ( result != STATUS_SUCCESS) { ; return 0 ; } return uncompBuffer; } int main ( void ) { char * path = ( char * ) "D:\\Utest\\TestDll.dll" ; char * NewPath = ( char * ) "D:\\Utest\\TestDllYY.dll" ; char * DecompressPath = ( char * ) "D:\\Utest\\TestDllJJ.dll" ;
DWORD bufferLen, numberBytesRead, compBufferSize, realDecompSize; char * data = ReadFileWs ( path, bufferLen) ;
UCHAR* bufferComprimido = compress_buffer ( data, bufferLen, bufferLen + 512 , & compBufferSize) ;
cout << "读取和压缩文件" << endl; WriteFileWs ( NewPath, ( char * ) bufferComprimido, compBufferSize, numberBytesRead) ;
cout << "在指定路径写入压缩后的文件" << endl;
UCHAR* bufferDescomprimido = decompress_buffer ( ( char * ) bufferComprimido, bufferLen, compBufferSize * 100 , & realDecompSize) ; WriteFileWs ( DecompressPath, ( char * ) bufferDescomprimido, bufferLen, numberBytesRead) ;
cout << "在指定路径写入解压后的文件 " << endl; delete [ ] data; delete [ ] bufferComprimido; delete [ ] bufferDescomprimido;
cin. get ( ) ; return 0 ; }
发布评论