[SETUPAPI] Fix broken control definition.
[reactos.git] / dll / win32 / setupapi / queue.c
index 3cb45ba..060984b 100644 (file)
@@ -136,11 +136,9 @@ static void concat_W( WCHAR *buffer, const WCHAR *src1, const WCHAR *src2, const
         if (buffer[-1] != '\\') *buffer++ = '\\';
         if (src3) while (*src3 == '\\') src3++;
     }
+
     if (src3)
-    {
         strcpyW( buffer, src3 );
-        buffer += strlenW(buffer );
-    }
 }
 
 
@@ -364,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
@@ -374,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" )))
@@ -407,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
 }
 
 
@@ -459,6 +532,7 @@ BOOL WINAPI SetupQueueCopyIndirectA( PSP_FILE_COPY_PARAMS_A params )
     op->src_tag    = strdupAtoW( params->SourceTagfile );
     op->dst_path   = strdupAtoW( params->TargetDirectory );
     op->dst_file   = strdupAtoW( params->TargetFilename );
+    op->dst_sd     = NULL;
 
     /* some defaults */
     if (!op->src_file) op->src_file = op->dst_file;
@@ -632,6 +706,7 @@ BOOL WINAPI SetupQueueDeleteA( HSPFILEQ handle, PCSTR part1, PCSTR part2 )
     op->src_tag    = NULL;
     op->dst_path   = strdupAtoW( part1 );
     op->dst_file   = strdupAtoW( part2 );
+    op->dst_sd     = NULL;
     queue_file_op( &queue->delete_queue, op );
     return TRUE;
 }
@@ -654,6 +729,7 @@ BOOL WINAPI SetupQueueDeleteW( HSPFILEQ handle, PCWSTR part1, PCWSTR part2 )
     op->src_tag    = NULL;
     op->dst_path   = strdupW( part1 );
     op->dst_file   = strdupW( part2 );
+    op->dst_sd     = NULL;
     queue_file_op( &queue->delete_queue, op );
     return TRUE;
 }
@@ -677,6 +753,7 @@ BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFi
     op->src_tag    = NULL;
     op->dst_path   = strdupAtoW( TargetPath );
     op->dst_file   = strdupAtoW( TargetFilename );
+    op->dst_sd     = NULL;
     queue_file_op( &queue->rename_queue, op );
     return TRUE;
 }
@@ -700,6 +777,7 @@ BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR Source
     op->src_tag    = NULL;
     op->dst_path   = strdupW( TargetPath );
     op->dst_file   = strdupW( TargetFilename );
+    op->dst_sd     = NULL;
     queue_file_op( &queue->rename_queue, op );
     return TRUE;
 }
@@ -984,9 +1062,57 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
 {
     BOOL rc = FALSE;
     BOOL docopy = TRUE;
+#ifdef __REACTOS__
+    INT hSource, hTemp;
+    OFSTRUCT OfStruct;
+    WCHAR TempPath[MAX_PATH];
+    WCHAR TempFile[MAX_PATH];
+#endif
 
     TRACE("copy %s to %s style 0x%x\n",debugstr_w(source),debugstr_w(target),style);
 
+#ifdef __REACTOS__
+    /* Get a temp file name */
+    if (!GetTempPathW(ARRAYSIZE(TempPath), TempPath))
+    {
+        ERR("GetTempPathW error\n");
+        return FALSE;
+    }
+    if (!GetTempFileNameW(TempPath, L"", 0, TempFile))
+    {
+        ERR("GetTempFileNameW(%s) error\n", debugstr_w(TempPath));
+        return FALSE;
+    }
+
+    /* Try to open the source file */
+    hSource = LZOpenFileW((LPWSTR)source, &OfStruct, OF_READ);
+    if (hSource < 0)
+    {
+        ERR("LZOpenFileW(1) error %d %s\n", (int)hSource, debugstr_w(source));
+        return FALSE;
+    }
+
+    /* Extract the compressed file to a temp location */
+    hTemp = LZOpenFileW(TempFile, &OfStruct, OF_CREATE);
+    if (hTemp < 0)
+    {
+        DWORD dwLastError = GetLastError();
+
+        ERR("LZOpenFileW(2) error %d %s\n", (int)hTemp, debugstr_w(TempFile));
+
+        /* Close the source handle */
+        LZClose(hSource);
+
+        /* Restore error condition triggered by LZOpenFileW */
+        SetLastError(dwLastError);
+        return FALSE;
+    }
+
+    LZCopy(hSource, hTemp);
+    LZClose(hSource);
+    LZClose(hTemp);
+#endif
+
     /* before copy processing */
     if (style & SP_COPY_REPLACEONLY)
     {
@@ -1010,9 +1136,9 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
          * we just basically unconditionally replace the builtin versions.
          */
         if ((GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES) &&
-            (GetFileAttributesW(source) != INVALID_FILE_ATTRIBUTES))
+            (GetFileAttributesW(TempFile) != INVALID_FILE_ATTRIBUTES))
         {
-            VersionSizeSource = GetFileVersionInfoSizeW((LPWSTR)source,&zero);
+            VersionSizeSource = GetFileVersionInfoSizeW(TempFile,&zero);
             VersionSizeTarget = GetFileVersionInfoSizeW((LPWSTR)target,&zero);
         }
 
@@ -1032,7 +1158,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
             VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);
             VersionTarget = HeapAlloc(GetProcessHeap(),0,VersionSizeTarget);
 
-            ret = GetFileVersionInfoW((LPWSTR)source,0,VersionSizeSource,VersionSource);
+            ret = GetFileVersionInfoW(TempFile,0,VersionSizeSource,VersionSource);
             if (ret)
               ret = GetFileVersionInfoW((LPWSTR)target, 0, VersionSizeTarget,
                     VersionTarget);
@@ -1107,7 +1233,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
 
     if (docopy)
     {
-        rc = CopyFileW(source,target,FALSE);
+        rc = MoveFileExW(TempFile,target,MOVEFILE_REPLACE_EXISTING);
         TRACE("Did copy... rc was %i\n",rc);
     }
 
@@ -1193,7 +1319,11 @@ BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source
             SetLastError( ERROR_NOT_ENOUGH_MEMORY );
             return FALSE;
         }
-        if (!SetupGetStringFieldW( inf_context, 1, inf_source, len, NULL )) return FALSE;
+        if (!SetupGetStringFieldW( inf_context, 1, inf_source, len, NULL ))
+        {
+            HeapFree( GetProcessHeap(), 0, inf_source );
+            return FALSE;
+        }
         source = inf_source;
     }
     else if (!source)