wine-staging/patches/advapi32-RegCopyTree/0003-advapi32-Implement-RegCopyTreeA-W.patch
2016-02-28 08:07:37 +01:00

180 lines
6.4 KiB
Diff

From d58022657d2eda1e50cabde52e96a6c8864b2123 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 26 Feb 2016 17:00:05 +0100
Subject: advapi32: Implement RegCopyTreeA/W.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Michael Müller <michael@fds-team.de>
Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
---
dlls/advapi32/advapi32.spec | 4 +-
dlls/advapi32/registry.c | 95 ++++++++++++++++++++++
dlls/advapi32/tests/registry.c | 2 +-
.../api-ms-win-core-registry-l1-1-0.spec | 2 +-
.../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 7664362..483df47 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