mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 13:38:19 +00:00
[SETUPAPI] Fix extraction of files from a cabinet file using the SetupQueueCopy and SetupCommitFileQueue method.
CORE-14164 - Contrary to what Wine thought, this works even if the cabinet file does not have a ".cab" extension. - Instead of polluting the directory where the cabinet file exists with all the files extracted from it, we only extract the needed file to a temporary folder (thus being sure it does not overwrite any other existing file with the same name), and then we move the extracted file to its final destination with rename.
This commit is contained in:
parent
7c447a15a0
commit
e0baa58f1b
1 changed files with 75 additions and 0 deletions
|
@ -362,7 +362,11 @@ static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
|
|||
}
|
||||
|
||||
|
||||
#ifndef __REACTOS__
|
||||
static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD );
|
||||
#else
|
||||
static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, LPSTR, LPVOID, DWORD );
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* extract_cabinet_file
|
||||
|
@ -372,14 +376,21 @@ static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD );
|
|||
static BOOL extract_cabinet_file( const WCHAR *cabinet, const WCHAR *root,
|
||||
const WCHAR *src, const WCHAR *dst )
|
||||
{
|
||||
#ifndef __REACTOS__
|
||||
static const WCHAR extW[] = {'.','c','a','b',0};
|
||||
#endif
|
||||
static HMODULE advpack;
|
||||
|
||||
char *cab_path, *cab_file;
|
||||
int len = strlenW( cabinet );
|
||||
|
||||
#ifdef __REACTOS__
|
||||
TRACE("extract_cabinet_file(cab = '%s' ; root = '%s' ; src = '%s' ; dst = '%s')\n",
|
||||
debugstr_w(cabinet), debugstr_w(root), debugstr_w(src), debugstr_w(dst));
|
||||
#else
|
||||
/* make sure the cabinet file has a .cab extension */
|
||||
if (len <= 4 || strcmpiW( cabinet + len - 4, extW )) return FALSE;
|
||||
#endif
|
||||
if (!pExtractFiles)
|
||||
{
|
||||
if (!advpack && !(advpack = LoadLibraryA( "advpack.dll" )))
|
||||
|
@ -405,10 +416,74 @@ static BOOL extract_cabinet_file( const WCHAR *cabinet, const WCHAR *root,
|
|||
if (cab_file[0] && cab_file[strlen(cab_file)-1] != '\\') strcat( cab_file, "\\" );
|
||||
WideCharToMultiByte( CP_ACP, 0, cabinet, -1, cab_file + strlen(cab_file), len, NULL, NULL );
|
||||
FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file) );
|
||||
|
||||
#ifdef __REACTOS__
|
||||
{
|
||||
BOOL Success;
|
||||
char *src_file;
|
||||
const WCHAR *src_fileW;
|
||||
WCHAR TempPath[MAX_PATH];
|
||||
|
||||
/* Retrieve the temporary path */
|
||||
if (!GetTempPathW(ARRAYSIZE(TempPath), TempPath))
|
||||
{
|
||||
ERR("GetTempPathW error\n");
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Build the real path to where the file will be extracted */
|
||||
HeapFree( GetProcessHeap(), 0, cab_path );
|
||||
if (!(cab_path = strdupWtoA( TempPath )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Build the file list */
|
||||
src_fileW = strrchrW(src, '\\'); // Find where the filename starts.
|
||||
if (src_fileW) ++src_fileW;
|
||||
else src_fileW = src;
|
||||
/* Convert to ANSI */
|
||||
if (!(src_file = strdupWtoA( src_fileW )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_path );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Prepare for the move operation */
|
||||
/* Build the full path to the extracted file, that will be renamed */
|
||||
if (!(src = HeapAlloc( GetProcessHeap(), 0, (strlenW(TempPath) + 1 + strlenW(src_fileW) + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, src_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_path );
|
||||
return FALSE;
|
||||
}
|
||||
concat_W( (WCHAR*)src, NULL, TempPath, src_fileW );
|
||||
|
||||
TRACE("pExtractFiles(cab_file = '%s' ; cab_path = '%s', src_file = '%s')\n",
|
||||
debugstr_a(cab_file), debugstr_a(cab_path), debugstr_a(src_file));
|
||||
|
||||
/* Extract to temporary folder */
|
||||
pExtractFiles( cab_file, cab_path, 0, src_file, NULL, 0 );
|
||||
HeapFree( GetProcessHeap(), 0, src_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_path );
|
||||
|
||||
/* Move to destination, overwriting the original file if needed */
|
||||
TRACE("Renaming src = '%s' to dst = '%s')\n", debugstr_w(src), debugstr_w(dst));
|
||||
Success = MoveFileExW( src, dst , MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED );
|
||||
HeapFree( GetProcessHeap(), 0, (WCHAR*)src );
|
||||
return Success;
|
||||
}
|
||||
#else
|
||||
pExtractFiles( cab_file, cab_path, 0, 0, 0, 0 );
|
||||
HeapFree( GetProcessHeap(), 0, cab_file );
|
||||
HeapFree( GetProcessHeap(), 0, cab_path );
|
||||
return CopyFileW( src, dst, FALSE /*FIXME*/ );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue