advapi32: Implement RegCopyTreeA/W.

Signed-off-by: Michael Müller <michael@fds-team.de>
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Michael Müller 2016-02-26 17:00:05 +01:00 committed by Alexandre Julliard
parent 8358fd1c26
commit 6b7c576bc5
5 changed files with 100 additions and 5 deletions

View File

@ -575,8 +575,8 @@
@ stdcall RegConnectRegistryW(wstr long ptr) @ stdcall RegConnectRegistryW(wstr long ptr)
# @ stub RegConnectRegistryExA # @ stub RegConnectRegistryExA
# @ stub RegConnectRegistryExW # @ stub RegConnectRegistryExW
# @ stub RegCopyTreeA @ stdcall RegCopyTreeA(long str long)
# @ stub RegCopyTreeW @ stdcall RegCopyTreeW(long wstr long)
@ stdcall RegCreateKeyA(long str ptr) @ stdcall RegCreateKeyA(long str ptr)
@ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) @ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr)
@ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) @ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr)

View File

@ -3104,6 +3104,101 @@ LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
return ret; return ret;
} }
/******************************************************************************
* RegCopyTreeW [ADVAPI32.@]
*
*/
LONG WINAPI RegCopyTreeW( HKEY hsrc, const WCHAR *subkey, HKEY hdst )
{
DWORD name_size, max_name;
DWORD value_size, max_value;
DWORD max_subkey, i, type;
WCHAR *name_buf = NULL;
BYTE *value_buf = NULL;
HKEY hkey;
LONG ret;
TRACE( "(%p, %s, %p)\n", hsrc, debugstr_w(subkey), hdst );
if (subkey)
{
ret = RegOpenKeyExW( hsrc, subkey, 0, KEY_READ, &hsrc );
if (ret) return ret;
}
ret = RegQueryInfoKeyW( hsrc, NULL, NULL, NULL, NULL, &max_subkey,
NULL, NULL, &max_name, &max_value, NULL, NULL );
if (ret)
goto cleanup;
max_name = max( max_subkey, max_name ) + 1;
if (!(name_buf = heap_alloc( max_name * sizeof(WCHAR) )))
{
ret = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
if (!(value_buf = heap_alloc( max_value )))
{
ret = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
/* Copy values */
for (i = 0;; i++)
{
name_size = max_name;
value_size = max_value;
ret = RegEnumValueW( hsrc, i, name_buf, &name_size, NULL, &type, value_buf, &value_size );
if (ret == ERROR_NO_MORE_ITEMS) break;
if (ret) goto cleanup;
ret = RegSetValueExW( hdst, name_buf, 0, type, value_buf, value_size );
if (ret) goto cleanup;
}
/* Recursively copy subkeys */
for (i = 0;; i++)
{
name_size = max_name;
ret = RegEnumKeyExW( hsrc, i, name_buf, &name_size, NULL, NULL, NULL, NULL );
if (ret == ERROR_NO_MORE_ITEMS) break;
if (ret) goto cleanup;
ret = RegCreateKeyExW( hdst, name_buf, 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL );
if (ret) goto cleanup;
ret = RegCopyTreeW( hsrc, name_buf, hkey );
RegCloseKey( hkey );
if (ret) goto cleanup;
}
ret = ERROR_SUCCESS;
cleanup:
heap_free( name_buf );
heap_free( value_buf );
if (subkey)
RegCloseKey( hsrc );
return ret;
}
/******************************************************************************
* RegCopyTreeA [ADVAPI32.@]
*
*/
LONG WINAPI RegCopyTreeA( HKEY hsrc, const char *subkey, HKEY hdst )
{
UNICODE_STRING subkeyW;
LONG ret;
if (subkey) RtlCreateUnicodeStringFromAsciiz( &subkeyW, subkey );
else subkeyW.Buffer = NULL;
ret = RegCopyTreeW( hsrc, subkeyW.Buffer, hdst );
RtlFreeUnicodeString( &subkeyW );
return ret;
}
/****************************************************************************** /******************************************************************************
* RegDisableReflectionKey [ADVAPI32.@] * RegDisableReflectionKey [ADVAPI32.@]
* *

View File

@ -2090,7 +2090,7 @@ static void test_reg_copy_tree(void)
if (!pRegCopyTreeA) if (!pRegCopyTreeA)
{ {
skip("Skipping RegCopyTreeA tests, function not present\n"); win_skip("Skipping RegCopyTreeA tests, function not present\n");
return; return;
} }

View File

@ -1,5 +1,5 @@
@ stdcall RegCloseKey(long) advapi32.RegCloseKey @ stdcall RegCloseKey(long) advapi32.RegCloseKey
@ stub RegCopyTreeW @ stdcall RegCopyTreeW(long wstr long) advapi32.RegCopyTreeW
@ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExA @ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExA
@ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW @ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW
@ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA @ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA

View File

@ -84,7 +84,7 @@
@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW @ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW
@ stub QuerySecurityAccessMask @ stub QuerySecurityAccessMask
@ stdcall RegCloseKey(long) advapi32.RegCloseKey @ stdcall RegCloseKey(long) advapi32.RegCloseKey
@ stub RegCopyTreeW @ stdcall RegCopyTreeW(long wstr long) advapi32.RegCopyTreeW
@ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExA @ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExA
@ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW @ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW
@ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA @ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA