[3/4] advapi32: Implement RegCopyTreeA/W.

Sebastian Lackner sebastian at fds-team.de
Fri Feb 26 10:00:05 CST 2016


From: Michael Müller <michael at fds-team.de>

Signed-off-by: Michael Müller <michael at fds-team.de>
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
 dlls/advapi32/advapi32.spec                                                         |    4 
 dlls/advapi32/registry.c                                                            |   95 ++++++++++
 dlls/advapi32/tests/registry.c                                                      |    2 
 dlls/api-ms-win-core-registry-l1-1-0/api-ms-win-core-registry-l1-1-0.spec           |    2 
 dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec |    2 
 5 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 88f7fee..08f799d 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -575,8 +575,8 @@
 @ stdcall RegConnectRegistryW(wstr long ptr)
 # @ stub RegConnectRegistryExA
 # @ stub RegConnectRegistryExW
-# @ stub RegCopyTreeA
-# @ stub RegCopyTreeW
+@ stdcall RegCopyTreeA(long str long)
+@ stdcall RegCopyTreeW(long wstr long)
 @ stdcall RegCreateKeyA(long str ptr)
 @ stdcall RegCreateKeyExA(long str long ptr long long ptr ptr ptr)
 @ stdcall RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr)
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 3508407..1e7639c 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -3104,6 +3104,101 @@ LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
     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.@]
  *
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index d29e131..658b356 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -2090,7 +2090,7 @@ static void test_reg_copy_tree(void)
 
     if (!pRegCopyTreeA)
     {
-        skip("Skipping RegCopyTreeA tests, function not present\n");
+        win_skip("Skipping RegCopyTreeA tests, function not present\n");
         return;
     }
 
diff --git a/dlls/api-ms-win-core-registry-l1-1-0/api-ms-win-core-registry-l1-1-0.spec b/dlls/api-ms-win-core-registry-l1-1-0/api-ms-win-core-registry-l1-1-0.spec
index d83fbdd..91b1a94 100644
--- a/dlls/api-ms-win-core-registry-l1-1-0/api-ms-win-core-registry-l1-1-0.spec
+++ b/dlls/api-ms-win-core-registry-l1-1-0/api-ms-win-core-registry-l1-1-0.spec
@@ -1,5 +1,5 @@
 @ 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 RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW
 @ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA
diff --git a/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec b/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec
index 4105e59..e1b4663 100644
--- a/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec
+++ b/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec
@@ -84,7 +84,7 @@
 @ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW
 @ stub QuerySecurityAccessMask
 @ 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 RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) advapi32.RegCreateKeyExW
 @ stdcall RegDeleteKeyExA(long str long long) advapi32.RegDeleteKeyExA
-- 
2.7.1



More information about the wine-patches mailing list