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