Literatecode

How to write your own WinZip

Nov 11, 2006

Have you ever wanted to make your very own data compression utility to beat WinZip, without being confused by all that math?

Well, here is your chance.

Three Windows Native API functions will do the trick:

  •  RtlCompressBuffer
  •  RtlDecompressBuffer
  •  RtlGetCompressionWorkSpaceSize
  

Without further ado, here is the C code example of how to use these functions:

  #include <windows.h>
  #include <stdlib.h>
  #include <stdio.h>

  /*
  #define COMPRESSION_FORMAT_LZNT1    0x0002
  #define COMPRESSION_ENGINE_STANDARD 0x0000 // Standart compression
  #define COMPRESSION_ENGINE_MAXIMUM  0x0100 // Maximum (slowest but better)
  */

  #define CMP_FRM     COMPRESSION_FORMAT_LZNT1|COMPRESSION_ENGINE_MAXIMUM

  typedef DWORD (__stdcall *RtlCompressBuffer_Fn)(
                      IN ULONG    CompressionFormat,
                      IN PVOID    SourceBuffer,
                      IN ULONG    SourceBufferLength,
                      OUT PVOID   DestinationBuffer,
                      IN ULONG    DestinationBufferLength,
                      IN ULONG    Unknown,
                      OUT PULONG  pDestinationSize,
                      IN PVOID    WorkspaceBuffer );

  typedef DWORD (__stdcall *RtlDecompressBuffer_Fn)(
                      IN ULONG    CompressionFormat,
                      OUT PVOID   DestinationBuffer,
                      IN ULONG    DestinationBufferLength,
                      IN PVOID    SourceBuffer,
                      IN ULONG    SourceBufferLength,
                      OUT PULONG  pDestinationSize );

  typedef DWORD (__stdcall *RtlGetCompressionWorkSpaceSize_Fn)(
                      IN ULONG    CompressionFormat,
                      OUT PULONG  pNeededBufferSize,
                      OUT PULONG  pUnknown );

  int main (void)
  {
    char dst[512] = {0};
    char buf[] = "abcabcabcabcabcabcabc";
    HANDLE hDLL;
    RtlCompressBuffer_Fn fcmp;
    RtlDecompressBuffer_Fn fdcp;
    RtlGetCompressionWorkSpaceSize_Fn fgcw;
    DWORD dw, xx, rc;
    void *tmpMem;
    register unsigned char i;

    hDLL = LoadLibrary ("ntdll.dll");
    if ( hDLL != NULL )
    {
      fcmp = (RtlCompressBuffer_Fn) GetProcAddress(hDLL, "RtlCompressBuffer");
      fdcp = (RtlDecompressBuffer_Fn) GetProcAddress(hDLL, "RtlDecompressBuffer");
      fgcw = (RtlGetCompressionWorkSpaceSize_Fn)
              GetProcAddress(hDLL, "RtlGetCompressionWorkSpaceSize");

      if ( fcmp && fdcp && fgcw)
      {
          rc = (*fgcw)(CMP_FRM, &dw,  &xx);
          tmpMem = LocalAlloc(LPTR, dw);
          rc = (*fcmp)(CMP_FRM, buf, sizeof(buf), dst, sizeof(dst), xx, &dw, tmpMem);
          LocalFree(tmpMem);
          for (i = 0; i< dw; i++) printf("%c", (BYTE) dst[i]); printf("\n--\n");
          for (i = 0; i< sizeof(buf); i++) buf[i] = 0;

          rc = (*fdcp)(CMP_FRM, buf, sizeof(buf), dst, dw, &xx);
          for (i = 0; i< xx; i++) printf("%c", (BYTE) buf[i]); printf("\n");
      }

      FreeLibrary(hDLL);
    }

    return 0;
  }
  

Updated on Nov 15, 2011

These functions were undocumented by Microsoft at the time this note was written back in 2006. Today all three are included in the Windows Driver Kit documentation, e.g. RtlCompressFunction


Contact Us

E-mail

hello@literatecode.com

Phone

+1 202 470 0042

Regular Mail

Literatecode
22 Sin Ming Lane #06-76
Midview City
Singapore 573969