xref: /reactos/dll/win32/userenv/registry.c (revision 3e1f4074)
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 */
336