mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
194 lines
6.9 KiB
Diff
194 lines
6.9 KiB
Diff
From 8303376b344d5525f7124016fef073da747c6acd Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
|
Date: Mon, 15 Feb 2016 06:27:10 +0100
|
|
Subject: advapi32: Implement RegCopyTreeA/W.
|
|
|
|
---
|
|
dlls/advapi32/advapi32.spec | 4 +-
|
|
dlls/advapi32/registry.c | 114 +++++++++++++++++++++
|
|
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, 119 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
|
|
index 36f176b..e3c7c4b 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..faca66c 100644
|
|
--- a/dlls/advapi32/registry.c
|
|
+++ b/dlls/advapi32/registry.c
|
|
@@ -3104,6 +3104,120 @@ LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
|
return ret;
|
|
}
|
|
|
|
+
|
|
+static LONG reg_get_buffers( HKEY hkey, WCHAR **name_buf, DWORD *name_size,
|
|
+ BYTE **value_buf, DWORD *value_size )
|
|
+{
|
|
+ DWORD ret, max_subkey, max_name, max_value;
|
|
+
|
|
+ ret = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, &max_subkey,
|
|
+ NULL, NULL, &max_name, &max_value, NULL, NULL );
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* allocate buffer for subkeys / names */
|
|
+ max_name = max( max_subkey, max_name ) + 1;
|
|
+ if (max_name > *name_size)
|
|
+ {
|
|
+ if (!(*name_buf = heap_alloc( max_name * sizeof(WCHAR) )))
|
|
+ return ERROR_NOT_ENOUGH_MEMORY;
|
|
+ *name_size = max_name;
|
|
+ }
|
|
+
|
|
+ /* allocate buffer for values */
|
|
+ if (max_value > *value_size)
|
|
+ {
|
|
+ if (!(*value_buf = heap_alloc( max_value )))
|
|
+ return ERROR_NOT_ENOUGH_MEMORY;
|
|
+ *value_size = max_value;
|
|
+ }
|
|
+
|
|
+ return ERROR_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
+/******************************************************************************
|
|
+ * RegCopyTreeW [ADVAPI32.@]
|
|
+ *
|
|
+ */
|
|
+LONG WINAPI RegCopyTreeW( HKEY hsrc, const WCHAR *subkey, HKEY hdst )
|
|
+{
|
|
+ WCHAR buf1[MAX_PATH], *name_buf = buf1;
|
|
+ BYTE buf2[MAX_PATH], *value_buf = buf2;
|
|
+ DWORD name_size, max_name = sizeof(buf1) / sizeof(WCHAR);
|
|
+ DWORD value_size, max_value = sizeof(buf2);
|
|
+ DWORD i, type;
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ /* Allocate required buffers */
|
|
+ ret = reg_get_buffers( hsrc, &name_buf, &max_name, &value_buf, &max_value );
|
|
+ if (ret) goto cleanup;
|
|
+
|
|
+ /* Copy all the 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 all the 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:
|
|
+ if (name_buf != buf1)
|
|
+ heap_free( name_buf );
|
|
+ if (value_buf != buf2)
|
|
+ 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
|
|
|