Piotr Caban : msi: Add support for re-caching package.

Alexandre Julliard julliard at winehq.org
Fri Jun 22 18:32:37 CDT 2018


Module: wine
Branch: master
Commit: 5924321ad63edc1d3fabf22d7b047e4efacbce66
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5924321ad63edc1d3fabf22d7b047e4efacbce66

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Jun 21 21:48:56 2018 +0200

msi: Add support for re-caching package.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msi/action.c        | 42 ++++++++++++++++++++++++++++++++++++++----
 dlls/msi/msi.c           | 27 +++++++++++++++++++++------
 dlls/msi/msipriv.h       |  4 +++-
 dlls/msi/package.c       | 14 ++++++++++++--
 dlls/msi/tests/package.c |  6 +++---
 5 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 9d216ab..15f1876 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -294,15 +294,18 @@ static int parse_prop( const WCHAR *str, WCHAR *value, int *quotes )
 
         default: break;
         }
-        if (!ignore) *out++ = *p;
+        if (!ignore && value) *out++ = *p;
         if (!count) in_quotes = FALSE;
     }
 
 done:
-    if (!len) *value = 0;
-    else *out = 0;
+    if (value)
+    {
+        if (!len) *value = 0;
+        else *out = 0;
+    }
 
-    *quotes = count;
+    if(quotes) *quotes = count;
     return p - str;
 }
 
@@ -378,6 +381,37 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine,
     return ERROR_SUCCESS;
 }
 
+const WCHAR *msi_get_command_line_option(const WCHAR *cmd, const WCHAR *option, UINT *len)
+{
+    DWORD opt_len = strlenW(option);
+
+    if (!cmd)
+        return NULL;
+
+    while (*cmd)
+    {
+        BOOL found = FALSE;
+
+        while (*cmd == ' ') cmd++;
+        if (!*cmd) break;
+
+        if(!strncmpiW(cmd, option, opt_len))
+            found = TRUE;
+
+        cmd = strchrW( cmd, '=' );
+        if(!cmd) break;
+        cmd++;
+        while (*cmd == ' ') cmd++;
+        if (!*cmd) break;
+
+        *len = parse_prop( cmd, NULL, NULL);
+        if (found) return cmd;
+        cmd += *len;
+    }
+
+    return NULL;
+}
+
 WCHAR **msi_split_string( const WCHAR *str, WCHAR sep )
 {
     LPCWSTR pc;
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index 2ae4db2..7d805af 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -137,7 +137,7 @@ static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
         goto done;
     }
 
-    r = MSI_OpenPackageW(path, package);
+    r = MSI_OpenPackageW(path, 0, package);
 
 done:
     RegCloseKey(props);
@@ -236,7 +236,9 @@ end:
 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
 {
     MSIPACKAGE *package = NULL;
-    UINT r;
+    const WCHAR *reinstallmode;
+    DWORD options = 0;
+    UINT r, len;
 
     TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
 
@@ -246,7 +248,20 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
     if (!*szPackagePath)
         return ERROR_PATH_NOT_FOUND;
 
-    r = MSI_OpenPackageW( szPackagePath, &package );
+    reinstallmode = msi_get_command_line_option(szCommandLine, szReinstallMode, &len);
+    if (reinstallmode)
+    {
+        while (len > 0)
+        {
+            if (reinstallmode[--len] == 'v' || reinstallmode[len] == 'V')
+            {
+                options |= WINE_OPENPACKAGEFLAGS_RECACHE;
+                break;
+            }
+        }
+    }
+
+    r = MSI_OpenPackageW( szPackagePath, options, &package );
     if (r == ERROR_SUCCESS)
     {
         r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
@@ -732,7 +747,7 @@ UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
 
     TRACE("%s, %u, %p\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
 
-    r = MSI_OpenPackageW( szProductPackagePath, &package );
+    r = MSI_OpenPackageW( szProductPackagePath, 0, &package );
     if (r != ERROR_SUCCESS)
     {
         ERR("failed to open package %u\n", r);
@@ -810,7 +825,7 @@ static UINT open_package( const WCHAR *product, const WCHAR *usersid,
     if (GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
         return ERROR_INSTALL_SOURCE_ABSENT;
 
-    return MSI_OpenPackageW( sourcepath, package );
+    return MSI_OpenPackageW( sourcepath, 0, package );
 }
 
 UINT WINAPI MsiDeterminePatchSequenceW( LPCWSTR product, LPCWSTR usersid,
@@ -4027,7 +4042,7 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, DWORD dw
     strcatW( sourcepath, filename );
 
     if (dwReinstallMode & REINSTALLMODE_PACKAGE)
-        r = MSI_OpenPackageW( sourcepath, &package );
+        r = MSI_OpenPackageW( sourcepath, 0, &package );
     else
         r = MSI_OpenProductW( szProduct, &package );
 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 8043d0a..789d541 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -799,6 +799,7 @@ extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN;
 extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN;
 extern UINT MSI_SetFeatureStates( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
 extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL preserve_case ) DECLSPEC_HIDDEN;
+extern const WCHAR *msi_get_command_line_option( const WCHAR *cmd, const WCHAR *option, UINT *len ) DECLSPEC_HIDDEN;
 extern UINT msi_schedule_action( MSIPACKAGE *package, UINT script, const WCHAR *action ) DECLSPEC_HIDDEN;
 extern INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp ) DECLSPEC_HIDDEN;
 extern INSTALLSTATE msi_get_feature_action( MSIPACKAGE *package, MSIFEATURE *feature ) DECLSPEC_HIDDEN;
@@ -863,8 +864,9 @@ extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **) DECLS
 extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) DECLSPEC_HIDDEN;
 
 /* package internals */
+#define WINE_OPENPACKAGEFLAGS_RECACHE 0x80000000
 extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE * ) DECLSPEC_HIDDEN;
-extern UINT MSI_OpenPackageW( LPCWSTR szPackage, MSIPACKAGE **pPackage ) DECLSPEC_HIDDEN;
+extern UINT MSI_OpenPackageW( LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage ) DECLSPEC_HIDDEN;
 extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN;
 extern INT MSI_ProcessMessageVerbatim( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * ) DECLSPEC_HIDDEN;
 extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * ) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 46fbeba..d6f22d0 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -1433,7 +1433,7 @@ UINT msi_set_original_database_property( MSIDATABASE *db, const WCHAR *package )
     return r;
 }
 
-UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
+UINT MSI_OpenPackageW(LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage)
 {
     static const WCHAR dotmsi[] = {'.','m','s','i',0};
     MSIDATABASE *db;
@@ -1509,6 +1509,16 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
             }
             delete_on_close = TRUE;
         }
+        else if (dwOptions & WINE_OPENPACKAGEFLAGS_RECACHE)
+        {
+            if (!CopyFileW( file, localfile, FALSE ))
+            {
+                r = GetLastError();
+                WARN("unable to update cached package (%u)\n", r);
+                msiobj_release( &db->hdr );
+                return r;
+            }
+        }
         else
             product_version = get_product_version( db );
         msiobj_release( &db->hdr );
@@ -1662,7 +1672,7 @@ UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phP
     if( dwOptions )
         FIXME("dwOptions %08x not supported\n", dwOptions);
 
-    ret = MSI_OpenPackageW( szPackage, &package );
+    ret = MSI_OpenPackageW( szPackage, 0, &package );
     if( ret == ERROR_SUCCESS )
     {
         *phPackage = alloc_msihandle( &package->hdr );
diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c
index b1c7a76..ace9b35 100644
--- a/dlls/msi/tests/package.c
+++ b/dlls/msi/tests/package.c
@@ -3840,15 +3840,15 @@ static void test_states(void)
     r = MsiInstallProductA(msifile2, "");
     ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
 
-    r = MsiInstallProductA(msifile2, "REINSTALLMODE=v");
-    todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     size = MAX_PATH;
     r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    todo_wine ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
+    ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
     MsiCloseHandle(hprod);
 
     /* major upgrade test */




More information about the wine-cvs mailing list