admin 管理员组

文章数量: 1184232

简述
在 Windows 环境下,使用 Windows API 可以进行文件的压缩和解压操作。这提供了一种有效的方式来
处理文件,减小存储空间,并在需要时快速解压。以下是一个使用 Windows API 进行压缩与解压的简单
示例,使用了 ntdll.dll 中的 RtlCompressBuffer 和 RtlDecompressBuffer 函数。	
#include<iostream>#include<windows.h>usingnamespace std;//typedef unsigned long NTSTATUS;#defineSTATUS_SUCCESS((NTSTATUS)0x00000000UL)#defineSTATUS_BUFFER_ALL_ZEROS((NTSTATUS)0x00000117UL)#defineSTATUS_INVALID_PARAMETER((NTSTATUS)0xC000000DUL)#defineSTATUS_UNSUPPORTED_COMPRESSION((NTSTATUS)0xC000025FUL)#defineSTATUS_NOT_SUPPORTED_ON_SBS((NTSTATUS)0xC0000300UL)#defineSTATUS_BUFFER_TOO_SMALL((NTSTATUS)0xC0000023UL)#defineSTATUS_BAD_COMPRESSION_BUFFER((NTSTATUS)0xC0000242UL)
 
HMODULE ntdll =GetModuleHandleA("ntdll.dll");typedefNTSTATUS(__stdcall* _RtlCompressBuffer)(
    USHORT CompressionFormatAndEngine,
    PUCHAR UncompressedBuffer,
    ULONG UncompressedBufferSize,
    PUCHAR CompressedBuffer,
    ULONG CompressedBufferSize,
    ULONG UncompressedChunkSize,
    PULONG FinalCompressedSize,
    PVOID WorkSpace
    );typedefNTSTATUS(__stdcall* _RtlDecompressBuffer)(
    USHORT CompressionFormat,
    PUCHAR UncompressedBuffer,
    ULONG UncompressedBufferSize,
    PUCHAR CompressedBuffer,
    ULONG CompressedBufferSize,
    PULONG FinalUncompressedSize
    );typedefNTSTATUS(__stdcall* _RtlGetCompressionWorkSpaceSize)(
    USHORT CompressionFormatAndEngine,
    PULONG CompressBufferWorkSpaceSize,
    PULONG CompressFragmentWorkSpaceSize
    );char*ReadFileWs(constchar* FilePath, DWORD& bufferLen){
    HANDLE File =CreateFileA(FilePath, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING,0,NULL);if(File == INVALID_HANDLE_VALUE){returnNULL;}
 
    DWORD _size =GetFileSize(File,0);char* Buffer =newchar[_size +1];bool result =ReadFile(File, Buffer, _size,&bufferLen,0);CloseHandle(File);if(result)return Buffer;elsereturnNULL;}boolWriteFileWs(constchar* 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){returnfalse;}bool result =WriteFile(File, Buffer, bufferLen,&numberBytesRead,NULL);CloseHandle(File);return result;}
 
 
UCHAR*compress_buffer(constchar* buffer,const ULONG bufferLen, ULONG compBufferLen, ULONG* compBufferSize){
    _RtlCompressBuffer RtlCompressBuffer =(_RtlCompressBuffer)GetProcAddress(ntdll,"RtlCompressBuffer");
    _RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize =(_RtlGetCompressionWorkSpaceSize)GetProcAddress(ntdll,"RtlGetCompressionWorkSpaceSize");
 
    ULONG bufWorkspaceSize;// Workspace Size
    ULONG fragWorkspaceSize;// Fragmented Workspace Size (Unused)
    NTSTATUS ret =RtlGetCompressionWorkSpaceSize(
        COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD,// CompressionFormatAndEngine&bufWorkspaceSize,// CompressBufferWorkSpaceSize&fragWorkspaceSize                                     // CompressFragmentWorkSpaceSize);if(ret != STATUS_SUCCESS)return0;
 
    VOID* workspace =(VOID*)LocalAlloc(LMEM_FIXED, bufWorkspaceSize);if(workspace ==NULL)return0;
 
    UCHAR* compBuffer =new UCHAR[compBufferLen];
    NTSTATUS result =RtlCompressBuffer(
        COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD,// CompressionFormatAndEngine(UCHAR*)buffer,// UncompressedBuffer
        bufferLen,// UncompressedBufferSize
        compBuffer,// CompressedBuffer
        compBufferLen,// CompressedBufferSize4096,// UncompressedChunkSize
        compBufferSize,// FinalCompressedSize
        workspace                                               // WorkSpace);LocalFree(workspace);if(result != STATUS_SUCCESS){return0;}return compBuffer;}
 
UCHAR*decompress_buffer(constchar* buffer,constint bufferLen,constint uncompBufferLen, ULONG* uncompBufferSize){
    _RtlDecompressBuffer RtlDecompressBuffer =(_RtlDecompressBuffer)GetProcAddress(ntdll,"RtlDecompressBuffer");
 
    UCHAR* uncompBuffer =new UCHAR[uncompBufferLen];
    NTSTATUS result =RtlDecompressBuffer(
        COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD,// CompressionFormat
        uncompBuffer,// UncompressedBuffer
        uncompBufferLen,// UncompressedBufferSize(UCHAR*)buffer,// CompressedBuffer
        bufferLen,// CompressedBufferSize
        uncompBufferSize                                        // FinalUncompressedSize);if(result != STATUS_SUCCESS){;return0;}return uncompBuffer;}intmain(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);//necesitara ser liberado
    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();return0;}

本文标签: 系统 深入 在指定路