45bb29afa9cdec222441cae680a26f3a342a705c
[reactos.git] / reactos / lib / userenv / setup.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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: setup.c,v 1.8 2004/10/02 12:31:28 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * FILE: lib/userenv/setup.c
24 * PURPOSE: Profile setup functions
25 * PROGRAMMER: Eric Kohl
26 */
27
28 #include "precomp.h"
29
30 typedef struct _FOLDERDATA
31 {
32 LPWSTR ValueName;
33 LPWSTR Path;
34 BOOL Hidden;
35 BOOL bShellFolder;
36 BOOL bUserShellFolder;
37 } FOLDERDATA, *PFOLDERDATA;
38
39
40 static FOLDERDATA
41 UserShellFolders[] =
42 {
43 {L"AppData", L"Application Data", TRUE, TRUE, TRUE},
44 {L"Desktop", L"Desktop", FALSE, TRUE, TRUE},
45 {L"Favorites", L"Favorites", FALSE, TRUE, TRUE},
46 {L"Personal", L"My Documents", FALSE, TRUE, TRUE},
47 {L"PrintHood", L"PrintHood", TRUE, TRUE, TRUE},
48 {L"Recent", L"Recent", TRUE, TRUE, TRUE},
49 {L"SendTo", L"SendTo", FALSE, TRUE, TRUE},
50 {L"Templates", L"Templates", FALSE, TRUE, TRUE},
51 {L"Start Menu", L"Start Menu", FALSE, TRUE, TRUE},
52 {L"Programs", L"Start Menu\\Programs", FALSE, TRUE, TRUE},
53 {L"Startup", L"Start Menu\\Programs\\Startup", FALSE, TRUE, TRUE},
54 {L"Local Settings", L"Local Settings", TRUE, TRUE, TRUE},
55 {L"Local AppData", L"Local Settings\\Application Data", TRUE, TRUE, TRUE},
56 {L"Temp", L"Local Settings\\Temp", FALSE, FALSE, FALSE},
57 {NULL, NULL, FALSE, FALSE, FALSE}
58 };
59
60
61 static FOLDERDATA
62 CommonShellFolders[] =
63 {
64 {L"Common AppData", L"Application Data", TRUE, TRUE, TRUE},
65 {L"Common Desktop", L"Desktop", FALSE, TRUE, TRUE},
66 {L"Common Favorites", L"Favorites", FALSE, TRUE, TRUE},
67 {L"Common Start Menu", L"Start Menu", FALSE, TRUE, TRUE},
68 {L"Common Programs", L"Start Menu\\Programs", FALSE, TRUE, TRUE},
69 {L"Common Administrative Tools", L"Start Menu\\Programs\\Administrative Tools", FALSE, TRUE, FALSE},
70 {L"Common Startup", L"Start Menu\\Programs\\Startup", FALSE, TRUE, TRUE},
71 {L"Common Templates", L"Templates", TRUE, TRUE, TRUE},
72 {L"Common Documents", L"My Documents", FALSE, TRUE, TRUE},
73 {L"CommonPictures", L"My Documents\\My Pictures", FALSE, TRUE, TRUE},
74 {L"CommonMusic", L"My Documents\\My Music", FALSE, TRUE, TRUE},
75 {L"CommonVideo", L"My Documents\\My Videos", FALSE, TRUE, TRUE},
76 {NULL, NULL, FALSE, FALSE, FALSE}
77 };
78
79
80 void
81 DebugPrint(char* fmt,...)
82 {
83 char buffer[512];
84 va_list ap;
85
86 va_start(ap, fmt);
87 vsprintf(buffer, fmt, ap);
88 va_end(ap);
89
90 OutputDebugStringA(buffer);
91 }
92
93
94 BOOL WINAPI
95 InitializeProfiles (VOID)
96 {
97 WCHAR szProfilesPath[MAX_PATH];
98 WCHAR szProfilePath[MAX_PATH];
99 WCHAR szBuffer[MAX_PATH];
100 DWORD dwLength;
101 PFOLDERDATA lpFolderData;
102 HKEY hKey;
103
104 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
105 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
106 0,
107 KEY_ALL_ACCESS,
108 &hKey))
109 {
110 DPRINT1("Error: %lu\n", GetLastError());
111 return FALSE;
112 }
113
114 /* Get profiles path */
115 dwLength = MAX_PATH * sizeof(WCHAR);
116 if (RegQueryValueExW (hKey,
117 L"ProfilesDirectory",
118 NULL,
119 NULL,
120 (LPBYTE)szBuffer,
121 &dwLength))
122 {
123 DPRINT1("Error: %lu\n", GetLastError());
124 RegCloseKey (hKey);
125 return FALSE;
126 }
127
128 /* Expand it */
129 if (!ExpandEnvironmentStringsW (szBuffer,
130 szProfilesPath,
131 MAX_PATH))
132 {
133 DPRINT1("Error: %lu\n", GetLastError());
134 RegCloseKey (hKey);
135 return FALSE;
136 }
137
138 /* Create profiles directory */
139 if (!CreateDirectoryW (szProfilesPath, NULL))
140 {
141 if (GetLastError () != ERROR_ALREADY_EXISTS)
142 {
143 DPRINT1("Error: %lu\n", GetLastError());
144 RegCloseKey (hKey);
145 return FALSE;
146 }
147 }
148
149 /* Set 'DefaultUserProfile' value */
150 wcscpy (szBuffer, L"Default User");
151 if (!AppendSystemPostfix (szBuffer, MAX_PATH))
152 {
153 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
154 RegCloseKey (hKey);
155 return FALSE;
156 }
157
158 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
159 if (RegSetValueExW (hKey,
160 L"DefaultUserProfile",
161 0,
162 REG_SZ,
163 (LPBYTE)szBuffer,
164 dwLength))
165 {
166 DPRINT1("Error: %lu\n", GetLastError());
167 RegCloseKey (hKey);
168 return FALSE;
169 }
170
171 RegCloseKey (hKey);
172
173 /* Create 'Default User' profile directory */
174 wcscpy (szProfilePath, szProfilesPath);
175 wcscat (szProfilePath, L"\\");
176 wcscat (szProfilePath, szBuffer);
177 if (!CreateDirectoryW (szProfilePath, NULL))
178 {
179 if (GetLastError () != ERROR_ALREADY_EXISTS)
180 {
181 DPRINT1("Error: %lu\n", GetLastError());
182 return FALSE;
183 }
184 }
185
186 /* Set current user profile */
187 SetEnvironmentVariableW (L"USERPROFILE", szProfilePath);
188
189 /* Create 'Default User' subdirectories */
190 /* FIXME: Get these paths from the registry */
191 lpFolderData = &UserShellFolders[0];
192 while (lpFolderData->ValueName != NULL)
193 {
194 wcscpy(szBuffer, szProfilePath);
195 wcscat(szBuffer, L"\\");
196 wcscat(szBuffer, lpFolderData->Path);
197
198 if (!CreateDirectoryW(szBuffer, NULL))
199 {
200 if (GetLastError () != ERROR_ALREADY_EXISTS)
201 {
202 DPRINT1("Error: %lu\n", GetLastError());
203 return FALSE;
204 }
205 }
206
207 if (lpFolderData->Hidden == TRUE)
208 {
209 SetFileAttributesW (szBuffer,
210 FILE_ATTRIBUTE_HIDDEN);
211 }
212
213 lpFolderData++;
214 }
215
216 /* Set default 'Shell Folders' values */
217 if (RegOpenKeyExW(HKEY_USERS,
218 L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
219 0,
220 KEY_ALL_ACCESS,
221 &hKey))
222 {
223 DPRINT1("Error: %lu\n", GetLastError());
224 return FALSE;
225 }
226
227 lpFolderData = &UserShellFolders[0];
228 while (lpFolderData->ValueName != NULL)
229 {
230 if (lpFolderData->bShellFolder)
231 {
232 wcscpy(szBuffer, szProfilePath);
233 wcscat(szBuffer, L"\\");
234 wcscat(szBuffer, lpFolderData->Path);
235
236 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
237 if (RegSetValueExW(hKey,
238 lpFolderData->ValueName,
239 0,
240 REG_SZ,
241 (LPBYTE)szBuffer,
242 dwLength))
243 {
244 DPRINT1("Error: %lu\n", GetLastError());
245 RegCloseKey(hKey);
246 return FALSE;
247 }
248 }
249
250 lpFolderData++;
251 }
252
253 /* Set 'Fonts' folder path */
254 GetWindowsDirectory(szBuffer, MAX_PATH);
255 wcscat(szBuffer, L"\\media\\fonts");
256
257 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
258 if (RegSetValueExW(hKey,
259 L"Fonts",
260 0,
261 REG_SZ,
262 (LPBYTE)szBuffer,
263 dwLength))
264 {
265 DPRINT1("Error: %lu\n", GetLastError());
266 RegCloseKey(hKey);
267 return FALSE;
268 }
269
270 RegCloseKey(hKey);
271
272 /* Set default 'User Shell Folders' values */
273 if (RegOpenKeyExW(HKEY_USERS,
274 L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
275 0,
276 KEY_ALL_ACCESS,
277 &hKey))
278 {
279 DPRINT1("Error: %lu\n", GetLastError());
280 return FALSE;
281 }
282
283 lpFolderData = &UserShellFolders[0];
284 while (lpFolderData->ValueName != NULL)
285 {
286 if (lpFolderData->bUserShellFolder)
287 {
288 wcscpy(szBuffer, L"%USERPROFILE%\\");
289 wcscat(szBuffer, lpFolderData->Path);
290
291 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
292 if (RegSetValueExW(hKey,
293 lpFolderData->ValueName,
294 0,
295 REG_EXPAND_SZ,
296 (LPBYTE)szBuffer,
297 dwLength))
298 {
299 DPRINT1("Error: %lu\n", GetLastError());
300 RegCloseKey(hKey);
301 return FALSE;
302 }
303 }
304
305 lpFolderData++;
306 }
307
308 RegCloseKey(hKey);
309
310
311 /* Set 'AllUsersProfile' value */
312 wcscpy (szBuffer, L"All Users");
313 if (!AppendSystemPostfix (szBuffer, MAX_PATH))
314 {
315 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
316 return FALSE;
317 }
318
319 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
320 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
321 0,
322 KEY_ALL_ACCESS,
323 &hKey))
324 {
325 DPRINT1("Error: %lu\n", GetLastError());
326 return FALSE;
327 }
328
329 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
330 if (RegSetValueExW (hKey,
331 L"AllUsersProfile",
332 0,
333 REG_SZ,
334 (LPBYTE)szBuffer,
335 dwLength))
336 {
337 DPRINT1("Error: %lu\n", GetLastError());
338 RegCloseKey (hKey);
339 return FALSE;
340 }
341
342 RegCloseKey (hKey);
343
344
345 /* Create 'All Users' profile directory */
346 wcscpy (szProfilePath, szProfilesPath);
347 wcscat (szProfilePath, L"\\");
348 wcscat (szProfilePath, szBuffer);
349 if (!CreateDirectoryW (szProfilePath, NULL))
350 {
351 if (GetLastError () != ERROR_ALREADY_EXISTS)
352 {
353 DPRINT1("Error: %lu\n", GetLastError());
354 return FALSE;
355 }
356 }
357
358 /* Set 'All Users' profile */
359 SetEnvironmentVariableW (L"ALLUSERSPROFILE", szProfilePath);
360
361 /* Create 'All Users' subdirectories */
362 /* FIXME: Take these paths from the registry */
363 lpFolderData = &CommonShellFolders[0];
364 while (lpFolderData->ValueName != NULL)
365 {
366 wcscpy(szBuffer, szProfilePath);
367 wcscat(szBuffer, L"\\");
368 wcscat(szBuffer, lpFolderData->Path);
369
370 if (!CreateDirectoryW(szBuffer, NULL))
371 {
372 if (GetLastError () != ERROR_ALREADY_EXISTS)
373 {
374 DPRINT1("Error: %lu\n", GetLastError());
375 return FALSE;
376 }
377 }
378
379 if (lpFolderData->Hidden)
380 {
381 SetFileAttributesW(szBuffer,
382 FILE_ATTRIBUTE_HIDDEN);
383 }
384
385 lpFolderData++;
386 }
387
388 /* Set common 'Shell Folders' values */
389 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
390 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
391 0,
392 KEY_ALL_ACCESS,
393 &hKey))
394 {
395 DPRINT1("Error: %lu\n", GetLastError());
396 return FALSE;
397 }
398
399 lpFolderData = &CommonShellFolders[0];
400 while (lpFolderData->ValueName != NULL)
401 {
402 if (lpFolderData->bShellFolder)
403 {
404 wcscpy(szBuffer, szProfilePath);
405 wcscat(szBuffer, L"\\");
406 wcscat(szBuffer, lpFolderData->Path);
407
408 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
409 if (RegSetValueExW(hKey,
410 lpFolderData->ValueName,
411 0,
412 REG_SZ,
413 (LPBYTE)szBuffer,
414 dwLength))
415 {
416 DPRINT1("Error: %lu\n", GetLastError());
417 RegCloseKey(hKey);
418 return FALSE;
419 }
420 }
421
422 lpFolderData++;
423 }
424
425 RegCloseKey(hKey);
426
427 /* Set common 'User Shell Folders' values */
428 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
429 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
430 0,
431 KEY_ALL_ACCESS,
432 &hKey))
433 {
434 DPRINT1("Error: %lu\n", GetLastError());
435 return FALSE;
436 }
437
438 lpFolderData = &CommonShellFolders[0];
439 while (lpFolderData->ValueName != NULL)
440 {
441 if (lpFolderData->bUserShellFolder)
442 {
443 wcscpy(szBuffer, L"%ALLUSERSPROFILE%\\");
444 wcscat(szBuffer, lpFolderData->Path);
445
446 dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
447 if (RegSetValueExW(hKey,
448 lpFolderData->ValueName,
449 0,
450 REG_EXPAND_SZ,
451 (LPBYTE)szBuffer,
452 dwLength))
453 {
454 DPRINT1("Error: %lu\n", GetLastError());
455 RegCloseKey(hKey);
456 return FALSE;
457 }
458 }
459
460 lpFolderData++;
461 }
462
463 RegCloseKey(hKey);
464
465
466 DPRINT1("Success\n");
467
468 return TRUE;
469 }
470
471 /* EOF */