James Hawkins : msi: Download install cabinet files if the msi package is remote.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 10 04:43:15 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 1ff96c63a82d8192454d3513a4e0110c1bc02026
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=1ff96c63a82d8192454d3513a4e0110c1bc02026

Author: James Hawkins <truiken at gmail.com>
Date:   Wed Aug  9 15:02:49 2006 -0700

msi: Download install cabinet files if the msi package is remote.

---

 dlls/msi/files.c   |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/msi/package.c |    4 ++-
 2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 914b699..443e6c3 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -42,6 +42,8 @@ #include "msidefs.h"
 #include "msvcrt/fcntl.h"
 #include "msipriv.h"
 #include "winuser.h"
+#include "winreg.h"
+#include "shlwapi.h"
 #include "wine/unicode.h"
 #include "action.h"
 
@@ -56,6 +58,7 @@ extern const WCHAR szRemoveFiles[];
 
 static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
 
+extern LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename );
 
 /*
  * This is a helper function for handling embedded cabinet media
@@ -378,6 +381,52 @@ static void free_media_info( struct medi
     msi_free( mi );
 }
 
+/* downloads a remote cabinet and extracts it if it exists */
+static UINT msi_extract_remote_cabinet( MSIPACKAGE *package, struct media_info *mi )
+{
+    FDICABINETINFO cabinfo;
+    WCHAR temppath[MAX_PATH];
+    WCHAR src[MAX_PATH];
+    LPSTR cabpath;
+    LPCWSTR file;
+    LPWSTR ptr;
+    HFDI hfdi;
+    ERF erf;
+    int hf;
+
+    /* the URL is the path prefix of the package URL and the filename
+     * of the file to download
+     */
+    ptr = strrchrW(package->PackagePath, '/');
+    lstrcpynW(src, package->PackagePath, ptr - package->PackagePath + 2);
+    ptr = strrchrW(mi->source, '\\');
+    lstrcatW(src, ptr + 1);
+
+    file = msi_download_file( src, temppath );
+    lstrcpyW(mi->source, file);
+
+    /* check if the remote cabinet still exists, ignore if it doesn't */
+    hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
+                     cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
+    if (!hfdi)
+    {
+        ERR("FDICreate failed\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    cabpath = strdupWtoA(mi->source);
+    hf = cabinet_open(cabpath, _O_RDONLY, 0);
+    if (!FDIIsCabinet(hfdi, hf, &cabinfo))
+    {
+        WARN("Remote cabinet %s does not exist.\n", debugstr_w(mi->source));
+        msi_free(cabpath);
+        return ERROR_SUCCESS;
+    }
+
+    msi_free(cabpath);
+    return !extract_cabinet_file(package, mi->source, mi->last_path);
+}
+
 static UINT ready_media_for_file( MSIPACKAGE *package, struct media_info *mi,
                                   MSIFILE *file )
 {
@@ -488,7 +537,17 @@ static UINT ready_media_for_file( MSIPAC
                     GetTempPathW(MAX_PATH,mi->last_path);
             }
         }
-        rc = !extract_cabinet_file(package, mi->source, mi->last_path);
+
+        /* only download the remote cabinet file if a local copy does not exist */
+        if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES &&
+            UrlIsW(package->PackagePath, URLIS_URL))
+        {
+            rc = msi_extract_remote_cabinet(package, mi);
+        }
+        else
+        {
+            rc = !extract_cabinet_file(package, mi->source, mi->last_path);
+        }
     }
     else
     {
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 4065ffb..d172c50 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -485,7 +485,7 @@ static LPCWSTR copy_package_to_temp( LPC
     return filename;
 }
 
-static LPCWSTR msi_download_package( LPCWSTR szUrl, LPWSTR filename )
+LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename )
 {
     LPINTERNET_CACHE_ENTRY_INFOW cache_entry;
     DWORD size = 0;
@@ -539,7 +539,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage,
         LPCWSTR file;
 
         if ( UrlIsW( szPackage, URLIS_URL ) )
-            file = msi_download_package( szPackage, temppath );
+            file = msi_download_file( szPackage, temppath );
         else
             file = copy_package_to_temp( szPackage, temppath );
 




More information about the wine-cvs mailing list