00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "ntrtlp.h"
00022
00023
#include <stdio.h>
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 typedef struct _MRCF_BIT_IO {
00038
00039 USHORT abitsBB;
00040 LONG
cbitsBB;
00041
00042 PUCHAR
pbBB;
00043 ULONG
cbBB;
00044 ULONG
cbBBInitial;
00045
00046 }
MRCF_BIT_IO;
00047 typedef MRCF_BIT_IO *
PMRCF_BIT_IO;
00048
00049
00050
00051
00052
00053 #define wBACKPOINTERMAX (4415)
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 typedef struct _MDSIGNATURE {
00077
00078
00079
00080
00081
00082 USHORT sigStamp;
00083
00084
00085
00086
00087
00088 USHORT sigType;
00089
00090 }
MDSIGNATURE;
00091 typedef MDSIGNATURE *
PMDSIGNATURE;
00092
00093 #define MD_STAMP 0x5344 // Signature stamp at start of compressed blk
00094 #define MASK_VALID_mds 0x0300 // All other bits must be zero
00095
00096
00097
00098
00099
00100
00101 #define minimum(a,b) (a < b ? a : b)
00102
00103
00104
00105
00106
00107
VOID
00108
MrcfSetBitBuffer (
00109 PUCHAR pb,
00110 ULONG cb,
00111 PMRCF_BIT_IO BitIo
00112 );
00113
00114
VOID
00115
MrcfFillBitBuffer (
00116 PMRCF_BIT_IO BitIo
00117 );
00118
00119
USHORT
00120
MrcfReadBit (
00121 PMRCF_BIT_IO BitIo
00122 );
00123
00124
USHORT
00125
MrcfReadNBits (
00126 LONG cbits,
00127 PMRCF_BIT_IO BitIo
00128 );
00129
00130
00131
NTSTATUS
00132 RtlDecompressBufferMrcf (
00133 OUT PUCHAR UncompressedBuffer,
00134 IN ULONG UncompressedBufferSize,
00135 IN PUCHAR CompressedBuffer,
00136 IN ULONG CompressedBufferSize,
00137 OUT PULONG FinalUncompressedSize
00138 )
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 {
00172
MRCF_BIT_IO WorkSpace;
00173
00174 ULONG cbMatch;
00175 ULONG i;
00176 ULONG iMatch;
00177 ULONG k;
00178 ULONG off;
00179
USHORT x;
00180 ULONG y;
00181
00182
00183
00184
00185
00186
if (CompressedBufferSize <
sizeof(
MDSIGNATURE) ||
00187 ((
PMDSIGNATURE)CompressedBuffer)->sigStamp !=
MD_STAMP ||
00188 ((
PMDSIGNATURE)CompressedBuffer)->sigType & (~
MASK_VALID_mds)) {
00189
00190 *FinalUncompressedSize = 0;
00191
return STATUS_BAD_COMPRESSION_BUFFER;
00192 }
00193
00194
00195
00196
00197
00198 CompressedBufferSize -=
sizeof(
MDSIGNATURE);
00199 CompressedBuffer +=
sizeof(
MDSIGNATURE);
00200
00201
00202
00203
00204
00205 i = 0;
00206
00207
00208
00209
00210
00211
MrcfSetBitBuffer(CompressedBuffer,CompressedBufferSize,&WorkSpace);
00212
00213
while (
TRUE) {
00214
00215 y =
MrcfReadNBits(2,&WorkSpace);
00216
00217
00218
00219
00220
00221
00222
if (y == 1 || y == 2) {
00223
00224
ASSERTMSG(
"Don't exceed expected length ", i<UncompressedBufferSize);
00225
00226 UncompressedBuffer[i] = (UCHAR)((y == 1 ? 0x80 : 0) |
MrcfReadNBits(7,&WorkSpace));
00227
00228 i++;
00229
00230 }
else {
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
if (y == 0) {
00241
00242
00243
00244
00245
00246 off =
MrcfReadNBits(6,&WorkSpace);
00247
00248
ASSERTMSG(
"offset 0 is invalid ", off != 0);
00249
00250 }
else {
00251
00252 x =
MrcfReadBit(&WorkSpace);
00253
00254
if (x == 0) {
00255
00256
00257
00258
00259
00260 off =
MrcfReadNBits(8, &WorkSpace) + 64;
00261
00262 }
else {
00263
00264
00265
00266
00267
00268 off =
MrcfReadNBits(12, &WorkSpace) + 320;
00269
00270
if (off ==
wBACKPOINTERMAX) {
00271
00272
00273
00274
00275
00276
if (i >= UncompressedBufferSize) {
00277
00278
00279
00280
00281
00282 *FinalUncompressedSize = i;
00283
return STATUS_SUCCESS;
00284
00285 }
else {
00286
00287
00288
00289
00290
00291
00292
continue;
00293 }
00294 }
00295 }
00296 }
00297
00298
ASSERTMSG(
"Don't exceed expected length ", i<UncompressedBufferSize);
00299
ASSERTMSG(
"Cannot match before start of uncoded buffer! ", off <= i);
00300
00301
00302
00303
00304
00305
for (k=0; (x=
MrcfReadBit(&WorkSpace)) == 0; k++) { NOTHING; }
00306
00307
ASSERT(k <= 8);
00308
00309
if (k == 0) {
00310
00311
00312
00313
00314
00315 cbMatch = 2;
00316
00317 }
else {
00318
00319 cbMatch = (1 << k) + 1 +
MrcfReadNBits(k, &WorkSpace);
00320 }
00321
00322
ASSERTMSG(
"Don't exceed buffer size ", (i - off + cbMatch - 1) <= UncompressedBufferSize);
00323
00324
00325
00326
00327
00328 iMatch = i - off;
00329
00330
while ( (cbMatch > 0) && (i<UncompressedBufferSize) ) {
00331
00332 UncompressedBuffer[i++] = UncompressedBuffer[iMatch++];
00333 cbMatch--;
00334 }
00335
00336
ASSERTMSG(
"Should have copied it all ", cbMatch == 0);
00337 }
00338 }
00339 }
00340
00341
00342
00343
00344
00345
00346
VOID
00347 MrcfSetBitBuffer (
00348 PUCHAR pb,
00349 ULONG cb,
00350 PMRCF_BIT_IO BitIo
00351 )
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 {
00374 BitIo->
pbBB = pb;
00375 BitIo->
cbBB = cb;
00376 BitIo->
cbBBInitial = cb;
00377 BitIo->
cbitsBB = 0;
00378 BitIo->
abitsBB = 0;
00379 }
00380
00381
00382
00383
00384
00385
00386
USHORT
00387 MrcfReadBit (
00388 PMRCF_BIT_IO BitIo
00389 )
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 {
00408
USHORT bit;
00409
00410
00411
00412
00413
00414
if ((BitIo->
cbitsBB) == 0) {
00415
00416
MrcfFillBitBuffer(BitIo);
00417 }
00418
00419
00420
00421
00422
00423
00424 (BitIo->
cbitsBB)--;
00425 bit = (BitIo->
abitsBB) & 1;
00426 (BitIo->
abitsBB) >>= 1;
00427
00428
return bit;
00429 }
00430
00431
00432
00433
00434
00435
00436
USHORT
00437 MrcfReadNBits (
00438 LONG cbits,
00439 PMRCF_BIT_IO BitIo
00440 )
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 {
00461 ULONG abits;
00462 LONG cbitsPart;
00463 ULONG cshift;
00464 ULONG mask;
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
ASSERT(cbits <= 12);
00475
00476
00477
00478
00479
00480 cshift = 0;
00481 abits = 0;
00482
00483
while (cbits > 0) {
00484
00485
00486
00487
00488
00489
if ((BitIo->
cbitsBB) == 0) {
00490
00491
MrcfFillBitBuffer(BitIo);
00492 }
00493
00494
00495
00496
00497
00498 cbitsPart =
minimum((BitIo->
cbitsBB), cbits);
00499
00500
00501
00502
00503
00504 mask = (1 << cbitsPart) - 1;
00505 abits |= ((BitIo->
abitsBB) & mask) << cshift;
00506
00507
00508
00509
00510
00511 cshift = cbitsPart;
00512
00513
00514
00515
00516
00517
00518 (BitIo->
abitsBB) >>= cbitsPart;
00519 (BitIo->
cbitsBB) -= cbitsPart;
00520
00521
00522
00523
00524
00525 cbits -= cbitsPart;
00526 }
00527
00528
00529
00530
00531
00532
return (
USHORT)abits;
00533 }
00534
00535
00536
00537
00538
00539
00540
VOID
00541 MrcfFillBitBuffer (
00542 PMRCF_BIT_IO BitIo
00543 )
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 {
00562
ASSERT((BitIo->
cbitsBB) == 0);
00563
00564
switch (BitIo->
cbBB) {
00565
00566
case 0:
00567
00568
ASSERTMSG(
"no bits left in coded buffer!",
FALSE);
00569
00570
break;
00571
00572
case 1:
00573
00574
00575
00576
00577
00578 BitIo->
cbitsBB = 8;
00579 BitIo->
abitsBB = *(BitIo->
pbBB)++;
00580 BitIo->
cbBB--;
00581
00582
break;
00583
00584
default:
00585
00586
00587
00588
00589
00590 BitIo->
cbitsBB = 16;
00591 BitIo->
abitsBB = *((
USHORT *)(BitIo->
pbBB))++;
00592 BitIo->
cbBB -= 2;
00593
00594
break;
00595 }
00596 }
00597
00598