ReactOS 0.4.16-dev-340-g0540c21
setup.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/userenv/setup.c
5 * PURPOSE: Profile setup functions
6 * PROGRAMMERS: Eric Kohl
7 * Hermes Belusca-Maito
8 */
9
10#include "precomp.h"
11
12#define NDEBUG
13#include <debug.h>
14
15#include "resources.h"
16
17typedef struct _FOLDERDATA
18{
26
27
28static FOLDERDATA
30{
31 {L"AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
32 {L"Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
33 {L"Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
34 {L"Personal", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
35 {L"NetHood", L"NetHood", IDS_NETHOOD, TRUE, TRUE, TRUE},
36 {L"PrintHood", L"PrintHood", IDS_PRINTHOOD, TRUE, TRUE, TRUE},
37 {L"Recent", L"Recent", IDS_RECENT, TRUE, TRUE, TRUE},
38 {L"SendTo", L"SendTo", IDS_SENDTO, FALSE, TRUE, TRUE},
39 {L"Templates", L"Templates", IDS_TEMPLATES, FALSE, TRUE, TRUE},
40 {L"Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
41 {L"Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
42 {L"Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
43 {L"Local Settings", L"Local Settings", IDS_LOCALSETTINGS, TRUE, TRUE, TRUE},
44 {L"Local AppData", L"Local Settings\\Application Data", IDS_LOCALAPPDATA, TRUE, TRUE, TRUE},
45 {L"Temp", L"Local Settings\\Temp", IDS_TEMP, FALSE, FALSE, FALSE},
46 {L"Cache", L"Local Settings\\Temporary Internet Files", IDS_CACHE, FALSE, TRUE, TRUE},
47 {L"History", L"Local Settings\\History", IDS_HISTORY, FALSE, TRUE, TRUE},
48 {L"Cookies", L"Cookies", IDS_COOKIES, FALSE, TRUE, TRUE},
49 {NULL, NULL, -1, FALSE, FALSE, FALSE}
50};
51
52
53static FOLDERDATA
55{
56 {L"Common AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
57 {L"Common Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
58 {L"Common Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
59 {L"Common Documents", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
60 {L"Common Templates", L"Templates", IDS_TEMPLATES, TRUE, TRUE, TRUE},
61 {L"Common Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
62 {L"Common Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
63 {L"Common Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
64 {NULL, NULL, -1, FALSE, FALSE, FALSE}
65};
66
67
68typedef struct _PROFILEPARAMS
69{
79
80
81static PROFILEPARAMS
83{
84 {
85 L"Default User", L"DefaultUserProfile",
86 L"USERPROFILE", L"%USERPROFILE%",
89 L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
90 L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"
91 },
92 {
93 L"All Users", L"AllUsersProfile",
94 L"ALLUSERSPROFILE", L"%ALLUSERSPROFILE%",
97 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
98 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"
99 },
100};
101
102
103static
104BOOL
106 IN HKEY hProfileListKey,
107 IN PPROFILEPARAMS pProfileParams)
108{
109 LONG Error;
110 PFOLDERDATA lpFolderData;
111 HKEY hKey;
113 WCHAR szProfilePath[MAX_PATH];
114 WCHAR szBuffer[MAX_PATH];
115
116 /*
117 * Create the standard profile main directory
118 */
119
120 StringCbCopyW(szBuffer, sizeof(szBuffer), pProfileParams->pszProfileName);
121
122 /* Build the profile directory path */
123 StringCbCopyW(szProfilePath, sizeof(szProfilePath), pszProfilesPath);
124 StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
125 StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
126
127 /* Attempt profile directory creation */
128 // FIXME: Security!
129 if (!CreateDirectoryW(szProfilePath, NULL))
130 {
132 {
133 DPRINT1("Error: %lu\n", GetLastError());
134 return FALSE;
135 }
136
137 /* Directory existed, let's try to append the postfix */
138 if (!AppendSystemPostfix(szBuffer, ARRAYSIZE(szBuffer)))
139 {
140 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
141 return FALSE;
142 }
143
144 /* Attempt again creation with appended postfix */
145 StringCbCopyW(szProfilePath, sizeof(szProfilePath), pszProfilesPath);
146 StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
147 StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
148
149 // FIXME: Security!
150 if (!CreateDirectoryW(szProfilePath, NULL))
151 {
153 {
154 DPRINT1("Error: %lu\n", GetLastError());
155 return FALSE;
156 }
157 }
158 }
159
160 /* Set 'DefaultUserProfile' / 'AllUsersProfile' value */
161 /* Store the default user / all users profile path in the registry */
162 dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
163 Error = RegSetValueExW(hProfileListKey,
164 pProfileParams->pszProfileRegValue,
165 0,
166 REG_SZ,
167 (LPBYTE)szBuffer,
168 dwLength);
169 if (Error != ERROR_SUCCESS)
170 {
171 DPRINT1("Error: %lu\n", Error);
173 return FALSE;
174 }
175
176 /* Set 'Default User' / 'All Users' profile */
177 SetEnvironmentVariableW(pProfileParams->pszEnvVar, szProfilePath);
178
179
180 /*
181 * Create the standard profile sub-directories and associated registry keys
182 */
183
184 /* Create 'Default User' / 'All Users' subdirectories */
185 /* FIXME: Take these paths from the registry */
186
187 lpFolderData = pProfileParams->pFolderList;
188 while (lpFolderData->lpValueName != NULL)
189 {
190 StringCbCopyW(szBuffer, sizeof(szBuffer), szProfilePath);
191 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
192
193 /* Append the folder name */
194 dwLength = wcslen(szBuffer);
196 lpFolderData->uId,
197 &szBuffer[dwLength],
198 ARRAYSIZE(szBuffer) - dwLength))
199 {
200 /* Use the default name instead */
201 StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
202 }
203
204 // FIXME: Security!
205 if (!CreateDirectoryW(szBuffer, NULL))
206 {
208 {
209 DPRINT1("Error: %lu\n", GetLastError());
210 return FALSE;
211 }
212 }
213
214 if (lpFolderData->bHidden)
216
217 lpFolderData++;
218 }
219
220 /* Set 'Shell Folders' values */
221 Error = RegOpenKeyExW(pProfileParams->hRootKey,
222 pProfileParams->pszShellFoldersKey,
223 0,
225 &hKey);
226 if (Error != ERROR_SUCCESS)
227 {
228 DPRINT1("Error: %lu\n", Error);
230 return FALSE;
231 }
232
233 /*
234 * NOTE: This is identical to UpdateUsersShellFolderSettings().
235 */
236 lpFolderData = pProfileParams->pFolderList;
237 while (lpFolderData->lpValueName != NULL)
238 {
239 if (lpFolderData->bShellFolder)
240 {
241 StringCbCopyW(szBuffer, sizeof(szBuffer), szProfilePath);
242 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
243
244 /* Append the folder name */
245 dwLength = wcslen(szBuffer);
247 lpFolderData->uId,
248 &szBuffer[dwLength],
249 ARRAYSIZE(szBuffer) - dwLength))
250 {
251 /* Use the default name instead */
252 StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
253 }
254
255 dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
257 lpFolderData->lpValueName,
258 0,
259 REG_SZ,
260 (LPBYTE)szBuffer,
261 dwLength);
262 if (Error != ERROR_SUCCESS)
263 {
264 DPRINT1("Error: %lu\n", Error);
267 return FALSE;
268 }
269 }
270
271 lpFolderData++;
272 }
273
275
276 /* Set 'User Shell Folders' values */
277 Error = RegOpenKeyExW(pProfileParams->hRootKey,
278 pProfileParams->pszUserShellFoldersKey,
279 0,
281 &hKey);
282 if (Error != ERROR_SUCCESS)
283 {
284 DPRINT1("Error: %lu\n", Error);
286 return FALSE;
287 }
288
289 lpFolderData = pProfileParams->pFolderList;
290 while (lpFolderData->lpValueName != NULL)
291 {
292 if (lpFolderData->bUserShellFolder)
293 {
294 StringCbCopyW(szBuffer, sizeof(szBuffer), pProfileParams->pszEnvVarProfilePath);
295 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
296
297 /* Append the folder name */
298 dwLength = wcslen(szBuffer);
300 lpFolderData->uId,
301 &szBuffer[dwLength],
302 ARRAYSIZE(szBuffer) - dwLength))
303 {
304 /* Use the default name instead */
305 StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
306 }
307
308 dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
310 lpFolderData->lpValueName,
311 0,
313 (LPBYTE)szBuffer,
314 dwLength);
315 if (Error != ERROR_SUCCESS)
316 {
317 DPRINT1("Error: %lu\n", Error);
320 return FALSE;
321 }
322 }
323
324 lpFolderData++;
325 }
326
328
329 return TRUE;
330}
331
332
333BOOL
334WINAPI
336{
337 LONG Error;
338 HKEY hKey;
340 WCHAR szProfilesPath[MAX_PATH];
341 WCHAR szBuffer[MAX_PATH];
342
343 DPRINT("InitializeProfiles()\n");
344
345 /* Load profiles directory path */
348 szBuffer,
349 ARRAYSIZE(szBuffer)))
350 {
351 DPRINT1("Error: %lu\n", GetLastError());
352 return FALSE;
353 }
354
356 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
357 0,
359 &hKey);
360 if (Error != ERROR_SUCCESS)
361 {
362 DPRINT1("Error: %lu\n", Error);
364 return FALSE;
365 }
366
367 /* Expand it */
368 if (!ExpandEnvironmentStringsW(szBuffer,
369 szProfilesPath,
370 ARRAYSIZE(szProfilesPath)))
371 {
372 DPRINT1("Error: %lu\n", GetLastError());
374 return FALSE;
375 }
376
377 /* Create profiles directory */
378 // FIXME: Security!
379 if (!CreateDirectoryW(szProfilesPath, NULL))
380 {
382 {
383 DPRINT1("Error: %lu\n", GetLastError());
385 return FALSE;
386 }
387 }
388
389 /* Store the profiles directory path (unexpanded) in the registry */
390 dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
392 L"ProfilesDirectory",
393 0,
395 (LPBYTE)szBuffer,
396 dwLength);
397 if (Error != ERROR_SUCCESS)
398 {
399 DPRINT1("Error: %lu\n", Error);
402 return FALSE;
403 }
404
405 /* Create 'Default User' profile directory path */
406 if (!CreateStandardProfile(szProfilesPath, hKey, &StandardProfiles[0]))
407 {
408 DPRINT1("CreateStandardProfile(L\"%S\") failed.\n", StandardProfiles[0].pszProfileName);
410 return FALSE;
411 }
412
413 /* Create 'All Users' profile directory path */
414 if (!CreateStandardProfile(szProfilesPath, hKey, &StandardProfiles[1]))
415 {
416 DPRINT1("CreateStandardProfile(L\"%S\") failed.\n", StandardProfiles[1].pszProfileName);
418 return FALSE;
419 }
420
422
423 DPRINT("Success\n");
424
425 return TRUE;
426}
427
428
429/*
430 * NOTE: See CreateStandardProfile() too.
431 * Used by registry.c!CreateUserHive()
432 */
433BOOL
435 HKEY hUserKey)
436{
437 WCHAR szBuffer[MAX_PATH];
439 PFOLDERDATA lpFolderData;
440 HKEY hFoldersKey;
441 LONG Error;
442
443 DPRINT("UpdateUsersShellFolderSettings() called\n");
444
445 DPRINT("User profile path: %S\n", lpUserProfilePath);
446
447 Error = RegOpenKeyExW(hUserKey,
448 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
449 0,
451 &hFoldersKey);
452 if (Error != ERROR_SUCCESS)
453 {
454 DPRINT1("Error: %lu\n", Error);
456 return FALSE;
457 }
458
459 lpFolderData = &UserShellFolders[0];
460 while (lpFolderData->lpValueName != NULL)
461 {
462 if (lpFolderData->bShellFolder)
463 {
464 StringCbCopyW(szBuffer, sizeof(szBuffer), lpUserProfilePath);
465 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
466
467 /* Append the folder name */
468 dwLength = wcslen(szBuffer);
470 lpFolderData->uId,
471 &szBuffer[dwLength],
472 ARRAYSIZE(szBuffer) - dwLength))
473 {
474 /* Use the default name instead */
475 StringCbCatW(szBuffer, sizeof(szBuffer), lpFolderData->lpPath);
476 }
477
478 DPRINT("%S: %S\n", lpFolderData->lpValueName, szBuffer);
479
480 dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
481 Error = RegSetValueExW(hFoldersKey,
482 lpFolderData->lpValueName,
483 0,
484 REG_SZ,
485 (LPBYTE)szBuffer,
486 dwLength);
487 if (Error != ERROR_SUCCESS)
488 {
489 DPRINT1("Error: %lu\n", Error);
490 RegCloseKey(hFoldersKey);
492 return FALSE;
493 }
494 }
495
496 lpFolderData++;
497 }
498
499 RegCloseKey(hFoldersKey);
500
501 DPRINT("UpdateUsersShellFolderSettings() done\n");
502
503 return TRUE;
504}
505
506/* EOF */
#define DPRINT1
Definition: precomp.h:8
#define IDS_PROGRAMS
Definition: resource.h:69
BOOL Error
Definition: chkdsk.c:66
#define RegCloseKey(hKey)
Definition: registry.h:49
HINSTANCE hInstance
Definition: charmap.c:19
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
#define SetLastError(x)
Definition: compat.h:752
#define MAX_PATH
Definition: compat.h:34
static DWORD DWORD * dwLength
Definition: fusion.c:86
#define IDS_FAVORITES
Definition: resource.h:35
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
BOOL AppendSystemPostfix(LPWSTR lpName, DWORD dwMaxLength)
Definition: profile.c:20
#define IDS_CACHE
Definition: resources.h:27
#define IDS_TEMP
Definition: resources.h:26
#define IDS_MYDOCUMENTS
Definition: resources.h:15
#define IDS_LOCALAPPDATA
Definition: resources.h:25
#define IDS_LOCALSETTINGS
Definition: resources.h:24
#define IDS_PROFILEPATH
Definition: resources.h:11
static PROFILEPARAMS StandardProfiles[]
Definition: setup.c:82
struct _FOLDERDATA FOLDERDATA
struct _FOLDERDATA * PFOLDERDATA
static BOOL CreateStandardProfile(IN LPCWSTR pszProfilesPath, IN HKEY hProfileListKey, IN PPROFILEPARAMS pProfileParams)
Definition: setup.c:105
struct _PROFILEPARAMS PROFILEPARAMS
BOOL WINAPI InitializeProfiles(VOID)
Definition: setup.c:335
static FOLDERDATA UserShellFolders[]
Definition: setup.c:29
BOOL UpdateUsersShellFolderSettings(LPCWSTR lpUserProfilePath, HKEY hUserKey)
Definition: setup.c:434
static FOLDERDATA CommonShellFolders[]
Definition: setup.c:54
struct _PROFILEPARAMS * PPROFILEPARAMS
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define IDS_DESKTOP
Definition: shresdef.h:71
#define IDS_RECENT
Definition: shresdef.h:88
#define IDS_NETHOOD
Definition: shresdef.h:94
#define IDS_COOKIES
Definition: shresdef.h:100
#define IDS_STARTUP
Definition: shresdef.h:87
#define IDS_APPDATA
Definition: shresdef.h:96
#define IDS_TEMPLATES
Definition: shresdef.h:95
#define IDS_PRINTHOOD
Definition: shresdef.h:97
#define IDS_SENDTO
Definition: shresdef.h:89
#define IDS_STARTMENU
Definition: shresdef.h:90
#define IDS_HISTORY
Definition: shresdef.h:101
#define DPRINT
Definition: sndvol32.h:73
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
UINT uId
Definition: setup.c:21
BOOL bHidden
Definition: setup.c:22
LPWSTR lpPath
Definition: setup.c:20
LPWSTR lpValueName
Definition: setup.c:19
BOOL bUserShellFolder
Definition: setup.c:24
BOOL bShellFolder
Definition: setup.c:23
LPCWSTR pszEnvVarProfilePath
Definition: setup.c:73
LPCWSTR pszProfileRegValue
Definition: setup.c:71
LPCWSTR pszProfileName
Definition: setup.c:70
LPCWSTR pszShellFoldersKey
Definition: setup.c:76
LPCWSTR pszUserShellFoldersKey
Definition: setup.c:77
PFOLDERDATA pFolderList
Definition: setup.c:74
HKEY hRootKey
Definition: setup.c:75
LPCWSTR pszEnvVar
Definition: setup.c:72
unsigned char * LPBYTE
Definition: typedefs.h:53
#define IN
Definition: typedefs.h:39
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_USERS
Definition: winreg.h:13
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185