diff --git a/dlls/msi/action.c b/dlls/msi/action.c index efdc79c1da6..ec008867b2d 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2578,6 +2578,11 @@ static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path ) return strdupW( path ); } +static BOOL is_special_entry( const WCHAR *name, const WCHAR *value ) +{ + return (name && (name[0] == '*' || name[0] == '+') && !name[1] && !value); +} + static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; @@ -2612,10 +2617,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) /* null values can have special meanings */ if (name[0]=='-' && name[1] == 0) return ERROR_SUCCESS; - else if ((name[0]=='+' && name[1] == 0) || - (name[0] == '*' && name[1] == 0)) - name = NULL; - check_first = TRUE; + if ((name[0] == '+' || name[0] == '*') && !name[1]) + check_first = TRUE; } root = MSI_RecordGetInteger(row,2); @@ -2652,28 +2655,30 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) } deformat_string(package, name, &deformated); - - if (!check_first) + if (!is_special_entry( name , value )) { - TRACE("Setting value %s of %s\n",debugstr_w(deformated), - debugstr_w(uikey)); - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); - } - else - { - DWORD sz = 0; - rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); - if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + if (!check_first) { - TRACE("value %s of %s checked already exists\n", - debugstr_w(deformated), debugstr_w(uikey)); + TRACE("Setting value %s of %s\n", debugstr_w(deformated), + debugstr_w(uikey)); + RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); } else { - TRACE("Checked and setting value %s of %s\n", - debugstr_w(deformated), debugstr_w(uikey)); - if (deformated || size) - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size); + DWORD sz = 0; + rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); + if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + { + TRACE("value %s of %s checked already exists\n", debugstr_w(deformated), + debugstr_w(uikey)); + } + else + { + TRACE("Checked and setting value %s of %s\n", debugstr_w(deformated), + debugstr_w(uikey)); + if (deformated || size) + RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); + } } } RegCloseKey(hkey); @@ -2773,7 +2778,7 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para { if (name[0] == '+' && !name[1]) return ERROR_SUCCESS; - else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1])) + if ((name[0] == '-' || name[0] == '*') && !name[1]) { delete_key = TRUE; name = NULL; diff --git a/dlls/msi/tests/action.c b/dlls/msi/tests/action.c index 2b482df14cd..0bd65a0871b 100644 --- a/dlls/msi/tests/action.c +++ b/dlls/msi/tests/action.c @@ -487,7 +487,10 @@ static const char wrv_registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_\n" "s72\ti2\tl255\tL255\tL0\ts72\n" "Registry\tRegistry\n" - "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus"; + "regdata\t2\tSOFTWARE\\Wine\\msitest\tValue\t[~]one[~]two[~]three\taugustus\n" + "regdata1\t2\tSOFTWARE\\Wine\\msitest\t*\t\taugustus\n" + "regdata2\t2\tSOFTWARE\\Wine\\msitest\t*\t#%\taugustus\n" + "regdata3\t2\tSOFTWARE\\Wine\\msitest\t*\t#x\taugustus\n"; static const char cf_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" @@ -4572,7 +4575,7 @@ static void test_write_registry_values(void) ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); size = MAX_PATH; - type = REG_MULTI_SZ; + type = 0xdeadbeef; memset(path, 'a', MAX_PATH); res = RegQueryValueExA(hkey, "Value", NULL, &type, (LPBYTE)path, &size); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -4580,9 +4583,12 @@ static void test_write_registry_values(void) ok(size == 15, "Expected 15, got %d\n", size); ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type); + res = RegQueryValueExA(hkey, "", NULL, NULL, NULL, NULL); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegDeleteValueA(hkey, "Value"); RegCloseKey(hkey); - RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest"); + RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest"); error: DeleteFile(msifile);