]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseUefiDecompressLib / BaseUefiDecompressLib.c
1 /** @file
2 UEFI Decompress Library implementation refer to UEFI specification.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10
11 #include <Base.h>
12 #include <Library/BaseLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/UefiDecompressLib.h>
16
17 #include "BaseUefiDecompressLibInternals.h"
18
19 /**
20 Read NumOfBit of bits from source into mBitBuf.
21
22 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
23
24 @param Sd The global scratch data.
25 @param NumOfBits The number of bits to shift and read.
26
27 **/
28 VOID
29 FillBuf (
30 IN SCRATCH_DATA *Sd,
31 IN UINT16 NumOfBits
32 )
33 {
34 //
35 // Left shift NumOfBits of bits in advance
36 //
37 Sd->mBitBuf = (UINT32) LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);
38
39 //
40 // Copy data needed in bytes into mSbuBitBuf
41 //
42 while (NumOfBits > Sd->mBitCount) {
43 NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
44 Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
45
46 if (Sd->mCompSize > 0) {
47 //
48 // Get 1 byte into SubBitBuf
49 //
50 Sd->mCompSize--;
51 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];
52 Sd->mBitCount = 8;
53
54 } else {
55 //
56 // No more bits from the source, just pad zero bit.
57 //
58 Sd->mSubBitBuf = 0;
59 Sd->mBitCount = 8;
60
61 }
62 }
63
64 //
65 // Calculate additional bit count read to update mBitCount
66 //
67 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);
68
69 //
70 // Copy NumOfBits of bits from mSubBitBuf into mBitBuf
71 //
72 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
73 }
74
75 /**
76 Get NumOfBits of bits out from mBitBuf.
77
78 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
79 NumOfBits of bits from source. Returns NumOfBits of bits that are
80 popped out.
81
82 @param Sd The global scratch data.
83 @param NumOfBits The number of bits to pop and read.
84
85 @return The bits that are popped out.
86
87 **/
88 UINT32
89 GetBits (
90 IN SCRATCH_DATA *Sd,
91 IN UINT16 NumOfBits
92 )
93 {
94 UINT32 OutBits;
95
96 //
97 // Pop NumOfBits of Bits from Left
98 //
99 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
100
101 //
102 // Fill up mBitBuf from source
103 //
104 FillBuf (Sd, NumOfBits);
105
106 return OutBits;
107 }
108
109 /**
110 Creates Huffman Code mapping table according to code length array.
111
112 Creates Huffman Code mapping table for Extra Set, Char&Len Set
113 and Position Set according to code length array.
114 If TableBits > 16, then ASSERT ().
115
116 @param Sd The global scratch data.
117 @param NumOfChar The number of symbols in the symbol set.
118 @param BitLen Code length array.
119 @param TableBits The width of the mapping table.
120 @param Table The table to be created.
121
122 @retval 0 OK.
123 @retval BAD_TABLE The table is corrupted.
124
125 **/
126 UINT16
127 MakeTable (
128 IN SCRATCH_DATA *Sd,
129 IN UINT16 NumOfChar,
130 IN UINT8 *BitLen,
131 IN UINT16 TableBits,
132 OUT UINT16 *Table
133 )
134 {
135 UINT16 Count[17];
136 UINT16 Weight[17];
137 UINT16 Start[18];
138 UINT16 *Pointer;
139 UINT16 Index3;
140 UINT16 Index;
141 UINT16 Len;
142 UINT16 Char;
143 UINT16 JuBits;
144 UINT16 Avail;
145 UINT16 NextCode;
146 UINT16 Mask;
147 UINT16 WordOfStart;
148 UINT16 WordOfCount;
149 UINT16 MaxTableLength;
150
151 //
152 // The maximum mapping table width supported by this internal
153 // working function is 16.
154 //
155 ASSERT (TableBits <= 16);
156
157 for (Index = 0; Index <= 16; Index++) {
158 Count[Index] = 0;
159 }
160
161 for (Index = 0; Index < NumOfChar; Index++) {
162 if (BitLen[Index] > 16) {
163 return (UINT16) BAD_TABLE;
164 }
165 Count[BitLen[Index]]++;
166 }
167
168 Start[0] = 0;
169 Start[1] = 0;
170
171 for (Index = 1; Index <= 16; Index++) {
172 WordOfStart = Start[Index];
173 WordOfCount = Count[Index];
174 Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));
175 }
176
177 if (Start[17] != 0) {
178 /*(1U << 16)*/
179 return (UINT16) BAD_TABLE;
180 }
181
182 JuBits = (UINT16) (16 - TableBits);
183
184 Weight[0] = 0;
185 for (Index = 1; Index <= TableBits; Index++) {
186 Start[Index] >>= JuBits;
187 Weight[Index] = (UINT16) (1U << (TableBits - Index));
188 }
189
190 while (Index <= 16) {
191 Weight[Index] = (UINT16) (1U << (16 - Index));
192 Index++;
193 }
194
195 Index = (UINT16) (Start[TableBits + 1] >> JuBits);
196
197 if (Index != 0) {
198 Index3 = (UINT16) (1U << TableBits);
199 if (Index < Index3) {
200 SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);
201 }
202 }
203
204 Avail = NumOfChar;
205 Mask = (UINT16) (1U << (15 - TableBits));
206 MaxTableLength = (UINT16) (1U << TableBits);
207
208 for (Char = 0; Char < NumOfChar; Char++) {
209
210 Len = BitLen[Char];
211 if (Len == 0 || Len >= 17) {
212 continue;
213 }
214
215 NextCode = (UINT16) (Start[Len] + Weight[Len]);
216
217 if (Len <= TableBits) {
218
219 if (Start[Len] >= NextCode || NextCode > MaxTableLength){
220 return (UINT16) BAD_TABLE;
221 }
222
223 for (Index = Start[Len]; Index < NextCode; Index++) {
224 Table[Index] = Char;
225 }
226
227 } else {
228
229 Index3 = Start[Len];
230 Pointer = &Table[Index3 >> JuBits];
231 Index = (UINT16) (Len - TableBits);
232
233 while (Index != 0) {
234 if (*Pointer == 0 && Avail < (2 * NC - 1)) {
235 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
236 *Pointer = Avail++;
237 }
238
239 if (*Pointer < (2 * NC - 1)) {
240 if ((Index3 & Mask) != 0) {
241 Pointer = &Sd->mRight[*Pointer];
242 } else {
243 Pointer = &Sd->mLeft[*Pointer];
244 }
245 }
246
247 Index3 <<= 1;
248 Index--;
249 }
250
251 *Pointer = Char;
252
253 }
254
255 Start[Len] = NextCode;
256 }
257 //
258 // Succeeds
259 //
260 return 0;
261 }
262
263 /**
264 Decodes a position value.
265
266 Get a position value according to Position Huffman Table.
267
268 @param Sd The global scratch data.
269
270 @return The position value decoded.
271
272 **/
273 UINT32
274 DecodeP (
275 IN SCRATCH_DATA *Sd
276 )
277 {
278 UINT16 Val;
279 UINT32 Mask;
280 UINT32 Pos;
281
282 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
283
284 if (Val >= MAXNP) {
285 Mask = 1U << (BITBUFSIZ - 1 - 8);
286
287 do {
288
289 if ((Sd->mBitBuf & Mask) != 0) {
290 Val = Sd->mRight[Val];
291 } else {
292 Val = Sd->mLeft[Val];
293 }
294
295 Mask >>= 1;
296 } while (Val >= MAXNP);
297 }
298 //
299 // Advance what we have read
300 //
301 FillBuf (Sd, Sd->mPTLen[Val]);
302
303 Pos = Val;
304 if (Val > 1) {
305 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));
306 }
307
308 return Pos;
309 }
310
311 /**
312 Reads code lengths for the Extra Set or the Position Set.
313
314 Read in the Extra Set or Position Set Length Array, then
315 generate the Huffman code mapping for them.
316
317 @param Sd The global scratch data.
318 @param nn The number of symbols.
319 @param nbit The number of bits needed to represent nn.
320 @param Special The special symbol that needs to be taken care of.
321
322 @retval 0 OK.
323 @retval BAD_TABLE Table is corrupted.
324
325 **/
326 UINT16
327 ReadPTLen (
328 IN SCRATCH_DATA *Sd,
329 IN UINT16 nn,
330 IN UINT16 nbit,
331 IN UINT16 Special
332 )
333 {
334 UINT16 Number;
335 UINT16 CharC;
336 UINT16 Index;
337 UINT32 Mask;
338
339 ASSERT (nn <= NPT);
340 //
341 // Read Extra Set Code Length Array size
342 //
343 Number = (UINT16) GetBits (Sd, nbit);
344
345 if (Number == 0) {
346 //
347 // This represents only Huffman code used
348 //
349 CharC = (UINT16) GetBits (Sd, nbit);
350
351 SetMem16 (&Sd->mPTTable[0] , sizeof (Sd->mPTTable), CharC);
352
353 SetMem (Sd->mPTLen, nn, 0);
354
355 return 0;
356 }
357
358 Index = 0;
359
360 while (Index < Number && Index < NPT) {
361
362 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
363
364 //
365 // If a code length is less than 7, then it is encoded as a 3-bit
366 // value. Or it is encoded as a series of "1"s followed by a
367 // terminating "0". The number of "1"s = Code length - 4.
368 //
369 if (CharC == 7) {
370 Mask = 1U << (BITBUFSIZ - 1 - 3);
371 while (Mask & Sd->mBitBuf) {
372 Mask >>= 1;
373 CharC += 1;
374 }
375 }
376
377 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));
378
379 Sd->mPTLen[Index++] = (UINT8) CharC;
380
381 //
382 // For Code&Len Set,
383 // After the third length of the code length concatenation,
384 // a 2-bit value is used to indicated the number of consecutive
385 // zero lengths after the third length.
386 //
387 if (Index == Special) {
388 CharC = (UINT16) GetBits (Sd, 2);
389 while ((INT16) (--CharC) >= 0 && Index < NPT) {
390 Sd->mPTLen[Index++] = 0;
391 }
392 }
393 }
394
395 while (Index < nn && Index < NPT) {
396 Sd->mPTLen[Index++] = 0;
397 }
398
399 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
400 }
401
402 /**
403 Reads code lengths for Char&Len Set.
404
405 Read in and decode the Char&Len Set Code Length Array, then
406 generate the Huffman Code mapping table for the Char&Len Set.
407
408 @param Sd The global scratch data.
409
410 **/
411 VOID
412 ReadCLen (
413 SCRATCH_DATA *Sd
414 )
415 {
416 UINT16 Number;
417 UINT16 CharC;
418 UINT16 Index;
419 UINT32 Mask;
420
421 Number = (UINT16) GetBits (Sd, CBIT);
422
423 if (Number == 0) {
424 //
425 // This represents only Huffman code used
426 //
427 CharC = (UINT16) GetBits (Sd, CBIT);
428
429 SetMem (Sd->mCLen, NC, 0);
430 SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);
431
432 return ;
433 }
434
435 Index = 0;
436 while (Index < Number && Index < NC) {
437 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
438 if (CharC >= NT) {
439 Mask = 1U << (BITBUFSIZ - 1 - 8);
440
441 do {
442
443 if (Mask & Sd->mBitBuf) {
444 CharC = Sd->mRight[CharC];
445 } else {
446 CharC = Sd->mLeft[CharC];
447 }
448
449 Mask >>= 1;
450
451 } while (CharC >= NT);
452 }
453 //
454 // Advance what we have read
455 //
456 FillBuf (Sd, Sd->mPTLen[CharC]);
457
458 if (CharC <= 2) {
459
460 if (CharC == 0) {
461 CharC = 1;
462 } else if (CharC == 1) {
463 CharC = (UINT16) (GetBits (Sd, 4) + 3);
464 } else if (CharC == 2) {
465 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);
466 }
467
468 while ((INT16) (--CharC) >= 0 && Index < NC) {
469 Sd->mCLen[Index++] = 0;
470 }
471
472 } else {
473
474 Sd->mCLen[Index++] = (UINT8) (CharC - 2);
475
476 }
477 }
478
479 SetMem (Sd->mCLen + Index, NC - Index, 0);
480
481 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);
482
483 return ;
484 }
485
486 /**
487 Decode a character/length value.
488
489 Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates
490 Huffman code mapping table for Extra Set, Code&Len Set and
491 Position Set.
492
493 @param Sd The global scratch data.
494
495 @return The value decoded.
496
497 **/
498 UINT16
499 DecodeC (
500 SCRATCH_DATA *Sd
501 )
502 {
503 UINT16 Index2;
504 UINT32 Mask;
505
506 if (Sd->mBlockSize == 0) {
507 //
508 // Starting a new block
509 // Read BlockSize from block header
510 //
511 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);
512
513 //
514 // Read in the Extra Set Code Length Array,
515 // Generate the Huffman code mapping table for Extra Set.
516 //
517 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);
518 if (Sd->mBadTableFlag != 0) {
519 return 0;
520 }
521
522 //
523 // Read in and decode the Char&Len Set Code Length Array,
524 // Generate the Huffman code mapping table for Char&Len Set.
525 //
526 ReadCLen (Sd);
527
528 //
529 // Read in the Position Set Code Length Array,
530 // Generate the Huffman code mapping table for the Position Set.
531 //
532 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));
533 if (Sd->mBadTableFlag != 0) {
534 return 0;
535 }
536 }
537
538 //
539 // Get one code according to Code&Set Huffman Table
540 //
541 Sd->mBlockSize--;
542 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];
543
544 if (Index2 >= NC) {
545 Mask = 1U << (BITBUFSIZ - 1 - 12);
546
547 do {
548 if ((Sd->mBitBuf & Mask) != 0) {
549 Index2 = Sd->mRight[Index2];
550 } else {
551 Index2 = Sd->mLeft[Index2];
552 }
553
554 Mask >>= 1;
555 } while (Index2 >= NC);
556 }
557 //
558 // Advance what we have read
559 //
560 FillBuf (Sd, Sd->mCLen[Index2]);
561
562 return Index2;
563 }
564
565 /**
566 Decode the source data and put the resulting data into the destination buffer.
567
568 @param Sd The global scratch data.
569
570 **/
571 VOID
572 Decode (
573 SCRATCH_DATA *Sd
574 )
575 {
576 UINT16 BytesRemain;
577 UINT32 DataIdx;
578 UINT16 CharC;
579
580 BytesRemain = (UINT16) (-1);
581
582 DataIdx = 0;
583
584 for (;;) {
585 //
586 // Get one code from mBitBuf
587 //
588 CharC = DecodeC (Sd);
589 if (Sd->mBadTableFlag != 0) {
590 goto Done;
591 }
592
593 if (CharC < 256) {
594 //
595 // Process an Original character
596 //
597 if (Sd->mOutBuf >= Sd->mOrigSize) {
598 goto Done;
599 } else {
600 //
601 // Write orignal character into mDstBase
602 //
603 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;
604 }
605
606 } else {
607 //
608 // Process a Pointer
609 //
610 CharC = (UINT16) (CharC - (BIT8 - THRESHOLD));
611
612 //
613 // Get string length
614 //
615 BytesRemain = CharC;
616
617 //
618 // Locate string position
619 //
620 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
621
622 //
623 // Write BytesRemain of bytes into mDstBase
624 //
625 BytesRemain--;
626
627 while ((INT16) (BytesRemain) >= 0) {
628 if (Sd->mOutBuf >= Sd->mOrigSize) {
629 goto Done;
630 }
631 if (DataIdx >= Sd->mOrigSize) {
632 Sd->mBadTableFlag = (UINT16) BAD_TABLE;
633 goto Done;
634 }
635 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
636
637 BytesRemain--;
638 }
639 //
640 // Once mOutBuf is fully filled, directly return
641 //
642 if (Sd->mOutBuf >= Sd->mOrigSize) {
643 goto Done;
644 }
645 }
646 }
647
648 Done:
649 return ;
650 }
651
652 /**
653 Given a compressed source buffer, this function retrieves the size of
654 the uncompressed buffer and the size of the scratch buffer required
655 to decompress the compressed source buffer.
656
657 Retrieves the size of the uncompressed buffer and the temporary scratch buffer
658 required to decompress the buffer specified by Source and SourceSize.
659 If the size of the uncompressed buffer or the size of the scratch buffer cannot
660 be determined from the compressed data specified by Source and SourceData,
661 then RETURN_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed
662 buffer is returned in DestinationSize, the size of the scratch buffer is returned
663 in ScratchSize, and RETURN_SUCCESS is returned.
664 This function does not have scratch buffer available to perform a thorough
665 checking of the validity of the source data. It just retrieves the "Original Size"
666 field from the beginning bytes of the source data and output it as DestinationSize.
667 And ScratchSize is specific to the decompression implementation.
668
669 If Source is NULL, then ASSERT().
670 If DestinationSize is NULL, then ASSERT().
671 If ScratchSize is NULL, then ASSERT().
672
673 @param Source The source buffer containing the compressed data.
674 @param SourceSize The size, in bytes, of the source buffer.
675 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
676 that will be generated when the compressed buffer specified
677 by Source and SourceSize is decompressed.
678 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that
679 is required to decompress the compressed buffer specified
680 by Source and SourceSize.
681
682 @retval RETURN_SUCCESS The size of the uncompressed data was returned
683 in DestinationSize, and the size of the scratch
684 buffer was returned in ScratchSize.
685 @retval RETURN_INVALID_PARAMETER
686 The size of the uncompressed data or the size of
687 the scratch buffer cannot be determined from
688 the compressed data specified by Source
689 and SourceSize.
690 **/
691 RETURN_STATUS
692 EFIAPI
693 UefiDecompressGetInfo (
694 IN CONST VOID *Source,
695 IN UINT32 SourceSize,
696 OUT UINT32 *DestinationSize,
697 OUT UINT32 *ScratchSize
698 )
699 {
700 UINT32 CompressedSize;
701
702 ASSERT (Source != NULL);
703 ASSERT (DestinationSize != NULL);
704 ASSERT (ScratchSize != NULL);
705
706 if (SourceSize < 8) {
707 return RETURN_INVALID_PARAMETER;
708 }
709
710 CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
711 if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) {
712 return RETURN_INVALID_PARAMETER;
713 }
714
715 *ScratchSize = sizeof (SCRATCH_DATA);
716 *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);
717
718 return RETURN_SUCCESS;
719 }
720
721 /**
722 Decompresses a compressed source buffer.
723
724 Extracts decompressed data to its original form.
725 This function is designed so that the decompression algorithm can be implemented
726 without using any memory services. As a result, this function is not allowed to
727 call any memory allocation services in its implementation. It is the caller's
728 responsibility to allocate and free the Destination and Scratch buffers.
729 If the compressed source data specified by Source is successfully decompressed
730 into Destination, then RETURN_SUCCESS is returned. If the compressed source data
731 specified by Source is not in a valid compressed data format,
732 then RETURN_INVALID_PARAMETER is returned.
733
734 If Source is NULL, then ASSERT().
735 If Destination is NULL, then ASSERT().
736 If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().
737
738 @param Source The source buffer containing the compressed data.
739 @param Destination The destination buffer to store the decompressed data.
740 @param Scratch A temporary scratch buffer that is used to perform the decompression.
741 This is an optional parameter that may be NULL if the
742 required scratch buffer size is 0.
743
744 @retval RETURN_SUCCESS Decompression completed successfully, and
745 the uncompressed buffer is returned in Destination.
746 @retval RETURN_INVALID_PARAMETER
747 The source buffer specified by Source is corrupted
748 (not in a valid compressed format).
749 **/
750 RETURN_STATUS
751 EFIAPI
752 UefiDecompress (
753 IN CONST VOID *Source,
754 IN OUT VOID *Destination,
755 IN OUT VOID *Scratch OPTIONAL
756 )
757 {
758 UINT32 CompSize;
759 UINT32 OrigSize;
760 SCRATCH_DATA *Sd;
761 CONST UINT8 *Src;
762 UINT8 *Dst;
763
764 ASSERT (Source != NULL);
765 ASSERT (Destination != NULL);
766 ASSERT (Scratch != NULL);
767
768 Src = Source;
769 Dst = Destination;
770
771 Sd = (SCRATCH_DATA *) Scratch;
772
773 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
774 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
775
776 //
777 // If compressed file size is 0, return
778 //
779 if (OrigSize == 0) {
780 return RETURN_SUCCESS;
781 }
782
783 Src = Src + 8;
784 SetMem (Sd, sizeof (SCRATCH_DATA), 0);
785
786 //
787 // The length of the field 'Position Set Code Length Array Size' in Block Header.
788 // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4
789 //
790 Sd->mPBit = 4;
791 Sd->mSrcBase = (UINT8 *)Src;
792 Sd->mDstBase = Dst;
793 //
794 // CompSize and OrigSize are calculated in bytes
795 //
796 Sd->mCompSize = CompSize;
797 Sd->mOrigSize = OrigSize;
798
799 //
800 // Fill the first BITBUFSIZ bits
801 //
802 FillBuf (Sd, BITBUFSIZ);
803
804 //
805 // Decompress it
806 //
807 Decode (Sd);
808
809 if (Sd->mBadTableFlag != 0) {
810 //
811 // Something wrong with the source
812 //
813 return RETURN_INVALID_PARAMETER;
814 }
815
816 return RETURN_SUCCESS;
817 }