Windows API压缩与解压
2023-12-29 17:12:45
简述
在 Windows 环境下,使用 Windows API 可以进行文件的压缩和解压操作。这提供了一种有效的方式来
处理文件,减小存储空间,并在需要时快速解压。以下是一个使用 Windows API 进行压缩与解压的简单
示例,使用了 ntdll.dll 中的 RtlCompressBuffer 和 RtlDecompressBuffer 函数。
#include <iostream>
#include <windows.h>
using namespace std;
//typedef unsigned long NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000UL)
#define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS)0x00000117UL)
#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DUL)
#define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS)0xC000025FUL)
#define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS)0xC0000300UL)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023UL)
#define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242UL)
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
typedef NTSTATUS(__stdcall* _RtlCompressBuffer)(
USHORT CompressionFormatAndEngine,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
ULONG UncompressedChunkSize,
PULONG FinalCompressedSize,
PVOID WorkSpace
);
typedef NTSTATUS(__stdcall* _RtlDecompressBuffer)(
USHORT CompressionFormat,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize
);
typedef NTSTATUS(__stdcall* _RtlGetCompressionWorkSpaceSize)(
USHORT CompressionFormatAndEngine,
PULONG CompressBufferWorkSpaceSize,
PULONG CompressFragmentWorkSpaceSize
);
char* ReadFileWs(const char* FilePath, DWORD& bufferLen) {
HANDLE File = CreateFileA(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (File == INVALID_HANDLE_VALUE) {
return NULL;
}
DWORD _size = GetFileSize(File, 0);
char* Buffer = new char[_size + 1];
bool result = ReadFile(File, Buffer, _size, &bufferLen, 0);
CloseHandle(File);
if (result)return Buffer;
else return NULL;
}
bool WriteFileWs(const char* 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) {
return false;
}
bool result = WriteFile(File, Buffer, bufferLen, &numberBytesRead, NULL);
CloseHandle(File);
return result;
}
UCHAR* compress_buffer(const char* 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) return 0;
VOID* workspace = (VOID*)LocalAlloc(LMEM_FIXED, bufWorkspaceSize);
if (workspace == NULL) return 0;
UCHAR* compBuffer = new UCHAR[compBufferLen];
NTSTATUS result = RtlCompressBuffer(
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, // CompressionFormatAndEngine
(UCHAR*)buffer, // UncompressedBuffer
bufferLen, // UncompressedBufferSize
compBuffer, // CompressedBuffer
compBufferLen, // CompressedBufferSize
4096, // UncompressedChunkSize
compBufferSize, // FinalCompressedSize
workspace // WorkSpace
);
LocalFree(workspace);
if (result != STATUS_SUCCESS) {
return 0;
}
return compBuffer;
}
UCHAR* decompress_buffer(const char* buffer, const int bufferLen, const int 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) {
;
return 0;
}
return uncompBuffer;
}
int main(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();
return 0;
}
文章来源:https://blog.csdn.net/qq_18811919/article/details/131045146
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!