From f9c5910f851677d6a8e7051043d254fb1538c0c3 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner 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