+ /* now decompress and discard any data in
+ the block before the start of the file */
+
+ /* start of comp data */
+ CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved;
+ RemainingBlock = CFData->CompSize;
+ InputLength = RemainingBlock;
+
+ while (CurrentOffset < Search->File->FileOffset)
+ {
+ /* compute remaining uncomp bytes to start
+ of file, bounded by sizeof junk */
+ OutputLength = Search->File->FileOffset - CurrentOffset;
+ if (OutputLength > (LONG)sizeof(Junk))
+ OutputLength = sizeof (Junk);
+
+ /* negate to signal NOT end of block */
+ OutputLength = -OutputLength;
+ CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength);
+ /* add the uncomp bytes extracted to current folder offset */
+ CurrentOffset += OutputLength;
+ /* add comp bytes consumed to CurrentBuffer */
+ CurrentBuffer += InputLength;
+ /* subtract bytes consumed from bytes remaining in block */
+ RemainingBlock -= InputLength;
+ /* neg for resume decompression of the same block */
+ InputLength = -RemainingBlock;
+ }
+
+ /* now CurrentBuffer points to the first comp byte
+ of the file, so we can begin decompressing */
+
+ /* Size = remaining uncomp bytes of the file to decompress */
+ Size = Search->File->FileSize;
+ while (Size > 0)
+ {
+ OutputLength = Size;
+ DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
+ CurrentBuffer, RemainingBlock, Size);
+
+ Status = CodecUncompress(CurrentDestBuffer,
+ CurrentBuffer,
+ &InputLength,
+ &OutputLength);
+
+ if (Status != CS_SUCCESS)
+ {
+ DPRINT("Cannot uncompress block\n");
+ if (Status == CS_NOMEMORY)
+ Status = CAB_STATUS_NOMEMORY;
+ Status = CAB_STATUS_INVALID_CAB;
+ goto UnmapDestFile;
+ }
+
+ /* advance dest buffer by bytes produced */
+ CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
+ /* advance src buffer by bytes consumed */
+ CurrentBuffer += InputLength;
+ /* reduce remaining file bytes by bytes produced */
+ Size -= OutputLength;
+ /* reduce remaining block size by bytes consumed */
+ RemainingBlock -= InputLength;
+ if (RemainingBlock == 0)
+ {
+ /* used up this block, move on to the next */
+ DPRINT("Out of block data\n");
+ CFData = (PCFDATA)CurrentBuffer;
+ RemainingBlock = CFData->CompSize;
+ CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved;
+ InputLength = RemainingBlock;
+ }
+ }
+
+ Status = CAB_STATUS_SUCCESS;
+
+UnmapDestFile:
+ NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
+
+CloseDestFileSection:
+ NtClose(DestFileSection);
+
+CloseDestFile:
+ NtClose(DestFile);
+
+ return Status;
+}