mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
218 lines
6.6 KiB
Diff
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
|
|
|