From 920fc345ba6d680b93c9d40a5cbfa33c47f3a1e2 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 4 May 2010 09:07:39 +0200 Subject: [PATCH] msi: Register more patch details. --- dlls/msi/action.c | 55 ++++++++++++++++++++++++++++++------- dlls/msi/msi.c | 4 --- dlls/msi/msipriv.h | 4 +++ dlls/msi/registry.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ dlls/msi/tests/patch.c | 14 +++++++--- 5 files changed, 133 insertions(+), 17 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index e744973ffd9..35030e25f28 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -3791,20 +3791,25 @@ static BOOL msi_check_unpublish(MSIPACKAGE *package) return TRUE; } -static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey, HKEY hudkey ) +static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey ) { + static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0}; WCHAR patch_squashed[GUID_SIZE]; - HKEY patches; + HKEY patches_key = NULL, product_patches_key; LONG res; MSIPATCHINFO *patch; - UINT r = ERROR_FUNCTION_FAILED; + UINT r; 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_key, NULL ); if (res != ERROR_SUCCESS) return ERROR_FUNCTION_FAILED; + r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; + LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) { squash_guid( patch->patchcode, patch_squashed ); @@ -3817,24 +3822,48 @@ static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey, HKEY hudkey LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry ) { + HKEY patch_key; + squash_guid( patch->patchcode, p ); p += strlenW( p ) + 1; - res = RegSetValueExW( patches, patch_squashed, 0, REG_SZ, + res = RegSetValueExW( patches_key, patch_squashed, 0, REG_SZ, (const BYTE *)patch->transforms, (strlenW(patch->transforms) + 1) * sizeof(WCHAR) ); if (res != ERROR_SUCCESS) goto done; + + r = MSIREG_OpenUserDataPatchKey( patch->patchcode, package->Context, &patch_key, TRUE ); + if (r != ERROR_SUCCESS) + goto done; + + res = RegSetValueExW( patch_key, szLocalPackage, 0, REG_SZ, + (const BYTE *)patch->localfile, + (strlenW(patch->localfile) + 1) * sizeof(WCHAR) ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; + + res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL ); + RegCloseKey( patch_key ); + if (res != ERROR_SUCCESS) + goto done; } all_patches[len] = 0; - res = RegSetValueExW( patches, szPatches, 0, REG_MULTI_SZ, + res = RegSetValueExW( patches_key, szPatches, 0, REG_MULTI_SZ, (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); - if (res == ERROR_SUCCESS) - r = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + goto done; + + res = RegSetValueExW( product_patches_key, szAllPatches, 0, REG_MULTI_SZ, + (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) ); + if (res != ERROR_SUCCESS) + r = ERROR_FUNCTION_FAILED; done: - RegCloseKey(patches); + RegCloseKey( product_patches_key ); + RegCloseKey( patches_key ); msi_free( all_patches ); return r; } @@ -3871,7 +3900,7 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package) if (!list_empty(&package->patches)) { - rc = msi_publish_patches(package, hukey, hudkey); + rc = msi_publish_patches(package, hukey); if (rc != ERROR_SUCCESS) goto end; } @@ -4671,6 +4700,7 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) LPWSTR *features = NULL; BOOL full_uninstall = TRUE; MSIFEATURE *feature; + MSIPATCHINFO *patch; static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0}; @@ -4723,6 +4753,11 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) msi_free(upgrade); } + LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry) + { + MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context); + } + done: msi_free(remove); msi_free(features); diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index e4ad6820150..2d33487b0cf 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -602,10 +602,6 @@ static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context, WCHAR sourcepath[MAX_PATH]; WCHAR filename[MAX_PATH]; - static const WCHAR szLocalPackage[] = { - 'L','o','c','a','l','P','a','c','k','a','g','e',0}; - - r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE); if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION; diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index a8594a84d33..354aca59999 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -785,12 +785,15 @@ extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT d LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create); +extern UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create); extern UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create); extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct); +extern UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context); extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid); @@ -1105,6 +1108,7 @@ static const WCHAR szDefaultIcon[] = {'D','e','f','a','u','l','t','I','c','o','n static const WCHAR szInprocHandler[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r',0}; static const WCHAR szInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; static const WCHAR szMIMEDatabase[] = {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',' ','T','y','p','e','\\',0}; +static const WCHAR szLocalPackage[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0}; /* memory allocation macro functions */ static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index 7a4c3f877a4..518303f5da0 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -183,6 +183,16 @@ static const WCHAR szUserDataPatch_fmt[] = { 'U','s','e','r','D','a','t','a','\\', '%','s','\\','P','a','t','c','h','e','s','\\','%','s',0}; +static const WCHAR szUserDataProductPatches_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'M','i','c','r','o','s','o','f','t','\\', +'W','i','n','d','o','w','s','\\', +'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', +'I','n','s','t','a','l','l','e','r','\\', +'U','s','e','r','D','a','t','a','\\', +'%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\', +'P','a','t','c','h','e','s',0}; + static const WCHAR szInstallProperties_fmt[] = { 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -887,6 +897,69 @@ UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } +UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context) +{ + UINT r; + WCHAR squished_patch[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(patch)); + if (!squash_guid(patch, squished_patch)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_patch)); + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataPatch_fmt, szLocalSid, squished_patch); + else + { + r = get_user_sid(&usersid); + if (r != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", r); + return r; + } + + sprintfW(keypath, szUserDataPatch_fmt, usersid, squished_patch); + LocalFree(usersid); + } + + return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); +} + +UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, + HKEY *key, BOOL create) +{ + UINT rc; + WCHAR squished_product[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + + TRACE("%s\n", debugstr_w(product)); + if (!squash_guid(product, squished_product)) + return ERROR_FUNCTION_FAILED; + + if (context == MSIINSTALLCONTEXT_MACHINE) + sprintfW(keypath, szUserDataProductPatches_fmt, szLocalSid, squished_product); + else + { + rc = get_user_sid(&usersid); + if (rc != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", rc); + return rc; + } + + sprintfW(keypath, szUserDataProductPatches_fmt, usersid, squished_product); + LocalFree(usersid); + } + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create) { diff --git a/dlls/msi/tests/patch.c b/dlls/msi/tests/patch.c index 048de2cfcc5..e3869259084 100644 --- a/dlls/msi/tests/patch.c +++ b/dlls/msi/tests/patch.c @@ -999,8 +999,8 @@ static void test_patch_registration( void ) "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", NULL, MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_LOCALPACKAGE, buffer, &size ); - todo_wine ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); - todo_wine ok( buffer[0], "buffer empty\n" ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + ok( buffer[0], "buffer empty\n" ); buffer[0] = 0; size = sizeof(buffer); @@ -1016,12 +1016,20 @@ static void test_patch_registration( void ) "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", NULL, MSIINSTALLCONTEXT_USERMANAGED, INSTALLPROPERTY_LOCALPACKAGE, buffer, &size ); - todo_wine ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); ok( !buffer[0], "got %s\n", buffer ); r = MsiInstallProductA( msifile, "REMOVE=ALL" ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); + buffer[0] = 0; + size = sizeof(buffer); + r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}", + "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", + NULL, MSIINSTALLCONTEXT_USERUNMANAGED, + INSTALLPROPERTY_LOCALPACKAGE, buffer, &size ); + ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r ); + DeleteFileA( msifile ); DeleteFileA( mspfile ); RemoveDirectoryA( "msitest" ); -- 2.11.4.GIT