/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Userinit Logon Application
- * FILE: subsys/system/userinit/userinit.c
+ * FILE: base/system/userinit/userinit.c
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org)
*/
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <winreg.h>
-#include <wingdi.h>
-#include <wincon.h>
-#include <shellapi.h>
-#include <regstr.h>
-#include <shlobj.h>
-#include <shlwapi.h>
-#include <undocuser.h>
-#include <wine/debug.h>
-
-#include "resource.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(userinit);
+#include "userinit.h"
#define CMP_MAGIC 0x01234567
/* GLOBALS ******************************************************************/
+HINSTANCE hInstance;
+
+
/* FUNCTIONS ****************************************************************/
-static LONG
+LONG
ReadRegSzKey(
IN HKEY hKey,
IN LPCWSTR pszKey,
- OUT LPWSTR* pValue)
+ OUT LPWSTR *pValue)
{
LONG rc;
DWORD dwType;
return rc;
}
/* NULL-terminate the string */
- Value[cbData / sizeof(WCHAR)] = '\0';
+ Value[cbData / sizeof(WCHAR)] = L'\0';
*pValue = Value;
return ERROR_SUCCESS;
}
-static
-BOOL IsConsoleShell(VOID)
+static BOOL
+IsConsoleShell(VOID)
{
HKEY ControlKey = NULL;
LPWSTR SystemStartOptions = NULL;
return ret;
}
-static
-BOOL GetShell(
+static BOOL
+GetShell(
OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */
IN HKEY hRootKey)
{
HKEY hKey;
DWORD Type, Size;
WCHAR Shell[MAX_PATH];
- BOOL Ret = FALSE;
BOOL ConsoleShell = IsConsoleShell();
LONG rc;
rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
0, KEY_QUERY_VALUE, &hKey);
- if (rc == ERROR_SUCCESS)
+ if (rc != ERROR_SUCCESS)
{
- Size = MAX_PATH * sizeof(WCHAR);
- rc = RegQueryValueExW(hKey,
- ConsoleShell ? L"ConsoleShell" : L"Shell",
- NULL,
- &Type,
- (LPBYTE)Shell,
- &Size);
- if (rc == ERROR_SUCCESS)
- {
- if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
- {
- TRACE("Found command line %s\n", debugstr_w(Shell));
- wcscpy(CommandLine, Shell);
- Ret = TRUE;
- }
- else
- WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ);
- }
- else
- WARN("RegQueryValueEx() failed with error %lu\n", rc);
- RegCloseKey(hKey);
- }
- else
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);
- return Ret;
+ 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 VOID
{
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (findData.nFileSizeHigh || findData.nFileSizeLow))
{
- memset(&ExecInfo, 0x0, sizeof(SHELLEXECUTEINFOW));
+ ZeroMemory(&ExecInfo, sizeof(ExecInfo));
ExecInfo.cbSize = sizeof(ExecInfo);
wcscpy(&szPath[len+1], findData.cFileName);
ExecInfo.lpVerb = L"open";
si.wShowWindow = SW_SHOWNORMAL;
ZeroMemory(&pi, sizeof(pi));
- ExpandEnvironmentStrings(Shell, ExpandedShell, MAX_PATH);
-
- if (!CreateProcess(NULL,
- ExpandedShell,
- NULL,
- NULL,
- FALSE,
- NORMAL_PRIORITY_CLASS,
- NULL,
- NULL,
- &si,
- &pi))
+ ExpandEnvironmentStringsW(Shell, ExpandedShell, ARRAYSIZE(ExpandedShell));
+
+ if (!CreateProcessW(NULL,
+ ExpandedShell,
+ NULL,
+ NULL,
+ FALSE,
+ NORMAL_PRIORITY_CLASS,
+ NULL,
+ NULL,
+ &si,
+ &pi))
{
WARN("CreateProcess() failed with error %lu\n", GetLastError());
return FALSE;
return TRUE;
}
-static
-VOID StartShell(VOID)
+static BOOL
+StartShell(VOID)
{
WCHAR Shell[MAX_PATH];
- TCHAR szMsg[RC_STRING_MAX_SIZE];
+ WCHAR szMsg[RC_STRING_MAX_SIZE];
DWORD Type, Size;
DWORD Value = 0;
LONG rc;
rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
0, KEY_QUERY_VALUE, &hKey);
- if(rc == ERROR_SUCCESS)
+ if (rc == ERROR_SUCCESS)
{
Size = sizeof(Value);
rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL,
&Type, (LPBYTE)&Value, &Size);
- if(rc == ERROR_SUCCESS)
+ RegCloseKey(hKey);
+
+ if (rc == ERROR_SUCCESS)
{
- RegCloseKey(hKey);
- if(Type == REG_DWORD)
+ if (Type == REG_DWORD)
{
- if(Value)
+ 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)
+ if (rc == ERROR_SUCCESS)
{
- Size = MAX_PATH * sizeof(WCHAR);
+ Size = sizeof(Shell);
rc = RegQueryValueExW(hKey, L"AlternateShell", NULL,
&Type, (LPBYTE)Shell, &Size);
- if(rc == ERROR_SUCCESS)
+ RegCloseKey(hKey);
+
+ if (rc == ERROR_SUCCESS)
{
- RegCloseKey(hKey);
if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
{
TRACE("Key located - %s\n", debugstr_w(Shell));
+
/* Try to run alternate shell */
if (TryToStartShell(Shell))
{
TRACE("Alternate shell started (Safe Mode)\n");
- return;
+ return TRUE;
}
}
else
}
}
}
+
/* Try to run shell in user key */
if (GetShell(Shell, HKEY_CURRENT_USER) && TryToStartShell(Shell))
{
TRACE("Started shell from HKEY_CURRENT_USER\n");
- return;
+ return TRUE;
}
/* Try to run shell in local machine key */
if (GetShell(Shell, HKEY_LOCAL_MACHINE) && TryToStartShell(Shell))
{
TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
- return;
+ return TRUE;
}
/* Try default shell */
if (IsConsoleShell())
{
- if (GetSystemDirectory(Shell, MAX_PATH - 8))
+ if (GetSystemDirectoryW(Shell, ARRAYSIZE(Shell) - 8))
wcscat(Shell, L"\\cmd.exe");
else
wcscpy(Shell, L"cmd.exe");
}
else
{
- if (GetWindowsDirectory(Shell, MAX_PATH - 13))
+ if (GetWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13))
wcscat(Shell, L"\\explorer.exe");
else
wcscpy(Shell, L"explorer.exe");
}
+
if (!TryToStartShell(Shell))
{
WARN("Failed to start default shell %s\n", debugstr_w(Shell));
- LoadString( GetModuleHandle(NULL), STRING_USERINIT_FAIL, szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
- MessageBox(0, szMsg, NULL, 0);
+ 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"MenuHilight", /* 29 = COLOR_MENUHILIGHT */
L"MenuBar" /* 30 = COLOR_MENUBAR */
};
-#define NUM_SYSCOLORS (sizeof(g_RegColorNames) / sizeof(g_RegColorNames[0]))
-static
-COLORREF StrToColorref(
+static COLORREF
+StrToColorref(
IN LPWSTR lpszCol)
{
BYTE rgb[3];
TRACE("(%s)\n", debugstr_w(lpszCol));
- rgb[0] = StrToIntW(lpszCol);
- lpszCol = StrChrW(lpszCol, L' ') + 1;
- rgb[1] = StrToIntW(lpszCol);
- lpszCol = StrChrW(lpszCol, L' ') + 1;
- rgb[2] = StrToIntW(lpszCol);
+ 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
-VOID SetUserSysColors(VOID)
+static VOID
+SetUserSysColors(VOID)
{
HKEY hKey;
INT i;
- WCHAR szColor[20];
+ WCHAR szColor[25];
DWORD Type, Size;
COLORREF crColor;
LONG rc;
TRACE("()\n");
- rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_COLORS,
- 0, KEY_QUERY_VALUE, &hKey);
+ 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 < NUM_SYSCOLORS; i++)
+
+ for (i = 0; i < ARRAYSIZE(g_RegColorNames); i++)
{
Size = sizeof(szColor);
- rc = RegQueryValueEx(hKey, g_RegColorNames[i], NULL, &Type,
- (LPBYTE)szColor, &Size);
+ 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
-VOID SetUserWallpaper(VOID)
+static VOID
+SetUserWallpaper(VOID)
{
HKEY hKey;
DWORD Type, Size;
TRACE("()\n");
- rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
- 0, KEY_QUERY_VALUE, &hKey);
- if (rc == ERROR_SUCCESS)
+ rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
+ 0, KEY_QUERY_VALUE, &hKey);
+ if (rc != ERROR_SUCCESS)
{
- Size = sizeof(szWallpaper);
- rc = RegQueryValueEx(hKey,
- L"Wallpaper",
- NULL,
- &Type,
- (LPBYTE)szWallpaper,
- &Size);
- if (rc == ERROR_SUCCESS && Type == REG_SZ)
- {
- ExpandEnvironmentStrings(szWallpaper, szWallpaper, MAX_PATH);
- TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper));
+ WARN("RegOpenKeyEx() failed with error %lu\n", rc);
+ return;
+ }
- /* Load and change the wallpaper */
- SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE);
- }
- else
- {
- /* remove the wallpaper */
- TRACE("No wallpaper set in registry (error %lu)\n", rc);
- SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
- }
- RegCloseKey(hKey);
+ 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
- WARN("RegOpenKeyEx() failed with error %lu\n", rc);
+ {
+ /* Remove the wallpaper */
+ TRACE("No wallpaper set in registry (error %lu)\n", rc);
+ SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
+ }
}
-static
-VOID SetUserSettings(VOID)
+static VOID
+SetUserSettings(VOID)
{
TRACE("()\n");
TRACE("()\n");
- hModule = LoadLibrary(L"setupapi.dll");
- if (hModule)
+ hModule = LoadLibraryW(L"setupapi.dll");
+ if (!hModule)
{
- 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);
+ 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("LoadLibrary() failed with error %lu\n", GetLastError());
+ WARN("GetProcAddress() failed\n");
+
+ FreeLibrary(hModule);
+}
+
+static BOOL
+StartInstaller(VOID)
+{
+ WCHAR Shell[MAX_PATH];
+ WCHAR szMsg[RC_STRING_MAX_SIZE];
+
+ if (GetWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 12))
+ wcscat(Shell, L"\\reactos.exe");
+ else
+ wcscpy(Shell, L"reactos.exe");
+
+ if (!TryToStartShell(Shell))
+ {
+ WARN("Failed to start the installer: %s\n", debugstr_w(Shell));
+ LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg));
+ MessageBoxW(NULL, szMsg, NULL, MB_OK);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Used to get the shutdown privilege */
+static BOOL
+EnablePrivilege(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;
}
-#ifdef _MSC_VER
-#pragma warning(disable : 4100)
-#endif /* _MSC_VER */
int WINAPI
wWinMain(IN HINSTANCE hInst,
IN LPWSTR lpszCmdLine,
IN int nCmdShow)
{
+ BOOL bIsLiveCD, Success = TRUE;
+ STATE State;
+
+ hInstance = hInst;
+
+ bIsLiveCD = IsLiveCD();
+
+Restart:
SetUserSettings();
- StartShell();
- NotifyLogon();
+
+ 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();
+ 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;
}