Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725/* * ReactOS applications * Copyright (C) 2001, 2002 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *//* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Userinit Logon Application * FILE: base/system/userinit/userinit.c * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) * Herv� Poussineau (hpoussin@reactos.org) */
#include "userinit.h"
#define CMP_MAGIC 0x01234567
/* GLOBALS ******************************************************************/
HINSTANCE hInstance;
/* FUNCTIONS ****************************************************************/
LONGReadRegSzKey( IN HKEY hKey, IN LPCWSTR pszKey, OUT LPWSTR *pValue){ LONG rc; DWORD dwType; DWORD cbData = 0; LPWSTR Value;
rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); if (rc != ERROR_SUCCESS) { WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); return rc; } if (dwType != REG_SZ) { WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ); return ERROR_FILE_NOT_FOUND; } Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); if (!Value) { WARN("No memory\n"); return ERROR_NOT_ENOUGH_MEMORY; } rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); if (rc != ERROR_SUCCESS) { WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc); HeapFree(GetProcessHeap(), 0, Value); return rc; } /* NULL-terminate the string */ Value[cbData / sizeof(WCHAR)] = L'\0';
*pValue = Value; return ERROR_SUCCESS;}
static BOOLIsConsoleShell(VOID){ HKEY ControlKey = NULL; LPWSTR SystemStartOptions = NULL; LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ LONG rc; BOOL ret = FALSE;
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_CURRENT_CONTROL_SET, 0, KEY_QUERY_VALUE, &ControlKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyEx() failed with error %lu\n", rc); goto cleanup; }
rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); if (rc != ERROR_SUCCESS) { WARN("ReadRegSzKey() failed with error %lu\n", rc); goto cleanup; }
/* Check for CONSOLE switch in SystemStartOptions */ CurrentOption = SystemStartOptions; while (CurrentOption) { NextOption = wcschr(CurrentOption, L' '); if (NextOption) *NextOption = L'\0'; if (_wcsicmp(CurrentOption, L"CONSOLE") == 0) { TRACE("Found 'CONSOLE' boot option\n"); ret = TRUE; goto cleanup; } CurrentOption = NextOption ? NextOption + 1 : NULL; }
cleanup: if (ControlKey != NULL) RegCloseKey(ControlKey); HeapFree(GetProcessHeap(), 0, SystemStartOptions);
TRACE("IsConsoleShell() returning %u\n", ret); return ret;}
static BOOLGetShell( OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */ IN HKEY hRootKey){ HKEY hKey; DWORD Type, Size; WCHAR Shell[MAX_PATH]; BOOL ConsoleShell = IsConsoleShell(); LONG rc;
rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyEx() failed with error %lu\n", rc); return FALSE; }
Size = sizeof(Shell); rc = RegQueryValueExW(hKey, ConsoleShell ? L"ConsoleShell" : L"Shell", NULL, &Type, (LPBYTE)Shell, &Size); RegCloseKey(hKey);
if (rc != ERROR_SUCCESS) { WARN("RegQueryValueEx() failed with error %lu\n", rc); return FALSE; }
if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) { TRACE("Found command line %s\n", debugstr_w(Shell)); wcscpy(CommandLine, Shell); return TRUE; } else { WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ); return FALSE; }}
static BOOLStartProcess( IN LPCWSTR CommandLine){ STARTUPINFO si; PROCESS_INFORMATION pi; WCHAR ExpandedCmdLine[MAX_PATH];
ExpandEnvironmentStringsW(CommandLine, ExpandedCmdLine, ARRAYSIZE(ExpandedCmdLine));
ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; ZeroMemory(&pi, sizeof(pi));
if (!CreateProcessW(NULL, ExpandedCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { WARN("CreateProcessW() failed with error %lu\n", GetLastError()); return FALSE; }
CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return TRUE;}
static BOOLStartShell(VOID){ WCHAR Shell[MAX_PATH]; WCHAR szMsg[RC_STRING_MAX_SIZE]; DWORD Type, Size; DWORD Value = 0; LONG rc; HKEY hKey;
/* Safe Mode shell run */ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option", 0, KEY_QUERY_VALUE, &hKey); if (rc == ERROR_SUCCESS) { Size = sizeof(Value); rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL, &Type, (LPBYTE)&Value, &Size); RegCloseKey(hKey);
if (rc == ERROR_SUCCESS) { if (Type == REG_DWORD) { if (Value) { /* Safe Mode Alternate Shell required */ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot", 0, KEY_READ, &hKey); if (rc == ERROR_SUCCESS) { Size = sizeof(Shell); rc = RegQueryValueExW(hKey, L"AlternateShell", NULL, &Type, (LPBYTE)Shell, &Size); RegCloseKey(hKey);
if (rc == ERROR_SUCCESS) { if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ)) { TRACE("Key located - %s\n", debugstr_w(Shell));
/* Try to run alternate shell */ if (StartProcess(Shell)) { TRACE("Alternate shell started (Safe Mode)\n"); return TRUE; } } else { WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ); } } else { WARN("Alternate shell in Safe Mode required but not specified.\n"); } } } } else { WARN("Wrong type %lu (expected %u)\n", Type, REG_DWORD); } } }
/* Try to run shell in user key */ if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell)) { TRACE("Started shell from HKEY_CURRENT_USER\n"); return TRUE; }
/* Try to run shell in local machine key */ if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell)) { TRACE("Started shell from HKEY_LOCAL_MACHINE\n"); return TRUE; }
/* Try default shell */ if (IsConsoleShell()) { *Shell = UNICODE_NULL; if (GetSystemDirectoryW(Shell, ARRAYSIZE(Shell) - 8)) StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\"); StringCchCatW(Shell, ARRAYSIZE(Shell), L"cmd.exe"); } else { *Shell = UNICODE_NULL; if (GetSystemWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13)) StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\"); StringCchCatW(Shell, ARRAYSIZE(Shell), L"explorer.exe"); }
if (!StartProcess(Shell)) { WARN("Failed to start default shell '%s'\n", debugstr_w(Shell)); LoadStringW(GetModuleHandle(NULL), IDS_SHELL_FAIL, szMsg, ARRAYSIZE(szMsg)); MessageBoxW(NULL, szMsg, NULL, MB_OK); return FALSE; } return TRUE;}
const WCHAR g_RegColorNames[][32] = { L"Scrollbar", /* 00 = COLOR_SCROLLBAR */ L"Background", /* 01 = COLOR_DESKTOP */ L"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */ L"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */ L"Menu", /* 04 = COLOR_MENU */ L"Window", /* 05 = COLOR_WINDOW */ L"WindowFrame", /* 06 = COLOR_WINDOWFRAME */ L"MenuText", /* 07 = COLOR_MENUTEXT */ L"WindowText", /* 08 = COLOR_WINDOWTEXT */ L"TitleText", /* 09 = COLOR_CAPTIONTEXT */ L"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */ L"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */ L"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */ L"Hilight", /* 13 = COLOR_HIGHLIGHT */ L"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */ L"ButtonFace", /* 15 = COLOR_BTNFACE */ L"ButtonShadow", /* 16 = COLOR_BTNSHADOW */ L"GrayText", /* 17 = COLOR_GRAYTEXT */ L"ButtonText", /* 18 = COLOR_BTNTEXT */ L"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */ L"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */ L"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */ L"ButtonLight", /* 22 = COLOR_3DLIGHT */ L"InfoText", /* 23 = COLOR_INFOTEXT */ L"InfoWindow", /* 24 = COLOR_INFOBK */ L"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */ L"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */ L"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */ L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */ L"MenuHilight", /* 29 = COLOR_MENUHILIGHT */ L"MenuBar" /* 30 = COLOR_MENUBAR */};
static COLORREFStrToColorref( IN LPWSTR lpszCol){ BYTE rgb[3];
rgb[0] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); rgb[1] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); rgb[2] = (BYTE)wcstoul(lpszCol, &lpszCol, 10); return RGB(rgb[0], rgb[1], rgb[2]);}
static VOIDSetUserSysColors(VOID){ HKEY hKey; INT i; WCHAR szColor[25]; DWORD Type, Size; COLORREF crColor; LONG rc;
rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_COLORS, 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyEx() failed with error %lu\n", rc); return; }
for (i = 0; i < ARRAYSIZE(g_RegColorNames); i++) { Size = sizeof(szColor); rc = RegQueryValueExW(hKey, g_RegColorNames[i], NULL, &Type, (LPBYTE)szColor, &Size); if (rc == ERROR_SUCCESS && Type == REG_SZ) { crColor = StrToColorref(szColor); SetSysColors(1, &i, &crColor); } else { WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(g_RegColorNames[i]), rc); } }
RegCloseKey(hKey);}
static VOIDSetUserWallpaper(VOID){ HKEY hKey; DWORD Type, Size; WCHAR szWallpaper[MAX_PATH + 1]; LONG rc;
rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP, 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { WARN("RegOpenKeyEx() failed with error %lu\n", rc); return; }
Size = sizeof(szWallpaper); rc = RegQueryValueExW(hKey, L"Wallpaper", NULL, &Type, (LPBYTE)szWallpaper, &Size); RegCloseKey(hKey);
if (rc == ERROR_SUCCESS && Type == REG_SZ) { ExpandEnvironmentStringsW(szWallpaper, szWallpaper, ARRAYSIZE(szWallpaper)); TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper));
/* Load and change the wallpaper */ SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE); } else { /* Remove the wallpaper */ TRACE("No wallpaper set in registry (error %lu)\n", rc); SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); }}
static VOIDSetUserSettings(VOID){ UpdatePerUserSystemParameters(1, TRUE); SetUserSysColors(); SetUserWallpaper();}
typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD);
static VOIDNotifyLogon(VOID){ HINSTANCE hModule; PCMP_REPORT_LOGON CMP_Report_LogOn;
hModule = LoadLibraryW(L"setupapi.dll"); if (!hModule) { WARN("LoadLibrary() failed with error %lu\n", GetLastError()); return; }
CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn"); if (CMP_Report_LogOn) CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId()); else WARN("GetProcAddress() failed\n");
FreeLibrary(hModule);}
/* * Expands the path for the ReactOS Installer "reactos.exe". * See also base/setup/welcome/welcome.c!ExpandInstallerPath() */BOOLExpandInstallerPath( IN LPCWSTR lpInstallerName, OUT LPWSTR lpInstallerPath, IN SIZE_T PathSize){ SYSTEM_INFO SystemInfo; SIZE_T cchInstallerNameLen; PWSTR ptr; DWORD dwAttribs;
cchInstallerNameLen = wcslen(lpInstallerName); if (PathSize < cchInstallerNameLen) { /* The buffer is not large enough to contain the installer file name */ *lpInstallerPath = UNICODE_NULL; return FALSE; }
/* * First, try to find the installer using the default drive, under * the directory whose name corresponds to the currently-running * CPU architecture. */ GetSystemInfo(&SystemInfo);
*lpInstallerPath = UNICODE_NULL; /* Alternatively one can use SharedUserData->NtSystemRoot */ GetSystemWindowsDirectoryW(lpInstallerPath, PathSize - cchInstallerNameLen - 1); ptr = wcschr(lpInstallerPath, L'\\'); if (ptr) *++ptr = UNICODE_NULL; else *lpInstallerPath = UNICODE_NULL;
/* Append the corresponding CPU architecture */ switch (SystemInfo.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_INTEL: StringCchCatW(lpInstallerPath, PathSize, L"I386"); break;
case PROCESSOR_ARCHITECTURE_MIPS: StringCchCatW(lpInstallerPath, PathSize, L"MIPS"); break;
case PROCESSOR_ARCHITECTURE_ALPHA: StringCchCatW(lpInstallerPath, PathSize, L"ALPHA"); break;
case PROCESSOR_ARCHITECTURE_PPC: StringCchCatW(lpInstallerPath, PathSize, L"PPC"); break;
case PROCESSOR_ARCHITECTURE_SHX: StringCchCatW(lpInstallerPath, PathSize, L"SHX"); break;
case PROCESSOR_ARCHITECTURE_ARM: StringCchCatW(lpInstallerPath, PathSize, L"ARM"); break;
case PROCESSOR_ARCHITECTURE_IA64: StringCchCatW(lpInstallerPath, PathSize, L"IA64"); break;
case PROCESSOR_ARCHITECTURE_ALPHA64: StringCchCatW(lpInstallerPath, PathSize, L"ALPHA64"); break;
case PROCESSOR_ARCHITECTURE_AMD64: StringCchCatW(lpInstallerPath, PathSize, L"AMD64"); break;
// case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */ case PROCESSOR_ARCHITECTURE_UNKNOWN: default: WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture); SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; break; }
if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN) StringCchCatW(lpInstallerPath, PathSize, L"\\"); StringCchCatW(lpInstallerPath, PathSize, lpInstallerName);
dwAttribs = GetFileAttributesW(lpInstallerPath); if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) { /* We have found the installer */ return TRUE; }
WARN("Couldn't find the installer '%s', trying alternative.\n", debugstr_w(lpInstallerPath));
/* * We failed. Try to find the installer from either the current * ReactOS installation directory, or from our current directory. */ *lpInstallerPath = UNICODE_NULL; /* Alternatively one can use SharedUserData->NtSystemRoot */ if (GetSystemWindowsDirectoryW(lpInstallerPath, PathSize - cchInstallerNameLen - 1)) StringCchCatW(lpInstallerPath, PathSize, L"\\"); StringCchCatW(lpInstallerPath, PathSize, lpInstallerName);
dwAttribs = GetFileAttributesW(lpInstallerPath); if ((dwAttribs != INVALID_FILE_ATTRIBUTES) && !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY)) { /* We have found the installer */ return TRUE; }
/* Installer not found */ ERR("Couldn't find the installer '%s'.\n", debugstr_w(lpInstallerPath)); *lpInstallerPath = UNICODE_NULL; return FALSE;}
static BOOLStartInstaller(IN LPCWSTR lpInstallerName){ WCHAR Installer[MAX_PATH]; WCHAR szMsg[RC_STRING_MAX_SIZE];
if (ExpandInstallerPath(lpInstallerName, Installer, ARRAYSIZE(Installer))) { /* We have found the installer */ if (StartProcess(Installer)) return TRUE; }
/* We failed. Display an error message and quit. */ ERR("Failed to start the installer '%s'.\n", debugstr_w(Installer)); LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg)); MessageBoxW(NULL, szMsg, NULL, MB_OK); return FALSE;}
/* Used to get the shutdown privilege */static BOOLEnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege){ BOOL Success; HANDLE hToken; TOKEN_PRIVILEGES tp;
Success = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); if (!Success) return Success;
Success = LookupPrivilegeValueW(NULL, lpszPrivilegeName, &tp.Privileges[0].Luid); if (!Success) goto Quit;
tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
Quit: CloseHandle(hToken); return Success;}
int WINAPIwWinMain(IN HINSTANCE hInst, IN HINSTANCE hPrevInstance, IN LPWSTR lpszCmdLine, IN int nCmdShow){ BOOL bIsLiveCD, Success = TRUE; STATE State;
hInstance = hInst;
bIsLiveCD = IsLiveCD();
Restart: SetUserSettings();
if (bIsLiveCD) { State.NextPage = LOCALEPAGE; State.Run = SHELL; } else { State.NextPage = DONE; State.Run = SHELL; }
if (State.NextPage != DONE) // && bIsLiveCD { RunLiveCD(&State); }
switch (State.Run) { case SHELL: Success = StartShell(); if (Success) NotifyLogon(); break;
case INSTALLER: Success = StartInstaller(L"reactos.exe"); break;
case REBOOT: { EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); ExitWindowsEx(EWX_REBOOT, 0); EnablePrivilege(SE_SHUTDOWN_NAME, FALSE); Success = TRUE; break; }
default: Success = FALSE; break; }
/* * In LiveCD mode, go back to the main menu if we failed * to either start the shell or the installer. */ if (bIsLiveCD && !Success) goto Restart;
return 0;}
/* EOF */