ReactOS 0.4.16-dev-106-g10b08aa
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);
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
210out:
211 if (final_size)
212 *final_size = dst_cur - dst;
213
214 return STATUS_SUCCESS;
215
216}
unsigned short WORD
Definition: ntddk_ex.h:93
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLintptr offset
Definition: glext.h:5920
static DWORD block_size(DWORD block)
Definition: jsutils.c:66
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define min(a, b)
Definition: monoChain.cc:55
#define STATUS_BAD_COMPRESSION_BUFFER
Definition: ntstatus.h:710
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
static FILE * out
Definition: regtests2xml.c:44
long dst_end
Definition: timezone.c:17
#define memset(x, y, z)
Definition: compat.h:39
static PUCHAR lznt1_decompress_chunk(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size)
Definition: compress.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: xmlstorage.h:181

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;
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}
#define NULL
Definition: types.h:112
GLbitfield flags
Definition: glext.h:7161
Definition: inflate.c:139

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
292
294 return(RtlpCompressBufferLZNT1(UncompressedBuffer,
298 UncompressedChunkSize,
299 FinalCompressedSize,
300 WorkSpace));
301
303}
_In_ ULONG _In_ ULONG CompressedBufferSize
Definition: rtlfuncs.h:3294
_In_ ULONG UncompressedBufferSize
Definition: rtlfuncs.h:3292
#define COMPRESSION_FORMAT_DEFAULT
#define COMPRESSION_FORMAT_NONE
#define COMPRESSION_FORMAT_LZNT1
#define STATUS_UNSUPPORTED_COMPRESSION
Definition: ntstatus.h:732
unsigned short USHORT
Definition: pedump.c:61
#define COMPRESSION_FORMAT_MASK
Definition: compress.c:20
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 STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Inout_ PUCHAR * CompressedBuffer
Definition: rtlfuncs.h:2288
_In_ ULONG _In_ ULONG _Out_ PULONG _In_ PVOID WorkSpace
Definition: rtlfuncs.h:2280

◆ 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{
320}
#define UNIMPLEMENTED
Definition: debug.h:118
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ 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:3296
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

◆ 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{
336}

◆ 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 DPRINT1
Definition: precomp.h:8
static const BYTE uncompressed[]
Definition: misc.c:392
#define COMPRESSION_ENGINE_MAXIMUM
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
#define DPRINT
Definition: sndvol32.h:73
Definition: format.c:58

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{
397}

◆ 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
414
416 return(RtlpWorkSpaceSizeLZNT1(Engine,
417 CompressBufferAndWorkSpaceSize,
418 CompressFragmentWorkSpaceSize));
419
421}
#define COMPRESSION_ENGINE_MASK
Definition: compress.c:21
static NTSTATUS RtlpWorkSpaceSizeLZNT1(USHORT Engine, PULONG BufferAndWorkSpaceSize, PULONG FragmentWorkSpaceSize)
Definition: compress.c:252

◆ 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}
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69

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 STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423

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{
437}