[ADVAPI32_VISTA] Introduce this module to hold Vista+ exports that we need to provide...
[reactos.git] / reactos / dll / win32 / advapi32_vista / RegDeleteTree.c
1
2 #include "advapi32_vista.h"
3
4 /* heap allocation helpers */
5 static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
6 static inline void *heap_alloc( size_t len )
7 {
8 return HeapAlloc( GetProcessHeap(), 0, len );
9 }
10
11 static inline BOOL heap_free( void *mem )
12 {
13 return HeapFree( GetProcessHeap(), 0, mem );
14 }
15
16 /* Taken from Wine advapi32/registry.c */
17
18 /******************************************************************************
19 * RegDeleteTreeW [ADVAPI32.@]
20 *
21 */
22 LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
23 {
24 LONG ret;
25 DWORD dwMaxSubkeyLen, dwMaxValueLen;
26 DWORD dwMaxLen, dwSize;
27 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
28 HKEY hSubKey = hKey;
29
30 if(lpszSubKey)
31 {
32 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
33 if (ret) return ret;
34 }
35
36 /* Get highest length for keys, values */
37 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
38 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
39 if (ret) goto cleanup;
40
41 dwMaxSubkeyLen++;
42 dwMaxValueLen++;
43 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
44 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
45 {
46 /* Name too big: alloc a buffer for it */
47 if (!(lpszName = heap_alloc( dwMaxLen*sizeof(WCHAR))))
48 {
49 ret = ERROR_NOT_ENOUGH_MEMORY;
50 goto cleanup;
51 }
52 }
53
54
55 /* Recursively delete all the subkeys */
56 while (TRUE)
57 {
58 dwSize = dwMaxLen;
59 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
60 NULL, NULL, NULL)) break;
61
62 ret = RegDeleteTreeW(hSubKey, lpszName);
63 if (ret) goto cleanup;
64 }
65
66 if (lpszSubKey)
67 ret = RegDeleteKeyW(hKey, lpszSubKey);
68 else
69 while (TRUE)
70 {
71 dwSize = dwMaxLen;
72 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
73 NULL, NULL, NULL, NULL)) break;
74
75 ret = RegDeleteValueW(hKey, lpszName);
76 if (ret) goto cleanup;
77 }
78
79 cleanup:
80 /* Free buffer if allocated */
81 if (lpszName != szNameBuf)
82 heap_free( lpszName);
83 if(lpszSubKey)
84 RegCloseKey(hSubKey);
85 return ret;
86 }
87
88 /******************************************************************************
89 * RegDeleteTreeA [ADVAPI32.@]
90 *
91 */
92 LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
93 {
94 LONG ret;
95 UNICODE_STRING lpszSubKeyW;
96
97 if (lpszSubKey) RtlCreateUnicodeStringFromAsciiz( &lpszSubKeyW, lpszSubKey);
98 else lpszSubKeyW.Buffer = NULL;
99 ret = RegDeleteTreeW( hKey, lpszSubKeyW.Buffer);
100 RtlFreeUnicodeString( &lpszSubKeyW );
101 return ret;
102 }