From 06afeec2a5cd7cf49842e9f245fc157835097a9a Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 22 Jul 2010 11:47:13 +0200 Subject: [PATCH] msi: Make sure properties are updated after applying a patch. --- 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 702a92abbf4..29071d06e90 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 bdb1884f605..0be3eb9451d 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 bff1bb43f0b..d3321686964 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; + + 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); - msiobj_release(&view->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 6b4faf1cb78..2453e99a2cb 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 );