wine-staging/patches/advapi32-RegCopyTree/0004-advapi32-Clean-up-RegDeleteTree-implementation.patch
2016-02-15 09:22:18 +01:00

218 lines
6.6 KiB
Diff

From f9c5910f851677d6a8e7051043d254fb1538c0c3 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 15 Feb 2016 06:40:17 +0100
Subject: advapi32: Clean up RegDeleteTree implementation.
---
dlls/advapi32/registry.c | 156 ++++++++++++++++++++++-------------------------
1 file changed, 74 insertions(+), 82 deletions(-)
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index faca66c..eb23eb1 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -3016,126 +3016,118 @@ LSTATUS WINAPI RegDisablePredefinedCache(void)
return ERROR_SUCCESS;
}
+
+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 (value_buf && max_value > *value_size)
+ {
+ if (!(*value_buf = heap_alloc( max_value )))
+ return ERROR_NOT_ENOUGH_MEMORY;
+ *value_size = max_value;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
/******************************************************************************
* RegDeleteTreeW [ADVAPI32.@]
*
*/
-LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
+LSTATUS WINAPI RegDeleteTreeW( HKEY hkey, const WCHAR *subkey )
{
+ static const WCHAR emptyW[] = {0};
+ WCHAR buf1[MAX_PATH], *name_buf = buf1;
+ DWORD name_size, max_name = sizeof(buf1) / sizeof(WCHAR);
LONG ret;
- DWORD dwMaxSubkeyLen, dwMaxValueLen;
- DWORD dwMaxLen, dwSize;
- WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
- HKEY hSubKey = hKey;
- TRACE("(hkey=%p,%p %s)\n", hKey, lpszSubKey, debugstr_w(lpszSubKey));
+ TRACE( "(%p, %s)\n", hkey, debugstr_w(subkey) );
- if(lpszSubKey)
+ if (subkey)
{
- ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
+ ret = RegOpenKeyExW( hkey, subkey, 0, KEY_READ, &hkey );
if (ret) return ret;
}
- /* Get highest length for keys, values */
- ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
- &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
+ /* Allocate required buffers */
+ ret = reg_get_buffers( hkey, &name_buf, &max_name, NULL, NULL );
if (ret) goto cleanup;
- dwMaxSubkeyLen++;
- dwMaxValueLen++;
- dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
- if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
+ /* Recursively delete all the subkeys */
+ for (;;)
{
- /* Name too big: alloc a buffer for it */
- if (!(lpszName = heap_alloc( dwMaxLen*sizeof(WCHAR))))
- {
- ret = ERROR_NOT_ENOUGH_MEMORY;
- goto cleanup;
- }
+ name_size = max_name;
+ ret = RegEnumKeyExW( hkey, 0, name_buf, &name_size, NULL, NULL, NULL, NULL );
+ if (ret == ERROR_NO_MORE_ITEMS) break;
+ if (ret) goto cleanup;
+ ret = RegDeleteTreeW( hkey, name_buf );
+ if (ret) goto cleanup;
}
-
- /* Recursively delete all the subkeys */
- while (TRUE)
+ /* Delete the key itself */
+ if (subkey)
{
- dwSize = dwMaxLen;
- if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
- NULL, NULL, NULL)) break;
+ ret = RegDeleteKeyW( hkey, emptyW );
+ goto cleanup;
+ }
- ret = RegDeleteTreeW(hSubKey, lpszName);
+ /* Delete the values */
+ for (;;)
+ {
+ name_size = max_name;
+ ret = RegEnumValueW( hkey, 0, name_buf, &name_size, NULL, NULL, NULL, NULL );
+ if (ret == ERROR_NO_MORE_ITEMS) break;
+ if (ret) goto cleanup;
+ ret = RegDeleteValueW( hkey, name_buf );
if (ret) goto cleanup;
}
- if (lpszSubKey)
- ret = RegDeleteKeyW(hKey, lpszSubKey);
- else
- while (TRUE)
- {
- dwSize = dwMaxLen;
- if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
- NULL, NULL, NULL, NULL)) break;
-
- ret = RegDeleteValueW(hKey, lpszName);
- if (ret) goto cleanup;
- }
+ ret = ERROR_SUCCESS;
cleanup:
- /* Free buffer if allocated */
- if (lpszName != szNameBuf)
- heap_free( lpszName);
- if(lpszSubKey)
- RegCloseKey(hSubKey);
+ if (name_buf != buf1)
+ heap_free( name_buf );
+ if (subkey)
+ RegCloseKey( hkey );
return ret;
}
+
/******************************************************************************
* RegDeleteTreeA [ADVAPI32.@]
*
*/
-LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
+LSTATUS WINAPI RegDeleteTreeA( HKEY hkey, const char *subkey )
{
+ UNICODE_STRING subkeyW;
LONG ret;
- UNICODE_STRING lpszSubKeyW;
- if (lpszSubKey) RtlCreateUnicodeStringFromAsciiz( &lpszSubKeyW, lpszSubKey);
- else lpszSubKeyW.Buffer = NULL;
- ret = RegDeleteTreeW( hKey, lpszSubKeyW.Buffer);
- RtlFreeUnicodeString( &lpszSubKeyW );
+ if (subkey) RtlCreateUnicodeStringFromAsciiz( &subkeyW, subkey );
+ else subkeyW.Buffer = NULL;
+ ret = RegDeleteTreeW( hkey, subkeyW.Buffer );
+ RtlFreeUnicodeString( &subkeyW );
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.@]
*
--
2.7.1