advapi32: Implement RegDeleteKeyValue().
This commit is contained in:
parent
f9a19f57e1
commit
da6d5e6ae6
|
@ -588,8 +588,8 @@
|
||||||
# @ stub RegDeleteKeyTransactedA
|
# @ stub RegDeleteKeyTransactedA
|
||||||
# @ stub RegDeleteKeyTransactedW
|
# @ stub RegDeleteKeyTransactedW
|
||||||
@ stdcall RegDeleteKeyW(long wstr)
|
@ stdcall RegDeleteKeyW(long wstr)
|
||||||
# @ stub RegDeleteKeyValueA
|
@ stdcall RegDeleteKeyValueA(long str str)
|
||||||
# @ stub RegDeleteKeyValueW
|
@ stdcall RegDeleteKeyValueW(long wstr wstr)
|
||||||
@ stdcall RegDeleteTreeA(long str)
|
@ stdcall RegDeleteTreeA(long str)
|
||||||
@ stdcall RegDeleteTreeW(long wstr)
|
@ stdcall RegDeleteTreeW(long wstr)
|
||||||
@ stdcall RegDeleteValueA(long str)
|
@ stdcall RegDeleteValueA(long str)
|
||||||
|
|
|
@ -2050,8 +2050,6 @@ LSTATUS WINAPI RegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_c
|
||||||
return RtlNtStatusToDosError(status);
|
return RtlNtStatusToDosError(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* RegDeleteValueW [ADVAPI32.@]
|
* 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 )
|
LSTATUS WINAPI RegDeleteValueW( HKEY hkey, LPCWSTR name )
|
||||||
{
|
{
|
||||||
UNICODE_STRING nameW;
|
return RegDeleteKeyValueW( hkey, NULL, name );
|
||||||
|
|
||||||
if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE;
|
|
||||||
|
|
||||||
RtlInitUnicodeString( &nameW, name );
|
|
||||||
return RtlNtStatusToDosError( NtDeleteValueKey( hkey, &nameW ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* RegDeleteValueA [ADVAPI32.@]
|
* RegDeleteValueA [ADVAPI32.@]
|
||||||
*
|
*
|
||||||
|
@ -2083,22 +2075,64 @@ LSTATUS WINAPI RegDeleteValueW( HKEY hkey, LPCWSTR name )
|
||||||
*/
|
*/
|
||||||
LSTATUS WINAPI RegDeleteValueA( HKEY hkey, LPCSTR 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;
|
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;
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE;
|
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 );
|
RtlInitAnsiString( &nameA, name );
|
||||||
if (!(status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
|
if (!(status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
|
||||||
{
|
{
|
||||||
status = NtDeleteValueKey( hkey, &nameW );
|
status = NtDeleteValueKey( hkey, &nameW );
|
||||||
RtlFreeUnicodeString( &nameW );
|
RtlFreeUnicodeString( &nameW );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hsubkey) RegCloseKey( hsubkey );
|
||||||
return RtlNtStatusToDosError( status );
|
return RtlNtStatusToDosError( status );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* RegLoadKeyW [ADVAPI32.@]
|
* RegLoadKeyW [ADVAPI32.@]
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,6 +47,7 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
|
||||||
static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
|
static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
|
||||||
static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
|
static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*);
|
||||||
static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
|
static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
|
||||||
|
static LONG (WINAPI *pRegDeleteKeyValueA)(HKEY,LPCSTR,LPCSTR);
|
||||||
|
|
||||||
static BOOL limited_user;
|
static BOOL limited_user;
|
||||||
|
|
||||||
|
@ -135,6 +136,7 @@ static void InitFunctionPtrs(void)
|
||||||
ADVAPI32_GET_PROC(RegGetValueA);
|
ADVAPI32_GET_PROC(RegGetValueA);
|
||||||
ADVAPI32_GET_PROC(RegDeleteTreeA);
|
ADVAPI32_GET_PROC(RegDeleteTreeA);
|
||||||
ADVAPI32_GET_PROC(RegDeleteKeyExA);
|
ADVAPI32_GET_PROC(RegDeleteKeyExA);
|
||||||
|
ADVAPI32_GET_PROC(RegDeleteKeyValueA);
|
||||||
|
|
||||||
pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" );
|
pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" );
|
||||||
pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" );
|
pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" );
|
||||||
|
@ -2768,6 +2770,56 @@ static void test_delete_value(void)
|
||||||
"expect ERROR_FILE_NOT_FOUND, got %i\n", res);
|
"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)
|
START_TEST(registry)
|
||||||
{
|
{
|
||||||
/* Load pointers for functions that are not available in all Windows versions */
|
/* Load pointers for functions that are not available in all Windows versions */
|
||||||
|
@ -2808,6 +2860,7 @@ START_TEST(registry)
|
||||||
test_rw_order();
|
test_rw_order();
|
||||||
test_deleted_key();
|
test_deleted_key();
|
||||||
test_delete_value();
|
test_delete_value();
|
||||||
|
test_delete_key_value();
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
delete_key( hkey_main );
|
delete_key( hkey_main );
|
||||||
|
|
Loading…
Reference in New Issue