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