James Hawkins : msi: Fix the PublishFeatures action to handle the package context.

Alexandre Julliard julliard at winehq.org
Thu Jun 19 06:41:22 CDT 2008


Module: wine
Branch: master
Commit: 2a180e060ac93006326844967ebc06c8fcb8076e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2a180e060ac93006326844967ebc06c8fcb8076e

Author: James Hawkins <jhawkins at codeweavers.com>
Date:   Thu Jun 19 00:32:59 2008 -0500

msi: Fix the PublishFeatures action to handle the package context.

---

 dlls/msi/action.c        |   39 ++++++++++++++++++++++++++++-----------
 dlls/msi/msipriv.h       |    2 ++
 dlls/msi/registry.c      |   44 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/msi/tests/install.c |   40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 114 insertions(+), 11 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index d3aeb38..c42c4f9 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -3733,19 +3733,35 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
 {
     MSIFEATURE *feature;
     UINT rc;
-    HKEY hukey=0;
-    HKEY userdata=0;
+    HKEY hkey;
+    HKEY userdata;
 
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
 
-    rc = MSIREG_OpenUserFeaturesKey(package->ProductCode,&hukey,TRUE);
-    if (rc != ERROR_SUCCESS)
-        goto end;
+    if (package->Context == MSIINSTALLCONTEXT_MACHINE)
+    {
+        rc = MSIREG_OpenLocalClassesFeaturesKey(package->ProductCode,
+                                                &hkey, TRUE);
+        if (rc != ERROR_SUCCESS)
+            goto end;
 
-    rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, &userdata, TRUE);
-    if (rc != ERROR_SUCCESS)
-        goto end;
+        rc = MSIREG_OpenLocalUserDataFeaturesKey(package->ProductCode,
+                                                 &userdata, TRUE);
+        if (rc != ERROR_SUCCESS)
+            goto end;
+    }
+    else
+    {
+        rc = MSIREG_OpenUserFeaturesKey(package->ProductCode, &hkey, TRUE);
+        if (rc != ERROR_SUCCESS)
+            goto end;
+
+        rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode,
+                                            &userdata, TRUE);
+        if (rc != ERROR_SUCCESS)
+            goto end;
+    }
 
     /* here the guids are base 85 encoded */
     LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
@@ -3806,7 +3822,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
         {
             static const WCHAR emptyW[] = {0};
             size += sizeof(WCHAR);
-            RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
+            RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
                            (LPBYTE)(feature->Feature_Parent ? feature->Feature_Parent : emptyW),size);
         }
         else
@@ -3817,7 +3833,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
             data[1] = 0;
             if (feature->Feature_Parent)
                 strcpyW( &data[1], feature->Feature_Parent );
-            RegSetValueExW(hukey,feature->Feature,0,REG_SZ,
+            RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
                        (LPBYTE)data,size);
             msi_free(data);
         }
@@ -3831,7 +3847,8 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
     }
 
 end:
-    RegCloseKey(hukey);
+    RegCloseKey(hkey);
+    RegCloseKey(userdata);
     return rc;
 }
 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 0982065..b045710 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -785,7 +785,9 @@ extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct);
 extern UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
 extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create);
 extern UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
+extern UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
 extern UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
+extern UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create);
 extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct);
 extern UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent);
 extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent);
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index 6135b47..7b586a8 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -204,6 +204,12 @@ static const WCHAR szInstaller_LocalClassesProd_fmt[] = {
 'I','n','s','t','a','l','l','e','r','\\',
 'P','r','o','d','u','c','t','s','\\','%','s',0};
 
+static const WCHAR szInstaller_LocalClassesFeat_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'C','l','a','s','s','e','s','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'F','e','a','t','u','r','e','s','\\','%','s',0};
+
 static const WCHAR szInstaller_LocalManagedProd_fmt[] = {
 'S','o','f','t','w','a','r','e','\\',
 'M','i','c','r','o','s','o','f','t','\\',
@@ -647,6 +653,24 @@ UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
     return rc;
 }
 
+UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n", debugstr_w(szProduct));
+    if (!squash_guid(szProduct, squished_pc))
+        return ERROR_FUNCTION_FAILED;
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath, szUserDataFeatures_fmt, localsid, squished_pc);
+
+    if (create)
+        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+
+    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+}
+
 UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
 {
     UINT rc;
@@ -1016,6 +1040,26 @@ UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL cr
     return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
 }
 
+UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n", debugstr_w(szProductCode));
+
+    if (!squash_guid(szProductCode, squished_pc))
+        return ERROR_FUNCTION_FAILED;
+
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath, szInstaller_LocalClassesFeat_fmt, squished_pc);
+
+    if (create)
+        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+
+    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+}
+
 UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
 {
     WCHAR squished_pc[GUID_SIZE];
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 9a952d3..bc37571 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -2500,6 +2500,8 @@ static void test_publish_publishfeatures(void)
                                  "\\84A88FD7F6998CE40A22FB59F6B9C2BB\\Features";
     static const CHAR featkey[] = "Software\\Microsoft\\Windows\\CurrentVersion"
                                   "\\Installer\\Features";
+    static const CHAR classfeat[] = "Software\\Classes\\Installer\\Features"
+                                    "\\84A88FD7F6998CE40A22FB59F6B9C2BB";
 
     get_user_sid(&usersid);
     if (!usersid)
@@ -2524,6 +2526,9 @@ static void test_publish_publishfeatures(void)
     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
 
+    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
+    ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
     res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
@@ -2547,6 +2552,41 @@ static void test_publish_publishfeatures(void)
     RegDeleteKeyA(hkey, "");
     RegCloseKey(hkey);
 
+    /* PublishFeatures, machine */
+    r = MsiInstallProductA(msifile, "PUBLISH_FEATURES=1 ALLUSERS=1");
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+    ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, featkey, &hkey);
+    ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+    res = RegOpenKeyA(HKEY_CURRENT_USER, cupath, &hkey);
+    ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
+
+    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, classfeat, &hkey);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+    CHECK_REG_STR(hkey, "feature", "");
+    CHECK_REG_STR(hkey, "montecristo", "");
+
+    RegDeleteValueA(hkey, "feature");
+    RegDeleteValueA(hkey, "montecristo");
+    RegDeleteKeyA(hkey, "");
+    RegCloseKey(hkey);
+
+    sprintf(keypath, udpath, "S-1-5-18");
+    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+    CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82 at JU1j_KE");
+    CHECK_REG_STR(hkey, "montecristo", "VGtfp^p+,?82 at JU1j_KE");
+
+    RegDeleteValueA(hkey, "feature");
+    RegDeleteValueA(hkey, "montecristo");
+    RegDeleteKeyA(hkey, "");
+    RegCloseKey(hkey);
+
     DeleteFile(msifile);
     DeleteFile("msitest\\maximus");
     RemoveDirectory("msitest");




More information about the wine-cvs mailing list