当前位置: 首页 > news >正文

C/C++ 使用API实现数据压缩与解压缩

在Windows编程中,经常会遇到需要对数据进行压缩和解压缩的情况,数据压缩是一种常见的优化手段,能够减小数据的存储空间并提高传输效率。Windows提供了这些API函数,本文将深入探讨使用Windows API进行数据压缩与解压缩的过程,主要使用ntdll.dll库中的相关函数。

RtlGetCompressionWorkSpaceSize

RtlGetCompressionWorkSpaceSize 函数,位于ntdll.dll库中。该函数用于获取数据压缩所需的工作空间大小。CompressionFormatAndEngine参数指定压缩格式和引擎,CompressBufferWorkSpaceSizeCompressFragmentWorkSpaceSize分别用于输出缓冲区和片段的工作空间大小。

以下是该函数的声明:

typedef NTSTATUS(WINAPI *typedef_RtlGetCompressionWorkSpaceSize)(_In_  USHORT CompressionFormatAndEngine,_Out_ PULONG CompressBufferWorkSpaceSize,_Out_ PULONG CompressFragmentWorkSpaceSize
);

该函数有以下参数:

  • CompressionFormatAndEngine:指定压缩格式和引擎的参数。
  • CompressBufferWorkSpaceSize:用于输出压缩缓冲区工作空间大小的指针。
  • CompressFragmentWorkSpaceSize:用于输出压缩片段工作空间大小的指针。

函数返回NTSTATUS类型的状态码,其中STATUS_SUCCESS表示成功执行。

在使用这个函数时,你需要提供足够大的缓冲区来存储工作空间大小。可以按照以下步骤使用该函数:

  • 加载 ntdll.dll 库。
  • 获取 RtlGetCompressionWorkSpaceSize 函数地址。
  • 定义变量用于存储工作空间大小。
  • 调用 RtlGetCompressionWorkSpaceSize 函数,获取工作空间大小。
RtlCompressBuffer

RtlCompressBuffer 同样位于ntdll.dll库中。该函数用于将数据进行压缩。CompressionFormatAndEngine参数指定压缩格式和引擎,UncompressedBufferUncompressedBufferSize表示输入的未压缩数据,CompressedBufferCompressedBufferSize表示输出的压缩数据,UncompressedChunkSize表示未压缩数据的块大小,FinalCompressedSize表示最终压缩后的大小,WorkSpace表示用于工作的缓冲区。

以下是该函数的声明:

typedef NTSTATUS(WINAPI *typedef_RtlCompressBuffer)(_In_  USHORT CompressionFormatAndEngine,_In_  PUCHAR UncompressedBuffer,_In_  ULONG  UncompressedBufferSize,_Out_ PUCHAR CompressedBuffer,_In_  ULONG  CompressedBufferSize,_In_  ULONG  UncompressedChunkSize,_Out_ PULONG FinalCompressedSize,_In_  PVOID  WorkSpace
);

该函数的参数包括:

  • CompressionFormatAndEngine:指定压缩格式和引擎的参数。
  • UncompressedBuffer:指向待压缩数据的指针。
  • UncompressedBufferSize:待压缩数据的大小。
  • CompressedBuffer:指向存储压缩数据的缓冲区的指针。
  • CompressedBufferSize:存储压缩数据的缓冲区的大小。
  • UncompressedChunkSize:未压缩的数据块的大小。
  • FinalCompressedSize:用于输出最终压缩数据的大小的指针。
  • WorkSpace:用于提供工作空间的指针。

函数返回NTSTATUS类型的状态码,其中STATUS_SUCCESS表示成功执行。

在使用这个函数时,你需要提供足够大的缓冲区来存储压缩后的数据。可以按照以下步骤使用该函数:

  • 加载ntdll.dll库。
  • 获取RtlCompressBuffer函数地址。
  • 定义变量并分配内存用于存储未压缩的数据和压缩后的数据。
  • 定义变量用于存储工作空间。
  • 调用RtlCompressBuffer函数,将数据进行压缩。
  • 处理压缩后的数据。
RtlDecompressBuffer

RtlDecompressBuffer 同样位于ntdll.dll库中。该函数用于将压缩数据进行解压缩。CompressionFormat参数指定压缩格式,UncompressedBufferUncompressedBufferSize表示输出的未压缩数据,CompressedBufferCompressedBufferSize表示输入的压缩数据,FinalUncompressedSize表示最终解压缩后的大小。

以下是该函数的声明:

typedef NTSTATUS(WINAPI *typedef_RtlDecompressBuffer)(_In_  USHORT CompressionFormat,_Out_ PUCHAR UncompressedBuffer,_In_  ULONG  UncompressedBufferSize,_In_  PUCHAR CompressedBuffer,_In_  ULONG  CompressedBufferSize,_Out_ PULONG FinalUncompressedSize
);

该函数的参数包括:

  • CompressionFormat:指定解压缩的格式。
  • UncompressedBuffer:指向存储解压后数据的缓冲区的指针。
  • UncompressedBufferSize:存储解压后数据的缓冲区的大小。
  • CompressedBuffer:指向待解压数据的指针。
  • CompressedBufferSize:待解压数据的大小。
  • FinalUncompressedSize:用于输出最终解压后数据的大小的指针。

函数返回NTSTATUS类型的状态码,其中STATUS_SUCCESS表示成功执行。

在使用这个函数时,你需要提供足够大的缓冲区来存储解压后的数据。可以按照以下步骤使用该函数:

  • 加载ntdll.dll库。
  • 获取RtlDecompressBuffer函数地址。
  • 定义变量并分配内存用于存储待解压的数据和解压后的数据。
  • 调用RtlDecompressBuffer函数,将数据进行解压。
  • 处理解压后的数据。
// 代码来源 《WINDOWS黑客编程技术详解》
// 作者:甘迪文
#include <Windows.h>
#include <iostream>
#include <windef.h>typedef NTSTATUS(WINAPI *typedef_RtlGetCompressionWorkSpaceSize)(_In_  USHORT CompressionFormatAndEngine,_Out_ PULONG CompressBufferWorkSpaceSize,_Out_ PULONG CompressFragmentWorkSpaceSize);typedef NTSTATUS(WINAPI *typedef_RtlCompressBuffer)(_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 *typedef_RtlDecompressBuffer)(_In_  USHORT CompressionFormat,_Out_ PUCHAR UncompressedBuffer,_In_  ULONG  UncompressedBufferSize,_In_  PUCHAR CompressedBuffer,_In_  ULONG  CompressedBufferSize,_Out_ PULONG FinalUncompressedSize);// 数据压缩
BOOL CompressData(BYTE *pUncompressData, DWORD dwUncompressDataLength, BYTE **ppCompressData, DWORD *pdwCompressDataLength)
{BOOL bRet = FALSE;NTSTATUS status = 0;HMODULE hModule = NULL;typedef_RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = NULL;typedef_RtlCompressBuffer RtlCompressBuffer = NULL;DWORD dwWorkSpaceSize = 0, dwFragmentWorkSpaceSize = 0;BYTE *pWorkSpace = NULL;BYTE *pCompressData = NULL;DWORD dwCompressDataLength = 4096;DWORD dwFinalCompressSize = 0;do{// 加载 ntdll.dll hModule = ::LoadLibrary("ntdll.dll");if (NULL == hModule){ShowError("LoadLibrary");break;}// 获取 RtlGetCompressionWorkSpaceSize 函数地址RtlGetCompressionWorkSpaceSize = (typedef_RtlGetCompressionWorkSpaceSize)::GetProcAddress(hModule, "RtlGetCompressionWorkSpaceSize");if (NULL == RtlGetCompressionWorkSpaceSize){ShowError("GetProcAddress");break;}// 获取 RtlCompressBuffer 函数地址RtlCompressBuffer = (typedef_RtlCompressBuffer)::GetProcAddress(hModule, "RtlCompressBuffer");if (NULL == RtlCompressBuffer){ShowError("GetProcAddress");break;}// 获取WorkSpqce大小status = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, &dwWorkSpaceSize, &dwFragmentWorkSpaceSize);if (0 != status){break;}// 申请动态内存pWorkSpace = new BYTE[dwWorkSpaceSize];if (NULL == pWorkSpace){break;}::RtlZeroMemory(pWorkSpace, dwWorkSpaceSize);while (TRUE){// 申请动态内存pCompressData = new BYTE[dwCompressDataLength];if (NULL == pCompressData){break;}::RtlZeroMemory(pCompressData, dwCompressDataLength);// 调用RtlCompressBuffer压缩数据RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, 4096, &dwFinalCompressSize, (PVOID)pWorkSpace);if (dwCompressDataLength < dwFinalCompressSize){// 释放内存if (pCompressData){delete[]pCompressData;pCompressData = NULL;}dwCompressDataLength = dwFinalCompressSize;}else{break;}}// 返回*ppCompressData = pCompressData;*pdwCompressDataLength = dwFinalCompressSize;bRet = TRUE;} while (FALSE);// 释放if (pWorkSpace){delete[]pWorkSpace;pWorkSpace = NULL;}if (hModule){::FreeLibrary(hModule);}return bRet;
}// 数据解压缩
BOOL UncompressData(BYTE *pCompressData, DWORD dwCompressDataLength, BYTE **ppUncompressData, DWORD *pdwUncompressDataLength)
{BOOL bRet = FALSE;HMODULE hModule = NULL;typedef_RtlDecompressBuffer RtlDecompressBuffer = NULL;BYTE *pUncompressData = NULL;DWORD dwUncompressDataLength = 4096;DWORD dwFinalUncompressSize = 0;do{// 加载 ntdll.dll hModule = ::LoadLibrary("ntdll.dll");if (NULL == hModule){break;}// 获取 RtlDecompressBuffer 函数地址RtlDecompressBuffer = (typedef_RtlDecompressBuffer)::GetProcAddress(hModule, "RtlDecompressBuffer");if (NULL == RtlDecompressBuffer){break;}while (TRUE){// 申请动态内存pUncompressData = new BYTE[dwUncompressDataLength];if (NULL == pUncompressData){break;}::RtlZeroMemory(pUncompressData, dwUncompressDataLength);// 调用RtlCompressBuffer压缩数据RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, &dwFinalUncompressSize);if (dwUncompressDataLength < dwFinalUncompressSize){// 释放内存if (pUncompressData){delete[]pUncompressData;pUncompressData = NULL;}dwUncompressDataLength = dwFinalUncompressSize;}else{break;}}// 返回*ppUncompressData = pUncompressData;*pdwUncompressDataLength = dwFinalUncompressSize;bRet = TRUE;} while (FALSE);// 释放if (hModule){::FreeLibrary(hModule);}return bRet;
}int main(int argc, char *argv[])
{DWORD i = 0;BOOL bRet = FALSE;char szBuffer[] = "DDDDDDDDDDGGGGGGGGGGGG";DWORD dwBufferLength = ::lstrlen(szBuffer);BYTE *pCompressData = NULL;DWORD dwCompressDataLength = 0;BYTE *pUncompressData = NULL;DWORD dwUncompressDataLength = 0;// 压缩数据CompressData((BYTE *)szBuffer, dwBufferLength, &pCompressData, &dwCompressDataLength);// 解压数据UncompressData(pCompressData, dwCompressDataLength, &pUncompressData, &dwUncompressDataLength);// 显示printf("原数据为:\n");for (i = 0; i < dwBufferLength; i++){printf("%X ", szBuffer[i]);}printf("\n\n压缩数据为:\n");for (i = 0; i < dwCompressDataLength; i++){printf("%X ", pCompressData[i]);}printf("\n\n解压缩数据为:\n");for (i = 0; i < dwUncompressDataLength; i++){printf("%X ", pUncompressData[i]);}printf("\n");// 释放if (pUncompressData){delete[]pUncompressData;pUncompressData = NULL;}if (pCompressData){delete[]pCompressData;pCompressData = NULL;}system("pause");return 0;
}
http://www.lryc.cn/news/239794.html

相关文章:

  • Visual Studio连接unity编辑器_unity基础开发教程
  • 2023亚太杯数学建模B题思路分析 - 玻璃温室中的微气候法规
  • 轻量封装WebGPU渲染系统示例<37>- 多个局部点光源应用于非金属材质形成的效果(源码)
  • 设备状态监测与故障诊断系统的作用
  • 浮点数运算精度丢失,如何解决
  • 使用微信小程序openMapApp接口,报错问题解决openMapApp:fail invaild coord
  • 2023亚太杯数学建模思路 - 案例:粒子群算法
  • 【开源】基于JAVA的开放实验室管理系统
  • LeetCode48旋转图像
  • sql手工注入漏洞测试(MYSQL)-墨者-url信息
  • 52.seata分布式事务
  • HTML所有功能大汇总
  • 层次分析法--可以帮助你做决策的简单算法
  • docker启动链接sqlservr的镜像时报SSl错误
  • 力扣:175. 组合两个表(Python3)
  • 【libGDX】使用Mesh绘制矩形
  • X2Keyarch迁移工具实战 | 将CentOS高效迁移至浪潮云峦操作系统KeyarchOS
  • 基于VM虚拟机下Ubuntu18.04系统,Hadoop的安装与详细配置
  • 【图像分类】基于深度学习的垃圾分类系统的设计与实现(ResNet网络,附代码和数据集)
  • MFS分布式文件系统
  • Hadoop -hdfs的读写请求
  • 【c++Leetcode】206. Reverse Linked List
  • [项目管理-33/创业之路-87/管理者与领导者-127]:如何提升自己项目管理的能力和水平
  • 记录一次因内存不足而导致hiveserver2和namenode进程宕机的排查
  • c# 基础语法
  • 【译】什么时候使用 Spring 6 JdbcClient
  • VR全景:赋能城市园区建设,打造3DVR城市名片
  • 孟德尔随机化写作技巧mr
  • 社会媒体营销提问常用的ChatGPT通用提示词模板
  • 智慧储能边缘计算网关应用,提升能源效率