[1/7] msi: Make sure properties are updated after applying a patch.

Hans Leidekker hans at codeweavers.com
Thu Jul 22 04:47:13 CDT 2010


Fixes http://bugs.winehq.org/show_bug.cgi?id=21133
---
 dlls/msi/action.c      |    3 ++
 dlls/msi/msipriv.h     |    1 +
 dlls/msi/package.c     |   79 ++++++++++++++++++++++++++++++++++--------------
 dlls/msi/tests/patch.c |   14 ++++++++-
 4 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 702a92a..29071d0 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -7536,6 +7536,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
 
     /* properties may have been added by a transform */
     msi_clone_properties( package );
+
+    msi_parse_command_line( package, szCommandLine, FALSE );
+    msi_adjust_allusers_property( package );
     msi_set_context( package );
 
     if (needs_ui_sequence( package))
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index bdb1884..0be3eb9 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -765,6 +765,7 @@ extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR);
 extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR);
 extern UINT msi_clone_properties(MSIPACKAGE *);
 extern UINT msi_set_context(MSIPACKAGE *);
+extern void msi_adjust_allusers_property(MSIPACKAGE *);
 extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT);
 
 /* for deformating */
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index bff1bb4..d332168 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -324,57 +324,85 @@ static UINT create_temp_property_table(MSIPACKAGE *package)
 
 UINT msi_clone_properties(MSIPACKAGE *package)
 {
-    MSIQUERY *view = NULL;
+    MSIQUERY *view_select = NULL;
     UINT rc;
 
-    static const WCHAR Query[] = {
+    static const WCHAR query_select[] = {
        'S','E','L','E','C','T',' ','*',' ',
        'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',0};
-    static const WCHAR Insert[] = {
+    static const WCHAR query_insert[] = {
        'I','N','S','E','R','T',' ','i','n','t','o',' ',
        '`','_','P','r','o','p','e','r','t','y','`',' ',
        '(','`','_','P','r','o','p','e','r','t','y','`',',',
        '`','V','a','l','u','e','`',')',' ',
        'V','A','L','U','E','S',' ','(','?',',','?',')',0};
+    static const WCHAR query_update[] = {
+        'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
+        'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ',
+        'W','H','E','R','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','?',0};
 
-    /* clone the existing properties */
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    rc = MSI_DatabaseOpenViewW( package->db, query_select, &view_select );
     if (rc != ERROR_SUCCESS)
         return rc;
 
-    rc = MSI_ViewExecute(view, 0);
+    rc = MSI_ViewExecute( view_select, 0 );
     if (rc != ERROR_SUCCESS)
     {
-        MSI_ViewClose(view);
-        msiobj_release(&view->hdr);
+        MSI_ViewClose( view_select );
+        msiobj_release( &view_select->hdr );
         return rc;
     }
 
     while (1)
     {
-        MSIRECORD *row;
-        MSIQUERY *view2;
+        MSIQUERY *view_insert, *view_update;
+        MSIRECORD *rec_select;
 
-        rc = MSI_ViewFetch(view, &row);
+        rc = MSI_ViewFetch( view_select, &rec_select );
         if (rc != ERROR_SUCCESS)
             break;
 
-        rc = MSI_DatabaseOpenViewW(package->db, Insert, &view2);
+        rc = MSI_DatabaseOpenViewW( package->db, query_insert, &view_insert );
         if (rc != ERROR_SUCCESS)
         {
-            msiobj_release(&row->hdr);
+            msiobj_release( &rec_select->hdr );
             continue;
         }
 
-        MSI_ViewExecute(view2, row);
-        MSI_ViewClose(view2);
-        msiobj_release(&view2->hdr);
-        msiobj_release(&row->hdr);
-    }
+        rc = MSI_ViewExecute( view_insert, rec_select );
+        MSI_ViewClose( view_insert );
+        msiobj_release( &view_insert->hdr );
+        if (rc != ERROR_SUCCESS)
+        {
+            MSIRECORD *rec_update;
 
-    MSI_ViewClose(view);
-    msiobj_release(&view->hdr);
+            TRACE("insert failed, trying update\n");
+
+            rc = MSI_DatabaseOpenViewW( package->db, query_update, &view_update );
+            if (rc != ERROR_SUCCESS)
+            {
+                WARN("open view failed %u\n", rc);
+                msiobj_release( &rec_select->hdr );
+                continue;
+            }
+
+            rec_update = MSI_CreateRecord( 2 );
+            MSI_RecordCopyField( rec_select, 1, rec_update, 2 );
+            MSI_RecordCopyField( rec_select, 2, rec_update, 1 );
+            rc = MSI_ViewExecute( view_update, rec_update );
+            if (rc != ERROR_SUCCESS)
+                WARN("update failed %u\n", rc);
+
+            MSI_ViewClose( view_update );
+            msiobj_release( &view_update->hdr );
+            msiobj_release( &rec_update->hdr );
+        }
+
+        msiobj_release( &rec_select->hdr );
+    }
 
+    MSI_ViewClose( view_select );
+    msiobj_release( &view_select->hdr );
     return rc;
 }
 
@@ -1014,7 +1042,7 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package)
     return r;
 }
 
-static void adjust_allusers_property( MSIPACKAGE *package )
+void msi_adjust_allusers_property( MSIPACKAGE *package )
 {
     /* FIXME: this should depend on the user's privileges */
     if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
@@ -1046,6 +1074,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
 
         create_temp_property_table( package );
         msi_clone_properties( package );
+        msi_adjust_allusers_property( package );
 
         package->ProductCode = msi_dup_property( package->db, szProductCode );
         package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
@@ -1065,8 +1094,6 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
 
         if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
             msi_load_admin_properties( package );
-
-        adjust_allusers_property( package );
     }
 
     return package;
@@ -1378,6 +1405,12 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
         index++;
     }
 
+    if (index)
+    {
+        msi_clone_properties( package );
+        msi_adjust_allusers_property( package );
+    }
+
     *pPackage = package;
     return ERROR_SUCCESS;
 }
diff --git a/dlls/msi/tests/patch.c b/dlls/msi/tests/patch.c
index 6b4faf1..2453e99 100644
--- a/dlls/msi/tests/patch.c
+++ b/dlls/msi/tests/patch.c
@@ -681,7 +681,7 @@ static void test_simple_patch( void )
 {
     UINT r;
     DWORD size;
-    char path[MAX_PATH], install_source[MAX_PATH];
+    char path[MAX_PATH], install_source[MAX_PATH], buffer[32];
     const char *query;
     MSIHANDLE hpackage, hdb, hview, hrec;
 
@@ -753,6 +753,12 @@ static void test_simple_patch( void )
     MsiViewClose( hview );
     MsiCloseHandle( hview );
 
+    buffer[0] = 0;
+    size = sizeof(buffer);
+    r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
+    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
+    ok( !strcmp( buffer, "Installer Database" ), "expected \'Installer Database\', got \'%s\'\n", buffer );
+
     MsiCloseHandle( hdb );
     MsiCloseHandle( hpackage );
 
@@ -805,6 +811,12 @@ static void test_simple_patch( void )
     MsiViewClose( hview );
     MsiCloseHandle( hview );
 
+    buffer[0] = 0;
+    size = sizeof(buffer);
+    r = MsiGetProperty( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
+    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
+    ok( !strcmp( buffer, "Installation Database" ), "expected \'Installation Database\', got \'%s\'\n", buffer );
+
     MsiCloseHandle( hdb );
     MsiCloseHandle( hpackage );
 
-- 
1.7.0.4







More information about the wine-patches mailing list