[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.
This commit is contained in:
Hermès Bélusca-Maïto 2017-08-14 17:11:50 +00:00
parent 1a173dfdb2
commit 9169e881aa
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 643 additions and 458 deletions

File diff suppressed because it is too large Load diff

View file

@ -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;
// Shadow types, implementation-specific
typedef struct _CFHEADER *PCFHEADER;
typedef struct _CFFOLDER *PCFFOLDER;
typedef struct _CFFILE *PCFFILE;
typedef struct _CFDATA *PCFDATA;
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;
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)(PCFFILE File,
PWCHAR FileName);
typedef BOOL (*PCABINET_OVERWRITE)(
IN struct _CABINET_CONTEXT* CabinetContext,
IN PCFFILE File,
IN PCWSTR FileName);
typedef VOID (*PCABINET_EXTRACT)(PCFFILE File,
PWCHAR FileName);
typedef VOID (*PCABINET_DISK_CHANGE)(PWCHAR CabinetName,
PWCHAR DiskLabel);
typedef VOID (*PCABINET_EXTRACT)(
IN struct _CABINET_CONTEXT* CabinetContext,
IN PCFFILE File,
IN PCWSTR FileName);
typedef VOID (*PCABINET_DISK_CHANGE)(
IN struct _CABINET_CONTEXT* CabinetContext,
IN PCWSTR CabinetName,
IN PCWSTR 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;
/* 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);

View file

@ -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,

View file

@ -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