Hans Leidekker : msi: Support multiple patches per package.
Alexandre Julliard
julliard at winehq.org
Thu Apr 29 14:45:06 CDT 2010
Module: wine
Branch: master
Commit: 162780d112d2aa1c856a807b6dc4898b731b74ff
URL: http://source.winehq.org/git/wine.git/?a=commit;h=162780d112d2aa1c856a807b6dc4898b731b74ff
Author: Hans Leidekker <hans at codeweavers.com>
Date: Thu Apr 29 09:39:22 2010 +0200
msi: Support multiple patches per package.
---
dlls/msi/action.c | 111 +++++++++++++++++++++++++++++++++-------------------
dlls/msi/msipriv.h | 3 +-
dlls/msi/package.c | 12 ++++--
3 files changed, 81 insertions(+), 45 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 96dbc3d..5ca786d 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -492,44 +492,31 @@ done:
return r;
}
-static UINT msi_parse_patch_summary( MSIPACKAGE *package, MSIDATABASE *patch_db )
+static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
{
- MSISUMMARYINFO *si;
+ MSIPATCHINFO *pi;
UINT r = ERROR_SUCCESS;
- si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
- if (!si)
- return ERROR_FUNCTION_FAILED;
-
- if (msi_check_patch_applicable( package, si ) != ERROR_SUCCESS)
- {
- TRACE("Patch not applicable\n");
- msiobj_release( &si->hdr );
- return ERROR_SUCCESS;
- }
-
- package->patch = msi_alloc(sizeof(MSIPATCHINFO));
- if (!package->patch)
- {
- msiobj_release( &si->hdr );
+ pi = msi_alloc( sizeof(MSIPATCHINFO) );
+ if (!pi)
return ERROR_OUTOFMEMORY;
- }
- package->patch->patchcode = msi_suminfo_dup_string(si, PID_REVNUMBER);
- if (!package->patch->patchcode)
+ pi->patchcode = msi_suminfo_dup_string( si, PID_REVNUMBER );
+ if (!pi->patchcode)
{
- msiobj_release( &si->hdr );
+ msi_free( pi );
return ERROR_OUTOFMEMORY;
}
- package->patch->transforms = msi_suminfo_dup_string(si, PID_LASTAUTHOR);
- if (!package->patch->transforms)
+ pi->transforms = msi_suminfo_dup_string( si, PID_LASTAUTHOR );
+ if (!pi->transforms)
{
- msiobj_release( &si->hdr );
+ msi_free( pi->patchcode );
+ msi_free( pi );
return ERROR_OUTOFMEMORY;
}
- msiobj_release( &si->hdr );
+ *patch = pi;
return r;
}
@@ -537,6 +524,8 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
{
MSIDATABASE *patch_db = NULL;
LPWSTR *substorage;
+ MSISUMMARYINFO *si;
+ MSIPATCHINFO *patch;
UINT i, r;
TRACE("%p %s\n", package, debugstr_w( file ) );
@@ -548,10 +537,32 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
return r;
}
- msi_parse_patch_summary( package, patch_db );
+ si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
+ if (!si)
+ {
+ msiobj_release( &patch_db->hdr );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ r = msi_check_patch_applicable( package, si );
+ if (r != ERROR_SUCCESS)
+ {
+ TRACE("patch not applicable\n");
+ msiobj_release( &si->hdr );
+ msiobj_release( &patch_db->hdr );
+ return ERROR_SUCCESS;
+ }
+
+ r = msi_parse_patch_summary( si, &patch );
+ if ( r != ERROR_SUCCESS )
+ {
+ msiobj_release( &si->hdr );
+ msiobj_release( &patch_db->hdr );
+ return r;
+ }
/* apply substorage transforms */
- substorage = msi_split_string( package->patch->transforms, ';' );
+ substorage = msi_split_string( patch->transforms, ';' );
for ( i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++ )
r = msi_apply_substorage_transform( package, patch_db, substorage[i] );
@@ -564,6 +575,9 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
*/
append_storage_to_db( package->db, patch_db->storage );
+ list_add_tail( &package->patches, &patch->entry );
+
+ msiobj_release( &si->hdr );
msiobj_release( &patch_db->hdr );
return ERROR_SUCCESS;
@@ -3753,34 +3767,51 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package)
return TRUE;
}
-static UINT msi_publish_patch(MSIPACKAGE *package, HKEY prodkey, HKEY hudkey)
+static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey, HKEY hudkey )
{
WCHAR patch_squashed[GUID_SIZE];
HKEY patches;
LONG res;
+ MSIPATCHINFO *patch;
UINT r = ERROR_FUNCTION_FAILED;
+ WCHAR *p, *all_patches = NULL;
+ DWORD len = 0;
- res = RegCreateKeyExW(prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
- &patches, NULL);
+ res = RegCreateKeyExW( prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches, NULL );
if (res != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
- squash_guid(package->patch->patchcode, patch_squashed);
+ LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
+ {
+ squash_guid( patch->patchcode, patch_squashed );
+ len += strlenW( patch_squashed ) + 1;
+ }
- res = RegSetValueExW(patches, szPatches, 0, REG_MULTI_SZ,
- (const BYTE *)patch_squashed,
- (lstrlenW(patch_squashed) + 1) * sizeof(WCHAR));
- if (res != ERROR_SUCCESS)
+ p = all_patches = msi_alloc( (len + 1) * sizeof(WCHAR) );
+ if (!all_patches)
goto done;
- res = RegSetValueExW(patches, patch_squashed, 0, REG_SZ,
- (const BYTE *)package->patch->transforms,
- (lstrlenW(package->patch->transforms) + 1) * sizeof(WCHAR));
+ LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
+ {
+ squash_guid( patch->patchcode, p );
+ p += strlenW( p ) + 1;
+
+ res = RegSetValueExW( patches, patch_squashed, 0, REG_SZ,
+ (const BYTE *)patch->transforms,
+ (strlenW(patch->transforms) + 1) * sizeof(WCHAR) );
+ if (res != ERROR_SUCCESS)
+ goto done;
+ }
+
+ all_patches[len] = 0;
+ res = RegSetValueExW( patches, szPatches, 0, REG_MULTI_SZ,
+ (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
if (res == ERROR_SUCCESS)
r = ERROR_SUCCESS;
done:
RegCloseKey(patches);
+ msi_free( all_patches );
return r;
}
@@ -3814,9 +3845,9 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
if (rc != ERROR_SUCCESS)
goto end;
- if (package->patch)
+ if (!list_empty(&package->patches))
{
- rc = msi_publish_patch(package, hukey, hudkey);
+ rc = msi_publish_patches(package, hukey, hudkey);
if (rc != ERROR_SUCCESS)
goto end;
}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 06a4367..c339ea9 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -148,6 +148,7 @@ typedef struct tagMSIMEDIAINFO
typedef struct tagMSIPATCHINFO
{
+ struct list entry;
LPWSTR patchcode;
LPWSTR transforms;
} MSIPATCHINFO;
@@ -302,7 +303,7 @@ typedef struct tagMSIPACKAGE
{
MSIOBJECTHDR hdr;
MSIDATABASE *db;
- MSIPATCHINFO *patch;
+ struct list patches;
struct list components;
struct list features;
struct list files;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 0c06088..45b4dc9 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -264,11 +264,14 @@ static void free_package_structures( MSIPACKAGE *package )
msi_free( package->script );
}
- if (package->patch)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->patches )
{
- msi_free( package->patch->patchcode );
- msi_free( package->patch->transforms );
- msi_free( package->patch );
+ MSIPATCHINFO *patch = LIST_ENTRY( item, MSIPATCHINFO, entry );
+
+ list_remove( &patch->entry );
+ msi_free( patch->patchcode );
+ msi_free( patch->transforms );
+ msi_free( patch );
}
msi_free( package->BaseURL );
@@ -987,6 +990,7 @@ static MSIPACKAGE *msi_alloc_package( void )
list_init( &package->RunningActions );
list_init( &package->sourcelist_info );
list_init( &package->sourcelist_media );
+ list_init( &package->patches );
}
return package;
More information about the wine-cvs
mailing list