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'\0' };
    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', '\0' };
    static char szRtlDecompressBuffer[] = { 'R', 't', 'l', 'D', 'e', 'c', 'o', 'm', 'p', 'r', 'e', 's', 's', 'B', 'u', 'f', 'f', 'e', 'r', '\0' };
    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', '\0' };
    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;


}

 

posted @ 2016-06-13 15:45  m4sterx  阅读(944)  评论(0编辑  收藏  举报