https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e0baa58f1b54b9d49e172…
commit e0baa58f1b54b9d49e1724ed559f7b9a5cff6a9c
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Dec 31 02:47:03 2017 +0100
[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.
---
dll/win32/setupapi/queue.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/dll/win32/setupapi/queue.c b/dll/win32/setupapi/queue.c
index b556418389..060984be8f 100644
--- a/dll/win32/setupapi/queue.c
+++ b/dll/win32/setupapi/queue.c
@@ -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
}