From ffcd78f426b79c964c20798736a37bf116d9d543 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 9 Dec 2011 14:51:57 +0000 Subject: [PATCH] [USETUP] - Optimize cabinet file processing by finding files sequentially instead of starting from the beginning each time svn path=/trunk/; revision=54624 --- reactos/base/setup/usetup/cabinet.c | 46 ++++++++++++----------------- reactos/base/setup/usetup/cabinet.h | 4 ++- reactos/base/setup/usetup/filesup.c | 22 ++++++++++++-- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/reactos/base/setup/usetup/cabinet.c b/reactos/base/setup/usetup/cabinet.c index 7d3486d7162..0ecb8be4f90 100644 --- a/reactos/base/setup/usetup/cabinet.c +++ b/reactos/base/setup/usetup/cabinet.c @@ -693,6 +693,23 @@ CabinetFindFirst(PWCHAR FileName, 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); +} + /* * FUNCTION: Finds next file in the cabinet that matches a search criteria * ARGUMENTS: @@ -703,7 +720,6 @@ CabinetFindFirst(PWCHAR FileName, ULONG CabinetFindNext(PCAB_SEARCH Search) { - ULONG Status; PCFFILE Prev; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; @@ -766,33 +782,9 @@ CabinetFindNext(PCAB_SEARCH Search) Search->Index++; if (Search->Index >= PCABHeader->FileCount) { - /* we have reached the end of this cabinet, try to open the next */ + /* we have reached the end of this cabinet */ DPRINT("End of cabinet reached\n"); - if (wcslen(DiskNext) > 0) - { - CloseCabinet(); - - CabinetSetCabinetName(CabinetNext); - wcscpy(Search->Cabinet, CabinetName); - - if (DiskChangeHandler != NULL) - { - DiskChangeHandler(CabinetNext, DiskNext); - } - - Status = CabinetOpen(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } - else - { - return CAB_STATUS_NOFILE; - } - - /* starting new search or cabinet */ - Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); - Search->Index = 0; - Prev = 0; + return CAB_STATUS_NOFILE; } else Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1); diff --git a/reactos/base/setup/usetup/cabinet.h b/reactos/base/setup/usetup/cabinet.h index 70fa34cc49f..98d175c6f98 100644 --- a/reactos/base/setup/usetup/cabinet.h +++ b/reactos/base/setup/usetup/cabinet.h @@ -191,8 +191,10 @@ ULONG CabinetOpen(VOID); VOID CabinetClose(VOID); /* Locates the first file in the current cabinet file that matches a search criteria */ ULONG CabinetFindFirst(PWCHAR FileName, PCAB_SEARCH Search); -/* Locates the next file in the current cabinet file */ +/* Locates the next file that matches the current search criteria */ ULONG CabinetFindNext(PCAB_SEARCH Search); +/* Locates the next file in the current cabinet file sequentially */ +ULONG CabinetFindNextFileSequential(PWCHAR FileName, PCAB_SEARCH Search); /* Extracts a file from the current cabinet file */ ULONG CabinetExtractFile(PCAB_SEARCH Search); /* Select codec engine to use */ diff --git a/reactos/base/setup/usetup/filesup.c b/reactos/base/setup/usetup/filesup.c index 0051b0abed0..525543d5104 100644 --- a/reactos/base/setup/usetup/filesup.c +++ b/reactos/base/setup/usetup/filesup.c @@ -35,6 +35,7 @@ static BOOLEAN HasCurrentCabinet = FALSE; static WCHAR CurrentCabinetName[MAX_PATH]; +static CAB_SEARCH Search; NTSTATUS SetupCreateDirectory(PWCHAR DirectoryName) @@ -275,7 +276,6 @@ SetupExtractFile(PWCHAR CabinetFileName, PWCHAR DestinationPathName) { ULONG CabStatus; - CAB_SEARCH Search; DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n", CabinetFileName, SourceFileName, DestinationPathName); @@ -288,6 +288,16 @@ SetupExtractFile(PWCHAR CabinetFileName, if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0)) { DPRINT("Using same cabinet as last time\n"); + + /* Use our last location because the files should be sequential */ + CabStatus = CabinetFindNextFileSequential(SourceFileName, &Search); + if (CabStatus != CAB_STATUS_SUCCESS) + { + DPRINT("Sequential miss on file: %S\n", SourceFileName); + + /* Looks like we got unlucky */ + CabStatus = CabinetFindFirst(SourceFileName, &Search); + } } else { @@ -315,10 +325,18 @@ SetupExtractFile(PWCHAR CabinetFileName, DPRINT("Cannot open cabinet (%d)\n", CabStatus); return STATUS_UNSUCCESSFUL; } + + /* We have to start at the beginning here */ + CabStatus = CabinetFindFirst(SourceFileName, &Search); } + + if (CabStatus != CAB_STATUS_SUCCESS) + { + DPRINT1("Unable to find '%S' in cabinet '%S'\n", SourceFileName, CabinetGetCabinetName()); + return STATUS_UNSUCCESSFUL; + } CabinetSetDestinationPath(DestinationPathName); - CabinetFindFirst( SourceFileName, &Search ); CabStatus = CabinetExtractFile(&Search); if (CabStatus != CAB_STATUS_SUCCESS) {