Compress.hpp
#pragma once
#include
typedef NTSTATUS(WINAPI *pRtlGetCompressionWorkSpaceSize)(
_In_ USHORT CompressionFormatAndEngine,
_Out_ PULONG CompressBufferWorkSpaceSize,
_Out_ PULONG CompressFragmentWorkSpaceSize
);
typedef NTSTATUS(WINAPI *pRtlCompressBuffer)(
_In_ USHORT CompressionFormatAndEngine,
_In_ PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_Out_ PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_ ULONG UncompressedChunkSize,
_Out_ PULONG FinalCompressedSize,
_In_ PVOID WorkSpace
);
typedef NTSTATUS(WINAPI *pRtlDecompressBuffer)(
_In_ USHORT CompressionFormat,
_Out_ PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_In_ PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_Out_ PULONG FinalUncompressedSize
);
pRtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = NULL;
pRtlCompressBuffer RtlCompressBuffer = NULL;
pRtlDecompressBuffer RtlDecompressBuffer = NULL;
bool InitAPI(){
auto hDll = LoadLibrary("ntdll.dll");
if (!hDll){
return FALSE;
}
RtlGetCompressionWorkSpaceSize = (pRtlGetCompressionWorkSpaceSize)GetProcAddress(hDll, "RtlGetCompressionWorkSpaceSize");
if (!RtlGetCompressionWorkSpaceSize){
return FALSE;
}
RtlCompressBuffer = (pRtlCompressBuffer)GetProcAddress(hDll, "RtlCompressBuffer");
if (!RtlCompressBuffer){
return FALSE;
}
RtlDecompressBuffer = (pRtlDecompressBuffer)GetProcAddress(hDll, "RtlDecompressBuffer");
if (!RtlDecompressBuffer){
return FALSE;
}
return TRUE;
}
bool Compress(BYTE* data, DWORD size, BYTE* buffer, DWORD &bufsize){
DWORD dwWorkSpaceSize = 0, dwFragmentWorkSpaceSize = 0;
BYTE *pWorkSpace = NULL;
BYTE *pCompressData = NULL;
NTSTATUS status = FALSE;
DWORD dwCompressDataLength = 4096;
DWORD dwFinalCompressSize = 0;
status = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, &dwWorkSpaceSize, &dwFragmentWorkSpaceSize);
if (status != 0){
return FALSE;
}
pWorkSpace = new BYTE[dwWorkSpaceSize];
if (NULL == pWorkSpace)
{
return FALSE;
}
::RtlZeroMemory(pWorkSpace, dwWorkSpaceSize);
status = RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, data, size, buffer, bufsize, 4096, &dwFinalCompressSize, (PVOID)pWorkSpace);
if (status != 0){
return FALSE;
}
delete[] pWorkSpace;
bufsize = dwFinalCompressSize;
return TRUE;
}
bool Decompress(BYTE* data, DWORD size, BYTE* buffer, DWORD &bufsize){
DWORD dwWorkSpaceSize = 0, dwFragmentWorkSpaceSize = 0;
BYTE *pWorkSpace = NULL;
BYTE *pCompressData = NULL;
NTSTATUS status = FALSE;
DWORD dwCompressDataLength = 4096;
DWORD dwFinalCompressSize = 0;
status = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, &dwWorkSpaceSize, &dwFragmentWorkSpaceSize);
if (status != 0){
return FALSE;
}
pWorkSpace = new BYTE[dwWorkSpaceSize];
if (pWorkSpace == NULL){
return FALSE;
}
RtlZeroMemory(pWorkSpace, dwWorkSpaceSize);
status = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buffer, bufsize, data, size, &dwFinalCompressSize);
if (status != 0){
return FALSE;
}
delete[] pWorkSpace;
bufsize = dwFinalCompressSize;
return TRUE;
}
使用方法
// Fork.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Compress.hpp"
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
BYTE data[] = "DDDDDDDDDDGGGGGGGGGGGG";
auto buffer = new BYTE[100];
DWORD size = 100;
if (!InitAPI()){
cout << "InitFailed" << endl;
return -1;
}
if (Compress(data, 22, buffer, size)){
for (int i = 0; i < size; i++){
printf("%02X ", buffer[i]);
}
DWORD bufSize = 100;
auto destBuf = new BYTE[bufSize];
if (!destBuf){
return -1;
}
if (Decompress(buffer, size, destBuf, bufSize)){
for (int i = 0; i < bufSize; i++){
printf("%c ", destBuf[i]);
}
}
}
else{
cout << "Failed" << endl;
}
delete[] buffer;
getchar();
return 0;
}