From: Akihiro Sagawa Subject: [8/8] msi: Avoid Wow6432Node usage in registry table handling. Message-Id: <20140715193406.B733.375B48EC@gmail.com> Date: Tue, 15 Jul 2014 19:34:49 +0900 Appending Wow6432Node is redundant and doesn't work properly for CLSIDs. Fixes bug #35270. --- dlls/msi/action.c | 85 ++++++++++++++++-------------------------------- dlls/msi/msipriv.h | 1 - dlls/msi/tests/install.c | 4 +-- 3 files changed, 30 insertions(+), 60 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 4c6d6af..33d94a0 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2588,39 +2588,13 @@ 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( HKEY root, const WCHAR *path, BOOL is_64key, BOOL create ) { - static const WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'}; - static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]); - - if ((is_64bit || is_wow64) && - !(comp->Attributes & msidbComponentAttributes64bit) && - root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len )) - { - UINT size; - WCHAR *path_32node; - - size = (strlenW( path ) + strlenW( szWow6432Node ) + 2) * sizeof(WCHAR); - if (!(path_32node = msi_alloc( size ))) return NULL; - - memcpy( path_32node, path, len * sizeof(WCHAR) ); - strcpyW( path_32node + len, szWow6432Node ); - strcatW( path_32node, szBackSlash ); - strcatW( path_32node, path + len ); - return path_32node; - } - return strdupW( path ); -} - -static HKEY open_key( HKEY root, const WCHAR *path, BOOL create ) -{ - REGSAM access = KEY_ALL_ACCESS; + REGSAM access = KEY_ALL_ACCESS | (is_64key ? KEY_WOW64_64KEY : KEY_WOW64_32KEY); WCHAR *subkey, *p, *q; HKEY hkey, ret = NULL; LONG res; - if (is_wow64) access |= KEY_WOW64_64KEY; - if (!(subkey = strdupW( path ))) return NULL; p = subkey; if ((q = strchrW( p, '\\' ))) *q = 0; @@ -2636,7 +2610,7 @@ static HKEY open_key( HKEY root, const WCHAR *path, BOOL create ) } if (q && q[1]) { - ret = open_key( hkey, q + 1, create ); + ret = open_key( hkey, q + 1, is_64key, create ); RegCloseKey( hkey ); } else ret = hkey; @@ -2817,13 +2791,14 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) BYTE *new_value, *old_value = NULL; HKEY root_key, hkey; DWORD type, old_type, new_size, old_size = 0; - LPWSTR deformated, uikey, keypath; + LPWSTR deformated, uikey; const WCHAR *szRoot, *component, *name, *key, *str; MSICOMPONENT *comp; MSIRECORD * uirow; INT root; BOOL check_first = FALSE; int len; + BOOL is_64key; msi_ui_progress( package, 2, REG_PROGRESS_VALUE, 0, 0 ); @@ -2861,13 +2836,12 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) strcpyW(uikey,szRoot); strcatW(uikey,deformated); - keypath = get_keypath( comp, root_key, deformated ); - msi_free( deformated ); - if (!(hkey = open_key( root_key, keypath, TRUE ))) + is_64key = !!(comp->Attributes & msidbComponentAttributes64bit); + if (!(hkey = open_key( root_key, deformated, is_64key, TRUE ))) { - ERR("Could not create key %s\n", debugstr_w(keypath)); + ERR("Could not create key %s\n", debugstr_w(deformated)); msi_free(uikey); - msi_free(keypath); + msi_free(deformated); return ERROR_FUNCTION_FAILED; } str = msi_record_get_string( row, 5, &len ); @@ -2925,7 +2899,6 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) msi_free(old_value); msi_free(deformated); msi_free(uikey); - msi_free(keypath); return ERROR_SUCCESS; } @@ -2947,20 +2920,18 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package) return rc; } -static void delete_key( HKEY root, const WCHAR *path ) +static void delete_key( HKEY root, const WCHAR *path, BOOL is_64key ) { - REGSAM access = 0; + REGSAM access = (is_64key ? KEY_WOW64_64KEY : KEY_WOW64_32KEY); WCHAR *subkey, *p; HKEY hkey; LONG res; - if (is_wow64) access |= KEY_WOW64_64KEY; - if (!(subkey = strdupW( path ))) return; for (;;) { if ((p = strrchrW( subkey, '\\' ))) *p = 0; - hkey = open_key( root, subkey, FALSE ); + hkey = open_key( root, subkey, is_64key, FALSE ); if (!hkey) break; if (p && p[1]) res = RegDeleteKeyExW( hkey, p + 1, access, 0 ); @@ -2977,13 +2948,13 @@ static void delete_key( HKEY root, const WCHAR *path ) msi_free( subkey ); } -static void delete_value( HKEY root, const WCHAR *path, const WCHAR *value ) +static void delete_value( HKEY root, const WCHAR *path, BOOL is_64key, const WCHAR *value ) { LONG res; HKEY hkey; DWORD num_subkeys, num_values; - if ((hkey = open_key( root, path, FALSE ))) + if ((hkey = open_key( root, path, is_64key, FALSE ))) { if ((res = RegDeleteValueW( hkey, value ))) TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res); @@ -2994,20 +2965,20 @@ static void delete_value( HKEY root, const WCHAR *path, const WCHAR *value ) if (!res && !num_subkeys && !num_values) { TRACE("removing empty key %s\n", debugstr_w(path)); - delete_key( root, path ); + delete_key( root, path, is_64key ); } } } -static void delete_tree( HKEY root, const WCHAR *path ) +static void delete_tree( HKEY root, const WCHAR *path, BOOL is_64key ) { LONG res; HKEY hkey; - if (!(hkey = open_key( root, path, FALSE ))) return; + if (!(hkey = open_key( root, path, is_64key, FALSE ))) return; res = RegDeleteTreeW( hkey, NULL ); if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(path), res); - delete_key( root, path ); + delete_key( root, path, is_64key ); RegCloseKey( hkey ); } @@ -3015,13 +2986,14 @@ 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; HKEY hkey_root; UINT size; INT root; + BOOL is_64key; msi_ui_progress( package, 2, REG_PROGRESS_VALUE, 0, 0 ); @@ -3064,11 +3036,10 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para deformat_string( package, name, &deformated_name ); - keypath = get_keypath( comp, hkey_root, deformated_key ); + is_64key = !!(comp->Attributes & msidbComponentAttributes64bit); + if (delete_key) delete_tree( hkey_root, deformated_key, is_64key ); + else delete_value( hkey_root, deformated_key, is_64key, deformated_name ); msi_free( deformated_key ); - if (delete_key) delete_tree( hkey_root, keypath ); - else delete_value( hkey_root, keypath, deformated_name ); - msi_free( keypath ); uirow = MSI_CreateRecord( 2 ); MSI_RecordSetStringW( uirow, 1, ui_key_str ); @@ -3085,13 +3056,14 @@ 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; HKEY hkey_root; UINT size; INT root; + BOOL is_64key; component = MSI_RecordGetString( row, 5 ); comp = msi_get_loaded_component( package, component ); @@ -3129,11 +3101,10 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param deformat_string( package, name, &deformated_name ); - keypath = get_keypath( comp, hkey_root, deformated_key ); + is_64key = !!(comp->Attributes & msidbComponentAttributes64bit); + if (delete_key) delete_tree( hkey_root, deformated_key, is_64key ); + else delete_value( hkey_root, deformated_key, is_64key, deformated_name ); msi_free( deformated_key ); - if (delete_key) delete_tree( hkey_root, keypath ); - else delete_value( hkey_root, keypath, deformated_name ); - msi_free( keypath ); uirow = MSI_CreateRecord( 2 ); MSI_RecordSetStringW( uirow, 1, ui_key_str ); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 75d1920..e43404f 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1159,7 +1159,6 @@ static const WCHAR szX64[] = {'x','6','4',0}; static const WCHAR szAMD64[] = {'A','M','D','6','4',0}; static const WCHAR szARM[] = {'A','r','m',0}; static const WCHAR szWow6432NodeCLSID[] = {'W','o','w','6','4','3','2','N','o','d','e','\\','C','L','S','I','D',0}; -static const WCHAR szWow6432Node[] = {'W','o','w','6','4','3','2','N','o','d','e',0}; static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0}; static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0}; static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0}; diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 6fa2603..b126ed8 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -5725,7 +5725,7 @@ static void test_mixed_package(void) res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey); - todo_wine ok(!res, "can't open 32-bit CLSID key, got %d\n", res); + ok(!res, "can't open 32-bit CLSID key, got %d\n", res); if (!res) { size = sizeof(value); res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size); @@ -5786,7 +5786,7 @@ static void test_mixed_package(void) res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{8dfef911-6885-41eb-b280-8f0304728e8b}\\InProcServer32", 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hkey); - todo_wine ok(!res, "can't open 32-bit CLSID key, got %d\n", res); + ok(!res, "can't open 32-bit CLSID key, got %d\n", res); if (!res) { size = sizeof(value); res = RegQueryValueExA(hkey, "", NULL, NULL, (LPBYTE)value, &size);