Module: wine Branch: master Commit: 162780d112d2aa1c856a807b6dc4898b731b74ff URL: http://source.winehq.org/git/wine.git/?a=commit;h=162780d112d2aa1c856a807b6d...
Author: Hans Leidekker hans@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;