ReactOS  0.4.15-dev-1049-g1062a29
compress.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for compress.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define COMPRESSION_FORMAT_MASK   0x00FF
 
#define COMPRESSION_ENGINE_MASK   0xFF00
 

Functions

static PUCHAR lznt1_decompress_chunk (UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size)
 
static NTSTATUS lznt1_decompress (UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size, ULONG offset, ULONG *final_size, UCHAR *workspace)
 
static NTSTATUS RtlpCompressBufferLZNT1 (UCHAR *src, ULONG src_size, UCHAR *dst, ULONG dst_size, ULONG chunk_size, ULONG *final_size, UCHAR *workspace)
 
static NTSTATUS RtlpWorkSpaceSizeLZNT1 (USHORT Engine, PULONG BufferAndWorkSpaceSize, PULONG FragmentWorkSpaceSize)
 
NTSTATUS NTAPI RtlCompressBuffer (IN USHORT CompressionFormatAndEngine, IN PUCHAR UncompressedBuffer, IN ULONG UncompressedBufferSize, OUT PUCHAR CompressedBuffer, IN ULONG CompressedBufferSize, IN ULONG UncompressedChunkSize, OUT PULONG FinalCompressedSize, IN PVOID WorkSpace)
 
NTSTATUS NTAPI RtlCompressChunks (IN PUCHAR UncompressedBuffer, IN ULONG UncompressedBufferSize, OUT PUCHAR CompressedBuffer, IN ULONG CompressedBufferSize, IN OUT PCOMPRESSED_DATA_INFO CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN PVOID WorkSpace)
 
NTSTATUS NTAPI RtlDecompressChunks (OUT PUCHAR UncompressedBuffer, IN ULONG UncompressedBufferSize, IN PUCHAR CompressedBuffer, IN ULONG CompressedBufferSize, IN PUCHAR CompressedTail, IN ULONG CompressedTailSize, IN PCOMPRESSED_DATA_INFO CompressedDataInfo)
 
NTSTATUS NTAPI RtlDecompressFragment (IN USHORT format, OUT PUCHAR uncompressed, IN ULONG uncompressed_size, IN PUCHAR compressed, IN ULONG compressed_size, IN ULONG offset, OUT PULONG final_size, IN PVOID workspace)
 
NTSTATUS NTAPI RtlDecompressBuffer (IN USHORT CompressionFormat, OUT PUCHAR UncompressedBuffer, IN ULONG UncompressedBufferSize, IN PUCHAR CompressedBuffer, IN ULONG CompressedBufferSize, OUT PULONG FinalUncompressedSize)
 
NTSTATUS NTAPI RtlDescribeChunk (IN USHORT CompressionFormat, IN OUT PUCHAR *CompressedBuffer, IN PUCHAR EndOfCompressedBufferPlus1, OUT PUCHAR *ChunkBuffer, OUT PULONG ChunkSize)
 
NTSTATUS NTAPI RtlGetCompressionWorkSpaceSize (IN USHORT CompressionFormatAndEngine, OUT PULONG CompressBufferAndWorkSpaceSize, OUT PULONG CompressFragmentWorkSpaceSize)
 
NTSTATUS NTAPI RtlReserveChunk (IN USHORT CompressionFormat, IN OUT PUCHAR *CompressedBuffer, IN PUCHAR EndOfCompressedBufferPlus1, OUT PUCHAR *ChunkBuffer, IN ULONG ChunkSize)
 

Macro Definition Documentation

◆ COMPRESSION_ENGINE_MASK

#define COMPRESSION_ENGINE_MASK   0xFF00

Definition at line 21 of file compress.c.

◆ COMPRESSION_FORMAT_MASK

#define COMPRESSION_FORMAT_MASK   0x00FF

Definition at line 20 of file compress.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file compress.c.

Function Documentation

◆ lznt1_decompress()

static NTSTATUS lznt1_decompress ( UCHAR dst,
ULONG  dst_size,
UCHAR src,
ULONG  src_size,
ULONG  offset,
ULONG final_size,
UCHAR workspace 
)
static

Definition at line 95 of file compress.c.

97 {
98  UCHAR *src_cur = src, *src_end = src + src_size;
99  UCHAR *dst_cur = dst, *dst_end = dst + dst_size;
100  ULONG chunk_size, block_size;
101  WORD chunk_header;
102  UCHAR *ptr;
103 
104  if (src_cur + sizeof(WORD) > src_end)
106 
107  /* skip over chunks which have a big distance (>= 0x1000) to the destination offset */
108  while (offset >= 0x1000 && src_cur + sizeof(WORD) <= src_end)
109  {
110  /* read chunk header and extract size */
111  chunk_header = *(WORD *)src_cur;
112  src_cur += sizeof(WORD);
113  if (!chunk_header) goto out;
114  chunk_size = (chunk_header & 0xFFF) + 1;
115 
116  /* ensure we have enough buffer to process chunk */
117  if (src_cur + chunk_size > src_end)
119 
120  src_cur += chunk_size;
121  offset -= 0x1000;
122  }
123 
124  /* this chunk is can be included partially */
125  if (offset && src_cur + sizeof(WORD) <= src_end)
126  {
127  /* read chunk header and extract size */
128  chunk_header = *(WORD *)src_cur;
129  src_cur += sizeof(WORD);
130  if (!chunk_header) goto out;
131  chunk_size = (chunk_header & 0xFFF) + 1;
132 
133  /* ensure we have enough buffer to process chunk */
134  if (src_cur + chunk_size > src_end)
136 
137  if (dst_cur >= dst_end)
138  goto out;
139 
140  if (chunk_header & 0x8000)
141  {
142  /* compressed chunk */
143  if (!workspace) return STATUS_ACCESS_VIOLATION;
144  ptr = lznt1_decompress_chunk(workspace, 0x1000, src_cur, chunk_size);
145  if (!ptr) return STATUS_BAD_COMPRESSION_BUFFER;
146  if (ptr - workspace > offset)
147  {
148  block_size = min((ptr - workspace) - offset, dst_end - dst_cur);
149  memcpy(dst_cur, workspace + offset, block_size);
150  dst_cur += block_size;
151  }
152  }
153  else
154  {
155  /* uncompressed chunk */
156  if (chunk_size > offset)
157  {
158  block_size = min(chunk_size - offset, dst_end - dst_cur);
159  memcpy(dst_cur, src_cur + offset, block_size);
160  dst_cur += block_size;
161  }
162  }
163 
164  src_cur += chunk_size;
165  }
166 
167  /* handle remaining chunks */
168  while (src_cur + sizeof(WORD) <= src_end)
169  {
170  /* read chunk header and extract size */
171  chunk_header = *(WORD *)src_cur;
172  src_cur += sizeof(WORD);
173  if (!chunk_header) goto out;
174  chunk_size = (chunk_header & 0xFFF) + 1;
175 
176  if (src_cur + chunk_size > src_end)
178 
179  /* add padding if required */
180  block_size = ((dst_cur - dst) + offset) & 0xFFF;
181  if (block_size)
182  {
183  block_size = 0x1000 - block_size;
184  if (dst_cur + block_size >= dst_end)
185  goto out;
186  memset(dst_cur, 0, block_size);
187  dst_cur += block_size;
188  }
189 
190  if (dst_cur >= dst_end)
191  goto out;
192 
193  if (chunk_header & 0x8000)
194  {
195  /* compressed chunk */
196  dst_cur = lznt1_decompress_chunk(dst_cur, dst_end - dst_cur, src_cur, chunk_size);
197  if (!dst_cur) return STATUS_BAD_COMPRESSION_BUFFER;
198  }
199  else
200  {
201  /* uncompressed chunk */
202  block_size = min(chunk_size, dst_end - dst_cur);
203  memcpy(dst_cur, src_cur, block_size);
204  dst_cur += block_size;
205  }
206 
207  src_cur += chunk_size;
208  }
209 
210 out:
211  if (final_size)
212  *final_size = dst_cur - dst;
213 
214  return STATUS_SUCCESS;
215 
216 }
static PUCHAR lznt1_decompress_chunk(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size)
Definition: compress.c:31
long dst_end
Definition: timezone.c:17
GLintptr offset
Definition: glext.h:5920
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
static PVOID ptr
Definition: dispmode.c:27
#define STATUS_BAD_COMPRESSION_BUFFER
Definition: ntstatus.h:710
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
unsigned char UCHAR
Definition: xmlstorage.h:181
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum src
Definition: glext.h:6340
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
GLenum GLenum dst
Definition: glext.h:6340
#define min(a, b)
Definition: monoChain.cc:55
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define memset(x, y, z)
Definition: compat.h:39

Referenced by RtlDecompressFragment().

◆ lznt1_decompress_chunk()

static PUCHAR lznt1_decompress_chunk ( UCHAR dst,
ULONG  dst_size,
UCHAR src,
ULONG  src_size 
)
static

Definition at line 31 of file compress.c.

32 {
33  UCHAR *src_cur, *src_end, *dst_cur, *dst_end;
34  ULONG displacement_bits, length_bits;
35  ULONG code_displacement, code_length;
36  WORD flags, code;
37 
38  src_cur = src;
39  src_end = src + src_size;
40  dst_cur = dst;
41  dst_end = dst + dst_size;
42 
43  /* Partial decompression is no error on Windows. */
44  while (src_cur < src_end && dst_cur < dst_end)
45  {
46  /* read flags header */
47  flags = 0x8000 | *src_cur++;
48 
49  /* parse following 8 entities, either uncompressed data or backwards reference */
50  while ((flags & 0xFF00) && src_cur < src_end)
51  {
52  if (flags & 1)
53  {
54  /* backwards reference */
55  if (src_cur + sizeof(WORD) > src_end)
56  return NULL;
57  code = *(WORD *)src_cur;
58  src_cur += sizeof(WORD);
59 
60  /* find length / displacement bits */
61  for (displacement_bits = 12; displacement_bits > 4; displacement_bits--)
62  if ((1 << (displacement_bits - 1)) < dst_cur - dst) break;
63  length_bits = 16 - displacement_bits;
64  code_length = (code & ((1 << length_bits) - 1)) + 3;
65  code_displacement = (code >> length_bits) + 1;
66 
67  /* ensure reference is valid */
68  if (dst_cur < dst + code_displacement)
69  return NULL;
70 
71  /* copy bytes of chunk - we can't use memcpy()
72  * since source and dest can be overlapping */
73  while (code_length--)
74  {
75  if (dst_cur >= dst_end) return dst_cur;
76  *dst_cur = *(dst_cur - code_displacement);
77  dst_cur++;
78  }
79  }
80  else
81  {
82  /* uncompressed data */
83  if (dst_cur >= dst_end) return dst_cur;
84  *dst_cur++ = *src_cur++;
85  }
86  flags >>= 1;
87  }
88 
89  }
90 
91  return dst_cur;
92 }
long dst_end
Definition: timezone.c:17
smooth NULL
Definition: ftsmooth.c:416
unsigned short WORD
Definition: ntddk_ex.h:93
GLbitfield flags
Definition: glext.h:7161
unsigned char UCHAR
Definition: xmlstorage.h:181
GLenum src
Definition: glext.h:6340
Definition: inflate.c:139
int code
Definition: i386-dis.c:3591
GLenum GLenum dst
Definition: glext.h:6340
unsigned int ULONG
Definition: retypes.h:1

Referenced by lznt1_decompress().

◆ RtlCompressBuffer()

NTSTATUS NTAPI RtlCompressBuffer ( IN USHORT  CompressionFormatAndEngine,
IN PUCHAR  UncompressedBuffer,
IN ULONG  UncompressedBufferSize,
OUT PUCHAR  CompressedBuffer,
IN ULONG  CompressedBufferSize,
IN ULONG  UncompressedChunkSize,
OUT PULONG  FinalCompressedSize,
IN PVOID  WorkSpace 
)

Definition at line 277 of file compress.c.

285 {
286  USHORT Format = CompressionFormatAndEngine & COMPRESSION_FORMAT_MASK;
287  /* USHORT Engine = CompressionFormatAndEngine & COMPRESSION_ENGINE_MASK; */
288 
289  if ((Format == COMPRESSION_FORMAT_NONE) ||
291  return(STATUS_INVALID_PARAMETER);
292 
294  return(RtlpCompressBufferLZNT1(UncompressedBuffer,
298  UncompressedChunkSize,
299  FinalCompressedSize,
300  WorkSpace));
301 
303 }
#define STATUS_UNSUPPORTED_COMPRESSION
Definition: ntstatus.h:732
#define COMPRESSION_FORMAT_NONE
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define COMPRESSION_FORMAT_MASK
Definition: compress.c:20
_Inout_ PUCHAR * CompressedBuffer
Definition: rtlfuncs.h:2276
static NTSTATUS RtlpCompressBufferLZNT1(UCHAR *src, ULONG src_size, UCHAR *dst, ULONG dst_size, ULONG chunk_size, ULONG *final_size, UCHAR *workspace)
Definition: compress.c:220
#define COMPRESSION_FORMAT_LZNT1
unsigned short USHORT
Definition: pedump.c:61
_In_ ULONG UncompressedBufferSize
Definition: rtlfuncs.h:3214
_In_ ULONG _In_ ULONG _Out_ PULONG _In_ PVOID WorkSpace
Definition: rtlfuncs.h:2267
_In_ ULONG _In_ ULONG CompressedBufferSize
Definition: rtlfuncs.h:3216
#define COMPRESSION_FORMAT_DEFAULT

◆ RtlCompressChunks()

NTSTATUS NTAPI RtlCompressChunks ( IN PUCHAR  UncompressedBuffer,
IN ULONG  UncompressedBufferSize,
OUT PUCHAR  CompressedBuffer,
IN ULONG  CompressedBufferSize,
IN OUT PCOMPRESSED_DATA_INFO  CompressedDataInfo,
IN ULONG  CompressedDataInfoLength,
IN PVOID  WorkSpace 
)

Definition at line 310 of file compress.c.

317 {
319  return STATUS_NOT_IMPLEMENTED;
320 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RtlDecompressBuffer()

NTSTATUS NTAPI RtlDecompressBuffer ( IN USHORT  CompressionFormat,
OUT PUCHAR  UncompressedBuffer,
IN ULONG  UncompressedBufferSize,
IN PUCHAR  CompressedBuffer,
IN ULONG  CompressedBufferSize,
OUT PULONG  FinalUncompressedSize 
)

Definition at line 374 of file compress.c.

380 {
381  return RtlDecompressFragment(CompressionFormat, UncompressedBuffer, UncompressedBufferSize,
383 }
_In_ ULONG _In_ ULONG _Out_ PULONG FinalUncompressedSize
Definition: rtlfuncs.h:3216
_Inout_ PUCHAR * CompressedBuffer
Definition: rtlfuncs.h:2276
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI RtlDecompressFragment(IN USHORT format, OUT PUCHAR uncompressed, IN ULONG uncompressed_size, IN PUCHAR compressed, IN ULONG compressed_size, IN ULONG offset, OUT PULONG final_size, IN PVOID workspace)
Definition: compress.c:342
_In_ ULONG UncompressedBufferSize
Definition: rtlfuncs.h:3214
_In_ ULONG _In_ ULONG CompressedBufferSize
Definition: rtlfuncs.h:3216

◆ RtlDecompressChunks()

NTSTATUS NTAPI RtlDecompressChunks ( OUT PUCHAR  UncompressedBuffer,
IN ULONG  UncompressedBufferSize,
IN PUCHAR  CompressedBuffer,
IN ULONG  CompressedBufferSize,
IN PUCHAR  CompressedTail,
IN ULONG  CompressedTailSize,
IN PCOMPRESSED_DATA_INFO  CompressedDataInfo 
)

Definition at line 326 of file compress.c.

333 {
335  return STATUS_NOT_IMPLEMENTED;
336 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RtlDecompressFragment()

NTSTATUS NTAPI RtlDecompressFragment ( IN USHORT  format,
OUT PUCHAR  uncompressed,
IN ULONG  uncompressed_size,
IN PUCHAR  compressed,
IN ULONG  compressed_size,
IN ULONG  offset,
OUT PULONG  final_size,
IN PVOID  workspace 
)

Definition at line 342 of file compress.c.

350 {
351  DPRINT("0x%04x, %p, %u, %p, %u, %u, %p, %p :stub\n", format, uncompressed,
352  uncompressed_size, compressed, compressed_size, offset, final_size, workspace);
353 
355  {
357  return lznt1_decompress(uncompressed, uncompressed_size, compressed,
358  compressed_size, offset, final_size, workspace);
359 
363 
364  default:
365  DPRINT1("format %d not implemented\n", format);
367  }
368 }
#define STATUS_UNSUPPORTED_COMPRESSION
Definition: ntstatus.h:732
#define COMPRESSION_FORMAT_NONE
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size, ULONG offset, ULONG *final_size, UCHAR *workspace)
Definition: compress.c:95
GLintptr offset
Definition: glext.h:5920
static const BYTE uncompressed[]
Definition: misc.c:392
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
void DPRINT(...)
Definition: polytest.cpp:61
#define COMPRESSION_FORMAT_LZNT1
#define COMPRESSION_ENGINE_MAXIMUM
#define DPRINT1
Definition: precomp.h:8
#define COMPRESSION_FORMAT_DEFAULT

Referenced by RtlDecompressBuffer().

◆ RtlDescribeChunk()

NTSTATUS NTAPI RtlDescribeChunk ( IN USHORT  CompressionFormat,
IN OUT PUCHAR CompressedBuffer,
IN PUCHAR  EndOfCompressedBufferPlus1,
OUT PUCHAR ChunkBuffer,
OUT PULONG  ChunkSize 
)

Definition at line 389 of file compress.c.

394 {
396  return STATUS_NOT_IMPLEMENTED;
397 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define UNIMPLEMENTED
Definition: debug.h:115

◆ RtlGetCompressionWorkSpaceSize()

NTSTATUS NTAPI RtlGetCompressionWorkSpaceSize ( IN USHORT  CompressionFormatAndEngine,
OUT PULONG  CompressBufferAndWorkSpaceSize,
OUT PULONG  CompressFragmentWorkSpaceSize 
)

Definition at line 404 of file compress.c.

407 {
408  USHORT Format = CompressionFormatAndEngine & COMPRESSION_FORMAT_MASK;
409  USHORT Engine = CompressionFormatAndEngine & COMPRESSION_ENGINE_MASK;
410 
411  if ((Format == COMPRESSION_FORMAT_NONE) ||
413  return(STATUS_INVALID_PARAMETER);
414 
416  return(RtlpWorkSpaceSizeLZNT1(Engine,
417  CompressBufferAndWorkSpaceSize,
418  CompressFragmentWorkSpaceSize));
419 
421 }
#define STATUS_UNSUPPORTED_COMPRESSION
Definition: ntstatus.h:732
#define COMPRESSION_FORMAT_NONE
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define COMPRESSION_FORMAT_MASK
Definition: compress.c:20
#define COMPRESSION_ENGINE_MASK
Definition: compress.c:21
#define COMPRESSION_FORMAT_LZNT1
unsigned short USHORT
Definition: pedump.c:61
static NTSTATUS RtlpWorkSpaceSizeLZNT1(USHORT Engine, PULONG BufferAndWorkSpaceSize, PULONG FragmentWorkSpaceSize)
Definition: compress.c:252
#define COMPRESSION_FORMAT_DEFAULT

◆ RtlpCompressBufferLZNT1()

static NTSTATUS RtlpCompressBufferLZNT1 ( UCHAR src,
ULONG  src_size,
UCHAR dst,
ULONG  dst_size,
ULONG  chunk_size,
ULONG final_size,
UCHAR workspace 
)
static

Definition at line 220 of file compress.c.

222 {
223  UCHAR *src_cur = src, *src_end = src + src_size;
224  UCHAR *dst_cur = dst, *dst_end = dst + dst_size;
226 
227  while (src_cur < src_end)
228  {
229  /* determine size of current chunk */
230  block_size = min(0x1000, src_end - src_cur);
231  if (dst_cur + sizeof(WORD) + block_size > dst_end)
233 
234  /* write (uncompressed) chunk header */
235  *(WORD *)dst_cur = 0x3000 | (block_size - 1);
236  dst_cur += sizeof(WORD);
237 
238  /* write chunk content */
239  memcpy(dst_cur, src_cur, block_size);
240  dst_cur += block_size;
241  src_cur += block_size;
242  }
243 
244  if (final_size)
245  *final_size = dst_cur - dst;
246 
247  return STATUS_SUCCESS;
248 }
long dst_end
Definition: timezone.c:17
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned char UCHAR
Definition: xmlstorage.h:181
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define min(a, b)
Definition: monoChain.cc:55
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by RtlCompressBuffer().

◆ RtlpWorkSpaceSizeLZNT1()

static NTSTATUS RtlpWorkSpaceSizeLZNT1 ( USHORT  Engine,
PULONG  BufferAndWorkSpaceSize,
PULONG  FragmentWorkSpaceSize 
)
static

Definition at line 252 of file compress.c.

255 {
256  if (Engine == COMPRESSION_ENGINE_STANDARD)
257  {
258  *BufferAndWorkSpaceSize = 0x8010;
259  *FragmentWorkSpaceSize = 0x1000;
260  return(STATUS_SUCCESS);
261  }
262  else if (Engine == COMPRESSION_ENGINE_MAXIMUM)
263  {
264  *BufferAndWorkSpaceSize = 0x10;
265  *FragmentWorkSpaceSize = 0x1000;
266  return(STATUS_SUCCESS);
267  }
268 
269  return(STATUS_NOT_SUPPORTED);
270 }
#define COMPRESSION_ENGINE_STANDARD
#define COMPRESSION_ENGINE_MAXIMUM
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by RtlGetCompressionWorkSpaceSize().

◆ RtlReserveChunk()

NTSTATUS NTAPI RtlReserveChunk ( IN USHORT  CompressionFormat,
IN OUT PUCHAR CompressedBuffer,
IN PUCHAR  EndOfCompressedBufferPlus1,
OUT PUCHAR ChunkBuffer,
IN ULONG  ChunkSize 
)

Definition at line 429 of file compress.c.

434 {
436  return STATUS_NOT_IMPLEMENTED;
437 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define UNIMPLEMENTED
Definition: debug.h:115