Final compression function code :
#include <Windows.h>
#include "huffman.h"
#include "MaxStruct.h"
#include "MaxUtils.h"
#include "Log.h"
int Error(LPSTR __lpszMessage) ;
size_t StringLength(const char * str) ;
LPVOID MemorySetTo0(LPVOID __lpszBuffer,__int64 __qwSize) ;
LPVOID MemoryAlloc(DWORD __dwSize) ;
void MemoryFree(LPVOID __lpBuffer) ;
typedef int (*ptrRtlCompressBuffer)(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,ULONG,PULONG,PVOID) ;
typedef int (*ptrRtlGetCompressionWorkSpaceSize)(USHORT,PULONG,PULONG) ;
ptrRtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize ;
ptrRtlCompressBuffer RtlCompressBuffer ;
HINSTANCE hNtDll ;
int InitCompress(void)
{
if(!hNtDll)
{
hNtDll = LoadLibrary("NtDll.dll") ;
if(hNtDll)
{
RtlGetCompressionWorkSpaceSize = (ptrRtlGetCompressionWorkSpaceSize) GetProcAddress(hNtDll,"RtlGetCompressionWorkSpaceSize") ;
RtlCompressBuffer = (ptrRtlCompressBuffer) GetProcAddress(hNtDll,"RtlCompressBuffer") ;
return (TRUE) ;
}
}
return (FALSE) ;
}
int ExitCompress(void)
{
if(hNtDll)
{
FreeLibrary(hNtDll) ;
hNtDll = NULL ;
return (TRUE) ;
}
return (FALSE) ;
}
LPBYTE LoadThisFile(LPSTR __lpszInputFileName,DWORD *__lpdwBufferSize)
{
HANDLE _hInput ;
DWORD _dwFileSizeLow, _dwFileSizeHigh ;
DWORD _dwTmp ;
LPBYTE _lpBuffer, _lpTmp ;
DWORD _dwBufferSize ;
LPSTR _lpszTmp ;
char _szTmp[1024] ;
_lpBuffer = _lpTmp = NULL ;
_lpszTmp = _szTmp ;
*__lpdwBufferSize = 0 ;
__stosq((unsigned long long *)_lpszTmp,0,sizeof(_szTmp) / ;
_hInput = CreateFile(__lpszInputFileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL) ;
if(_hInput == INVALID_HANDLE_VALUE)
{
wsprintf(_lpszTmp,"Cannot open this file: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
_dwFileSizeLow = GetFileSize(_hInput,&_dwFileSizeHigh) ;
if(_dwFileSizeHigh)
{
CloseHandle(_hInput) ;
wsprintf(_lpszTmp,"This file is too big: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
if(!_dwFileSizeLow && !_dwFileSizeHigh)
{
CloseHandle(_hInput) ;
wsprintf(_lpszTmp,"This file is empty: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
_dwBufferSize = _dwFileSizeLow + 4096 ;
_lpBuffer = MemoryAlloc(_dwBufferSize) ;
if(!_lpBuffer)
{
CloseHandle(_hInput) ;
wsprintf(_lpszTmp,"Not enougth memory available for this file: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
FlushFileBuffers(_hInput) ;
if(!ReadFile(_hInput,_lpBuffer,_dwFileSizeLow,&_dwTmp,NULL))
{
MemoryFree(_lpBuffer) ;
CloseHandle(_hInput) ;
wsprintf(_lpszTmp,"Cannot read this file: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
CloseHandle(_hInput) ;
if(_dwFileSizeLow - _dwTmp)
{
MemoryFree(_lpBuffer) ;
wsprintf(_lpszTmp,"Error while reading this file: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
return ((LPBYTE) Error(_lpszTmp)) ;
}
*__lpdwBufferSize = _dwFileSizeLow + 4096 ;
return (_lpBuffer) ;
}
int CompressMax(LPSTR __lpszInputFileName,LPSTR __lpszOutputFileName)
{
LPBYTE _lpUnCompressedBuffer, _lpCompressedBuffer ;
LPVOID _lpWorkSpaceSize ;
DWORD _dwUnCompressedBufferSize, _dwFinalCompressedSize ;
DWORD _dwCompressBufferWorkSpaceSize, _dwCompressFragmentWorkSpaceSize ;
DWORD _dwCompressedBufferSize ;
HANDLE _hOutput ;
int _bRes ;
COMPRESS _Compress, *_lpCompress ;
char _szTmp[1024] ;
LPSTR _lpszTmp = _szTmp ;
_bRes = FALSE ;
_lpCompress = &_Compress ;
__stosq((unsigned long long *)_lpCompress,0,sizeof(COMPRESS) / ;
_lpUnCompressedBuffer = LoadThisFile(__lpszInputFileName,&_dwUnCompressedBufferSize) ;
if(_lpUnCompressedBuffer)
{
_dwCompressedBufferSize = _dwUnCompressedBufferSize + 4096 ;
_lpCompressedBuffer = MemoryAlloc(_dwCompressedBufferSize) ;
if(_lpCompressedBuffer)
{
_dwCompressBufferWorkSpaceSize = _dwCompressedBufferSize ;
_dwCompressFragmentWorkSpaceSize = 0 ;
_bRes = RtlGetCompressionWorkSpaceSize( COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
&_dwCompressBufferWorkSpaceSize,
&_dwCompressFragmentWorkSpaceSize) ;
_lpWorkSpaceSize = (LPVOID) MemoryAlloc(_dwCompressBufferWorkSpaceSize) ;
if(_lpWorkSpaceSize)
{
_lpCompress->dwAlgorithme = COMPRESS_NT ;
_dwFinalCompressedSize = 0 ;
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-rtlcompressbuffer
_bRes = RtlCompressBuffer( COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
_lpUnCompressedBuffer,
_dwUnCompressedBufferSize,
_lpCompressedBuffer,
_dwCompressedBufferSize,
4096,
&_dwFinalCompressedSize,
_lpWorkSpaceSize) ;
MemoryFree(_lpWorkSpaceSize) ;
if(_bRes != STATUS_SUCCESS)
{
_lpCompress->dwAlgorithme = COMPRESS_HUFFMAN ;
_dwFinalCompressedSize = Huffman_Compress(_lpUnCompressedBuffer,_lpCompressedBuffer,_dwUnCompressedBufferSize) ;
}
}
else
{
_lpCompress->dwAlgorithme = COMPRESS_HUFFMAN ;
_dwFinalCompressedSize = Huffman_Compress(_lpUnCompressedBuffer,_lpCompressedBuffer,_dwUnCompressedBufferSize) ;
}
if(_dwFinalCompressedSize)
{
_hOutput = CreateFile(__lpszOutputFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL) ;
if(_hOutput == INVALID_HANDLE_VALUE)
{
FlushFileBuffers(_hOutput) ;
CloseHandle(_hOutput) ;
DeleteFile(__lpszOutputFileName) ;
wsprintf(_lpszTmp,"Cannot open this file: %s",__lpszOutputFileName) ;
Log(_lpszTmp) ;
_bRes = Error(_lpszTmp) ;
}
else
{
_lpCompress->dwSignature = 'MAXI' ;
_lpCompress->dwMethod = METHOD_COMPRESS ;
_lpCompress->dwUncompressedFileSize = _dwUnCompressedBufferSize ;
_lpCompress->dwCompressedFileSize = _dwFinalCompressedSize ;
lstrcpy(_lpCompress->szUncompressedFileName,__lpszInputFileName) ;
if(MaxWriteFile(_hOutput,(LPBYTE) _lpCompress,sizeof(COMPRESS)))
{
if(MaxWriteFile(_hOutput,_lpCompressedBuffer,_dwFinalCompressedSize))
{
FlushFileBuffers(_hOutput) ;
_bRes = TRUE ;
}
}
else
{
wsprintf(_lpszTmp,"Error while writing to file: %s",__lpszOutputFileName) ;
Log(_lpszTmp) ;
_bRes = Error(_lpszTmp) ;
}
CloseHandle(_hOutput) ;
if(!_bRes)
DeleteFile(__lpszOutputFileName) ;
}
}
else
{
wsprintf(_lpszTmp,"Error while compressing file: %s",__lpszInputFileName) ;
Log(_lpszTmp) ;
_bRes = Error(_lpszTmp) ;
}
MemoryFree(_lpCompressedBuffer) ;
}
MemoryFree(_lpUnCompressedBuffer) ;
}
return (_bRes) ;
}