3 * Copyright (C) 2001, 2002 ReactOS Team
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.
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.
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.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS Userinit Logon Application
22 * FILE: subsys/system/userinit/userinit.c
23 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * Hervé Poussineau (hpoussin@reactos.org)
33 #define CMP_MAGIC 0x01234567
35 /* GLOBALS ******************************************************************/
37 /* FUNCTIONS ****************************************************************/
50 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
51 if (rc
!= ERROR_SUCCESS
)
54 return ERROR_FILE_NOT_FOUND
;
55 Value
= (WCHAR
*) HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
57 return ERROR_NOT_ENOUGH_MEMORY
;
58 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
59 if (rc
!= ERROR_SUCCESS
)
61 HeapFree(GetProcessHeap(), 0, Value
);
64 /* NULL-terminate the string */
65 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
72 BOOL
IsConsoleShell(void)
74 HKEY ControlKey
= NULL
;
75 LPWSTR SystemStartOptions
= NULL
;
76 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
82 REGSTR_PATH_CURRENT_CONTROL_SET
,
87 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
88 if (rc
!= ERROR_SUCCESS
)
91 /* Check for CMDCONS in SystemStartOptions */
92 CurrentOption
= SystemStartOptions
;
95 NextOption
= wcschr(CurrentOption
, L
' ');
98 if (wcsicmp(CurrentOption
, L
"CMDCONS") == 0)
103 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
107 if (ControlKey
!= NULL
)
108 RegCloseKey(ControlKey
);
109 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
114 BOOL
GetShell(WCHAR
*CommandLine
, HKEY hRootKey
)
118 WCHAR Shell
[MAX_PATH
];
120 BOOL ConsoleShell
= IsConsoleShell();
122 if(RegOpenKeyEx(hRootKey
,
123 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", /* FIXME: should be REGSTR_PATH_WINLOGON */
124 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
126 Size
= MAX_PATH
* sizeof(WCHAR
);
127 if(RegQueryValueEx(hKey
,
128 ConsoleShell
? L
"ConsoleShell" : L
"Shell",
132 &Size
) == ERROR_SUCCESS
)
134 if((Type
== REG_SZ
) || (Type
== REG_EXPAND_SZ
))
136 wcscpy(CommandLine
, Shell
);
147 StartAutoApplications(int clsid
)
149 WCHAR szPath
[MAX_PATH
] = {0};
152 WIN32_FIND_DATAW findData
;
153 SHELLEXECUTEINFOW ExecInfo
;
156 hResult
= SHGetFolderPathW(NULL
, clsid
, NULL
, SHGFP_TYPE_CURRENT
, szPath
);
157 len
= wcslen(szPath
);
158 if (!SUCCEEDED(hResult
) || len
== 0)
163 wcscat(szPath
, L
"\\*");
164 hFind
= FindFirstFileW(szPath
, &findData
);
165 if (hFind
== INVALID_HANDLE_VALUE
)
173 if (!(findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) && (findData
.nFileSizeHigh
|| findData
.nFileSizeLow
))
175 memset(&ExecInfo
, 0x0, sizeof(SHELLEXECUTEINFOW
));
176 ExecInfo
.cbSize
= sizeof(ExecInfo
);
177 ExecInfo
.lpVerb
= L
"open";
178 ExecInfo
.lpFile
= findData
.cFileName
;
179 ExecInfo
.lpDirectory
= szPath
;
180 ShellExecuteExW(&ExecInfo
);
182 }while(FindNextFileW(hFind
, &findData
));
188 TryToStartShell(LPCWSTR Shell
)
191 PROCESS_INFORMATION pi
;
192 WCHAR ExpandedShell
[MAX_PATH
];
194 ZeroMemory(&si
, sizeof(STARTUPINFO
));
195 si
.cb
= sizeof(STARTUPINFO
);
196 ZeroMemory(&pi
, sizeof(PROCESS_INFORMATION
));
198 ExpandEnvironmentStrings(Shell
, ExpandedShell
, MAX_PATH
);
200 if(!CreateProcess(NULL
,
205 NORMAL_PRIORITY_CLASS
,
212 StartAutoApplications(CSIDL_STARTUP
);
213 StartAutoApplications(CSIDL_COMMON_STARTUP
);
214 WaitForSingleObject(pi
.hProcess
, INFINITE
);
215 CloseHandle(pi
.hProcess
);
216 CloseHandle(pi
.hThread
);
221 void StartShell(void)
223 WCHAR Shell
[MAX_PATH
];
224 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
226 /* Try to run shell in user key */
227 if (GetShell(Shell
, HKEY_CURRENT_USER
) && TryToStartShell(Shell
))
230 /* Try to run shell in local machine key */
231 if (GetShell(Shell
, HKEY_LOCAL_MACHINE
) && TryToStartShell(Shell
))
234 /* Try default shell */
235 if (IsConsoleShell())
237 if(GetSystemDirectory(Shell
, MAX_PATH
- 8))
238 wcscat(Shell
, L
"\\cmd.exe");
240 wcscpy(Shell
, L
"cmd.exe");
244 if(GetWindowsDirectory(Shell
, MAX_PATH
- 13))
245 wcscat(Shell
, L
"\\explorer.exe");
247 wcscpy(Shell
, L
"explorer.exe");
249 if (!TryToStartShell(Shell
))
251 LoadString( GetModuleHandle(NULL
), STRING_USERINIT_FAIL
, szMsg
, sizeof(szMsg
) / sizeof(szMsg
[0]));
252 MessageBox(0, szMsg
, NULL
, 0);
256 WCHAR g_RegColorNames
[][32] =
257 {L
"Scrollbar", /* 00 = COLOR_SCROLLBAR */
258 L
"Background", /* 01 = COLOR_DESKTOP */
259 L
"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */
260 L
"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */
261 L
"Menu", /* 04 = COLOR_MENU */
262 L
"Window", /* 05 = COLOR_WINDOW */
263 L
"WindowFrame", /* 06 = COLOR_WINDOWFRAME */
264 L
"MenuText", /* 07 = COLOR_MENUTEXT */
265 L
"WindowText", /* 08 = COLOR_WINDOWTEXT */
266 L
"TitleText", /* 09 = COLOR_CAPTIONTEXT */
267 L
"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */
268 L
"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */
269 L
"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */
270 L
"Hilight", /* 13 = COLOR_HIGHLIGHT */
271 L
"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */
272 L
"ButtonFace", /* 15 = COLOR_BTNFACE */
273 L
"ButtonShadow", /* 16 = COLOR_BTNSHADOW */
274 L
"GrayText", /* 17 = COLOR_GRAYTEXT */
275 L
"ButtonText", /* 18 = COLOR_BTNTEXT */
276 L
"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */
277 L
"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */
278 L
"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */
279 L
"ButtonLight", /* 22 = COLOR_3DLIGHT */
280 L
"InfoText", /* 23 = COLOR_INFOTEXT */
281 L
"InfoWindow", /* 24 = COLOR_INFOBK */
282 L
"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */
283 L
"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */
284 L
"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */
285 L
"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */
286 L
"MenuHilight", /* 29 = COLOR_MENUHILIGHT */
287 L
"MenuBar" /* 30 = COLOR_MENUBAR */
289 #define NUM_SYSCOLORS (sizeof(g_RegColorNames) / sizeof(g_RegColorNames[0]))
292 COLORREF
StrToColorref(LPWSTR lpszCol
)
296 rgb
[0] = StrToIntW(lpszCol
);
297 lpszCol
= StrChrW(lpszCol
, L
' ') + 1;
298 rgb
[1] = StrToIntW(lpszCol
);
299 lpszCol
= StrChrW(lpszCol
, L
' ') + 1;
300 rgb
[2] = StrToIntW(lpszCol
);
301 return RGB(rgb
[0], rgb
[1], rgb
[2]);
305 void SetUserSysColors(void)
313 if(!RegOpenKeyEx(HKEY_CURRENT_USER
,
314 L
"Control Panel\\Colors",
315 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
319 for(i
= 0; i
< NUM_SYSCOLORS
; i
++)
321 Size
= sizeof(szColor
);
322 if(RegQueryValueEx(hKey
, g_RegColorNames
[i
], NULL
, &Type
,
323 (LPBYTE
)szColor
, &Size
) == ERROR_SUCCESS
&& Type
== REG_SZ
)
325 crColor
= StrToColorref(szColor
);
326 SetSysColors(1, &i
, &crColor
);
334 void LoadUserFontSetting(LPWSTR lpValueName
, PLOGFONTW pFont
)
341 Size
= sizeof(LOGFONTW
);
342 if(!RegOpenKeyEx(HKEY_CURRENT_USER
,
343 L
"Control Panel\\Desktop\\WindowMetrics",
344 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
348 error
= RegQueryValueEx(hKey
, lpValueName
, NULL
, &Type
, (LPBYTE
)&lfTemp
, &Size
);
349 if ((error
!= ERROR_SUCCESS
) || (Type
!= REG_BINARY
))
354 /* FIXME: Check if lfTemp is a valid font */
360 void LoadUserMetricSetting(LPWSTR lpValueName
, INT
*pValue
)
367 Size
= sizeof(strValue
);
368 if(!RegOpenKeyEx(HKEY_CURRENT_USER
,
369 L
"Control Panel\\Desktop\\WindowMetrics",
370 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
374 ret
= RegQueryValueEx(hKey
, lpValueName
, NULL
, &Type
, (LPBYTE
)&strValue
, &Size
);
375 if ((ret
!= ERROR_SUCCESS
) || (Type
!= REG_SZ
))
380 *pValue
= StrToInt(strValue
);
385 void SetUserMetrics(void)
387 NONCLIENTMETRICSW ncmetrics
;
388 MINIMIZEDMETRICS mmmetrics
;
390 ncmetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
391 mmmetrics
.cbSize
= sizeof(MINIMIZEDMETRICS
);
392 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, sizeof(NONCLIENTMETRICSW
), &ncmetrics
, 0);
393 SystemParametersInfoW(SPI_GETMINIMIZEDMETRICS
, sizeof(MINIMIZEDMETRICS
), &mmmetrics
, 0);
395 LoadUserFontSetting(L
"CaptionFont", &ncmetrics
.lfCaptionFont
);
396 LoadUserFontSetting(L
"SmCaptionFont", &ncmetrics
.lfSmCaptionFont
);
397 LoadUserFontSetting(L
"MenuFont", &ncmetrics
.lfMenuFont
);
398 LoadUserFontSetting(L
"StatusFont", &ncmetrics
.lfStatusFont
);
399 LoadUserFontSetting(L
"MessageFont", &ncmetrics
.lfMessageFont
);
400 /* FIXME: load icon font ? */
402 LoadUserMetricSetting(L
"BorderWidth", &ncmetrics
.iBorderWidth
);
403 LoadUserMetricSetting(L
"ScrollWidth", &ncmetrics
.iScrollWidth
);
404 LoadUserMetricSetting(L
"ScrollHeight", &ncmetrics
.iScrollHeight
);
405 LoadUserMetricSetting(L
"CaptionWidth", &ncmetrics
.iCaptionWidth
);
406 LoadUserMetricSetting(L
"CaptionHeight", &ncmetrics
.iCaptionHeight
);
407 LoadUserMetricSetting(L
"SmCaptionWidth", &ncmetrics
.iSmCaptionWidth
);
408 LoadUserMetricSetting(L
"SmCaptionHeight", &ncmetrics
.iSmCaptionHeight
);
409 LoadUserMetricSetting(L
"Menuwidth", &ncmetrics
.iMenuWidth
);
410 LoadUserMetricSetting(L
"MenuHeight", &ncmetrics
.iMenuHeight
);
412 SystemParametersInfoW(SPI_SETNONCLIENTMETRICS
, sizeof(NONCLIENTMETRICSW
), &ncmetrics
, 0);
418 void SetUserWallpaper(void)
422 WCHAR szWallpaper
[MAX_PATH
+ 1];
424 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
426 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
428 Size
= sizeof(szWallpaper
);
429 if(RegQueryValueEx(hKey
,
434 &Size
) == ERROR_SUCCESS
437 ExpandEnvironmentStrings(szWallpaper
, szWallpaper
, MAX_PATH
);
439 /* Load and change the wallpaper */
440 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, szWallpaper
, SPIF_SENDCHANGE
);
444 /* remove the wallpaper */
445 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, NULL
, SPIF_SENDCHANGE
);
452 void SetUserSettings(void)
459 typedef DWORD (WINAPI
*PCMP_REPORT_LOGON
)(DWORD
, DWORD
);
465 PCMP_REPORT_LOGON CMP_Report_LogOn
;
467 hModule
= LoadLibrary(L
"setupapi.dll");
470 CMP_Report_LogOn
= (PCMP_REPORT_LOGON
)GetProcAddress(hModule
, "CMP_Report_LogOn");
471 if (CMP_Report_LogOn
)
472 CMP_Report_LogOn(CMP_MAGIC
, GetCurrentProcessId());
474 FreeLibrary(hModule
);
481 #pragma warning(disable : 4100)
482 #endif /* _MSC_VER */
485 WinMain(HINSTANCE hInst
,
486 HINSTANCE hPrevInstance
,