From da6d5e6ae60da276eb2a9b749c4d6eeb0b703afe Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sat, 28 Jun 2014 20:15:47 +0400 Subject: [PATCH] advapi32: Implement RegDeleteKeyValue(). --- dlls/advapi32/advapi32.spec | 4 +-- dlls/advapi32/registry.c | 56 +++++++++++++++++++++++++++------- dlls/advapi32/tests/registry.c | 53 ++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 0b654c8d1c2..0efdc2c18ec 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -588,8 +588,8 @@ # @ stub RegDeleteKeyTransactedA # @ stub RegDeleteKeyTransactedW @ stdcall RegDeleteKeyW(long wstr) -# @ stub RegDeleteKeyValueA -# @ stub RegDeleteKeyValueW +@ stdcall RegDeleteKeyValueA(long str str) +@ stdcall RegDeleteKeyValueW(long wstr wstr) @ stdcall RegDeleteTreeA(long str) @ stdcall RegDeleteTreeW(long wstr) @ stdcall RegDeleteValueA(long str) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 0a04bc77343..c7ba3ef221f 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -2050,8 +2050,6 @@ LSTATUS WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_c return RtlNtStatusToDosError(status); } - - /****************************************************************************** * RegDeleteValueW [ADVAPI32.@] * @@ -2059,15 +2057,9 @@ LSTATUS WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_c */ LSTATUS WINAPI RegDeleteValueW( HKEY hkey, LPCWSTR name ) { - UNICODE_STRING nameW; - - if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE; - - RtlInitUnicodeString( &nameW, name ); - return RtlNtStatusToDosError( NtDeleteValueKey( hkey, &nameW ) ); + return RegDeleteKeyValueW( hkey, NULL, name ); } - /****************************************************************************** * RegDeleteValueA [ADVAPI32.@] * @@ -2083,22 +2075,64 @@ LSTATUS WINAPI RegDeleteValueW( HKEY hkey, LPCWSTR name ) */ LSTATUS WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name ) { - ANSI_STRING nameA; + return RegDeleteKeyValueA( hkey, NULL, name ); +} + +/****************************************************************************** + * RegDeleteKeyValueW [ADVAPI32.@] + */ +LONG WINAPI RegDeleteKeyValueW( HKEY hkey, LPCWSTR subkey, LPCWSTR name ) +{ UNICODE_STRING nameW; + HKEY hsubkey = 0; + LONG ret; + + if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE; + + if (subkey) + { + if ((ret = RegOpenKeyExW( hkey, subkey, 0, KEY_SET_VALUE, &hsubkey ))) + return ret; + hkey = hsubkey; + } + + RtlInitUnicodeString( &nameW, name ); + ret = RtlNtStatusToDosError( NtDeleteValueKey( hkey, &nameW ) ); + if (hsubkey) RegCloseKey( hsubkey ); + return ret; +} + +/****************************************************************************** + * RegDeleteKeyValueA [ADVAPI32.@] + */ +LONG WINAPI RegDeleteKeyValueA( HKEY hkey, LPCSTR subkey, LPCSTR name ) +{ + UNICODE_STRING nameW; + HKEY hsubkey = 0; + ANSI_STRING nameA; NTSTATUS status; if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE; + if (subkey) + { + LONG ret = RegOpenKeyExA( hkey, subkey, 0, KEY_SET_VALUE, &hsubkey ); + if (ret) + return ret; + hkey = hsubkey; + } + RtlInitAnsiString( &nameA, name ); if (!(status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE ))) { status = NtDeleteValueKey( hkey, &nameW ); RtlFreeUnicodeString( &nameW ); } + + if (hsubkey) RegCloseKey( hsubkey ); return RtlNtStatusToDosError( status ); } - /****************************************************************************** * RegLoadKeyW [ADVAPI32.@] * diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index d3392535cac..7c4db4048a7 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -47,6 +47,7 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); 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 BOOL limited_user; @@ -135,6 +136,7 @@ static void InitFunctionPtrs(void) ADVAPI32_GET_PROC(RegGetValueA); ADVAPI32_GET_PROC(RegDeleteTreeA); ADVAPI32_GET_PROC(RegDeleteKeyExA); + ADVAPI32_GET_PROC(RegDeleteKeyValueA); pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" ); pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" ); @@ -2768,6 +2770,56 @@ static void test_delete_value(void) "expect ERROR_FILE_NOT_FOUND, got %i\n", res); } +static void test_delete_key_value(void) +{ + HKEY subkey; + LONG ret; + + if (!pRegDeleteKeyValueA) + { + win_skip("RegDeleteKeyValue is not available.\n"); + return; + } + + ret = pRegDeleteKeyValueA(NULL, NULL, NULL); + ok(ret == ERROR_INVALID_HANDLE, "got %d\n", ret); + + ret = pRegDeleteKeyValueA(hkey_main, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + ret = RegSetValueExA(hkey_main, "test", 0, REG_SZ, (const BYTE*)"value", 6); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + /* NULL subkey name means delete from open key */ + ret = pRegDeleteKeyValueA(hkey_main, NULL, "test"); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + /* now with real subkey */ + ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_WRITE|KEY_READ, NULL, &subkey, NULL); + ok(!ret, "failed with error %d\n", ret); + + ret = RegSetValueExA(subkey, "test", 0, REG_SZ, (const BYTE*)"value", 6); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = pRegDeleteKeyValueA(hkey_main, "Subkey1", "test"); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + RegDeleteKeyA(subkey, ""); + RegCloseKey(subkey); +} + START_TEST(registry) { /* Load pointers for functions that are not available in all Windows versions */ @@ -2808,6 +2860,7 @@ START_TEST(registry) test_rw_order(); test_deleted_key(); test_delete_value(); + test_delete_key_value(); /* cleanup */ delete_key( hkey_main );