[SHELL32] SHChangeNotify: Add drive, remove drive (#6782)
[reactos.git] / 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 dwMaxSubKeyNameLength++;
93 dwMaxValueNameLength++;
94
95 DPRINT("dwSubKeys %lu\n", dwSubKeys);
96 DPRINT("dwMaxSubKeyNameLength %lu\n", dwMaxSubKeyNameLength);
97 DPRINT("dwValues %lu\n", dwValues);
98 DPRINT("dwMaxValueNameLength %lu\n", dwMaxValueNameLength);
99 DPRINT("dwMaxValueLength %lu\n", dwMaxValueLength);
100
101 /* Copy subkeys */
102 if (dwSubKeys != 0)
103 {
104 lpNameBuffer = HeapAlloc(GetProcessHeap(),
105 0,
106 dwMaxSubKeyNameLength * sizeof(WCHAR));
107 if (lpNameBuffer == NULL)
108 {
109 DPRINT1("Buffer allocation failed\n");
110 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
111 return FALSE;
112 }
113
114 for (i = 0; i < dwSubKeys; i++)
115 {
116 dwSubKeyNameLength = dwMaxSubKeyNameLength;
117 Error = RegEnumKeyExW(hSrcKey,
118 i,
119 lpNameBuffer,
120 &dwSubKeyNameLength,
121 NULL,
122 NULL,
123 NULL,
124 &LastWrite);
125 if (Error != ERROR_SUCCESS)
126 {
127 DPRINT1("Subkey enumeration failed (Error %lu)\n", Error);
128 HeapFree(GetProcessHeap(),
129 0,
130 lpNameBuffer);
131 SetLastError((DWORD)Error);
132 return FALSE;
133 }
134
135 Error = RegCreateKeyExW(hDstKey,
136 lpNameBuffer,
137 0,
138 NULL,
139 REG_OPTION_NON_VOLATILE,
140 KEY_WRITE,
141 NULL,
142 &hDstSubKey,
143 &dwDisposition);
144 if (Error != ERROR_SUCCESS)
145 {
146 DPRINT1("Subkey creation failed (Error %lu)\n", Error);
147 HeapFree(GetProcessHeap(),
148 0,
149 lpNameBuffer);
150 SetLastError((DWORD)Error);
151 return FALSE;
152 }
153
154 Error = RegOpenKeyExW(hSrcKey,
155 lpNameBuffer,
156 0,
157 KEY_READ,
158 &hSrcSubKey);
159 if (Error != ERROR_SUCCESS)
160 {
161 DPRINT1("Error: %lu\n", Error);
162 RegCloseKey(hDstSubKey);
163 HeapFree(GetProcessHeap(),
164 0,
165 lpNameBuffer);
166 SetLastError((DWORD)Error);
167 return FALSE;
168 }
169
170 if (!CopyKey(hDstSubKey,
171 hSrcSubKey))
172 {
173 DPRINT1("Error: %lu\n", GetLastError());
174 RegCloseKey (hSrcSubKey);
175 RegCloseKey (hDstSubKey);
176 HeapFree(GetProcessHeap(),
177 0,
178 lpNameBuffer);
179 return FALSE;
180 }
181
182 RegCloseKey(hSrcSubKey);
183 RegCloseKey(hDstSubKey);
184 }
185
186 HeapFree(GetProcessHeap(),
187 0,
188 lpNameBuffer);
189 }
190
191 /* Copy values */
192 if (dwValues != 0)
193 {
194 lpNameBuffer = HeapAlloc(GetProcessHeap(),
195 0,
196 dwMaxValueNameLength * sizeof(WCHAR));
197 if (lpNameBuffer == NULL)
198 {
199 DPRINT1("Buffer allocation failed\n");
200 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
201 return FALSE;
202 }
203
204 lpDataBuffer = HeapAlloc(GetProcessHeap(),
205 0,
206 dwMaxValueLength);
207 if (lpDataBuffer == NULL)
208 {
209 DPRINT1("Buffer allocation failed\n");
210 HeapFree(GetProcessHeap(),
211 0,
212 lpNameBuffer);
213 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
214 return FALSE;
215 }
216
217 for (i = 0; i < dwValues; i++)
218 {
219 dwValueNameLength = dwMaxValueNameLength;
220 dwValueLength = dwMaxValueLength;
221 Error = RegEnumValueW(hSrcKey,
222 i,
223 lpNameBuffer,
224 &dwValueNameLength,
225 NULL,
226 &dwType,
227 lpDataBuffer,
228 &dwValueLength);
229 if (Error != ERROR_SUCCESS)
230 {
231 DPRINT1("Error: %lu\n", Error);
232 HeapFree(GetProcessHeap(),
233 0,
234 lpDataBuffer);
235 HeapFree(GetProcessHeap(),
236 0,
237 lpNameBuffer);
238 SetLastError((DWORD)Error);
239 return FALSE;
240 }
241
242 Error = RegSetValueExW(hDstKey,
243 lpNameBuffer,
244 0,
245 dwType,
246 lpDataBuffer,
247 dwValueLength);
248 if (Error != ERROR_SUCCESS)
249 {
250 DPRINT1("Error: %lu\n", Error);
251 HeapFree(GetProcessHeap(),
252 0,
253 lpDataBuffer);
254 HeapFree(GetProcessHeap(),
255 0,
256 lpNameBuffer);
257 SetLastError((DWORD)Error);
258 return FALSE;
259 }
260 }
261
262 HeapFree(GetProcessHeap(),
263 0,
264 lpDataBuffer);
265
266 HeapFree(GetProcessHeap(),
267 0,
268 lpNameBuffer);
269 }
270
271 DPRINT("CopyKey() done\n");
272
273 return TRUE;
274 #endif
275 }
276
277
278 BOOL
279 CreateUserHive(LPCWSTR lpKeyName,
280 LPCWSTR lpProfilePath)
281 {
282 HKEY hDefaultKey = NULL;
283 HKEY hUserKey = NULL;
284 LONG Error;
285 BOOL Ret = FALSE;
286
287 DPRINT("CreateUserHive(%S) called\n", lpKeyName);
288
289 Error = RegOpenKeyExW(HKEY_USERS,
290 L".Default",
291 0,
292 KEY_READ,
293 &hDefaultKey);
294 if (Error != ERROR_SUCCESS)
295 {
296 SetLastError((DWORD)Error);
297 goto Cleanup;
298 }
299
300 Error = RegOpenKeyExW(HKEY_USERS,
301 lpKeyName,
302 0,
303 KEY_ALL_ACCESS,
304 &hUserKey);
305 if (Error != ERROR_SUCCESS)
306 {
307 SetLastError((DWORD)Error);
308 goto Cleanup;
309 }
310
311 if (!CopyKey(hUserKey, hDefaultKey))
312 {
313 goto Cleanup;
314 }
315
316 if (!UpdateUsersShellFolderSettings(lpProfilePath,
317 hUserKey))
318 {
319 goto Cleanup;
320 }
321
322 RegFlushKey(hUserKey);
323 Ret = TRUE;
324
325 Cleanup:
326 if (hUserKey != NULL)
327 RegCloseKey (hUserKey);
328
329 if (hDefaultKey != NULL)
330 RegCloseKey (hDefaultKey);
331
332 return Ret;
333 }
334
335 /* EOF */