Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenuserinit.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS applications 00003 * Copyright (C) 2001, 2002 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS Userinit Logon Application 00022 * FILE: subsys/system/userinit/userinit.c 00023 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) 00024 * Hervé Poussineau (hpoussin@reactos.org) 00025 */ 00026 #include <windows.h> 00027 #include <cfgmgr32.h> 00028 #include <regstr.h> 00029 #include <shlobj.h> 00030 #include <shlwapi.h> 00031 #include <undocuser.h> 00032 #include "resource.h" 00033 #include <wine/debug.h> 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(userinit); 00036 00037 #define CMP_MAGIC 0x01234567 00038 00039 /* GLOBALS ******************************************************************/ 00040 00041 /* FUNCTIONS ****************************************************************/ 00042 00043 static LONG 00044 ReadRegSzKey( 00045 IN HKEY hKey, 00046 IN LPCWSTR pszKey, 00047 OUT LPWSTR* pValue) 00048 { 00049 LONG rc; 00050 DWORD dwType; 00051 DWORD cbData = 0; 00052 LPWSTR Value; 00053 00054 TRACE("(%p, %s, %p)\n", hKey, debugstr_w(pszKey), pValue); 00055 00056 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); 00057 if (rc != ERROR_SUCCESS) 00058 { 00059 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); 00060 return rc; 00061 } 00062 if (dwType != REG_SZ) 00063 { 00064 WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ); 00065 return ERROR_FILE_NOT_FOUND; 00066 } 00067 Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); 00068 if (!Value) 00069 { 00070 WARN("No memory\n"); 00071 return ERROR_NOT_ENOUGH_MEMORY; 00072 } 00073 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); 00074 if (rc != ERROR_SUCCESS) 00075 { 00076 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); 00077 HeapFree(GetProcessHeap(), 0, Value); 00078 return rc; 00079 } 00080 /* NULL-terminate the string */ 00081 Value[cbData / sizeof(WCHAR)] = '\0'; 00082 00083 *pValue = Value; 00084 return ERROR_SUCCESS; 00085 } 00086 00087 static 00088 BOOL IsConsoleShell(VOID) 00089 { 00090 HKEY ControlKey = NULL; 00091 LPWSTR SystemStartOptions = NULL; 00092 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ 00093 LONG rc; 00094 BOOL ret = FALSE; 00095 00096 TRACE("()\n"); 00097 00098 rc = RegOpenKeyEx( 00099 HKEY_LOCAL_MACHINE, 00100 REGSTR_PATH_CURRENT_CONTROL_SET, 00101 0, 00102 KEY_QUERY_VALUE, 00103 &ControlKey); 00104 if (rc != ERROR_SUCCESS) 00105 { 00106 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 00107 goto cleanup; 00108 } 00109 00110 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); 00111 if (rc != ERROR_SUCCESS) 00112 { 00113 WARN("ReadRegSzKey() failed with error %lu\n", rc); 00114 goto cleanup; 00115 } 00116 00117 /* Check for CONSOLE in SystemStartOptions */ 00118 CurrentOption = SystemStartOptions; 00119 while (CurrentOption) 00120 { 00121 NextOption = wcschr(CurrentOption, L' '); 00122 if (NextOption) 00123 *NextOption = L'\0'; 00124 if (_wcsicmp(CurrentOption, L"CONSOLE") == 0) 00125 { 00126 TRACE("Found 'CONSOLE' boot option\n"); 00127 ret = TRUE; 00128 goto cleanup; 00129 } 00130 CurrentOption = NextOption ? NextOption + 1 : NULL; 00131 } 00132 00133 cleanup: 00134 if (ControlKey != NULL) 00135 RegCloseKey(ControlKey); 00136 HeapFree(GetProcessHeap(), 0, SystemStartOptions); 00137 TRACE("IsConsoleShell() returning %d\n", ret); 00138 return ret; 00139 } 00140 00141 static 00142 BOOL GetShell( 00143 OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */ 00144 IN HKEY hRootKey) 00145 { 00146 HKEY hKey; 00147 DWORD Type, Size; 00148 WCHAR Shell[MAX_PATH]; 00149 BOOL Ret = FALSE; 00150 BOOL ConsoleShell = IsConsoleShell(); 00151 LONG rc; 00152 00153 TRACE("(%p, %p)\n", CommandLine, hRootKey); 00154 00155 rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 00156 0, KEY_QUERY_VALUE, &hKey); 00157 if (rc == ERROR_SUCCESS) 00158 { 00159 Size = MAX_PATH * sizeof(WCHAR); 00160 rc = RegQueryValueExW(hKey, 00161 ConsoleShell ? L"ConsoleShell" : L"Shell", 00162 NULL, 00163 &Type, 00164 (LPBYTE)Shell, 00165 &Size); 00166 if (rc == ERROR_SUCCESS) 00167 { 00168 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) 00169 { 00170 TRACE("Found command line %s\n", debugstr_w(Shell)); 00171 wcscpy(CommandLine, Shell); 00172 Ret = TRUE; 00173 } 00174 else 00175 WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ); 00176 } 00177 else 00178 WARN("RegQueryValueEx() failed with error %lu\n", rc); 00179 RegCloseKey(hKey); 00180 } 00181 else 00182 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 00183 00184 return Ret; 00185 } 00186 00187 static VOID 00188 StartAutoApplications( 00189 IN INT clsid) 00190 { 00191 WCHAR szPath[MAX_PATH] = {0}; 00192 HRESULT hResult; 00193 HANDLE hFind; 00194 WIN32_FIND_DATAW findData; 00195 SHELLEXECUTEINFOW ExecInfo; 00196 size_t len; 00197 00198 TRACE("(%d)\n", clsid); 00199 00200 hResult = SHGetFolderPathW(NULL, clsid, NULL, SHGFP_TYPE_CURRENT, szPath); 00201 len = wcslen(szPath); 00202 if (!SUCCEEDED(hResult) || len == 0) 00203 { 00204 WARN("SHGetFolderPath() failed with error %lu\n", GetLastError()); 00205 return; 00206 } 00207 00208 wcscat(szPath, L"\\*"); 00209 hFind = FindFirstFileW(szPath, &findData); 00210 if (hFind == INVALID_HANDLE_VALUE) 00211 { 00212 WARN("FindFirstFile(%s) failed with error %lu\n", debugstr_w(szPath), GetLastError()); 00213 return; 00214 } 00215 00216 do 00217 { 00218 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (findData.nFileSizeHigh || findData.nFileSizeLow)) 00219 { 00220 memset(&ExecInfo, 0x0, sizeof(SHELLEXECUTEINFOW)); 00221 ExecInfo.cbSize = sizeof(ExecInfo); 00222 wcscpy(&szPath[len+1], findData.cFileName); 00223 ExecInfo.lpVerb = L"open"; 00224 ExecInfo.lpFile = szPath; 00225 ExecInfo.lpDirectory = NULL; 00226 TRACE("Executing %s in directory %s\n", 00227 debugstr_w(findData.cFileName), debugstr_w(szPath)); 00228 ShellExecuteExW(&ExecInfo); 00229 } 00230 } while (FindNextFileW(hFind, &findData)); 00231 FindClose(hFind); 00232 } 00233 00234 static BOOL 00235 TryToStartShell( 00236 IN LPCWSTR Shell) 00237 { 00238 STARTUPINFO si; 00239 PROCESS_INFORMATION pi; 00240 WCHAR ExpandedShell[MAX_PATH]; 00241 00242 TRACE("(%s)\n", debugstr_w(Shell)); 00243 00244 ZeroMemory(&si, sizeof(STARTUPINFO)); 00245 si.cb = sizeof(STARTUPINFO); 00246 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); 00247 00248 ExpandEnvironmentStrings(Shell, ExpandedShell, MAX_PATH); 00249 00250 if (!CreateProcess(NULL, 00251 ExpandedShell, 00252 NULL, 00253 NULL, 00254 FALSE, 00255 NORMAL_PRIORITY_CLASS, 00256 NULL, 00257 NULL, 00258 &si, 00259 &pi)) 00260 { 00261 WARN("CreateProcess() failed with error %lu\n", GetLastError()); 00262 return FALSE; 00263 } 00264 00265 StartAutoApplications(CSIDL_STARTUP); 00266 StartAutoApplications(CSIDL_COMMON_STARTUP); 00267 CloseHandle(pi.hProcess); 00268 CloseHandle(pi.hThread); 00269 return TRUE; 00270 } 00271 00272 static 00273 VOID StartShell(VOID) 00274 { 00275 WCHAR Shell[MAX_PATH]; 00276 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00277 DWORD Type, Size; 00278 DWORD Value = 0; 00279 LONG rc; 00280 HKEY hKey; 00281 00282 TRACE("()\n"); 00283 00284 /* Safe Mode shell run */ 00285 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 00286 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option", 00287 0, KEY_QUERY_VALUE, &hKey); 00288 if(rc == ERROR_SUCCESS) 00289 { 00290 Size = sizeof(Value); 00291 rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL, 00292 &Type, (LPBYTE)&Value, &Size); 00293 if(rc == ERROR_SUCCESS) 00294 { 00295 RegCloseKey(hKey); 00296 if(Type == REG_DWORD) 00297 { 00298 if(Value) 00299 { 00300 /* Safe Mode Alternate Shell required */ 00301 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 00302 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot", 00303 0, KEY_READ, &hKey); 00304 if(rc == ERROR_SUCCESS) 00305 { 00306 Size = MAX_PATH * sizeof(WCHAR); 00307 rc = RegQueryValueExW(hKey, L"AlternateShell", NULL, 00308 &Type, (LPBYTE)Shell, &Size); 00309 if(rc == ERROR_SUCCESS) 00310 { 00311 RegCloseKey(hKey); 00312 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) 00313 { 00314 TRACE("Key located - %s\n", debugstr_w(Shell)); 00315 /* Try to run alternate shell */ 00316 if (TryToStartShell(Shell)) 00317 { 00318 TRACE("Alternate shell started (Safe Mode)\n"); 00319 return; 00320 } 00321 } 00322 else 00323 { 00324 WARN("Wrong type %lu (expected %u or %u)\n", 00325 Type, REG_SZ, REG_EXPAND_SZ); 00326 } 00327 } 00328 else 00329 { 00330 WARN("Alternate shell in Safe Mode required but not specified."); 00331 } 00332 } 00333 } 00334 } 00335 else 00336 { 00337 WARN("Wrong type %lu (expected %u)\n", Type, REG_DWORD); 00338 } 00339 } 00340 } 00341 /* Try to run shell in user key */ 00342 if (GetShell(Shell, HKEY_CURRENT_USER) && TryToStartShell(Shell)) 00343 { 00344 TRACE("Started shell from HKEY_CURRENT_USER\n"); 00345 return; 00346 } 00347 00348 /* Try to run shell in local machine key */ 00349 if (GetShell(Shell, HKEY_LOCAL_MACHINE) && TryToStartShell(Shell)) 00350 { 00351 TRACE("Started shell from HKEY_LOCAL_MACHINE\n"); 00352 return; 00353 } 00354 00355 /* Try default shell */ 00356 if (IsConsoleShell()) 00357 { 00358 if (GetSystemDirectory(Shell, MAX_PATH - 8)) 00359 wcscat(Shell, L"\\cmd.exe"); 00360 else 00361 wcscpy(Shell, L"cmd.exe"); 00362 } 00363 else 00364 { 00365 if (GetWindowsDirectory(Shell, MAX_PATH - 13)) 00366 wcscat(Shell, L"\\explorer.exe"); 00367 else 00368 wcscpy(Shell, L"explorer.exe"); 00369 } 00370 if (!TryToStartShell(Shell)) 00371 { 00372 WARN("Failed to start default shell %s\n", debugstr_w(Shell)); 00373 LoadString( GetModuleHandle(NULL), STRING_USERINIT_FAIL, szMsg, sizeof(szMsg) / sizeof(szMsg[0])); 00374 MessageBox(0, szMsg, NULL, 0); 00375 } 00376 } 00377 00378 const WCHAR g_RegColorNames[][32] = { 00379 L"Scrollbar", /* 00 = COLOR_SCROLLBAR */ 00380 L"Background", /* 01 = COLOR_DESKTOP */ 00381 L"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */ 00382 L"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */ 00383 L"Menu", /* 04 = COLOR_MENU */ 00384 L"Window", /* 05 = COLOR_WINDOW */ 00385 L"WindowFrame", /* 06 = COLOR_WINDOWFRAME */ 00386 L"MenuText", /* 07 = COLOR_MENUTEXT */ 00387 L"WindowText", /* 08 = COLOR_WINDOWTEXT */ 00388 L"TitleText", /* 09 = COLOR_CAPTIONTEXT */ 00389 L"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */ 00390 L"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */ 00391 L"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */ 00392 L"Hilight", /* 13 = COLOR_HIGHLIGHT */ 00393 L"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */ 00394 L"ButtonFace", /* 15 = COLOR_BTNFACE */ 00395 L"ButtonShadow", /* 16 = COLOR_BTNSHADOW */ 00396 L"GrayText", /* 17 = COLOR_GRAYTEXT */ 00397 L"ButtonText", /* 18 = COLOR_BTNTEXT */ 00398 L"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */ 00399 L"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */ 00400 L"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */ 00401 L"ButtonLight", /* 22 = COLOR_3DLIGHT */ 00402 L"InfoText", /* 23 = COLOR_INFOTEXT */ 00403 L"InfoWindow", /* 24 = COLOR_INFOBK */ 00404 L"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */ 00405 L"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */ 00406 L"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */ 00407 L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */ 00408 L"MenuHilight", /* 29 = COLOR_MENUHILIGHT */ 00409 L"MenuBar" /* 30 = COLOR_MENUBAR */ 00410 }; 00411 #define NUM_SYSCOLORS (sizeof(g_RegColorNames) / sizeof(g_RegColorNames[0])) 00412 00413 static 00414 COLORREF StrToColorref( 00415 IN LPWSTR lpszCol) 00416 { 00417 BYTE rgb[3]; 00418 00419 TRACE("(%s)\n", debugstr_w(lpszCol)); 00420 00421 rgb[0] = StrToIntW(lpszCol); 00422 lpszCol = StrChrW(lpszCol, L' ') + 1; 00423 rgb[1] = StrToIntW(lpszCol); 00424 lpszCol = StrChrW(lpszCol, L' ') + 1; 00425 rgb[2] = StrToIntW(lpszCol); 00426 return RGB(rgb[0], rgb[1], rgb[2]); 00427 } 00428 00429 static 00430 VOID SetUserSysColors(VOID) 00431 { 00432 HKEY hKey; 00433 INT i; 00434 WCHAR szColor[20]; 00435 DWORD Type, Size; 00436 COLORREF crColor; 00437 LONG rc; 00438 00439 TRACE("()\n"); 00440 00441 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_COLORS, 00442 0, KEY_QUERY_VALUE, &hKey); 00443 if (rc != ERROR_SUCCESS) 00444 { 00445 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 00446 return; 00447 } 00448 for(i = 0; i < NUM_SYSCOLORS; i++) 00449 { 00450 Size = sizeof(szColor); 00451 rc = RegQueryValueEx(hKey, g_RegColorNames[i], NULL, &Type, 00452 (LPBYTE)szColor, &Size); 00453 if (rc == ERROR_SUCCESS && Type == REG_SZ) 00454 { 00455 crColor = StrToColorref(szColor); 00456 SetSysColors(1, &i, &crColor); 00457 } 00458 else 00459 WARN("RegQueryValueEx(%s) failed with error %lu\n", 00460 debugstr_w(g_RegColorNames[i]), rc); 00461 } 00462 RegCloseKey(hKey); 00463 } 00464 00465 static 00466 VOID SetUserWallpaper(VOID) 00467 { 00468 HKEY hKey; 00469 DWORD Type, Size; 00470 WCHAR szWallpaper[MAX_PATH + 1]; 00471 LONG rc; 00472 00473 TRACE("()\n"); 00474 00475 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP, 00476 0, KEY_QUERY_VALUE, &hKey); 00477 if (rc == ERROR_SUCCESS) 00478 { 00479 Size = sizeof(szWallpaper); 00480 rc = RegQueryValueEx(hKey, 00481 L"Wallpaper", 00482 NULL, 00483 &Type, 00484 (LPBYTE)szWallpaper, 00485 &Size); 00486 if (rc == ERROR_SUCCESS && Type == REG_SZ) 00487 { 00488 ExpandEnvironmentStrings(szWallpaper, szWallpaper, MAX_PATH); 00489 TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper)); 00490 00491 /* Load and change the wallpaper */ 00492 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE); 00493 } 00494 else 00495 { 00496 /* remove the wallpaper */ 00497 TRACE("No wallpaper set in registry (error %lu)\n", rc); 00498 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); 00499 } 00500 RegCloseKey(hKey); 00501 } 00502 else 00503 WARN("RegOpenKeyEx() failed with error %lu\n", rc); 00504 } 00505 00506 static 00507 VOID SetUserSettings(VOID) 00508 { 00509 TRACE("()\n"); 00510 00511 UpdatePerUserSystemParameters(1, TRUE); 00512 SetUserSysColors(); 00513 SetUserWallpaper(); 00514 } 00515 00516 typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD); 00517 00518 static VOID 00519 NotifyLogon(VOID) 00520 { 00521 HINSTANCE hModule; 00522 PCMP_REPORT_LOGON CMP_Report_LogOn; 00523 00524 TRACE("()\n"); 00525 00526 hModule = LoadLibrary(L"setupapi.dll"); 00527 if (hModule) 00528 { 00529 CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn"); 00530 if (CMP_Report_LogOn) 00531 CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId()); 00532 else 00533 WARN("GetProcAddress() failed\n"); 00534 00535 FreeLibrary(hModule); 00536 } 00537 else 00538 WARN("LoadLibrary() failed with error %lu\n", GetLastError()); 00539 } 00540 00541 #ifdef _MSC_VER 00542 #pragma warning(disable : 4100) 00543 #endif /* _MSC_VER */ 00544 00545 int WINAPI 00546 wWinMain(IN HINSTANCE hInst, 00547 IN HINSTANCE hPrevInstance, 00548 IN LPWSTR lpszCmdLine, 00549 IN int nCmdShow) 00550 { 00551 SetUserSettings(); 00552 StartShell(); 00553 NotifyLogon(); 00554 return 0; 00555 } 00556 00557 /* EOF */ Generated on Sun May 27 2012 04:18:53 for ReactOS by
1.7.6.1
|