source: trunk/src/advapi32/registry.c@ 22014

Last change on this file since 22014 was 21353, checked in by rlwalsh, 16 years ago

eliminate VACPP warning & info msgs - see Ticket #1

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/*
2 * Registry management
3 *
4 * Copyright (C) 1999 Alexandre Julliard
5 *
6 * Based on misc/registry.c code
7 * Copyright (C) 1996 Marcus Meissner
8 * Copyright (C) 1998 Matthew Becker
9 * Copyright (C) 1999 Sylvain St-Germain
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25#include <stdlib.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <string.h>
29
30#include "ntstatus.h"
31#define WIN32_NO_STATUS
32#include "windef.h"
33#include "winbase.h"
34#include "winreg.h"
35#include "winerror.h"
36#include "winternl.h"
37#include "winuser.h"
38#include "thread.h"
39
40#include "wine/unicode.h"
41#include "debugtools.h"
42
43//WINE_DEFAULT_DEBUG_CHANNEL(reg);
44
45#define NtCurrentTeb GetThreadTEB
46TEB *WIN32API GetThreadTEB();
47
48#define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT
49#define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA
50#define NB_SPECIAL_ROOT_KEYS ((UINT)HKEY_SPECIAL_ROOT_LAST - (UINT)HKEY_SPECIAL_ROOT_FIRST + 1)
51
52static HKEY special_root_keys[NB_SPECIAL_ROOT_KEYS];
53static BOOL hkcu_cache_disabled;
54
55static const WCHAR name_CLASSES_ROOT[] =
56 {'M','a','c','h','i','n','e','\\',
57 'S','o','f','t','w','a','r','e','\\',
58 'C','l','a','s','s','e','s',0};
59static const WCHAR name_LOCAL_MACHINE[] =
60 {'M','a','c','h','i','n','e',0};
61static const WCHAR name_USERS[] =
62 {'U','s','e','r',0};
63static const WCHAR name_PERFORMANCE_DATA[] =
64 {'P','e','r','f','D','a','t','a',0};
65static const WCHAR name_CURRENT_CONFIG[] =
66 {'M','a','c','h','i','n','e','\\',
67 'S','y','s','t','e','m','\\',
68 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
69 'H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s','\\',
70 'C','u','r','r','e','n','t',0};
71static const WCHAR name_DYN_DATA[] =
72 {'D','y','n','D','a','t','a',0};
73
74static const WCHAR * const root_key_names[NB_SPECIAL_ROOT_KEYS] =
75{
76 name_CLASSES_ROOT,
77 NULL, /* HKEY_CURRENT_USER is determined dynamically */
78 name_LOCAL_MACHINE,
79 name_USERS,
80 name_PERFORMANCE_DATA,
81 name_CURRENT_CONFIG,
82 name_DYN_DATA
83};
84
85
86/* check if value type needs string conversion (Ansi<->Unicode) */
87static inline int is_string( DWORD type )
88{
89 return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
90}
91
92/* check if current version is NT or Win95 */
93static inline int is_version_nt(void)
94{
95 return !(GetVersion() & 0x80000000);
96}
97
98/* create one of the HKEY_* special root keys */
99static HKEY create_special_root_hkey( HANDLE hkey, DWORD access )
100{
101 HKEY ret = 0;
102 int idx = (UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST;
103
104 if (hkey == HKEY_CURRENT_USER)
105 {
106 if (RtlOpenCurrentUser( access, &hkey )) return 0;
107 TRACE( "HKEY_CURRENT_USER -> %p\n", hkey );
108
109 /* don't cache the key in the table if caching is disabled */
110 if (hkcu_cache_disabled)
111 return hkey;
112 }
113 else
114 {
115 OBJECT_ATTRIBUTES attr;
116 UNICODE_STRING name;
117
118 attr.Length = sizeof(attr);
119 attr.RootDirectory = 0;
120 attr.ObjectName = &name;
121 attr.Attributes = 0;
122 attr.SecurityDescriptor = NULL;
123 attr.SecurityQualityOfService = NULL;
124 RtlInitUnicodeString( &name, root_key_names[idx] );
125 if (NtCreateKey( &hkey, access, &attr, 0, NULL, 0, NULL )) return 0;
126 TRACE( "%s -> %p\n", debugstr_w(attr.ObjectName->Buffer), hkey );
127 }
128
129 if (!(ret = (HKEY)InterlockedCompareExchangePointer( (void **)&special_root_keys[idx], hkey, 0 )))
130 ret = hkey;
131 else
132 NtClose( hkey ); /* somebody beat us to it */
133 return ret;
134}
135
136/* map the hkey from special root to normal key if necessary */
137static inline HKEY get_special_root_hkey( HKEY hkey )
138{
139 HKEY ret = hkey;
140
141 if ((hkey >= HKEY_SPECIAL_ROOT_FIRST) && (hkey <= HKEY_SPECIAL_ROOT_LAST))
142 {
143 if (!(ret = special_root_keys[(UINT_PTR)hkey - (UINT_PTR)HKEY_SPECIAL_ROOT_FIRST]))
144 ret = create_special_root_hkey( hkey, KEY_ALL_ACCESS );
145 }
146 return ret;
147}
148
149
150/******************************************************************************
151 * RegDeleteTreeW [ADVAPI32.@]
152 *
153 */
154LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
155{
156 LONG ret;
157 DWORD dwMaxSubkeyLen, dwMaxValueLen;
158 DWORD dwMaxLen, dwSize;
159 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
160 HKEY hSubKey = hKey;
161 BOOL isTrue = TRUE;
162
163 TRACE("(hkey=%p,%p %s)\n", hKey, lpszSubKey, debugstr_w(lpszSubKey));
164
165 if(lpszSubKey)
166 {
167 ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
168 if (ret) return ret;
169 }
170
171 /* Get highest length for keys, values */
172 ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
173 &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
174 if (ret) goto cleanup;
175
176 dwMaxSubkeyLen++;
177 dwMaxValueLen++;
178 dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
179 if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
180 {
181 /* Name too big: alloc a buffer for it */
182 if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
183 {
184 ret = ERROR_NOT_ENOUGH_MEMORY;
185 goto cleanup;
186 }
187 }
188
189
190 /* Recursively delete all the subkeys */
191 while (isTrue)
192 {
193 dwSize = dwMaxLen;
194 if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
195 NULL, NULL, NULL)) break;
196
197 ret = RegDeleteTreeW(hSubKey, lpszName);
198 if (ret) goto cleanup;
199 }
200
201 if (lpszSubKey)
202 ret = RegDeleteKeyW(hKey, lpszSubKey);
203 else
204 while (isTrue)
205 {
206 dwSize = dwMaxLen;
207 if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
208 NULL, NULL, NULL, NULL)) break;
209
210 ret = RegDeleteValueW(hKey, lpszName);
211 if (ret) goto cleanup;
212 }
213
214cleanup:
215 /* Free buffer if allocated */
216 if (lpszName != szNameBuf)
217 HeapFree( GetProcessHeap(), 0, lpszName);
218 if(lpszSubKey)
219 RegCloseKey(hSubKey);
220 return ret;
221}
222
223/******************************************************************************
224 * RegDeleteTreeA [ADVAPI32.@]
225 *
226 */
227LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
228{
229 LONG ret;
230 UNICODE_STRING lpszSubKeyW;
231
232 if (lpszSubKey) RtlCreateUnicodeStringFromAsciiz( &lpszSubKeyW, lpszSubKey);
233 else lpszSubKeyW.Buffer = NULL;
234 ret = RegDeleteTreeW( hKey, lpszSubKeyW.Buffer);
235 RtlFreeUnicodeString( &lpszSubKeyW );
236 return ret;
237}
Note: See TracBrowser for help on using the repository browser.