- Update address of Free Software Foundation.
[reactos.git] / reactos / dll / win32 / userenv / registry.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * FILE: lib/userenv/registry.c
24 * PURPOSE: User profile code
25 * PROGRAMMER: Eric Kohl
26 */
27
28 #include <precomp.h>
29
30 #define NDEBUG
31 #include <debug.h>
32
33
34 /* FUNCTIONS ***************************************************************/
35
36 static BOOL
37 CopyKey (HKEY hDstKey,
38 HKEY hSrcKey)
39 {
40 LONG Error;
41
42 #if (_WIN32_WINNT >= 0x0600)
43 Error = RegCopyTreeW(hSrcKey,
44 NULL,
45 hDstKey);
46 if (Error != ERROR_SUCCESS)
47 {
48 SetLastError((DWORD)Error);
49 return FALSE;
50 }
51
52 return TRUE;
53
54 #else
55 FILETIME LastWrite;
56 DWORD dwSubKeys;
57 DWORD dwValues;
58 DWORD dwType;
59 DWORD dwMaxSubKeyNameLength;
60 DWORD dwSubKeyNameLength;
61 DWORD dwMaxValueNameLength;
62 DWORD dwValueNameLength;
63 DWORD dwMaxValueLength;
64 DWORD dwValueLength;
65 DWORD dwDisposition;
66 DWORD i;
67 LPWSTR lpNameBuffer;
68 LPBYTE lpDataBuffer;
69 HKEY hDstSubKey;
70 HKEY hSrcSubKey;
71
72 DPRINT ("CopyKey() called \n");
73
74 Error = RegQueryInfoKey (hSrcKey,
75 NULL,
76 NULL,
77 NULL,
78 &dwSubKeys,
79 &dwMaxSubKeyNameLength,
80 NULL,
81 &dwValues,
82 &dwMaxValueNameLength,
83 &dwMaxValueLength,
84 NULL,
85 NULL);
86 if (Error != ERROR_SUCCESS)
87 {
88 DPRINT1 ("RegQueryInfoKey() failed (Error %lu)\n", Error);
89 SetLastError((DWORD)Error);
90 return FALSE;
91 }
92
93 DPRINT ("dwSubKeys %lu\n", dwSubKeys);
94 DPRINT ("dwMaxSubKeyNameLength %lu\n", dwMaxSubKeyNameLength);
95 DPRINT ("dwValues %lu\n", dwValues);
96 DPRINT ("dwMaxValueNameLength %lu\n", dwMaxValueNameLength);
97 DPRINT ("dwMaxValueLength %lu\n", dwMaxValueLength);
98
99 /* Copy subkeys */
100 if (dwSubKeys != 0)
101 {
102 lpNameBuffer = HeapAlloc (GetProcessHeap (),
103 0,
104 dwMaxSubKeyNameLength * sizeof(WCHAR));
105 if (lpNameBuffer == NULL)
106 {
107 DPRINT1("Buffer allocation failed\n");
108 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
109 return FALSE;
110 }
111
112 for (i = 0; i < dwSubKeys; i++)
113 {
114 dwSubKeyNameLength = dwMaxSubKeyNameLength;
115 Error = RegEnumKeyExW (hSrcKey,
116 i,
117 lpNameBuffer,
118 &dwSubKeyNameLength,
119 NULL,
120 NULL,
121 NULL,
122 &LastWrite);
123 if (Error != ERROR_SUCCESS)
124 {
125 DPRINT1 ("Subkey enumeration failed (Error %lu)\n", Error);
126 HeapFree (GetProcessHeap (),
127 0,
128 lpNameBuffer);
129 SetLastError((DWORD)Error);
130 return FALSE;
131 }
132
133 Error = RegCreateKeyExW (hDstKey,
134 lpNameBuffer,
135 0,
136 NULL,
137 REG_OPTION_NON_VOLATILE,
138 KEY_WRITE,
139 NULL,
140 &hDstSubKey,
141 &dwDisposition);
142 if (Error != ERROR_SUCCESS)
143 {
144 DPRINT1 ("Subkey creation failed (Error %lu)\n", Error);
145 HeapFree (GetProcessHeap (),
146 0,
147 lpNameBuffer);
148 SetLastError((DWORD)Error);
149 return FALSE;
150 }
151
152 Error = RegOpenKeyExW (hSrcKey,
153 lpNameBuffer,
154 0,
155 KEY_READ,
156 &hSrcSubKey);
157 if (Error != ERROR_SUCCESS)
158 {
159 DPRINT1 ("Error: %lu\n", Error);
160 RegCloseKey (hDstSubKey);
161 HeapFree (GetProcessHeap (),
162 0,
163 lpNameBuffer);
164 SetLastError((DWORD)Error);
165 return FALSE;
166 }
167
168 if (!CopyKey (hDstSubKey,
169 hSrcSubKey))
170 {
171 DPRINT1 ("Error: %lu\n", GetLastError());
172 RegCloseKey (hSrcSubKey);
173 RegCloseKey (hDstSubKey);
174 HeapFree (GetProcessHeap (),
175 0,
176 lpNameBuffer);
177 return FALSE;
178 }
179
180 RegCloseKey (hSrcSubKey);
181 RegCloseKey (hDstSubKey);
182 }
183
184 HeapFree (GetProcessHeap (),
185 0,
186 lpNameBuffer);
187 }
188
189 /* Copy values */
190 if (dwValues != 0)
191 {
192 lpNameBuffer = HeapAlloc (GetProcessHeap (),
193 0,
194 dwMaxValueNameLength * sizeof(WCHAR));
195 if (lpNameBuffer == NULL)
196 {
197 DPRINT1 ("Buffer allocation failed\n");
198 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
199 return FALSE;
200 }
201
202 lpDataBuffer = HeapAlloc (GetProcessHeap (),
203 0,
204 dwMaxValueLength);
205 if (lpDataBuffer == NULL)
206 {
207 DPRINT1 ("Buffer allocation failed\n");
208 HeapFree (GetProcessHeap (),
209 0,
210 lpNameBuffer);
211 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
212 return FALSE;
213 }
214
215 for (i = 0; i < dwValues; i++)
216 {
217 dwValueNameLength = dwMaxValueNameLength;
218 dwValueLength = dwMaxValueLength;
219 Error = RegEnumValueW (hSrcKey,
220 i,
221 lpNameBuffer,
222 &dwValueNameLength,
223 NULL,
224 &dwType,
225 lpDataBuffer,
226 &dwValueLength);
227 if (Error != ERROR_SUCCESS)
228 {
229 DPRINT1("Error: %lu\n", Error);
230 HeapFree (GetProcessHeap (),
231 0,
232 lpDataBuffer);
233 HeapFree (GetProcessHeap (),
234 0,
235 lpNameBuffer);
236 SetLastError((DWORD)Error);
237 return FALSE;
238 }
239
240 Error = RegSetValueExW (hDstKey,
241 lpNameBuffer,
242 0,
243 dwType,
244 lpDataBuffer,
245 dwValueLength);
246 if (Error != ERROR_SUCCESS)
247 {
248 DPRINT1("Error: %lu\n", Error);
249 HeapFree (GetProcessHeap (),
250 0,
251 lpDataBuffer);
252 HeapFree (GetProcessHeap (),
253 0,
254 lpNameBuffer);
255 SetLastError((DWORD)Error);
256 return FALSE;
257 }
258 }
259
260 HeapFree (GetProcessHeap (),
261 0,
262 lpDataBuffer);
263
264 HeapFree (GetProcessHeap (),
265 0,
266 lpNameBuffer);
267 }
268
269 DPRINT ("CopyKey() done \n");
270
271 return TRUE;
272 #endif
273 }
274
275
276 BOOL
277 CreateUserHive (LPCWSTR lpKeyName,
278 LPCWSTR lpProfilePath)
279 {
280 HKEY hDefaultKey = NULL;
281 HKEY hUserKey = NULL;
282 LONG Error;
283 BOOL Ret = FALSE;
284
285 DPRINT ("CreateUserHive(%S) called\n", lpKeyName);
286
287 Error = RegOpenKeyExW (HKEY_USERS,
288 L".Default",
289 0,
290 KEY_READ,
291 &hDefaultKey);
292 if (Error != ERROR_SUCCESS)
293 {
294 SetLastError((DWORD)Error);
295 goto Cleanup;
296 }
297
298 Error = RegOpenKeyExW (HKEY_USERS,
299 lpKeyName,
300 0,
301 KEY_ALL_ACCESS,
302 &hUserKey);
303 if (Error != ERROR_SUCCESS)
304 {
305 SetLastError((DWORD)Error);
306 goto Cleanup;
307 }
308
309 if (!CopyKey(hUserKey, hDefaultKey))
310 {
311 goto Cleanup;
312 }
313
314 if (!UpdateUsersShellFolderSettings(lpProfilePath,
315 hUserKey))
316 {
317 goto Cleanup;
318 }
319
320 RegFlushKey (hUserKey);
321 Ret = TRUE;
322
323 Cleanup:
324 if (hUserKey != NULL)
325 RegCloseKey (hUserKey);
326
327 if (hDefaultKey != NULL)
328 RegCloseKey (hDefaultKey);
329
330 return Ret;
331 }
332
333 /* EOF */