- Optimize cabinet file processing by finding files sequentially instead of starting from the beginning each time

svn path=/trunk/; revision=54624
This commit is contained in:
Cameron Gutman 2011-12-09 14:51:57 +00:00
parent 417b739dbe
commit ffcd78f426
3 changed files with 42 additions and 30 deletions

View file

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

View file

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

View file

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