zoukankan      html  css  js  c++  java
  • windows平台(不包括ARM的CE)通用的压缩和解压缩

    通用是相对的,这里指的是xp和win7(其他版本我没测试过,不要用不要来找我)

    #define CMP_FRM     COMPRESSION_FORMAT_LZNT1|COMPRESSION_ENGINE_MAXIMUM
    
    typedef DWORD(__stdcall *RtlCompressBuffer_Fn)(
        IN ULONG   CompressionFormat,
        IN PVOID   SourceBuffer,
        IN ULONG   SourceBufferLength,
        OUT PVOID   DestinationBuffer,
        IN ULONG   DestinationBufferLength,
        IN ULONG   Unknown,
        OUT PULONG   pDestinationSize,
        IN PVOID   WorkspaceBuffer);
    
    typedef DWORD(__stdcall *RtlDecompressBuffer_Fn)(
        IN ULONG   CompressionFormat,
        OUT PVOID   DestinationBuffer,
        IN ULONG   DestinationBufferLength,
        IN PVOID   SourceBuffer,
        IN ULONG   SourceBufferLength,
        OUT PULONG   pDestinationSize);
    
    typedef DWORD(__stdcall *RtlGetCompressionWorkSpaceSize_Fn)(
        IN ULONG   CompressionFormat,
        OUT PULONG   pNeededBufferSize,
        OUT PULONG   pUnknown);
    
    
    LPBYTE CompressBuffer(LPBYTE lpIn, int iInLen, int & iOut);
    
    LPBYTE DecompressBuffer(LPBYTE lpIn, int iInlen, int & iOut);

    static RtlCompressBuffer_Fn compress = NULL;
    static RtlDecompressBuffer_Fn decompress = NULL;
    static RtlGetCompressionWorkSpaceSize_Fn getcompressionworkspacesize = NULL;
    void GetCompressApis()
    {
        
    
        if (compress && decompress && getcompressionworkspacesize)
        {
            return;
        }
        static WCHAR wszntdll[] = { L'n', L't', L'd', L'l', L'l', L'.', L'd', L'l', L'l', L'' };
        static HMODULE hDll = LoadLibrary(wszntdll);
        static char szRtlCompressBuffer[] = { 'R', 't', 'l', 'C', 'o', 'm', 'p', 'r', 'e', 's', 's', 'B', 'u', 'f', 'f', 'e', 'r', '' };
        static char szRtlDecompressBuffer[] = { 'R', 't', 'l', 'D', 'e', 'c', 'o', 'm', 'p', 'r', 'e', 's', 's', 'B', 'u', 'f', 'f', 'e', 'r', '' };
        static char szRtlGetCompressionWorkSpaceSize[] = { 'R', 't', 'l', 'G', 'e', 't', 'C', 'o', 'm', 'p', 'r', 'e', 's', 's', 'i', 'o', 'n', 'W', 'o', 'r', 'k', 'S', 'p', 'a', 'c', 'e', 'S', 'i', 'z', 'e', '' };
        if (hDll)
        {
            compress = (RtlCompressBuffer_Fn)GetProcAddress(hDll, szRtlCompressBuffer);
            decompress = (RtlDecompressBuffer_Fn)GetProcAddress(hDll, szRtlDecompressBuffer);
            getcompressionworkspacesize = (RtlGetCompressionWorkSpaceSize_Fn)GetProcAddress(hDll, szRtlGetCompressionWorkSpaceSize);
    
        }
    
    
    }
    //
    // compress buffer 
    //
    LPBYTE CompressBuffer(LPBYTE lpIn, int iInLen, int & iOut)
    {
        // 压缩格式 |原大小 2 | 压缩后大小 2| 数据 .....|hash 4|
        GetCompressApis();
        int dwOutBufferLen = iInLen*1.2 + 20;
        LPBYTE lpOut = (LPBYTE)zMalloc(dwOutBufferLen);
        // 获取工作缓冲区大小
        DWORD dwNeed, rc;
        ULONG unKnow;
        void* tempMeme;
        rc = getcompressionworkspacesize(CMP_FRM, &dwNeed, &unKnow);
        tempMeme = LocalAlloc(LPTR, dwNeed);
        iOut = 0;
        rc = compress(CMP_FRM, lpIn, iInLen, lpOut + 2, dwOutBufferLen, unKnow, &dwNeed, tempMeme);
    
        LocalFree(tempMeme);
        if (rc != 0)
        {
            zFree(lpOut);
            return NULL;
        }
        *(short*)lpOut = iInLen;
        iOut = dwNeed + 2;
    
        return lpOut;
    
    
    }
    //
    // decompress buffer 
    //
    LPBYTE DecompressBuffer(LPBYTE lpIn, int iInlen, int & iOut)
    {
        GetCompressApis();
        short len = *(short*)lpIn;
        if (len < 0 || len > 1024*8)
        {
            return NULL ;
        }
        LPBYTE lpOut = (LPBYTE)zMalloc(len);
        iOut = 0;
        DWORD dwRc = decompress(CMP_FRM, lpOut, len, lpIn + 2, iInlen - 2, (PULONG)&iOut);
        if (dwRc != 0)
        {
            zFree(lpOut);
            return NULL;
        }
        return lpOut;
    
    
    }
    签名档: 从事网络安全和编程的我,很希望能找到志同道合的朋友交流。 欢迎cn博客的好友拍砖,留言。
  • 相关阅读:
    android monkey测试学习
    学习python的*args和 **kwargs
    TotoiseSVN 使用参考文章
    脚本判断访问终端是什么内核的浏览器
    Git两分钟指南-学习入门参考
    访问WebServcie遇到配额不足的时候,请增加配额
    错误1083:配置成在该可执行程序中运行的这个服务不能执行该服务 【解决】
    C# 如何获取错误所在行数
    mysql中如何使用一句话将一个表的数据导入到另一个表中:insert into ...select
    Windows Server 2008 MetaFile设置占用内存限制
  • 原文地址:https://www.cnblogs.com/M4ster/p/win_api_compress_decompress.html
Copyright © 2011-2022 走看看