* PROJECT: ReactOS Userinit Logon Application
* FILE: subsys/system/userinit/userinit.c
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ * Hervé Poussineau (hpoussin@reactos.org)
*/
#include <windows.h>
#include <cfgmgr32.h>
/* FUNCTIONS ****************************************************************/
+static LONG
+ReadRegSzKey(
+ 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)
+ return rc;
+ if (dwType != REG_SZ)
+ return ERROR_FILE_NOT_FOUND;
+ Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
+ if (!Value)
+ return ERROR_NOT_ENOUGH_MEMORY;
+ rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, Value);
+ return rc;
+ }
+ /* NULL-terminate the string */
+ Value[cbData / sizeof(WCHAR)] = '\0';
+
+ *pValue = Value;
+ return ERROR_SUCCESS;
+}
+
+static
+BOOL IsConsoleShell(void)
+{
+ HKEY ControlKey = NULL;
+ LPWSTR SystemStartOptions = NULL;
+ LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
+ LONG rc;
+ BOOL ret = FALSE;
+
+ rc = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Control",
+ 0,
+ KEY_QUERY_VALUE,
+ &ControlKey);
+
+ rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+
+ /* Check for CMDCONS in SystemStartOptions */
+ CurrentOption = SystemStartOptions;
+ while (CurrentOption)
+ {
+ NextOption = wcschr(CurrentOption, L' ');
+ if (NextOption)
+ *NextOption = L'\0';
+ if (wcsicmp(CurrentOption, L"CMDCONS") == 0)
+ {
+ ret = TRUE;
+ goto cleanup;
+ }
+ CurrentOption = NextOption ? NextOption + 1 : NULL;
+ }
+
+cleanup:
+ if (ControlKey != NULL)
+ RegCloseKey(ControlKey);
+ HeapFree(GetProcessHeap(), 0, SystemStartOptions);
+ return ret;
+}
+
static
BOOL GetShell(WCHAR *CommandLine)
{
DWORD Type, Size;
WCHAR Shell[MAX_PATH];
BOOL Ret = FALSE;
+ BOOL ConsoleShell = IsConsoleShell();
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon",
{
Size = MAX_PATH * sizeof(WCHAR);
if(RegQueryValueEx(hKey,
- L"Shell",
+ ConsoleShell ? L"ConsoleShell" : L"Shell",
NULL,
&Type,
(LPBYTE)Shell,
if(!Ret)
{
- if(GetWindowsDirectory(CommandLine, MAX_PATH - 13))
- wcscat(CommandLine, L"\\explorer.exe");
+ if (ConsoleShell)
+ {
+ if(GetSystemDirectory(CommandLine, MAX_PATH - 8))
+ wcscat(CommandLine, L"\\cmd.exe");
+ else
+ wcscpy(CommandLine, L"cmd.exe");
+ }
else
- wcscpy(CommandLine, L"explorer.exe");
+ {
+ if(GetWindowsDirectory(CommandLine, MAX_PATH - 13))
+ wcscat(CommandLine, L"\\explorer.exe");
+ else
+ wcscpy(CommandLine, L"explorer.exe");
+ }
}
return Ret;
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-;HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\system32\cmd.exe"
+HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","ConsoleShell",0x00020000,"%SystemRoot%\system32\cmd.exe"
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe"
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartServices",0x00010001,0x00000001
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartLsass",0x00010001,0x00000001
-HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartGUI",0x00010001,0x00000000
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Userinit",0x00020000,"%SystemRoot%\system32\userinit.exe"
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","AutoAdminLogon",0x00000000,"1"
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","DefaultUserName",0x00000000,"Administrator"
#include "msgina.h"
+//#define YDEBUG
#include <wine/debug.h>
extern HINSTANCE hDllInstance;
extern GINA_UI GinaGraphicalUI;
extern GINA_UI GinaTextUI;
-static PGINA_UI pGinaUI = &GinaGraphicalUI; /* Default value */
+static PGINA_UI pGinaUI;
/*
* @implemented
return TRUE;
}
+static LONG
+ReadRegSzKey(
+ 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)
+ return rc;
+ if (dwType != REG_SZ)
+ return ERROR_FILE_NOT_FOUND;
+ Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
+ if (!Value)
+ return ERROR_NOT_ENOUGH_MEMORY;
+ rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
+ if (rc != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, Value);
+ return rc;
+ }
+ /* NULL-terminate the string */
+ Value[cbData / sizeof(WCHAR)] = '\0';
+
+ *pValue = Value;
+ return ERROR_SUCCESS;
+}
+
static VOID
ChooseGinaUI(VOID)
{
- HKEY WinLogonKey = NULL;
- DWORD Type, Size, Value;
+ HKEY ControlKey = NULL;
+ LPWSTR SystemStartOptions = NULL;
+ LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
+ BOOL ConsoleBoot = FALSE;
LONG rc;
rc = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
- L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
+ L"SYSTEM\\CurrentControlSet\\Control",
0,
KEY_QUERY_VALUE,
- &WinLogonKey);
+ &ControlKey);
+
+ rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
if (rc != ERROR_SUCCESS)
goto cleanup;
- Size = sizeof(DWORD);
- rc = RegQueryValueEx(
- WinLogonKey,
- L"StartGUI",
- NULL,
- &Type,
- (LPBYTE)&Value,
- &Size);
- if (rc != ERROR_SUCCESS || Type != REG_DWORD || Size != sizeof(DWORD))
- goto cleanup;
+ /* Check for CMDCONS in SystemStartOptions */
+ CurrentOption = SystemStartOptions;
+ while (CurrentOption)
+ {
+ NextOption = wcschr(CurrentOption, L' ');
+ if (NextOption)
+ *NextOption = L'\0';
+ if (wcsicmp(CurrentOption, L"CMDCONS") == 0)
+ {
+ TRACE("Found %S. Switching to console boot\n", CurrentOption);
+ ConsoleBoot = TRUE;
+ goto cleanup;
+ }
+ CurrentOption = NextOption ? NextOption + 1 : NULL;
+ }
- if (Value != 0)
- pGinaUI = &GinaGraphicalUI;
- else
+cleanup:
+ if (ConsoleBoot)
pGinaUI = &GinaTextUI;
+ else
+ pGinaUI = &GinaGraphicalUI;
-cleanup:
- if (WinLogonKey != NULL)
- RegCloseKey(WinLogonKey);
+ if (ControlKey != NULL)
+ RegCloseKey(ControlKey);
+ HeapFree(GetProcessHeap(), 0, SystemStartOptions);
}
/*
/* Locates the authentification package */
//LsaRegisterLogonProcess(...);
- pgContext->DoAutoLogonOnce = FALSE;
+ pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY;
ChooseGinaUI();
return pGinaUI->Initialize(pgContext);
IN PVOID pWlxContext)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
- if (pgContext->hStatusWindow)
- {
- EndDialog(pgContext->hStatusWindow, 0);
- pgContext->hStatusWindow = 0;
- }
-
- return TRUE;
-}
-
-static LONG
-ReadRegSzKey(
- 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)
- return rc;
- if (dwType != REG_SZ)
- return ERROR_FILE_NOT_FOUND;
- Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
- if (!Value)
- return ERROR_NOT_ENOUGH_MEMORY;
- rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
- if (rc != ERROR_SUCCESS)
- {
- HeapFree(GetProcessHeap(), 0, Value);
- return rc;
- }
- /* NULL-terminate the string */
- Value[cbData / sizeof(WCHAR)] = '\0';
+ TRACE("WlxRemoveStatusMessage()\n");
- *pValue = Value;
- return ERROR_SUCCESS;
+ return pGinaUI->RemoveStatusMessage(pgContext);
}
static PWSTR
static BOOL
DoAutoLogon(
- IN PGINA_CONTEXT pgContext,
- IN BOOL CheckOnly)
+ IN PGINA_CONTEXT pgContext)
{
HKEY WinLogonKey = NULL;
LPWSTR AutoLogon = NULL;
BOOL result = FALSE;
LONG rc;
+ TRACE("DoAutoLogon(): AutoLogonState = %lu\n",
+ pgContext->AutoLogonState);
+
+ if (pgContext->AutoLogonState == AUTOLOGON_DISABLED)
+ return FALSE;
+
rc = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
if (rc != ERROR_SUCCESS)
goto cleanup;
- rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon);
- if (rc != ERROR_SUCCESS)
- goto cleanup;
- if (wcscmp(AutoLogon, L"1") != 0)
- goto cleanup;
+ if (pgContext->AutoLogonState == AUTOLOGON_CHECK_REGISTRY)
+ {
+ /* Set it by default to disabled, we might reenable it again later */
+ pgContext->AutoLogonState = AUTOLOGON_DISABLED;
- rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount);
- if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0)
- goto cleanup;
- else if (rc != ERROR_FILE_NOT_FOUND)
- goto cleanup;
+ rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+ if (wcscmp(AutoLogon, L"1") != 0)
+ goto cleanup;
- rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName);
- if (rc == ERROR_SUCCESS)
- {
- if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0)
+ rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount);
+ if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0)
+ goto cleanup;
+ else if (rc != ERROR_FILE_NOT_FOUND)
goto cleanup;
- }
- else if (GetKeyState(VK_SHIFT) < 0)
- {
- /* User pressed SHIFT */
- goto cleanup;
- }
- if (CheckOnly)
- {
+ rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName);
+ if (rc == ERROR_SUCCESS)
+ {
+ if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0)
+ goto cleanup;
+ }
+ else if (GetKeyState(VK_SHIFT) < 0)
+ {
+ /* User pressed SHIFT */
+ goto cleanup;
+ }
+
+ pgContext->AutoLogonState = AUTOLOGON_ONCE;
result = TRUE;
- goto cleanup;
}
+ else /* pgContext->AutoLogonState == AUTOLOGON_ONCE */
+ {
+ pgContext->AutoLogonState = AUTOLOGON_DISABLED;
- rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName);
- if (rc != ERROR_SUCCESS)
- goto cleanup;
- rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName);
- if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
- goto cleanup;
- rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password);
- if (rc != ERROR_SUCCESS)
- goto cleanup;
+ rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
+ rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName);
+ if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
+ goto cleanup;
+ rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password);
+ if (rc != ERROR_SUCCESS)
+ goto cleanup;
- result = DoLoginTasks(pgContext, UserName, DomainName, Password);
+ result = DoLoginTasks(pgContext, UserName, DomainName, Password);
+ }
cleanup:
if (WinLogonKey != NULL)
HeapFree(GetProcessHeap(), 0, UserName);
HeapFree(GetProcessHeap(), 0, DomainName);
HeapFree(GetProcessHeap(), 0, Password);
+ TRACE("DoAutoLogon(): AutoLogonState = %lu, returning %d\n",
+ pgContext->AutoLogonState, result);
return result;
}
return;
}
- if (DoAutoLogon(NULL, TRUE))
+ if (DoAutoLogon(pgContext))
{
/* Don't display the window, we want to do an automatic logon */
- pgContext->DoAutoLogonOnce = TRUE;
+ pgContext->AutoLogonState = AUTOLOGON_ONCE;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
return;
}
+ else
+ pgContext->AutoLogonState = AUTOLOGON_DISABLED;
pGinaUI->DisplaySASNotice(pgContext);
pgContext->pProfile = pProfile;
if (!GetSystemMetrics(SM_REMOTESESSION) &&
- pgContext->DoAutoLogonOnce &&
- DoAutoLogon(pgContext, FALSE))
+ DoAutoLogon(pgContext))
{
/* User is local and registry contains information
* to log on him automatically */
- pgContext->DoAutoLogonOnce = FALSE;
return WLX_SAS_ACTION_LOGON;
}