We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Sep 28, 2010 4:55:56 PM
{
untNtCompress
by ErazerZ
25. Juni 2006
Orginal assembler code by Max_Power
Thanks to Veritas for Idea.
Compression types:
COMPRESSION_FORMAT_NONE
COMPRESSION_FORMAT_DEFAULT
COMPRESSION_FORMAT_LZNT1
COMPRESSION_FORMAT_NS3
COMPRESSION_FORMAT_NS15
COMPRESSION_FORMAT_SPARSE
Example:
CompressFile('C:\MyFile.dat', 'C:\Compressed.dat', COMPRESSION_FORMAT_LZNT1 or COMPRESSION_ENGINE_MAXIMUM);
DecompressFile('C:\Compressed.dat', 'C:\Uncompressed.dat', COMPRESSION_FORMAT_LZNT1 or COMPRESSION_ENGINE_MAXIMUM);
you can also call it like that:
CompressFile('C:\MyFile.dat', 'C:\Compressed.dat');
DecompressFile('C:\Compressed.dat', 'C:\Uncompressed.dat');
}
unit untNtCompress;
//ErazerZ
interface
uses Windows;
const
COMPRESSION_FORMAT_NONE = $00000000;
COMPRESSION_FORMAT_DEFAULT = $00000001;
COMPRESSION_FORMAT_LZNT1 = $00000002;
COMPRESSION_FORMAT_NS3 = $00000003;
COMPRESSION_FORMAT_NS15 = $0000000F;
COMPRESSION_FORMAT_SPARSE = $00004000;
COMPRESSION_ENGINE_STANDARD = $00000000;
COMPRESSION_ENGINE_MAXIMUM = $00000100;
COMPRESSION_ENGINE_HIBER = $00000200;
function CompressMemory(lpMemory: Pointer; var Size: Cardinal; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Pointer;
function DecompressMemory(lpMemory: Pointer; var Size: Cardinal; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Pointer;
function CompressFile(lpFilename, lpOutputfile: String; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Boolean;
function DecompressFile(lpFilename, lpOutputfile: String; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Boolean;
implementation
const
ntdll = 'ntdll.dll';
function RtlGetCompressionWorkSpaceSize(CompressionFormatAndEngine: ULONG; CompressBufferWorkSpaceSize, CompressFragmentWorkSpaceSize : PULONG): Cardinal; stdcall; external ntdll name 'RtlGetCompressionWorkSpaceSize';
function RtlCompressBuffer(CompressionFormatAndEngine: ULONG; SourceBuffer: Pointer; SourceBufferLength: ULONG; DestinationBuffer: Pointer; DestinationBufferLength: ULONG;
SourceChunkSize: ULONG; pDestinationSize: PULONG; WorkspaceBuffer: Pointer): Cardinal; stdcall; external ntdll name 'RtlCompressBuffer';
function RtlDeCompressBuffer(CompressionFormatAndEngine:ULONG; DestinationBuffer: Pointer; DestinationBufferLength: ULONG; SourceBuffer: Pointer; SourceBufferLength: ULONG;
pDestinationSize: PULONG): Cardinal; stdcall; external ntdll name 'RtlDecompressBuffer';
function GetPointerSize(lpBuffer: Pointer): Cardinal;
begin
if lpBuffer = nil then
Result := Cardinal(-1)
else
Result := Cardinal(Pointer(Cardinal(lpBuffer) -4)^) and $7FFFFFFC -4;
end;
{
Result: Pointer of the Compressed Buffer.
lpMemory: Buffer that should be compressed.
var Size: Length of how much should be compressed, later the compressed size.
dwCompression: Compression type.
}
function CompressMemory(lpMemory: Pointer; var Size: Cardinal; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Pointer;
var
lpWorkspace, lpOutput: Pointer;
dwTemp, dwOutputSize: DWORD;
begin
Result := nil;
if Size = INVALID_HANDLE_VALUE then
Size := GetPointerSize(lpMemory);
dwOutputSize := Size;
lpOutput := VirtualAlloc(nil, Size, MEM_COMMIT, PAGE_READWRITE);
if lpOutput <> nil then
begin
RtlGetCompressionWorkSpaceSize(dwCompression, @dwTemp, @dwOutputSize);
lpWorkspace := VirtualAlloc(nil, dwTemp, MEM_COMMIT, PAGE_READWRITE);
if lpWorkspace <> nil then
begin
dwTemp := 0;
RtlCompressBuffer(dwCompression, lpMemory, Size, lpOutput, Size, 0, @dwTemp, lpWorkspace);
if dwTemp <> 0 then
begin
VirtualFree(lpWorkspace, 0, MEM_RELEASE);
Size := dwTemp;
Result := lpOutput;
end;
end;
end;
end;
{
Result: Pointer of the Decompressed Buffer.
lpMemory: Buffer that should be decompressed.
var Size: Length of how much should be decompressed (FileSize), later the decompressed size.
dwCompression: Compression type.
}
function DecompressMemory(lpMemory: Pointer; var Size: Cardinal; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Pointer;
var
lpOutput: Pointer;
dwTemp, dwOutputSize: DWORD;
begin
Result := nil;
dwOutputSize := Round(Size * 12.5);
lpOutput := VirtualAlloc(nil, dwOutputSize, MEM_COMMIT, PAGE_READWRITE);
if lpOutput <> nil then
begin
begin
dwTemp := 0;
RtlDecompressBuffer(dwCompression, lpOutput, dwOutputSize, lpMemory, Size, @dwTemp);
if dwTemp <> 0 then
begin
Size := dwTemp;
Result := lpOutput;
end;
end;
end;
end;
function CompressFile(lpFilename, lpOutputfile: String; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Boolean;
var
hFileIn, hFileMappingObjectIn,
hFileOut: THandle;
dwFileSize, lpNumberOfBytesWritten: DWORD;
lpBaseAddressIn, lpBuffer: Pointer;
begin
Result := False;
hFileIn := CreateFile(PChar(lpFilename), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
if hFileIn = INVALID_HANDLE_VALUE then
Exit;
dwFileSize := GetFileSize(hFileIn, nil);
hFileMappingObjectIn := CreateFileMapping(hFileIn, nil, PAGE_READWRITE, 0, 0, nil);
lpBaseAddressIn := MapViewOfFile(hFileMappingObjectIn, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0);
lpBuffer := CompressMemory(lpBaseAddressIn, dwFileSize, dwCompression);
hFileOut := CreateFile(PChar(lpOutputfile), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
if hFileOut <> INVALID_HANDLE_VALUE then
begin
WriteFile(hFileOut, lpBuffer^, dwFileSize, lpNumberOfBytesWritten, nil);
CloseHandle(hFileOut);
end;
UnmapViewOfFile(lpBaseAddressIn);
CloseHandle(hFileMappingObjectIn);
CloseHandle(hFileIn);
end;
function DecompressFile(lpFilename, lpOutputfile: String; dwCompression: DWORD = COMPRESSION_FORMAT_LZNT1): Boolean;
var
hFileIn, hFileMappingObjectIn,
hFileOut: THandle;
dwFileSize, lpNumberOfBytesWritten: DWORD;
lpBaseAddressIn, lpBuffer: Pointer;
begin
Result := False;
hFileIn := CreateFile(PChar(lpFilename), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_ALWAYS, 0, 0);
if hFileIn = INVALID_HANDLE_VALUE then
Exit;
dwFileSize := GetFileSize(hFileIn, nil);
hFileMappingObjectIn := CreateFileMapping(hFileIn, nil, PAGE_READWRITE, 0, 0, nil);
lpBaseAddressIn := MapViewOfFile(hFileMappingObjectIn, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0);
lpBuffer := DecompressMemory(lpBaseAddressIn, dwFileSize, dwCompression);
hFileOut := CreateFile(PChar(lpOutputfile), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
if hFileOut <> INVALID_HANDLE_VALUE then
begin
WriteFile(hFileOut, lpBuffer^, dwFileSize, lpNumberOfBytesWritten, nil);
CloseHandle(hFileOut);
end;
VirtualFree(lpBuffer, 0, MEM_RELEASE);
UnmapViewOfFile(lpBaseAddressIn);
CloseHandle(hFileMappingObjectIn);
CloseHandle(hFileIn);
end;
end.