https://git.reactos.org/?p=reactos.git;a=commitdiff;h=04ec14e23ee9b7b5d0f2b…
commit 04ec14e23ee9b7b5d0f2b5edecea6c819110e068
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon May 13 23:28:19 2019 +0200
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Sun Apr 26 14:57:40 2020 +0200
[USETUP] Support a custom way to extract files for cabinet files
This will be used to extract files from cabinet to memory, instead of
writing them to disk.
---
base/setup/usetup/spapisup/cabinet.c | 248 ++++++++++++++++++----------------
base/setup/usetup/spapisup/cabinet.h | 7 +-
base/setup/usetup/spapisup/fileqsup.c | 2 +-
3 files changed, 140 insertions(+), 117 deletions(-)
diff --git a/base/setup/usetup/spapisup/cabinet.c b/base/setup/usetup/spapisup/cabinet.c
index 7e8450ca42c..8d8391a3250 100644
--- a/base/setup/usetup/spapisup/cabinet.c
+++ b/base/setup/usetup/spapisup/cabinet.c
@@ -1018,134 +1018,147 @@ CabinetExtractFile(
DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
(UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);
- RtlInitAnsiString(&AnsiString, Search->File->FileName);
- wcscpy(DestName, CabinetContext->DestPath);
- UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR);
- UnicodeString.Buffer = DestName + wcslen(DestName);
- UnicodeString.Length = 0;
- RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
-
- /* Create destination file, fail if it already exists */
- RtlInitUnicodeString(&UnicodeString, DestName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &UnicodeString,
- OBJ_CASE_INSENSITIVE,
- NULL, NULL);
-
- NtStatus = NtCreateFile(&DestFile,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_CREATE,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL, 0);
-
- if (!NT_SUCCESS(NtStatus))
+ if (CabinetContext->CreateFileHandler)
{
- DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
+ /* Call create context */
+ CurrentDestBuffer = CabinetContext->CreateFileHandler(CabinetContext,
Search->File->FileSize);
+ if (!CurrentDestBuffer)
+ {
+ DPRINT1("CreateFileHandler() failed\n");
+ return CAB_STATUS_CANNOT_CREATE;
+ }
+ }
+ else
+ {
+ RtlInitAnsiString(&AnsiString, Search->File->FileName);
+ wcscpy(DestName, CabinetContext->DestPath);
+ UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) *
sizeof(WCHAR);
+ UnicodeString.Buffer = DestName + wcslen(DestName);
+ UnicodeString.Length = 0;
+ RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
+
+ /* Create destination file, fail if it already exists */
+ RtlInitUnicodeString(&UnicodeString, DestName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &UnicodeString,
+ OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+
+ NtStatus = NtCreateFile(&DestFile,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_CREATE,
+ FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL, 0);
- /* If file exists, ask to overwrite file */
- if (CabinetContext->OverwriteHandler == NULL ||
- CabinetContext->OverwriteHandler(CabinetContext, Search->File,
DestName))
+ if (!NT_SUCCESS(NtStatus))
{
- /* Create destination file, overwrite if it already exists */
- NtStatus = NtCreateFile(&DestFile,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OVERWRITE,
- FILE_SYNCHRONOUS_IO_ALERT,
- NULL, 0);
+ DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
- if (!NT_SUCCESS(NtStatus))
+ /* If file exists, ask to overwrite file */
+ if (CabinetContext->OverwriteHandler == NULL ||
+ CabinetContext->OverwriteHandler(CabinetContext, Search->File,
DestName))
{
- DPRINT1("NtCreateFile() failed (%S) (%x)\n", DestName,
NtStatus);
- return CAB_STATUS_CANNOT_CREATE;
+ /* Create destination file, overwrite if it already exists */
+ NtStatus = NtCreateFile(&DestFile,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OVERWRITE,
+ FILE_SYNCHRONOUS_IO_ALERT,
+ NULL, 0);
+
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("NtCreateFile() failed (%S) (%x)\n", DestName,
NtStatus);
+ return CAB_STATUS_CANNOT_CREATE;
+ }
+ }
+ else
+ {
+ DPRINT1("File (%S) exists\n", DestName);
+ return CAB_STATUS_FILE_EXISTS;
}
}
- else
- {
- DPRINT1("File (%S) exists\n", DestName);
- return CAB_STATUS_FILE_EXISTS;
- }
- }
- MaxDestFileSize.QuadPart = Search->File->FileSize;
- NtStatus = NtCreateSection(&DestFileSection,
- SECTION_ALL_ACCESS,
- 0,
- &MaxDestFileSize,
- PAGE_READWRITE,
- SEC_COMMIT,
- DestFile);
+ MaxDestFileSize.QuadPart = Search->File->FileSize;
+ NtStatus = NtCreateSection(&DestFileSection,
+ SECTION_ALL_ACCESS,
+ 0,
+ &MaxDestFileSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ DestFile);
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT1("NtCreateSection failed for %ls: %x\n", DestName, NtStatus);
- Status = CAB_STATUS_NOMEMORY;
- goto CloseDestFile;
- }
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("NtCreateSection failed for %ls: %x\n", DestName,
NtStatus);
+ Status = CAB_STATUS_NOMEMORY;
+ goto CloseDestFile;
+ }
- DestFileBuffer = 0;
- CabinetContext->DestFileSize = 0;
- NtStatus = NtMapViewOfSection(DestFileSection,
- NtCurrentProcess(),
- &DestFileBuffer,
- 0, 0, 0,
- &CabinetContext->DestFileSize,
- ViewUnmap,
- 0,
- PAGE_READWRITE);
+ DestFileBuffer = 0;
+ CabinetContext->DestFileSize = 0;
+ NtStatus = NtMapViewOfSection(DestFileSection,
+ NtCurrentProcess(),
+ &DestFileBuffer,
+ 0, 0, 0,
+ &CabinetContext->DestFileSize,
+ ViewUnmap,
+ 0,
+ PAGE_READWRITE);
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
- Status = CAB_STATUS_NOMEMORY;
- goto CloseDestFileSection;
- }
-
- CurrentDestBuffer = DestFileBuffer;
- if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
- Search->File->FileTime,
- &FileTime))
- {
- DPRINT1("DosDateTimeToFileTime() failed\n");
- Status = CAB_STATUS_CANNOT_WRITE;
- goto UnmapDestFile;
- }
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
+ Status = CAB_STATUS_NOMEMORY;
+ goto CloseDestFileSection;
+ }
- NtStatus = NtQueryInformationFile(DestFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(NtStatus))
- {
- DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
- }
- else
- {
- memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));
+ CurrentDestBuffer = DestFileBuffer;
+ if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
+ Search->File->FileTime,
+ &FileTime))
+ {
+ DPRINT1("DosDateTimeToFileTime() failed\n");
+ Status = CAB_STATUS_CANNOT_WRITE;
+ goto UnmapDestFile;
+ }
- NtStatus = NtSetInformationFile(DestFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
+ NtStatus = NtQueryInformationFile(DestFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
if (!NT_SUCCESS(NtStatus))
{
- DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
+ DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
}
- }
+ else
+ {
+ memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));
- SetAttributesOnFile(Search->File, DestFile);
+ NtStatus = NtSetInformationFile(DestFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (!NT_SUCCESS(NtStatus))
+ {
+ DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
+ }
+ }
+
+ SetAttributesOnFile(Search->File, DestFile);
+ }
/* Call extract event handler */
if (CabinetContext->ExtractHandler != NULL)
@@ -1250,13 +1263,16 @@ CabinetExtractFile(
Status = CAB_STATUS_SUCCESS;
UnmapDestFile:
- NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
+ if (!CabinetContext->CreateFileHandler)
+ NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
CloseDestFileSection:
- NtClose(DestFileSection);
+ if (!CabinetContext->CreateFileHandler)
+ NtClose(DestFileSection);
CloseDestFile:
- NtClose(DestFile);
+ if (!CabinetContext->CreateFileHandler)
+ NtClose(DestFile);
return Status;
}
@@ -1316,11 +1332,13 @@ CabinetSetEventHandlers(
IN PCABINET_CONTEXT CabinetContext,
IN PCABINET_OVERWRITE Overwrite,
IN PCABINET_EXTRACT Extract,
- IN PCABINET_DISK_CHANGE DiskChange)
+ IN PCABINET_DISK_CHANGE DiskChange,
+ IN PCABINET_CREATE_FILE CreateFile)
{
CabinetContext->OverwriteHandler = Overwrite;
CabinetContext->ExtractHandler = Extract;
CabinetContext->DiskChangeHandler = DiskChange;
+ CabinetContext->CreateFileHandler = CreateFile;
}
/*
diff --git a/base/setup/usetup/spapisup/cabinet.h b/base/setup/usetup/spapisup/cabinet.h
index 4dfd36e7506..0ba74c9e9d6 100644
--- a/base/setup/usetup/spapisup/cabinet.h
+++ b/base/setup/usetup/spapisup/cabinet.h
@@ -65,6 +65,9 @@ typedef VOID (*PCABINET_DISK_CHANGE)(
IN PCWSTR CabinetName,
IN PCWSTR DiskLabel);
+typedef PVOID (*PCABINET_CREATE_FILE)(
+ IN struct _CABINET_CONTEXT* CabinetContext,
+ IN ULONG FileSize);
/* Classes */
@@ -106,6 +109,7 @@ typedef struct _CABINET_CONTEXT
PCABINET_OVERWRITE OverwriteHandler;
PCABINET_EXTRACT ExtractHandler;
PCABINET_DISK_CHANGE DiskChangeHandler;
+ PCABINET_CREATE_FILE CreateFileHandler;
PVOID CabinetReservedArea;
} CABINET_CONTEXT, *PCABINET_CONTEXT;
@@ -204,7 +208,8 @@ CabinetSetEventHandlers(
IN PCABINET_CONTEXT CabinetContext,
IN PCABINET_OVERWRITE Overwrite,
IN PCABINET_EXTRACT Extract,
- IN PCABINET_DISK_CHANGE DiskChange);
+ IN PCABINET_DISK_CHANGE DiskChange,
+ IN PCABINET_CREATE_FILE CreateFile);
/* Get pointer to cabinet reserved area. NULL if none */
PVOID
diff --git a/base/setup/usetup/spapisup/fileqsup.c
b/base/setup/usetup/spapisup/fileqsup.c
index b82fcd889d5..d6846881d96 100644
--- a/base/setup/usetup/spapisup/fileqsup.c
+++ b/base/setup/usetup/spapisup/fileqsup.c
@@ -117,7 +117,7 @@ SetupExtractFile(
CabinetInitialize(&QueueHeader->CabinetContext);
CabinetSetEventHandlers(&QueueHeader->CabinetContext,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
CabinetSetCabinetName(&QueueHeader->CabinetContext, CabinetFileName);
CabStatus = CabinetOpen(&QueueHeader->CabinetContext);