https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e0baa58f1b54b9d49e1724ed559f7b9a5cff6a9c

commit e0baa58f1b54b9d49e1724ed559f7b9a5cff6a9c
Author: Hermès Bélusca-Maïto <[email protected]>
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
 }
 
 

Reply via email to