https://git.reactos.org/?p=reactos.git;a=commitdiff;h=04ec14e23ee9b7b5d0f2b5...
commit 04ec14e23ee9b7b5d0f2b5edecea6c819110e068 Author: Hervé Poussineau hpoussin@reactos.org AuthorDate: Mon May 13 23:28:19 2019 +0200 Commit: Hervé Poussineau hpoussin@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);