[3/5] msi: Don't access Wow6432Node directly in WriteRegistryValues and RemoveRegistryValues.

Hans Leidekker hans at codeweavers.com
Tue Jun 5 06:43:34 CDT 2012


---
 dlls/msi/action.c |  107 +++++++++++++++++++++++++++--------------------------
 1 files changed, 54 insertions(+), 53 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 3629a3e..187c6a5 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -2558,28 +2558,42 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key
     return ret;
 }
 
-static WCHAR *get_keypath( MSICOMPONENT *comp, HKEY root, const WCHAR *path )
+static HKEY open_key( MSICOMPONENT *comp, HKEY root, const WCHAR *path, BOOL create )
 {
-    static const WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'};
-    static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]);
+    HKEY ret;
+    REGSAM access = KEY_ALL_ACCESS;
+    LONG res;
 
-    if ((is_64bit || is_wow64) &&
-        !(comp->Attributes & msidbComponentAttributes64bit) &&
-        root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
+    if (is_64bit || is_wow64)
     {
-        UINT size;
-        WCHAR *path_32node;
+        if (comp->Attributes & msidbComponentAttributes64bit)
+            access |= KEY_WOW64_64KEY;
+        else
+            access |= KEY_WOW64_32KEY;
+    }
+    if (create)
+        res = RegCreateKeyExW( root, path, 0, NULL, 0, access, NULL, &ret, NULL );
+    else
+        res = RegOpenKeyExW( root, path, 0, access, &ret );
+
+    if (res) TRACE("failed to open key %s (%d)\n", debugstr_w(path), res);
+    return ret;
+}
 
-        size = (strlenW( path ) + strlenW( szWow6432Node ) + 2) * sizeof(WCHAR);
-        if (!(path_32node = msi_alloc( size ))) return NULL;
+static void delete_key( MSICOMPONENT *comp, HKEY root, const WCHAR *path )
+{
+    REGSAM access = 0;
+    LONG res;
 
-        memcpy( path_32node, path, len * sizeof(WCHAR) );
-        strcpyW( path_32node + len, szWow6432Node );
-        strcatW( path_32node, szBackSlash );
-        strcatW( path_32node, path + len );
-        return path_32node;
+    if (is_64bit || is_wow64)
+    {
+        if (comp->Attributes & msidbComponentAttributes64bit)
+            access = KEY_WOW64_64KEY;
+        else
+            access = KEY_WOW64_32KEY;
     }
-    return strdupW( path );
+    res = RegDeleteKeyExW( root, path, access, 0 );
+    if (res) TRACE("failed to delete key %s (%d)\n", debugstr_w(path), res);
 }
 
 static BOOL is_special_entry( const WCHAR *name )
@@ -2632,21 +2646,20 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
     if (!szRoot)
         return ERROR_SUCCESS;
 
-    deformat_string(package, key , &deformated);
-    size = strlenW(deformated) + strlenW(szRoot) + 1;
+    deformat_string(package, key, &keypath);
+    size = strlenW(keypath) + strlenW(szRoot) + 1;
     uikey = msi_alloc(size*sizeof(WCHAR));
     strcpyW(uikey,szRoot);
-    strcatW(uikey,deformated);
+    strcatW(uikey,keypath);
 
-    keypath = get_keypath( comp, root_key, deformated );
-    msi_free( deformated );
-    if (RegCreateKeyExW( root_key, keypath, 0, NULL, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, NULL, &hkey, NULL ))
+    if (!(hkey = open_key( comp, root_key, keypath, TRUE )))
     {
         ERR("Could not create key %s\n", debugstr_w(keypath));
         msi_free(uikey);
         msi_free(keypath);
-        return ERROR_SUCCESS;
+        return ERROR_FUNCTION_FAILED;
     }
+    msi_free(keypath);
     value = parse_value(package, MSI_RecordGetString(row, 5), &type, &size); 
     deformat_string(package, name, &deformated);
 
@@ -2689,7 +2702,6 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
     msi_free(value);
     msi_free(deformated);
     msi_free(uikey);
-    msi_free(keypath);
 
     return ERROR_SUCCESS;
 }
@@ -2711,44 +2723,37 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
     return rc;
 }
 
-static void delete_reg_value( HKEY root, const WCHAR *keypath, const WCHAR *value )
+static void delete_value( MSICOMPONENT *comp, HKEY root, const WCHAR *path, const WCHAR *value )
 {
-    LONG res;
     HKEY hkey;
     DWORD num_subkeys, num_values;
+    LONG res;
 
-    if (!(res = RegOpenKeyExW( root, keypath, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey )))
+    if ((hkey = open_key( comp, root, path, FALSE )))
     {
         if ((res = RegDeleteValueW( hkey, value )))
-        {
             TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res);
-        }
+
         res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values,
                                 NULL, NULL, NULL, NULL );
         RegCloseKey( hkey );
         if (!res && !num_subkeys && !num_values)
         {
-            TRACE("removing empty key %s\n", debugstr_w(keypath));
-            RegDeleteKeyExW( root, keypath, KEY_WOW64_64KEY, 0 );
+            TRACE("removing empty key %s\n", debugstr_w(path));
+            delete_key( comp, root, path );
         }
-        return;
     }
-    TRACE("failed to open key %s (%d)\n", debugstr_w(keypath), res);
 }
 
-static void delete_reg_key( HKEY root, const WCHAR *keypath )
+static void delete_tree( MSICOMPONENT *comp, HKEY root, const WCHAR *path )
 {
     HKEY hkey;
-    LONG res = RegOpenKeyExW( root, keypath, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hkey );
-    if (res)
-    {
-        TRACE("failed to open key %s (%d)\n", debugstr_w(keypath), res);
-        return;
-    }
+    LONG res;
+
+    if (!(hkey = open_key( comp, root, path, FALSE ))) return;
     res = RegDeleteTreeW( hkey, NULL );
-    if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(keypath), res);
-    res = RegDeleteKeyExW( root, keypath, KEY_WOW64_64KEY, 0 );
-    if (res) TRACE("failed to delete key %s (%d)\n", debugstr_w(keypath), res);
+    if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(path), res);
+    delete_key( comp, root, path );
     RegCloseKey( hkey );
 }
 
@@ -2756,7 +2761,7 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
 {
     MSIPACKAGE *package = param;
     LPCWSTR component, name, key_str, root_key_str;
-    LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
+    LPWSTR deformated_key, deformated_name, ui_key_str;
     MSICOMPONENT *comp;
     MSIRECORD *uirow;
     BOOL delete_key = FALSE;
@@ -2805,11 +2810,9 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
 
     deformat_string( package, name, &deformated_name );
 
-    keypath = get_keypath( comp, hkey_root, deformated_key );
+    if (delete_key) delete_tree( comp, hkey_root, deformated_key );
+    else delete_value( comp, hkey_root, deformated_key, deformated_name );
     msi_free( deformated_key );
-    if (delete_key) delete_reg_key( hkey_root, keypath );
-    else delete_reg_value( hkey_root, keypath, deformated_name );
-    msi_free( keypath );
 
     uirow = MSI_CreateRecord( 2 );
     MSI_RecordSetStringW( uirow, 1, ui_key_str );
@@ -2826,7 +2829,7 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
 {
     MSIPACKAGE *package = param;
     LPCWSTR component, name, key_str, root_key_str;
-    LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
+    LPWSTR deformated_key, deformated_name, ui_key_str;
     MSICOMPONENT *comp;
     MSIRECORD *uirow;
     BOOL delete_key = FALSE;
@@ -2870,11 +2873,9 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
 
     deformat_string( package, name, &deformated_name );
 
-    keypath = get_keypath( comp, hkey_root, deformated_key );
+    if (delete_key) delete_tree( comp, hkey_root, deformated_key );
+    else delete_value( comp, hkey_root, deformated_key, deformated_name );
     msi_free( deformated_key );
-    if (delete_key) delete_reg_key( hkey_root, keypath );
-    else delete_reg_value( hkey_root, keypath, deformated_name );
-    msi_free( keypath );
 
     uirow = MSI_CreateRecord( 2 );
     MSI_RecordSetStringW( uirow, 1, ui_key_str );
-- 
1.7.5.4







More information about the wine-patches mailing list