https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9169e881aa1ed3e7f8ac6…
commit 9169e881aa1ed3e7f8ac66af78203123daf6b3c9
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Aug 14 17:11:50 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Oct 28 23:57:06 2018 +0100
[USETUP] Refactor the cabinet handling code to place all the global state variables
into a CABINET_CONTEXT structure.
Place also all the private cabinet definitions into the .c, keeping
into the header file only the "public" structures and function prototypes.
---
base/setup/usetup/cabinet.c | 774 +++++++++++++++++++++++++-----------------
base/setup/usetup/cabinet.h | 272 +++++++--------
base/setup/usetup/filequeue.c | 16 +
base/setup/usetup/usetup.c | 13 +
4 files changed, 630 insertions(+), 445 deletions(-)
diff --git a/base/setup/usetup/cabinet.c b/base/setup/usetup/cabinet.c
index f6bc22b485..7e8450ca42 100644
--- a/base/setup/usetup/cabinet.c
+++ b/base/setup/usetup/cabinet.c
@@ -16,6 +16,11 @@
#define NDEBUG
#include <debug.h>
+
+/* DEFINITIONS **************************************************************/
+
+/* File management definitions */
+
#define SEEK_BEGIN 0
#define SEEK_CURRENT 1
#ifndef SEEK_END
@@ -29,7 +34,6 @@ typedef struct _DOSTIME
WORD Hour:5;
} DOSTIME, *PDOSTIME;
-
typedef struct _DOSDATE
{
WORD Day:5;
@@ -37,37 +41,102 @@ typedef struct _DOSDATE
WORD Year:5;
} DOSDATE, *PDOSDATE;
-static WCHAR CabinetName[256]; // Filename of current cabinet
-static WCHAR CabinetPrev[256]; // Filename of previous cabinet
-static WCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev
-static WCHAR CabinetNext[256]; // Filename of next cabinet
-static WCHAR DiskNext[256]; // Label of cabinet in file CabinetNext
-static ULONG FolderUncompSize = 0; // Uncompressed size of folder
-static ULONG BytesLeftInBlock = 0; // Number of bytes left in current block
-static WCHAR DestPath[MAX_PATH];
-static HANDLE FileHandle;
-static HANDLE FileSectionHandle;
-static PUCHAR FileBuffer;
-static SIZE_T DestFileSize;
-static SIZE_T FileSize;
-static BOOL FileOpen = FALSE;
-static PCFHEADER PCABHeader;
-static PCFFOLDER CabinetFolders;
-static ULONG CabinetReserved = 0;
-static ULONG FolderReserved = 0;
-static ULONG DataReserved = 0;
-static ULONG CodecId;
-static PCABINET_CODEC_UNCOMPRESS CodecUncompress = NULL;
-static BOOL CodecSelected = FALSE;
-static ULONG LastFileOffset = 0; // Uncompressed offset of last extracted file
-static PCABINET_OVERWRITE OverwriteHandler = NULL;
-static PCABINET_EXTRACT ExtractHandler = NULL;
-static PCABINET_DISK_CHANGE DiskChangeHandler = NULL;
-static z_stream ZStream;
-static PVOID CabinetReservedArea = NULL;
-
-
-/* Needed by zlib, but we don't want the dependency on msvcrt.dll */
+
+/* Cabinet constants */
+
+#define CAB_SIGNATURE 0x4643534D // "MSCF"
+#define CAB_VERSION 0x0103
+#define CAB_BLOCKSIZE 32768
+
+#define CAB_COMP_MASK 0x00FF
+#define CAB_COMP_NONE 0x0000
+#define CAB_COMP_MSZIP 0x0001
+#define CAB_COMP_QUANTUM 0x0002
+#define CAB_COMP_LZX 0x0003
+
+#define CAB_FLAG_HASPREV 0x0001
+#define CAB_FLAG_HASNEXT 0x0002
+#define CAB_FLAG_RESERVE 0x0004
+
+#define CAB_ATTRIB_READONLY 0x0001
+#define CAB_ATTRIB_HIDDEN 0x0002
+#define CAB_ATTRIB_SYSTEM 0x0004
+#define CAB_ATTRIB_VOLUME 0x0008
+#define CAB_ATTRIB_DIRECTORY 0x0010
+#define CAB_ATTRIB_ARCHIVE 0x0020
+#define CAB_ATTRIB_EXECUTE 0x0040
+#define CAB_ATTRIB_UTF_NAME 0x0080
+
+#define CAB_FILE_MAX_FOLDER 0xFFFC
+#define CAB_FILE_CONTINUED 0xFFFD
+#define CAB_FILE_SPLIT 0xFFFE
+#define CAB_FILE_PREV_NEXT 0xFFFF
+
+
+/* Cabinet structures */
+
+typedef struct _CFHEADER
+{
+ ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE)
+ ULONG Reserved1; // Reserved field
+ ULONG CabinetSize; // Cabinet file size
+ ULONG Reserved2; // Reserved field
+ ULONG FileTableOffset; // Offset of first CFFILE
+ ULONG Reserved3; // Reserved field
+ USHORT Version; // Cabinet version (CAB_VERSION)
+ USHORT FolderCount; // Number of folders
+ USHORT FileCount; // Number of files
+ USHORT Flags; // Cabinet flags (CAB_FLAG_*)
+ USHORT SetID; // Cabinet set id
+ USHORT CabinetNumber; // Zero-based cabinet number
+/* Optional fields (depends on Flags)
+ USHORT CabinetResSize // Per-cabinet reserved area size
+ CHAR FolderResSize // Per-folder reserved area size
+ CHAR FileResSize // Per-file reserved area size
+ CHAR CabinetReserved[] // Per-cabinet reserved area
+ CHAR CabinetPrev[] // Name of previous cabinet file
+ CHAR DiskPrev[] // Name of previous disk
+ CHAR CabinetNext[] // Name of next cabinet file
+ CHAR DiskNext[] // Name of next disk
+ */
+} CFHEADER, *PCFHEADER;
+
+typedef struct _CFFOLDER
+{
+ ULONG DataOffset; // Absolute offset of first CFDATA block in this folder
+ USHORT DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet
+ USHORT CompressionType; // Type of compression used for all CFDATA blocks in this
folder
+/* Optional fields (depends on Flags)
+ CHAR FolderReserved[] // Per-folder reserved area
+ */
+} CFFOLDER, *PCFFOLDER;
+
+typedef struct _CFFILE
+{
+ ULONG FileSize; // Uncompressed file size in bytes
+ ULONG FileOffset; // Uncompressed offset of file in the folder
+ USHORT FolderIndex; // Index number of the folder that contains this file
+ USHORT FileDate; // File date stamp, as used by DOS
+ USHORT FileTime; // File time stamp, as used by DOS
+ USHORT Attributes; // File attributes (CAB_ATTRIB_*)
+ CHAR FileName[ANYSIZE_ARRAY];
+ /* After this is the NULL terminated filename */
+} CFFILE, *PCFFILE;
+
+typedef struct _CFDATA
+{
+ ULONG Checksum; // Checksum of CFDATA entry
+ USHORT CompSize; // Number of compressed bytes in this block
+ USHORT UncompSize; // Number of uncompressed bytes in this block
+/* Optional fields (depends on Flags)
+ CHAR DataReserved[] // Per-datablock reserved area
+ */
+} CFDATA, *PCFDATA;
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* Needed by zlib, but we don't want the dependency on the CRT */
void *__cdecl
malloc(size_t size)
{
@@ -86,6 +155,25 @@ calloc(size_t nmemb, size_t size)
return (void *)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, nmemb * size);
}
+
+/* Codecs */
+
+/* Uncompresses a data block */
+typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(
+ IN struct _CAB_CODEC* Codec,
+ OUT PVOID OutputBuffer,
+ IN PVOID InputBuffer,
+ IN OUT PLONG InputLength,
+ IN OUT PLONG OutputLength);
+
+typedef struct _CAB_CODEC
+{
+ PCABINET_CODEC_UNCOMPRESS Uncompress;
+ z_stream ZStream;
+ // Other CODEC-related structures
+} CAB_CODEC, *PCAB_CODEC;
+
+
/* RAW codec */
/*
@@ -99,10 +187,12 @@ calloc(size_t nmemb, size_t size)
* Negative to indicate that this is not the end of the block
*/
ULONG
-RawCodecUncompress(PVOID OutputBuffer,
- PVOID InputBuffer,
- PLONG InputLength,
- PLONG OutputLength)
+RawCodecUncompress(
+ IN OUT PCAB_CODEC Codec,
+ OUT PVOID OutputBuffer,
+ IN PVOID InputBuffer,
+ IN OUT PLONG InputLength,
+ IN OUT PLONG OutputLength)
{
LONG Len = min(abs(*InputLength), abs(*OutputLength));
@@ -112,8 +202,15 @@ RawCodecUncompress(PVOID OutputBuffer,
return CS_SUCCESS;
}
+static CAB_CODEC RawCodec =
+{
+ RawCodecUncompress, {0}
+};
+
/* MSZIP codec */
+#define MSZIP_MAGIC 0x4B43
+
/*
* FUNCTION: Uncompresses data in a buffer
* ARGUMENTS:
@@ -125,10 +222,12 @@ RawCodecUncompress(PVOID OutputBuffer,
* Negative to indicate that this is not the end of the block
*/
ULONG
-MSZipCodecUncompress(PVOID OutputBuffer,
- PVOID InputBuffer,
- PLONG InputLength,
- PLONG OutputLength)
+MSZipCodecUncompress(
+ IN OUT PCAB_CODEC Codec,
+ OUT PVOID OutputBuffer,
+ IN PVOID InputBuffer,
+ IN OUT PLONG InputLength,
+ IN OUT PLONG OutputLength)
{
USHORT Magic;
INT Status;
@@ -136,6 +235,7 @@ MSZipCodecUncompress(PVOID OutputBuffer,
DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, "
"InputLength = %d, OutputLength = %d)\n", OutputBuffer,
InputBuffer, *InputLength, *OutputLength);
+
if (*InputLength > 0)
{
Magic = *(PUSHORT)InputBuffer;
@@ -146,38 +246,38 @@ MSZipCodecUncompress(PVOID OutputBuffer,
return CS_BADSTREAM;
}
- ZStream.next_in = (PUCHAR)InputBuffer + 2;
- ZStream.avail_in = *InputLength - 2;
- ZStream.next_out = (PUCHAR)OutputBuffer;
- ZStream.avail_out = abs(*OutputLength);
+ Codec->ZStream.next_in = (PUCHAR)InputBuffer + 2;
+ Codec->ZStream.avail_in = *InputLength - 2;
+ Codec->ZStream.next_out = (PUCHAR)OutputBuffer;
+ Codec->ZStream.avail_out = abs(*OutputLength);
/* WindowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and
* return Z_STREAM_END.
*/
- Status = inflateInit2(&ZStream, -MAX_WBITS);
+ Status = inflateInit2(&Codec->ZStream, -MAX_WBITS);
if (Status != Z_OK)
{
DPRINT("inflateInit2() returned (%d)\n", Status);
return CS_BADSTREAM;
}
- ZStream.total_in = 2;
+ Codec->ZStream.total_in = 2;
}
else
{
- ZStream.avail_in = -*InputLength;
- ZStream.next_in = (PUCHAR)InputBuffer;
- ZStream.next_out = (PUCHAR)OutputBuffer;
- ZStream.avail_out = abs(*OutputLength);
- ZStream.total_in = 0;
+ Codec->ZStream.avail_in = -*InputLength;
+ Codec->ZStream.next_in = (PUCHAR)InputBuffer;
+ Codec->ZStream.next_out = (PUCHAR)OutputBuffer;
+ Codec->ZStream.avail_out = abs(*OutputLength);
+ Codec->ZStream.total_in = 0;
}
- ZStream.total_out = 0;
- Status = inflate(&ZStream, Z_SYNC_FLUSH);
+ Codec->ZStream.total_out = 0;
+ Status = inflate(&Codec->ZStream, Z_SYNC_FLUSH);
if (Status != Z_OK && Status != Z_STREAM_END)
{
- DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg);
+ DPRINT("inflate() returned (%d) (%s)\n", Status,
Codec->ZStream.msg);
if (Status == Z_MEM_ERROR)
return CS_NOMEMORY;
return CS_BADSTREAM;
@@ -185,7 +285,7 @@ MSZipCodecUncompress(PVOID OutputBuffer,
if (*OutputLength > 0)
{
- Status = inflateEnd(&ZStream);
+ Status = inflateEnd(&Codec->ZStream);
if (Status != Z_OK)
{
DPRINT("inflateEnd() returned (%d)\n", Status);
@@ -193,12 +293,18 @@ MSZipCodecUncompress(PVOID OutputBuffer,
}
}
- *OutputLength = ZStream.total_out;
- *InputLength = ZStream.total_in;
+ *InputLength = Codec->ZStream.total_in;
+ *OutputLength = Codec->ZStream.total_out;
return CS_SUCCESS;
}
+static CAB_CODEC MSZipCodec =
+{
+ MSZipCodecUncompress, {0}
+};
+
+
/* Memory functions */
voidpf
@@ -374,14 +480,15 @@ SetAttributesOnFile(PCFFILE File,
* Status of operation
*/
static ULONG
-CloseCabinet(VOID)
+CloseCabinet(
+ IN PCABINET_CONTEXT CabinetContext)
{
- if (FileBuffer)
+ if (CabinetContext->FileBuffer)
{
- NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer);
- NtClose(FileSectionHandle);
- NtClose(FileHandle);
- FileBuffer = NULL;
+ NtUnmapViewOfSection(NtCurrentProcess(), CabinetContext->FileBuffer);
+ NtClose(CabinetContext->FileSectionHandle);
+ NtClose(CabinetContext->FileHandle);
+ CabinetContext->FileBuffer = NULL;
}
return 0;
@@ -391,34 +498,38 @@ CloseCabinet(VOID)
* FUNCTION: Initialize archiver
*/
VOID
-CabinetInitialize(VOID)
+CabinetInitialize(
+ IN OUT PCABINET_CONTEXT CabinetContext)
{
- ZStream.zalloc = MSZipAlloc;
- ZStream.zfree = MSZipFree;
- ZStream.opaque = (voidpf)0;
-
- FileOpen = FALSE;
- wcscpy(DestPath, L"");
-
- CodecId = CAB_CODEC_RAW;
- CodecSelected = TRUE;
-
- FolderUncompSize = 0;
- BytesLeftInBlock = 0;
- CabinetReserved = 0;
- FolderReserved = 0;
- DataReserved = 0;
- CabinetReservedArea = NULL;
- LastFileOffset = 0;
+ RtlZeroMemory(CabinetContext, sizeof(*CabinetContext));
+
+ CabinetContext->FileOpen = FALSE;
+ wcscpy(CabinetContext->DestPath, L"");
+
+ CabinetContext->CodecSelected = FALSE;
+ CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
+
+ CabinetContext->OverwriteHandler = NULL;
+ CabinetContext->ExtractHandler = NULL;
+ CabinetContext->DiskChangeHandler = NULL;
+
+ CabinetContext->FolderUncompSize = 0;
+ CabinetContext->BytesLeftInBlock = 0;
+ CabinetContext->CabinetReserved = 0;
+ CabinetContext->FolderReserved = 0;
+ CabinetContext->DataReserved = 0;
+ CabinetContext->CabinetReservedArea = NULL;
+ CabinetContext->LastFileOffset = 0;
}
/*
* FUNCTION: Cleanup archiver
*/
VOID
-CabinetCleanup(VOID)
+CabinetCleanup(
+ IN OUT PCABINET_CONTEXT CabinetContext)
{
- CabinetClose();
+ CabinetClose(CabinetContext);
}
/*
@@ -429,7 +540,7 @@ CabinetCleanup(VOID)
* RETURNS:
* TRUE if there was enough room in Path, or FALSE
*/
-BOOL
+static BOOL
CabinetNormalizePath(PWCHAR Path,
ULONG Length)
{
@@ -453,10 +564,11 @@ CabinetNormalizePath(PWCHAR Path,
* RETURNS:
* Pointer to string with name of cabinet
*/
-PWCHAR
-CabinetGetCabinetName(VOID)
+PCWSTR
+CabinetGetCabinetName(
+ IN PCABINET_CONTEXT CabinetContext)
{
- return CabinetName;
+ return CabinetContext->CabinetName;
}
/*
@@ -465,9 +577,11 @@ CabinetGetCabinetName(VOID)
* FileName = Pointer to string with name of cabinet
*/
VOID
-CabinetSetCabinetName(PWCHAR FileName)
+CabinetSetCabinetName(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName)
{
- wcscpy(CabinetName, FileName);
+ wcscpy(CabinetContext->CabinetName, FileName);
}
/*
@@ -476,12 +590,14 @@ CabinetSetCabinetName(PWCHAR FileName)
* DestinationPath = Pointer to string with name of destination path
*/
VOID
-CabinetSetDestinationPath(PWCHAR DestinationPath)
+CabinetSetDestinationPath(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR DestinationPath)
{
- wcscpy(DestPath, DestinationPath);
+ wcscpy(CabinetContext->DestPath, DestinationPath);
- if (wcslen(DestPath) > 0)
- CabinetNormalizePath(DestPath, MAX_PATH);
+ if (wcslen(CabinetContext->DestPath) > 0)
+ CabinetNormalizePath(CabinetContext->DestPath, MAX_PATH);
}
/*
@@ -489,10 +605,11 @@ CabinetSetDestinationPath(PWCHAR DestinationPath)
* RETURNS:
* Pointer to string with name of destination path
*/
-PWCHAR
-CabinetGetDestinationPath(VOID)
+PCWSTR
+CabinetGetDestinationPath(
+ IN PCABINET_CONTEXT CabinetContext)
{
- return DestPath;
+ return CabinetContext->DestPath;
}
/*
@@ -501,164 +618,170 @@ CabinetGetDestinationPath(VOID)
* Status of operation
*/
ULONG
-CabinetOpen(VOID)
+CabinetOpen(
+ IN OUT PCABINET_CONTEXT CabinetContext)
{
PUCHAR Buffer;
UNICODE_STRING ustring;
ANSI_STRING astring;
- if (!FileOpen)
- {
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING FileName;
- NTSTATUS NtStatus;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING FileName;
+ NTSTATUS NtStatus;
- RtlInitUnicodeString(&FileName, CabinetName);
+ if (CabinetContext->FileOpen)
+ {
+ /* Cabinet file already opened */
+ DPRINT("CabinetOpen returning SUCCESS\n");
+ return CAB_STATUS_SUCCESS;
+ }
- InitializeObjectAttributes(&ObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- NULL, NULL);
+ RtlInitUnicodeString(&FileName, CabinetContext->CabinetName);
- NtStatus = NtOpenFile(&FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT1("Cannot open file (%S) (%x)\n", CabinetName, NtStatus);
- return CAB_STATUS_CANNOT_OPEN;
- }
+ NtStatus = NtOpenFile(&CabinetContext->FileHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
- FileOpen = TRUE;
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("Cannot open file (%S) (%x)\n", CabinetContext->CabinetName,
NtStatus);
+ return CAB_STATUS_CANNOT_OPEN;
+ }
- NtStatus = NtCreateSection(&FileSectionHandle,
- SECTION_ALL_ACCESS,
- 0, 0,
- PAGE_READONLY,
- SEC_COMMIT,
- FileHandle);
+ CabinetContext->FileOpen = TRUE;
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetName,
NtStatus);
- return CAB_STATUS_NOMEMORY;
- }
+ NtStatus = NtCreateSection(&CabinetContext->FileSectionHandle,
+ SECTION_ALL_ACCESS,
+ 0, 0,
+ PAGE_READONLY,
+ SEC_COMMIT,
+ CabinetContext->FileHandle);
- FileBuffer = 0;
- FileSize = 0;
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("NtCreateSection failed for %ls: %x\n",
CabinetContext->CabinetName, NtStatus);
+ return CAB_STATUS_NOMEMORY;
+ }
- NtStatus = NtMapViewOfSection(FileSectionHandle,
- NtCurrentProcess(),
- (PVOID *)&FileBuffer,
- 0, 0, 0,
- &FileSize,
- ViewUnmap,
- 0,
- PAGE_READONLY);
+ CabinetContext->FileBuffer = 0;
+ CabinetContext->FileSize = 0;
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
- return CAB_STATUS_NOMEMORY;
- }
+ NtStatus = NtMapViewOfSection(CabinetContext->FileSectionHandle,
+ NtCurrentProcess(),
+ (PVOID*)&CabinetContext->FileBuffer,
+ 0, 0, 0,
+ &CabinetContext->FileSize,
+ ViewUnmap,
+ 0,
+ PAGE_READONLY);
- DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName,
FileBuffer);
- PCABHeader = (PCFHEADER) FileBuffer;
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
+ return CAB_STATUS_NOMEMORY;
+ }
- /* Check header */
- if (FileSize <= sizeof(CFHEADER) ||
- PCABHeader->Signature != CAB_SIGNATURE ||
- PCABHeader->Version != CAB_VERSION ||
- PCABHeader->FolderCount == 0 ||
- PCABHeader->FileCount == 0 ||
- PCABHeader->FileTableOffset < sizeof(CFHEADER))
- {
- CloseCabinet();
- DPRINT1("File has invalid header\n");
- return CAB_STATUS_INVALID_CAB;
- }
+ DPRINT("Cabinet file %S opened and mapped to %x\n",
+ CabinetContext->CabinetName, CabinetContext->FileBuffer);
+ CabinetContext->PCABHeader = (PCFHEADER)CabinetContext->FileBuffer;
+
+ /* Check header */
+ if (CabinetContext->FileSize <= sizeof(CFHEADER) ||
+ CabinetContext->PCABHeader->Signature != CAB_SIGNATURE ||
+ CabinetContext->PCABHeader->Version != CAB_VERSION ||
+ CabinetContext->PCABHeader->FolderCount == 0 ||
+ CabinetContext->PCABHeader->FileCount == 0 ||
+ CabinetContext->PCABHeader->FileTableOffset < sizeof(CFHEADER))
+ {
+ CloseCabinet(CabinetContext);
+ DPRINT1("File has invalid header\n");
+ return CAB_STATUS_INVALID_CAB;
+ }
- Buffer = (PUCHAR)(PCABHeader + 1);
+ Buffer = (PUCHAR)(CabinetContext->PCABHeader + 1);
- /* Read/skip any reserved bytes */
- if (PCABHeader->Flags & CAB_FLAG_RESERVE)
+ /* Read/skip any reserved bytes */
+ if (CabinetContext->PCABHeader->Flags & CAB_FLAG_RESERVE)
+ {
+ CabinetContext->CabinetReserved = *(PUSHORT)Buffer;
+ Buffer += 2;
+ CabinetContext->FolderReserved = *Buffer;
+ Buffer++;
+ CabinetContext->DataReserved = *Buffer;
+ Buffer++;
+
+ if (CabinetContext->CabinetReserved > 0)
{
- CabinetReserved = *(PUSHORT)Buffer;
- Buffer += 2;
- FolderReserved = *Buffer;
- Buffer++;
- DataReserved = *Buffer;
- Buffer++;
-
- if (CabinetReserved > 0)
- {
- CabinetReservedArea = Buffer;
- Buffer += CabinetReserved;
- }
+ CabinetContext->CabinetReservedArea = Buffer;
+ Buffer += CabinetContext->CabinetReserved;
}
+ }
- if (PCABHeader->Flags & CAB_FLAG_HASPREV)
- {
- /* The previous cabinet file is in
- the same directory as the current */
- wcscpy(CabinetPrev, CabinetName);
- RemoveFileName(CabinetPrev);
- CabinetNormalizePath(CabinetPrev, 256);
- RtlInitAnsiString(&astring, (LPSTR)Buffer);
- ustring.Length = wcslen(CabinetPrev);
- ustring.Buffer = CabinetPrev + ustring.Length;
- ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length;
- RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
- Buffer += astring.Length + 1;
-
- /* Read label of prev disk */
- RtlInitAnsiString(&astring, (LPSTR)Buffer);
- ustring.Length = 0;
- ustring.Buffer = DiskPrev;
- ustring.MaximumLength = sizeof(DiskPrev);
- RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
- Buffer += astring.Length + 1;
- }
- else
- {
- wcscpy(CabinetPrev, L"");
- wcscpy(DiskPrev, L"");
- }
+ if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASPREV)
+ {
+ /* The previous cabinet file is in
+ the same directory as the current */
+ wcscpy(CabinetContext->CabinetPrev, CabinetContext->CabinetName);
+ RemoveFileName(CabinetContext->CabinetPrev);
+ CabinetNormalizePath(CabinetContext->CabinetPrev, 256);
+ RtlInitAnsiString(&astring, (LPSTR)Buffer);
+ ustring.Length = wcslen(CabinetContext->CabinetPrev);
+ ustring.Buffer = CabinetContext->CabinetPrev + ustring.Length;
+ ustring.MaximumLength = sizeof(CabinetContext->CabinetPrev) - ustring.Length;
+ RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
+ Buffer += astring.Length + 1;
+
+ /* Read label of prev disk */
+ RtlInitAnsiString(&astring, (LPSTR)Buffer);
+ ustring.Length = 0;
+ ustring.Buffer = CabinetContext->DiskPrev;
+ ustring.MaximumLength = sizeof(CabinetContext->DiskPrev);
+ RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
+ Buffer += astring.Length + 1;
+ }
+ else
+ {
+ wcscpy(CabinetContext->CabinetPrev, L"");
+ wcscpy(CabinetContext->DiskPrev, L"");
+ }
- if (PCABHeader->Flags & CAB_FLAG_HASNEXT)
- {
- /* The next cabinet file is in
- the same directory as the previous */
- wcscpy(CabinetNext, CabinetName);
- RemoveFileName(CabinetNext);
- CabinetNormalizePath(CabinetNext, 256);
- RtlInitAnsiString(&astring, (LPSTR)Buffer);
- ustring.Length = wcslen(CabinetNext);
- ustring.Buffer = CabinetNext + ustring.Length;
- ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length;
- RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
- Buffer += astring.Length + 1;
-
- /* Read label of next disk */
- RtlInitAnsiString(&astring, (LPSTR)Buffer);
- ustring.Length = 0;
- ustring.Buffer = DiskNext;
- ustring.MaximumLength = sizeof(DiskNext);
- RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
- Buffer += astring.Length + 1;
- }
- else
- {
- wcscpy(CabinetNext, L"");
- wcscpy(DiskNext, L"");
- }
- CabinetFolders = (PCFFOLDER)Buffer;
+ if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASNEXT)
+ {
+ /* The next cabinet file is in
+ the same directory as the previous */
+ wcscpy(CabinetContext->CabinetNext, CabinetContext->CabinetName);
+ RemoveFileName(CabinetContext->CabinetNext);
+ CabinetNormalizePath(CabinetContext->CabinetNext, 256);
+ RtlInitAnsiString(&astring, (LPSTR)Buffer);
+ ustring.Length = wcslen(CabinetContext->CabinetNext);
+ ustring.Buffer = CabinetContext->CabinetNext + ustring.Length;
+ ustring.MaximumLength = sizeof(CabinetContext->CabinetNext) - ustring.Length;
+ RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
+ Buffer += astring.Length + 1;
+
+ /* Read label of next disk */
+ RtlInitAnsiString(&astring, (LPSTR)Buffer);
+ ustring.Length = 0;
+ ustring.Buffer = CabinetContext->DiskNext;
+ ustring.MaximumLength = sizeof(CabinetContext->DiskNext);
+ RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
+ Buffer += astring.Length + 1;
+ }
+ else
+ {
+ wcscpy(CabinetContext->CabinetNext, L"");
+ wcscpy(CabinetContext->DiskNext, L"");
}
+ CabinetContext->CabinetFolders = (PCFFOLDER)Buffer;
DPRINT("CabinetOpen returning SUCCESS\n");
return CAB_STATUS_SUCCESS;
@@ -668,13 +791,14 @@ CabinetOpen(VOID)
* FUNCTION: Closes the cabinet file
*/
VOID
-CabinetClose(VOID)
+CabinetClose(
+ IN OUT PCABINET_CONTEXT CabinetContext)
{
- if (FileOpen)
- {
- CloseCabinet();
- FileOpen = FALSE;
- }
+ if (!CabinetContext->FileOpen)
+ return;
+
+ CloseCabinet(CabinetContext);
+ CabinetContext->FileOpen = FALSE;
}
/*
@@ -686,31 +810,16 @@ CabinetClose(VOID)
* Status of operation
*/
ULONG
-CabinetFindFirst(PWCHAR FileName,
- PCAB_SEARCH Search)
+CabinetFindFirst(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName,
+ IN OUT PCAB_SEARCH Search)
{
- DPRINT("CabinetFindFirst( FileName = %S )\n", FileName);
+ DPRINT("CabinetFindFirst(FileName = %S)\n", FileName);
wcsncpy(Search->Search, FileName, MAX_PATH);
- wcsncpy(Search->Cabinet, CabinetName, MAX_PATH);
+ wcsncpy(Search->Cabinet, CabinetContext->CabinetName, MAX_PATH);
Search->File = 0;
- return CabinetFindNext(Search);
-}
-
-/*
- * FUNCTION: Finds the next file in the cabinet that matches a search criteria
- * ARGUMENTS:
- * FileName = Pointer to search criteria
- * Search = Pointer to search structure
- * RETURNS:
- * Status of operation
- */
-ULONG
-CabinetFindNextFileSequential(PWCHAR FileName,
- PCAB_SEARCH Search)
-{
- DPRINT("CabinetFindNextFileSequential( FileName = %S )\n", FileName);
- wcsncpy(Search->Search, FileName, MAX_PATH);
- return CabinetFindNext(Search);
+ return CabinetFindNext(CabinetContext, Search);
}
/*
@@ -721,14 +830,16 @@ CabinetFindNextFileSequential(PWCHAR FileName,
* Status of operation
*/
ULONG
-CabinetFindNext(PCAB_SEARCH Search)
+CabinetFindNext(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN OUT PCAB_SEARCH Search)
{
PCFFILE Prev;
ANSI_STRING AnsiString;
UNICODE_STRING UnicodeString;
WCHAR FileName[MAX_PATH];
- if (wcscmp(Search->Cabinet, CabinetName) != 0)
+ if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0)
{
/* restart search of cabinet has changed since last find */
Search->File = 0;
@@ -737,7 +848,7 @@ CabinetFindNext(PCAB_SEARCH Search)
if (!Search->File)
{
/* starting new search or cabinet */
- Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset);
+ Search->File = (PCFFILE)(CabinetContext->FileBuffer +
CabinetContext->PCABHeader->FileTableOffset);
Search->Index = 0;
Prev = 0;
}
@@ -753,7 +864,7 @@ CabinetFindNext(PCAB_SEARCH Search)
/* skip files continued from previous cab */
DPRINT("Skipping file (%s): FileOffset (0x%X), "
"LastFileOffset (0x%X)\n", (char *)(Search->File + 1),
- Search->File->FileOffset, LastFileOffset);
+ Search->File->FileOffset, CabinetContext->LastFileOffset);
}
else
{
@@ -789,7 +900,7 @@ CabinetFindNext(PCAB_SEARCH Search)
/* if we make it here we found no match, so move to the next file */
Search->Index++;
- if (Search->Index >= PCABHeader->FileCount)
+ if (Search->Index >= CabinetContext->PCABHeader->FileCount)
{
/* we have reached the end of this cabinet */
DPRINT("End of cabinet reached\n");
@@ -803,6 +914,25 @@ CabinetFindNext(PCAB_SEARCH Search)
return CAB_STATUS_SUCCESS;
}
+/*
+ * FUNCTION: Finds the next file in the cabinet that matches a search criteria
+ * ARGUMENTS:
+ * FileName = Pointer to search criteria
+ * Search = Pointer to search structure
+ * RETURNS:
+ * Status of operation
+ */
+ULONG
+CabinetFindNextFileSequential(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName,
+ IN OUT PCAB_SEARCH Search)
+{
+ DPRINT("CabinetFindNextFileSequential(FileName = %S)\n", FileName);
+ wcsncpy(Search->Search, FileName, MAX_PATH);
+ return CabinetFindNext(CabinetContext, Search);
+}
+
#if 0
int
Validate(VOID)
@@ -819,7 +949,9 @@ Validate(VOID)
* Status of operation
*/
ULONG
-CabinetExtractFile(PCAB_SEARCH Search)
+CabinetExtractFile(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCAB_SEARCH Search)
{
ULONG Size; // remaining file bytes to decompress
ULONG CurrentOffset; // current uncompressed offset within the folder
@@ -842,13 +974,13 @@ CabinetExtractFile(PCAB_SEARCH Search)
PCFFOLDER CurrentFolder;
LARGE_INTEGER MaxDestFileSize;
LONG InputLength, OutputLength;
- char Junk[512];
+ char Chunk[512];
- if (wcscmp(Search->Cabinet, CabinetName) != 0)
+ if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0)
{
/* the file is not in the current cabinet */
DPRINT("File is not in this cabinet (%S != %S)\n",
- Search->Cabinet, CabinetName);
+ Search->Cabinet, CabinetContext->CabinetName);
return CAB_STATUS_NOFILE;
}
@@ -863,21 +995,21 @@ CabinetExtractFile(PCAB_SEARCH Search)
else if (Search->File->FolderIndex == 0xFFFE)
{
/* folder is the last in this cabinet and continues into next */
- CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1];
+ CurrentFolder =
&CabinetContext->CabinetFolders[CabinetContext->PCABHeader->FolderCount -
1];
}
else
{
/* folder is completely contained within this cabinet */
- CurrentFolder = &CabinetFolders[Search->File->FolderIndex];
+ CurrentFolder =
&CabinetContext->CabinetFolders[Search->File->FolderIndex];
}
switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
{
case CAB_COMP_NONE:
- CabinetSelectCodec(CAB_CODEC_RAW);
+ CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
break;
case CAB_COMP_MSZIP:
- CabinetSelectCodec(CAB_CODEC_MSZIP);
+ CabinetSelectCodec(CabinetContext, CAB_CODEC_MSZIP);
break;
default:
return CAB_STATUS_UNSUPPCOMP;
@@ -887,7 +1019,7 @@ CabinetExtractFile(PCAB_SEARCH Search)
(UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);
RtlInitAnsiString(&AnsiString, Search->File->FileName);
- wcscpy(DestName, DestPath);
+ wcscpy(DestName, CabinetContext->DestPath);
UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR);
UnicodeString.Buffer = DestName + wcslen(DestName);
UnicodeString.Length = 0;
@@ -917,7 +1049,8 @@ CabinetExtractFile(PCAB_SEARCH Search)
DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
/* If file exists, ask to overwrite file */
- if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName))
+ if (CabinetContext->OverwriteHandler == NULL ||
+ CabinetContext->OverwriteHandler(CabinetContext, Search->File,
DestName))
{
/* Create destination file, overwrite if it already exists */
NtStatus = NtCreateFile(&DestFile,
@@ -955,18 +1088,18 @@ CabinetExtractFile(PCAB_SEARCH Search)
if (!NT_SUCCESS(NtStatus))
{
- DPRINT1("NtCreateSection failed for %ls, %x\n", DestName, NtStatus);
+ DPRINT1("NtCreateSection failed for %ls: %x\n", DestName, NtStatus);
Status = CAB_STATUS_NOMEMORY;
goto CloseDestFile;
}
DestFileBuffer = 0;
- DestFileSize = 0;
+ CabinetContext->DestFileSize = 0;
NtStatus = NtMapViewOfSection(DestFileSection,
NtCurrentProcess(),
&DestFileBuffer,
0, 0, 0,
- &DestFileSize,
+ &CabinetContext->DestFileSize,
ViewUnmap,
0,
PAGE_READWRITE);
@@ -1015,15 +1148,13 @@ CabinetExtractFile(PCAB_SEARCH Search)
SetAttributesOnFile(Search->File, DestFile);
/* Call extract event handler */
- if (ExtractHandler != NULL)
- {
- ExtractHandler(Search->File, DestName);
- }
+ if (CabinetContext->ExtractHandler != NULL)
+ CabinetContext->ExtractHandler(CabinetContext, Search->File, DestName);
if (Search->CFData)
CFData = Search->CFData;
else
- CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset +
FileBuffer);
+ CFData =
(PCFDATA)(CabinetContext->CabinetFolders[Search->File->FolderIndex].DataOffset +
CabinetContext->FileBuffer);
CurrentOffset = Search->Offset;
while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
@@ -1031,7 +1162,7 @@ CabinetExtractFile(PCAB_SEARCH Search)
/* walk the data blocks until we reach
the one containing the start of the file */
CurrentOffset += CFData->UncompSize;
- CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize);
+ CFData = (PCFDATA)((char *)(CFData + 1) + CabinetContext->DataReserved +
CFData->CompSize);
}
Search->CFData = CFData;
@@ -1041,21 +1172,27 @@ CabinetExtractFile(PCAB_SEARCH Search)
the block before the start of the file */
/* start of comp data */
- CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved;
+ CurrentBuffer = ((unsigned char *)(CFData + 1)) + CabinetContext->DataReserved;
RemainingBlock = CFData->CompSize;
InputLength = RemainingBlock;
while (CurrentOffset < Search->File->FileOffset)
{
/* compute remaining uncomp bytes to start
- of file, bounded by sizeof junk */
+ of file, bounded by size of chunk */
OutputLength = Search->File->FileOffset - CurrentOffset;
- if (OutputLength > (LONG)sizeof(Junk))
- OutputLength = sizeof (Junk);
+ if (OutputLength > (LONG)sizeof(Chunk))
+ OutputLength = sizeof(Chunk);
/* negate to signal NOT end of block */
OutputLength = -OutputLength;
- CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength);
+
+ CabinetContext->Codec->Uncompress(CabinetContext->Codec,
+ Chunk,
+ CurrentBuffer,
+ &InputLength,
+ &OutputLength);
+
/* add the uncomp bytes extracted to current folder offset */
CurrentOffset += OutputLength;
/* add comp bytes consumed to CurrentBuffer */
@@ -1077,11 +1214,11 @@ CabinetExtractFile(PCAB_SEARCH Search)
DPRINT("Decompressing block at %x with RemainingBlock = %d, Size =
%d\n",
CurrentBuffer, RemainingBlock, Size);
- Status = CodecUncompress(CurrentDestBuffer,
- CurrentBuffer,
- &InputLength,
- &OutputLength);
-
+ Status = CabinetContext->Codec->Uncompress(CabinetContext->Codec,
+ CurrentDestBuffer,
+ CurrentBuffer,
+ &InputLength,
+ &OutputLength);
if (Status != CS_SUCCESS)
{
DPRINT("Cannot uncompress block\n");
@@ -1105,7 +1242,7 @@ CabinetExtractFile(PCAB_SEARCH Search)
DPRINT("Out of block data\n");
CFData = (PCFDATA)CurrentBuffer;
RemainingBlock = CFData->CompSize;
- CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved;
+ CurrentBuffer = (unsigned char *)(CFData + 1) +
CabinetContext->DataReserved;
InputLength = RemainingBlock;
}
}
@@ -1130,30 +1267,41 @@ CloseDestFile:
* Id = Codec identifier
*/
VOID
-CabinetSelectCodec(ULONG Id)
+CabinetSelectCodec(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN ULONG Id)
{
- if (CodecSelected)
+ if (CabinetContext->CodecSelected)
{
- if (Id == CodecId)
+ if (Id == CabinetContext->CodecId)
return;
- CodecSelected = FALSE;
+ CabinetContext->CodecSelected = FALSE;
}
switch (Id)
{
case CAB_CODEC_RAW:
- CodecUncompress = RawCodecUncompress;
+ {
+ CabinetContext->Codec = &RawCodec;
break;
+ }
+
case CAB_CODEC_MSZIP:
- CodecUncompress = MSZipCodecUncompress;
+ {
+ CabinetContext->Codec = &MSZipCodec;
+ CabinetContext->Codec->ZStream.zalloc = MSZipAlloc;
+ CabinetContext->Codec->ZStream.zfree = MSZipFree;
+ CabinetContext->Codec->ZStream.opaque = (voidpf)0;
break;
+ }
+
default:
return;
}
- CodecId = Id;
- CodecSelected = TRUE;
+ CabinetContext->CodecId = Id;
+ CabinetContext->CodecSelected = TRUE;
}
/*
@@ -1164,29 +1312,33 @@ CabinetSelectCodec(ULONG Id)
* DiskChange = Handler called when changing the disk
*/
VOID
-CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite,
- PCABINET_EXTRACT Extract,
- PCABINET_DISK_CHANGE DiskChange)
+CabinetSetEventHandlers(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCABINET_OVERWRITE Overwrite,
+ IN PCABINET_EXTRACT Extract,
+ IN PCABINET_DISK_CHANGE DiskChange)
{
- OverwriteHandler = Overwrite;
- ExtractHandler = Extract;
- DiskChangeHandler = DiskChange;
+ CabinetContext->OverwriteHandler = Overwrite;
+ CabinetContext->ExtractHandler = Extract;
+ CabinetContext->DiskChangeHandler = DiskChange;
}
/*
* FUNCTION: Get pointer to cabinet reserved area. NULL if none
*/
PVOID
-CabinetGetCabinetReservedArea(PULONG Size)
+CabinetGetCabinetReservedArea(
+ IN PCABINET_CONTEXT CabinetContext,
+ OUT PULONG Size)
{
- if (CabinetReservedArea != NULL)
+ if (CabinetContext->CabinetReservedArea != NULL)
{
if (Size != NULL)
{
- *Size = CabinetReserved;
+ *Size = CabinetContext->CabinetReserved;
}
- return CabinetReservedArea;
+ return CabinetContext->CabinetReservedArea;
}
else
{
diff --git a/base/setup/usetup/cabinet.h b/base/setup/usetup/cabinet.h
index 82392687d7..4dfd36e750 100644
--- a/base/setup/usetup/cabinet.h
+++ b/base/setup/usetup/cabinet.h
@@ -6,111 +6,15 @@
*/
#pragma once
-#include <string.h>
-
-/* Cabinet constants */
-
-#define CAB_SIGNATURE 0x4643534D // "MSCF"
-#define CAB_VERSION 0x0103
-#define CAB_BLOCKSIZE 32768
-
-#define CAB_COMP_MASK 0x00FF
-#define CAB_COMP_NONE 0x0000
-#define CAB_COMP_MSZIP 0x0001
-#define CAB_COMP_QUANTUM 0x0002
-#define CAB_COMP_LZX 0x0003
-
-#define CAB_FLAG_HASPREV 0x0001
-#define CAB_FLAG_HASNEXT 0x0002
-#define CAB_FLAG_RESERVE 0x0004
-
-#define CAB_ATTRIB_READONLY 0x0001
-#define CAB_ATTRIB_HIDDEN 0x0002
-#define CAB_ATTRIB_SYSTEM 0x0004
-#define CAB_ATTRIB_VOLUME 0x0008
-#define CAB_ATTRIB_DIRECTORY 0x0010
-#define CAB_ATTRIB_ARCHIVE 0x0020
-#define CAB_ATTRIB_EXECUTE 0x0040
-#define CAB_ATTRIB_UTF_NAME 0x0080
-
-#define CAB_FILE_MAX_FOLDER 0xFFFC
-#define CAB_FILE_CONTINUED 0xFFFD
-#define CAB_FILE_SPLIT 0xFFFE
-#define CAB_FILE_PREV_NEXT 0xFFFF
-
-
/* Cabinet structures */
-typedef struct _CFHEADER
-{
- ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE)
- ULONG Reserved1; // Reserved field
- ULONG CabinetSize; // Cabinet file size
- ULONG Reserved2; // Reserved field
- ULONG FileTableOffset; // Offset of first CFFILE
- ULONG Reserved3; // Reserved field
- WORD Version; // Cabinet version (CAB_VERSION)
- WORD FolderCount; // Number of folders
- WORD FileCount; // Number of files
- WORD Flags; // Cabinet flags (CAB_FLAG_*)
- WORD SetID; // Cabinet set id
- WORD CabinetNumber; // Zero-based cabinet number
-/* Optional fields (depends on Flags)
- WORD CabinetResSize // Per-cabinet reserved area size
- CHAR FolderResSize // Per-folder reserved area size
- CHAR FileResSize // Per-file reserved area size
- CHAR CabinetReserved[] // Per-cabinet reserved area
- CHAR CabinetPrev[] // Name of previous cabinet file
- CHAR DiskPrev[] // Name of previous disk
- CHAR CabinetNext[] // Name of next cabinet file
- CHAR DiskNext[] // Name of next disk
- */
-} CFHEADER, *PCFHEADER;
-
-
-typedef struct _CFFOLDER
-{
- ULONG DataOffset; // Absolute offset of first CFDATA block in this folder
- WORD DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet
- WORD CompressionType; // Type of compression used for all CFDATA blocks in this
folder
-/* Optional fields (depends on Flags)
- CHAR FolderReserved[] // Per-folder reserved area
- */
-} CFFOLDER, *PCFFOLDER;
-
-
-typedef struct _CFFILE
-{
- ULONG FileSize; // Uncompressed file size in bytes
- ULONG FileOffset; // Uncompressed offset of file in the folder
- WORD FolderIndex; // Index number of the folder that contains this file
- WORD FileDate; // File date stamp, as used by DOS
- WORD FileTime; // File time stamp, as used by DOS
- WORD Attributes; // File attributes (CAB_ATTRIB_*)
- CHAR FileName[ANYSIZE_ARRAY];
- /* After this is the NULL terminated filename */
-} CFFILE, *PCFFILE;
-
-
-typedef struct _CFDATA
-{
- ULONG Checksum; // Checksum of CFDATA entry
- WORD CompSize; // Number of compressed bytes in this block
- WORD UncompSize; // Number of uncompressed bytes in this block
-/* Optional fields (depends on Flags)
- CHAR DataReserved[] // Per-datablock reserved area
- */
-} CFDATA, *PCFDATA;
+// Shadow types, implementation-specific
+typedef struct _CFHEADER *PCFHEADER;
+typedef struct _CFFOLDER *PCFFOLDER;
+typedef struct _CFFILE *PCFFILE;
+typedef struct _CFDATA *PCFDATA;
-typedef struct _CAB_SEARCH
-{
- WCHAR Search[MAX_PATH]; // Search criteria
- WCHAR Cabinet[MAX_PATH];
- USHORT Index;
- PCFFILE File; // Pointer to current CFFILE
- PCFDATA CFData;
- ULONG Offset;
-} CAB_SEARCH, *PCAB_SEARCH;
+struct _CABINET_CONTEXT;
/* Constants */
@@ -131,12 +35,7 @@ typedef struct _CAB_SEARCH
/* Codecs */
-/* Uncompresses a data block */
-typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer,
- PVOID InputBuffer,
- PLONG InputLength,
- PLONG OutputLength);
-
+typedef struct _CAB_CODEC *PCAB_CODEC;
/* Codec status codes */
#define CS_SUCCESS 0x0000 /* All data consumed */
@@ -148,62 +47,167 @@ typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer,
#define CAB_CODEC_LZX 0x01
#define CAB_CODEC_MSZIP 0x02
-#define MSZIP_MAGIC 0x4B43
+/* Event handler prototypes */
+typedef BOOL (*PCABINET_OVERWRITE)(
+ IN struct _CABINET_CONTEXT* CabinetContext,
+ IN PCFFILE File,
+ IN PCWSTR FileName);
-/* Event handler prototypes */
+typedef VOID (*PCABINET_EXTRACT)(
+ IN struct _CABINET_CONTEXT* CabinetContext,
+ IN PCFFILE File,
+ IN PCWSTR FileName);
-typedef BOOL (*PCABINET_OVERWRITE)(PCFFILE File,
- PWCHAR FileName);
+typedef VOID (*PCABINET_DISK_CHANGE)(
+ IN struct _CABINET_CONTEXT* CabinetContext,
+ IN PCWSTR CabinetName,
+ IN PCWSTR DiskLabel);
-typedef VOID (*PCABINET_EXTRACT)(PCFFILE File,
- PWCHAR FileName);
-typedef VOID (*PCABINET_DISK_CHANGE)(PWCHAR CabinetName,
- PWCHAR DiskLabel);
+/* Classes */
+typedef struct _CAB_SEARCH
+{
+ WCHAR Search[MAX_PATH]; // Search criteria
+ WCHAR Cabinet[MAX_PATH];
+ USHORT Index;
+ PCFFILE File; // Pointer to current CFFILE
+ PCFDATA CFData;
+ ULONG Offset;
+} CAB_SEARCH, *PCAB_SEARCH;
+typedef struct _CABINET_CONTEXT
+{
+ WCHAR CabinetName[256]; // Filename of current cabinet
+ WCHAR CabinetPrev[256]; // Filename of previous cabinet
+ WCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev
+ WCHAR CabinetNext[256]; // Filename of next cabinet
+ WCHAR DiskNext[256]; // Label of cabinet in file CabinetNext
+ ULONG FolderUncompSize; // Uncompressed size of folder
+ ULONG BytesLeftInBlock; // Number of bytes left in current block
+ WCHAR DestPath[MAX_PATH];
+ HANDLE FileHandle;
+ HANDLE FileSectionHandle;
+ PUCHAR FileBuffer;
+ SIZE_T DestFileSize;
+ SIZE_T FileSize;
+ BOOL FileOpen;
+ PCFHEADER PCABHeader;
+ PCFFOLDER CabinetFolders;
+ ULONG CabinetReserved;
+ ULONG FolderReserved;
+ ULONG DataReserved;
+ PCAB_CODEC Codec;
+ ULONG CodecId;
+ BOOL CodecSelected;
+ ULONG LastFileOffset; // Uncompressed offset of last extracted file
+ PCABINET_OVERWRITE OverwriteHandler;
+ PCABINET_EXTRACT ExtractHandler;
+ PCABINET_DISK_CHANGE DiskChangeHandler;
+ PVOID CabinetReservedArea;
+} CABINET_CONTEXT, *PCABINET_CONTEXT;
-/* Classes */
/* Default constructor */
-VOID CabinetInitialize(VOID);
+VOID
+CabinetInitialize(
+ IN OUT PCABINET_CONTEXT CabinetContext);
+
/* Default destructor */
-VOID CabinetCleanup(VOID);
+VOID
+CabinetCleanup(
+ IN OUT PCABINET_CONTEXT CabinetContext);
+
+#if 0
/* Returns a pointer to the filename part of a fully qualified filename */
PWCHAR CabinetGetFileName(PWCHAR Path);
/* Removes a filename from a fully qualified filename */
VOID CabinetRemoveFileName(PWCHAR Path);
/* Normalizes a path */
BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length);
+#endif
+
/* Returns name of cabinet file */
-PWCHAR CabinetGetCabinetName(VOID);
+PCWSTR
+CabinetGetCabinetName(
+ IN PCABINET_CONTEXT CabinetContext);
+
/* Sets the name of the cabinet file */
-VOID CabinetSetCabinetName(PWCHAR FileName);
+VOID
+CabinetSetCabinetName(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName);
+
/* Sets destination path for extracted files */
-VOID CabinetSetDestinationPath(PWCHAR DestinationPath);
+VOID
+CabinetSetDestinationPath(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR DestinationPath);
+
/* Returns destination path */
-PWCHAR CabinetGetDestinationPath(VOID);
+PCWSTR
+CabinetGetDestinationPath(
+ IN PCABINET_CONTEXT CabinetContext);
+
+#if 0
/* Returns zero-based current disk number */
ULONG CabinetGetCurrentDiskNumber(VOID);
+#endif
+
/* Opens the current cabinet file */
-ULONG CabinetOpen(VOID);
+ULONG
+CabinetOpen(
+ IN OUT PCABINET_CONTEXT CabinetContext);
+
/* Closes the current open cabinet file */
-VOID CabinetClose(VOID);
+VOID
+CabinetClose(
+ IN OUT PCABINET_CONTEXT CabinetContext);
+
/* Locates the first file in the current cabinet file that matches a search criteria */
-ULONG CabinetFindFirst(PWCHAR FileName, PCAB_SEARCH Search);
+ULONG
+CabinetFindFirst(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName,
+ IN OUT PCAB_SEARCH Search);
+
/* Locates the next file that matches the current search criteria */
-ULONG CabinetFindNext(PCAB_SEARCH Search);
+ULONG
+CabinetFindNext(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN OUT PCAB_SEARCH Search);
+
/* Locates the next file in the current cabinet file sequentially */
-ULONG CabinetFindNextFileSequential(PWCHAR FileName, PCAB_SEARCH Search);
+ULONG
+CabinetFindNextFileSequential(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCWSTR FileName,
+ IN OUT PCAB_SEARCH Search);
+
/* Extracts a file from the current cabinet file */
-ULONG CabinetExtractFile(PCAB_SEARCH Search);
+ULONG
+CabinetExtractFile(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCAB_SEARCH Search);
+
/* Select codec engine to use */
-VOID CabinetSelectCodec(ULONG Id);
+VOID
+CabinetSelectCodec(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN ULONG Id);
+
/* Set event handlers */
-VOID CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite,
- PCABINET_EXTRACT Extract,
- PCABINET_DISK_CHANGE DiskChange);
+VOID
+CabinetSetEventHandlers(
+ IN PCABINET_CONTEXT CabinetContext,
+ IN PCABINET_OVERWRITE Overwrite,
+ IN PCABINET_EXTRACT Extract,
+ IN PCABINET_DISK_CHANGE DiskChange);
+
/* Get pointer to cabinet reserved area. NULL if none */
-PVOID CabinetGetCabinetReservedArea(PULONG Size);
+PVOID
+CabinetGetCabinetReservedArea(
+ IN PCABINET_CONTEXT CabinetContext,
+ OUT PULONG Size);
diff --git a/base/setup/usetup/filequeue.c b/base/setup/usetup/filequeue.c
index b49e56e9ba..bb1f71218c 100644
--- a/base/setup/usetup/filequeue.c
+++ b/base/setup/usetup/filequeue.c
@@ -60,6 +60,22 @@ static BOOLEAN HasCurrentCabinet = FALSE;
static WCHAR CurrentCabinetName[MAX_PATH];
static CAB_SEARCH Search;
+// HACK: Temporary compatibility code.
+#if 1
+ static CABINET_CONTEXT CabinetContext;
+ #define CabinetInitialize() (CabinetInitialize(&CabinetContext))
+ #define CabinetSetEventHandlers(a,b,c)
(CabinetSetEventHandlers(&CabinetContext,(a),(b),(c)))
+ #define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a)))
+ #define CabinetOpen() (CabinetOpen(&CabinetContext))
+ #define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext))
+ #define CabinetGetCabinetReservedArea(a)
(CabinetGetCabinetReservedArea(&CabinetContext,(a)))
+ #define CabinetFindNextFileSequential(a,b)
(CabinetFindNextFileSequential(&CabinetContext,(a),(b)))
+ #define CabinetFindFirst(a,b) (CabinetFindFirst(&CabinetContext,(a),(b)))
+ #define CabinetSetDestinationPath(a)
(CabinetSetDestinationPath(&CabinetContext,(a)))
+ #define CabinetExtractFile(a) (CabinetExtractFile(&CabinetContext,(a)))
+ #define CabinetCleanup() (CabinetCleanup(&CabinetContext))
+#endif
+
NTSTATUS
SetupExtractFile(
PWCHAR CabinetFileName,
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index b544e207b3..edd98fd654 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -69,6 +69,19 @@ static PNTOS_INSTALLATION CurrentInstallation = NULL;
static PGENERIC_LIST NtOsInstallsList = NULL;
+// HACK: Temporary compatibility code.
+#if 1
+ static CABINET_CONTEXT CabinetContext;
+ #define CabinetInitialize() (CabinetInitialize(&CabinetContext))
+ #define CabinetSetEventHandlers(a,b,c)
(CabinetSetEventHandlers(&CabinetContext,(a),(b),(c)))
+ #define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a)))
+ #define CabinetOpen() (CabinetOpen(&CabinetContext))
+ #define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext))
+ #define CabinetGetCabinetReservedArea(a)
(CabinetGetCabinetReservedArea(&CabinetContext,(a)))
+ #define CabinetCleanup() (CabinetCleanup(&CabinetContext))
+#endif
+
+
/* FUNCTIONS ****************************************************************/
static VOID