diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 0efdc2c18ec..b4bf440c3e6 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -645,8 +645,8 @@ # @ stub RegSaveKeyExW @ stdcall RegSaveKeyW(long ptr ptr) @ stdcall RegSetKeySecurity(long long ptr) -# @ stub RegSetKeyValueA -# @ stub RegSetKeyValueW +@ stdcall RegSetKeyValueA(long str str long ptr long) +@ stdcall RegSetKeyValueW(long wstr wstr long ptr long) @ stdcall RegSetValueA(long str long ptr long) @ stdcall RegSetValueExA(long str long long ptr long) @ stdcall RegSetValueExW(long wstr long long ptr long) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index c7ba3ef221f..d568ae06440 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -1276,61 +1276,80 @@ LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD typ * Sets the data for the default or unnamed value of a reg key. * * PARAMS - * hKey [I] Handle to an open key. - * lpSubKey [I] Name of a subkey of hKey. - * dwType [I] Type of information to store. - * lpData [I] String that contains the data to set for the default value. - * cbData [I] Ignored. + * hkey [I] Handle to an open key. + * subkey [I] Name of a subkey of hKey. + * type [I] Type of information to store. + * data [I] String that contains the data to set for the default value. + * count [I] Ignored. * * RETURNS * Success: ERROR_SUCCESS * Failure: nonzero error code from Winerror.h */ -LSTATUS WINAPI RegSetValueW( HKEY hkey, LPCWSTR name, DWORD type, LPCWSTR data, DWORD count ) +LSTATUS WINAPI RegSetValueW( HKEY hkey, LPCWSTR subkey, DWORD type, LPCWSTR data, DWORD count ) { - HKEY subkey = hkey; - DWORD ret; - - TRACE("(%p,%s,%d,%s,%d)\n", hkey, debugstr_w(name), type, debugstr_w(data), count ); + TRACE("(%p,%s,%d,%s,%d)\n", hkey, debugstr_w(subkey), type, debugstr_w(data), count ); if (type != REG_SZ || !data) return ERROR_INVALID_PARAMETER; - if (name && name[0]) /* need to create the subkey */ - { - if ((ret = RegCreateKeyW( hkey, name, &subkey )) != ERROR_SUCCESS) return ret; - } - - ret = RegSetValueExW( subkey, NULL, 0, REG_SZ, (const BYTE*)data, - (strlenW( data ) + 1) * sizeof(WCHAR) ); - if (subkey != hkey) RegCloseKey( subkey ); - return ret; + return RegSetKeyValueW( hkey, subkey, NULL, type, data, (strlenW(data) + 1)*sizeof(WCHAR) ); } - /****************************************************************************** * RegSetValueA [ADVAPI32.@] * * See RegSetValueW. */ -LSTATUS WINAPI RegSetValueA( HKEY hkey, LPCSTR name, DWORD type, LPCSTR data, DWORD count ) +LSTATUS WINAPI RegSetValueA( HKEY hkey, LPCSTR subkey, DWORD type, LPCSTR data, DWORD count ) { - HKEY subkey = hkey; - DWORD ret; - - TRACE("(%p,%s,%d,%s,%d)\n", hkey, debugstr_a(name), type, debugstr_a(data), count ); + TRACE("(%p,%s,%d,%s,%d)\n", hkey, debugstr_a(subkey), type, debugstr_a(data), count ); if (type != REG_SZ || !data) return ERROR_INVALID_PARAMETER; - if (name && name[0]) /* need to create the subkey */ + return RegSetKeyValueA( hkey, subkey, NULL, type, data, strlen(data) + 1 ); +} + +/****************************************************************************** + * RegSetKeyValueW [ADVAPI32.@] + */ +LONG WINAPI RegSetKeyValueW( HKEY hkey, LPCWSTR subkey, LPCWSTR name, DWORD type, const void *data, DWORD len ) +{ + HKEY hsubkey = NULL; + DWORD ret; + + TRACE("(%p,%s,%s,%d,%p,%d)\n", hkey, debugstr_w(subkey), debugstr_w(name), type, data, len ); + + if (subkey && subkey[0]) /* need to create the subkey */ { - if ((ret = RegCreateKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret; + if ((ret = RegCreateKeyW( hkey, subkey, &hsubkey )) != ERROR_SUCCESS) return ret; + hkey = hsubkey; } - ret = RegSetValueExA( subkey, NULL, 0, REG_SZ, (const BYTE*)data, strlen(data)+1 ); - if (subkey != hkey) RegCloseKey( subkey ); + + ret = RegSetValueExW( hkey, name, 0, type, (const BYTE*)data, len ); + if (hsubkey) RegCloseKey( hsubkey ); return ret; } +/****************************************************************************** + * RegSetKeyValueA [ADVAPI32.@] + */ +LONG WINAPI RegSetKeyValueA( HKEY hkey, LPCSTR subkey, LPCSTR name, DWORD type, const void *data, DWORD len ) +{ + HKEY hsubkey = NULL; + DWORD ret; + TRACE("(%p,%s,%s,%d,%p,%d)\n", hkey, debugstr_a(subkey), debugstr_a(name), type, data, len ); + + if (subkey && subkey[0]) /* need to create the subkey */ + { + if ((ret = RegCreateKeyA( hkey, subkey, &hsubkey )) != ERROR_SUCCESS) return ret; + hkey = hsubkey; + } + + ret = RegSetValueExA( hkey, name, 0, type, (const BYTE*)data, len ); + if (hsubkey) RegCloseKey( hsubkey ); + return ret; +} /****************************************************************************** * RegQueryValueExW [ADVAPI32.@] diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 7c4db4048a7..0626aff3bbd 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -48,6 +48,7 @@ static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE); static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*); static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING); static LONG (WINAPI *pRegDeleteKeyValueA)(HKEY,LPCSTR,LPCSTR); +static LONG (WINAPI *pRegSetKeyValueW)(HKEY,LPCWSTR,LPCWSTR,DWORD,const void*,DWORD); static BOOL limited_user; @@ -137,6 +138,7 @@ static void InitFunctionPtrs(void) ADVAPI32_GET_PROC(RegDeleteTreeA); ADVAPI32_GET_PROC(RegDeleteKeyExA); ADVAPI32_GET_PROC(RegDeleteKeyValueA); + ADVAPI32_GET_PROC(RegSetKeyValueW); pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" ); pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" ); @@ -433,6 +435,37 @@ static void test_set_value(void) ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); ret = RegSetValueExW(hkey_main, name2W, 0, REG_DWORD, (const BYTE *)1, 1); ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + + /* RegSetKeyValue */ + if (!pRegSetKeyValueW) + win_skip("RegSetKeyValue() is not supported.\n"); + else + { + static const WCHAR subkeyW[] = {'s','u','b','k','e','y',0}; + DWORD len, type; + HKEY subkey; + + ret = pRegSetKeyValueW(hkey_main, NULL, name1W, REG_SZ, (const BYTE*)string2W, sizeof(string2W)); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + test_hkey_main_Value_A(name1A, string2A, sizeof(string2A)); + test_hkey_main_Value_W(name1W, string2W, sizeof(string2W)); + + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, string1W, sizeof(string1W)); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegOpenKeyExW(hkey_main, subkeyW, 0, KEY_QUERY_VALUE, &subkey); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + type = len = 0; + ret = RegQueryValueExW(subkey, name1W, 0, &type, NULL, &len); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(len == sizeof(string1W), "got %d\n", len); + ok(type == REG_SZ, "got type %d\n", type); + + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + RegCloseKey(subkey); + } } static void create_test_entries(void) diff --git a/include/winreg.h b/include/winreg.h index 56d96500acf..cf6bd475b54 100644 --- a/include/winreg.h +++ b/include/winreg.h @@ -169,6 +169,8 @@ WINADVAPI LSTATUS WINAPI RegSaveKeyA(HKEY,LPCSTR,LPSECURITY_ATTRIBUTES); WINADVAPI LSTATUS WINAPI RegSaveKeyW(HKEY,LPCWSTR,LPSECURITY_ATTRIBUTES); #define RegSaveKey WINELIB_NAME_AW(RegSaveKey) WINADVAPI LSTATUS WINAPI RegSetKeySecurity(HKEY,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); +WINADVAPI LSTATUS WINAPI RegSetKeyValueA(HKEY,LPCSTR,LPCSTR,DWORD,const void*,DWORD); +WINADVAPI LSTATUS WINAPI RegSetKeyValueW(HKEY,LPCWSTR,LPCWSTR,DWORD,const void*,DWORD); WINADVAPI LSTATUS WINAPI RegSetValueA(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); WINADVAPI LSTATUS WINAPI RegSetValueW(HKEY,LPCWSTR,DWORD,LPCWSTR,DWORD); #define RegSetValue WINELIB_NAME_AW(RegSetValue)