admin 管理员组文章数量: 1184232
简述
在 Windows 环境下,使用 Windows API 可以进行文件的压缩和解压操作。这提供了一种有效的方式来
处理文件,减小存储空间,并在需要时快速解压。以下是一个使用 Windows API 进行压缩与解压的简单
示例,使用了 ntdll.dll 中的 RtlCompressBuffer 和 RtlDecompressBuffer 函数。
#include<iostream>#include<windows.h>usingnamespace std;//typedef unsigned long NTSTATUS;#defineSTATUS_SUCCESS((NTSTATUS)0x00000000UL)#defineSTATUS_BUFFER_ALL_ZEROS((NTSTATUS)0x00000117UL)#defineSTATUS_INVALID_PARAMETER((NTSTATUS)0xC000000DUL)#defineSTATUS_UNSUPPORTED_COMPRESSION((NTSTATUS)0xC000025FUL)#defineSTATUS_NOT_SUPPORTED_ON_SBS((NTSTATUS)0xC0000300UL)#defineSTATUS_BUFFER_TOO_SMALL((NTSTATUS)0xC0000023UL)#defineSTATUS_BAD_COMPRESSION_BUFFER((NTSTATUS)0xC0000242UL)
HMODULE ntdll =GetModuleHandleA("ntdll.dll");typedefNTSTATUS(__stdcall* _RtlCompressBuffer)(
USHORT CompressionFormatAndEngine,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
ULONG UncompressedChunkSize,
PULONG FinalCompressedSize,
PVOID WorkSpace
);typedefNTSTATUS(__stdcall* _RtlDecompressBuffer)(
USHORT CompressionFormat,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize
);typedefNTSTATUS(__stdcall* _RtlGetCompressionWorkSpaceSize)(
USHORT CompressionFormatAndEngine,
PULONG CompressBufferWorkSpaceSize,
PULONG CompressFragmentWorkSpaceSize
);char*ReadFileWs(constchar* FilePath, DWORD& bufferLen){
HANDLE File =CreateFileA(FilePath, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING,0,NULL);if(File == INVALID_HANDLE_VALUE){returnNULL;}
DWORD _size =GetFileSize(File,0);char* Buffer =newchar[_size +1];bool result =ReadFile(File, Buffer, _size,&bufferLen,0);CloseHandle(File);if(result)return Buffer;elsereturnNULL;}boolWriteFileWs(constchar* 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){returnfalse;}bool result =WriteFile(File, Buffer, bufferLen,&numberBytesRead,NULL);CloseHandle(File);return result;}
UCHAR*compress_buffer(constchar* 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)return0;
VOID* workspace =(VOID*)LocalAlloc(LMEM_FIXED, bufWorkspaceSize);if(workspace ==NULL)return0;
UCHAR* compBuffer =new UCHAR[compBufferLen];
NTSTATUS result =RtlCompressBuffer(
COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD,// CompressionFormatAndEngine(UCHAR*)buffer,// UncompressedBuffer
bufferLen,// UncompressedBufferSize
compBuffer,// CompressedBuffer
compBufferLen,// CompressedBufferSize4096,// UncompressedChunkSize
compBufferSize,// FinalCompressedSize
workspace // WorkSpace);LocalFree(workspace);if(result != STATUS_SUCCESS){return0;}return compBuffer;}
UCHAR*decompress_buffer(constchar* buffer,constint bufferLen,constint 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){;return0;}return uncompBuffer;}intmain(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();return0;}版权声明:本文标题:深入Windows API压缩技巧,优化Flash资源大小 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1773654066a3564428.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论