[4/4] msi: Register more patch details.

Hans Leidekker hans at codeweavers.com
Tue May 4 02:07:39 CDT 2010


---
 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 e744973..35030e2 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 e4ad682..2d33487 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 a8594a8..354aca5 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 7a4c3f8..518303f 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 048de2c..e386925 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" );
-- 
1.7.0.4






More information about the wine-patches mailing list