Winlogon:

- Register CTRL+ALT+DELETE notification
- Better session loop between all GINA dialogs
- Display a dialog box if GINA DLL cannot be loaded
GINA:
- Add an graphical and text interface to enter username/password
- Take care of autologon parameters in registry

svn path=/trunk/; revision=23424
This commit is contained in:
Hervé Poussineau 2006-08-02 21:01:37 +00:00
parent d99c9b45f0
commit d194ee80a5
11 changed files with 2168 additions and 1536 deletions

View file

@ -3,75 +3,256 @@
* PROJECT: ReactOS kernel
* FILE: services/winlogon/sas.c
* PURPOSE: Secure Attention Sequence
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org)
* UPDATE HISTORY:
* Created 28/03/2004
*/
#include "winlogon.h"
#define NDEBUG
#include <debug.h>
#define YDEBUG
#include <wine/debug.h>
#define WINLOGON_SAS_CLASS L"SAS window class"
#define WINLOGON_SAS_TITLE L"SAS"
#define WINLOGON_SAS_CLASS L"SAS Window class"
#define WINLOGON_SAS_TITLE L"SAS window"
#define HK_CTRL_ALT_DEL 0
#define HK_CTRL_SHIFT_ESC 1
#define HK_CTRL_ALT_DEL 0
#define HK_CTRL_SHIFT_ESC 1
#ifdef __USE_W32API
extern BOOL STDCALL SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta);
#endif
void
DispatchSAS(PWLSESSION Session, DWORD dwSasType)
static BOOL
StartTaskManager(
IN OUT PWLSESSION Session)
{
Session->SASAction = dwSasType;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
if (Session->LogonStatus == WKSTA_IS_LOGGED_OFF)
return FALSE;
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
CreateProcessW(
L"taskmgr.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread);
return TRUE;
}
void
UninitSAS(PWLSESSION Session)
static BOOL
HandleLogon(
IN OUT PWLSESSION Session)
{
if(Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
PROFILEINFOW ProfileInfo;
LPVOID lpEnvironment = NULL;
BOOLEAN Old;
if (!(Session->Options & WLX_LOGON_OPT_NO_PROFILE))
{
/* Load the user profile */
ProfileInfo.dwSize = sizeof(PROFILEINFOW);
ProfileInfo.dwFlags = 0;
ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName;
ProfileInfo.lpProfilePath = Session->Profile.pszProfile;
ProfileInfo.lpDefaultPath = Session->Profile.pszNetworkDefaultUserProfile;
ProfileInfo.lpServerName = Session->Profile.pszServerName;
ProfileInfo.lpPolicyPath = Session->Profile.pszPolicy;
ProfileInfo.hProfile = NULL;
if (!LoadUserProfileW(Session->UserToken, &ProfileInfo))
{
ERR("WL: LoadUserProfileW() failed\n");
CloseHandle(Session->UserToken);
return FALSE;
}
}
/* Create environment block for the user */
if (!CreateEnvironmentBlock(
&lpEnvironment,
Session->UserToken,
TRUE))
{
ERR("WL: CreateEnvironmentBlock() failed\n");
UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile);
CloseHandle(Session->UserToken);
return FALSE;
}
/* FIXME: use Session->Profile.pszEnvironment */
/* Get privilege */
/* FIXME: who should do it? winlogon or gina? */
/* FIXME: reverting to lower privileges after creating user shell? */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
return Session->MsGina.Functions.WlxActivateUserShell(
Session->MsGina.Context,
L"WinSta0\\Default",//NULL, /* FIXME */
NULL, /* FIXME */
lpEnvironment);
}
BOOL
SetupSAS(PWLSESSION Session, HWND hwndSAS)
static BOOL
HandleLogoff(
IN OUT PWLSESSION Session)
{
/* Register Ctrl+Alt+Del Hotkey */
if(!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE))
{
DPRINT1("WL-SAS: Unable to register Ctrl+Alt+Del hotkey!\n");
return FALSE;
}
/* Register Ctrl+Shift+Esc */
Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE);
if(!Session->TaskManHotkey)
{
DPRINT1("WL-SAS: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n");
}
return TRUE;
FIXME("FIXME: HandleLogoff() unimplemented\n");
return FALSE;
}
BOOL
DestroySAS(PWLSESSION Session, HWND hwndSAS)
static BOOL
HandleShutdown(
IN OUT PWLSESSION Session)
{
/* Unregister hotkeys */
FIXME("FIXME: HandleShutdown() unimplemented\n");
return FALSE;
}
UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL);
static VOID
DoGenericAction(
IN OUT PWLSESSION Session,
IN DWORD wlxAction)
{
switch (wlxAction)
{
case WLX_SAS_ACTION_LOGON: /* 0x01 */
if (HandleLogon(Session))
{
Session->LogonStatus = WKSTA_IS_LOGGED_ON;
SwitchDesktop(WLSession->ApplicationDesktop);
}
break;
case WLX_SAS_ACTION_NONE: /* 0x02 */
break;
case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */
if (Session->MsGina.Functions.WlxIsLockOk(Session->MsGina.Context))
{
SwitchDesktop(WLSession->WinlogonDesktop);
Session->LogonStatus = WKSTA_IS_LOCKED;
Session->MsGina.Functions.WlxDisplayLockedNotice(Session->MsGina.Context);
}
break;
case WLX_SAS_ACTION_LOGOFF: /* 0x04 */
case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */
if (Session->LogonStatus != WKSTA_IS_LOGGED_OFF)
{
if (!Session->MsGina.Functions.WlxIsLogoffOk(Session->MsGina.Context))
break;
SwitchDesktop(WLSession->WinlogonDesktop);
Session->MsGina.Functions.WlxLogoff(Session->MsGina.Context);
HandleLogoff(Session);
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context);
}
if (WLX_SHUTTINGDOWN(wlxAction))
HandleShutdown(Session);
break;
case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
StartTaskManager(Session);
break;
default:
WARN("Unknown SAS action 0x%lx\n", wlxAction);
}
}
if(Session->TaskManHotkey)
{
UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC);
}
VOID
DispatchSAS(
IN OUT PWLSESSION Session,
IN DWORD dwSasType)
{
DWORD wlxAction = WLX_SAS_ACTION_NONE;
return TRUE;
if (Session->LogonStatus == WKSTA_IS_LOGGED_ON)
wlxAction = Session->MsGina.Functions.WlxLoggedOnSAS(Session->MsGina.Context, dwSasType, NULL);
else if (Session->LogonStatus == WKSTA_IS_LOCKED)
wlxAction = Session->MsGina.Functions.WlxWkstaLockedSAS(Session->MsGina.Context, dwSasType);
else
{
/* Display a new dialog (if necessary) */
switch (dwSasType)
{
case WLX_SAS_TYPE_TIMEOUT: /* 0x00 */
{
Session->MsGina.Functions.WlxDisplaySASNotice(Session->MsGina.Context);
break;
}
case WLX_SAS_TYPE_CTRL_ALT_DEL: /* 0x01 */
{
PSID LogonSid = NULL; /* FIXME */
ZeroMemory(&Session->Profile, sizeof(Session->Profile));
Session->Options = 0;
wlxAction = Session->MsGina.Functions.WlxLoggedOutSAS(
Session->MsGina.Context,
Session->SASAction,
&Session->LogonId,
LogonSid,
&Session->Options,
&Session->UserToken,
&Session->MprNotifyInfo,
(PVOID*)&Session->Profile);
break;
}
default:
WARN("Unknown SAS type 0x%lx\n", dwSasType);
}
}
DoGenericAction(Session, wlxAction);
}
static BOOL
RegisterHotKeys(
IN PWLSESSION Session,
IN HWND hwndSAS)
{
/* Register Ctrl+Alt+Del Hotkey */
if (!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE))
{
ERR("WL: Unable to register Ctrl+Alt+Del hotkey!\n");
return FALSE;
}
/* Register Ctrl+Shift+Esc (optional) */
Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE);
if (!Session->TaskManHotkey)
WARN("WL: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n");
return TRUE;
}
static BOOL
UnregisterHotKeys(
IN PWLSESSION Session,
IN HWND hwndSAS)
{
/* Unregister hotkeys */
UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL);
if (Session->TaskManHotkey)
UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC);
return TRUE;
}
#define EWX_ACTION_MASK 0xffffffeb
@ -196,95 +377,115 @@ HandleExitWindows(PWLSESSION Session, DWORD RequestingProcessId, UINT Flags)
return 1;
}
LRESULT CALLBACK
SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static LRESULT CALLBACK
SASWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!Session)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
switch(uMsg)
{
case WM_HOTKEY:
{
switch(wParam)
{
case HK_CTRL_ALT_DEL:
DPRINT1("SAS: CTR+ALT+DEL\n");
break;
case HK_CTRL_SHIFT_ESC:
DPRINT1("SAS: CTR+SHIFT+ESC\n");
break;
}
return 0;
}
case WM_CREATE:
{
/* Get the session pointer from the create data */
Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
/* Save the Session pointer */
SetWindowLongPtr(Session->SASWindow, GWLP_USERDATA, (DWORD_PTR)Session);
switch (uMsg)
{
case WM_HOTKEY:
{
switch (lParam)
{
case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE):
{
TRACE("SAS: CONTROL+ALT+DELETE\n");
DispatchSAS(Session, WLX_SAS_TYPE_CTRL_ALT_DEL);
return TRUE;
}
case MAKELONG(MOD_CONTROL | MOD_SHIFT, VK_ESCAPE):
{
TRACE("SAS: CONTROL+SHIFT+ESCAPE\n");
DoGenericAction(Session, WLX_SAS_ACTION_TASKLIST);
return TRUE;
}
}
break;
}
case WM_CREATE:
{
/* Get the session pointer from the create data */
Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
if(!SetupSAS(Session, hwnd))
{
/* Fail! */
return 1;
}
return 0;
}
case PM_WINLOGON_EXITWINDOWS:
{
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam);
}
case WM_DESTROY:
{
DestroySAS(Session, hwnd);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
/* Save the Session pointer */
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)Session);
return RegisterHotKeys(Session, hwndDlg);
}
case WM_DESTROY:
{
UnregisterHotKeys(Session, hwndDlg);
return TRUE;
}
case PM_WINLOGON_EXITWINDOWS:
{
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam);
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
static VOID
UninitializeSAS(
IN OUT PWLSESSION Session)
{
if (Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
}
BOOL
InitializeSAS(PWLSESSION Session)
InitializeSAS(
IN OUT PWLSESSION Session)
{
WNDCLASSEX swc;
WNDCLASSEX swc;
/* register SAS window class.
WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */
swc.cbSize = sizeof(WNDCLASSEXW);
swc.style = CS_SAVEBITS;
swc.lpfnWndProc = SASProc;
swc.cbClsExtra = 0;
swc.cbWndExtra = 0;
swc.hInstance = hAppInstance;
swc.hIcon = NULL;
swc.hCursor = NULL;
swc.hbrBackground = NULL;
swc.lpszMenuName = NULL;
swc.lpszClassName = WINLOGON_SAS_CLASS;
swc.hIconSm = NULL;
RegisterClassEx(&swc);
/* register SAS window class.
* WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */
swc.cbSize = sizeof(WNDCLASSEXW);
swc.style = CS_SAVEBITS;
swc.lpfnWndProc = SASWindowProc;
swc.cbClsExtra = 0;
swc.cbWndExtra = 0;
swc.hInstance = hAppInstance;
swc.hIcon = NULL;
swc.hCursor = NULL;
swc.hbrBackground = NULL;
swc.lpszMenuName = NULL;
swc.lpszClassName = WINLOGON_SAS_CLASS;
swc.hIconSm = NULL;
RegisterClassEx(&swc); /* FIXME: check return code */
/* create invisible SAS window */
Session->SASWindow = CreateWindowEx(0, WINLOGON_SAS_CLASS, WINLOGON_SAS_TITLE, WS_POPUP,
0, 0, 0, 0, 0, 0, hAppInstance, Session);
if(!Session->SASWindow)
{
DPRINT1("WL: Failed to create SAS window\n");
return FALSE;
}
/* create invisible SAS window */
DPRINT1("Session %p\n", Session);
Session->SASWindow = CreateWindowEx(
0,
WINLOGON_SAS_CLASS,
WINLOGON_SAS_TITLE,
WS_POPUP,
0, 0, 0, 0, 0, 0,
hAppInstance, Session);
if (!Session->SASWindow)
{
ERR("WL: Failed to create SAS window\n");
return FALSE;
}
/* Register SAS window to receive SAS notifications */
if(!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation))
{
UninitSAS(Session);
DPRINT1("WL: Failed to register SAS window\n");
return FALSE;
}
/* Register SAS window to receive SAS notifications */
if (!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation))
{
UninitializeSAS(Session);
ERR("WL: Failed to register SAS window\n");
return FALSE;
}
return TRUE;
return TRUE;
}

View file

@ -3,80 +3,55 @@
* PROJECT: ReactOS Winlogon
* FILE: services/winlogon/winlogon.c
* PURPOSE: Logon
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 22/05/98
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Filip Navara
* Hervé Poussineau (hpoussin@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include "winlogon.h"
#define NDEBUG
#include <debug.h>
#define YDEBUG
#include <wine/debug.h>
/* GLOBALS ******************************************************************/
BOOL
LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion);
PWLSESSION
MsGinaInit(void);
void
SessionLoop(PWLSESSION Session);
BOOL
InitServices(void);
BOOL
WlxCreateWindowStationAndDesktops(PWLSESSION Session);
HINSTANCE hAppInstance;
PWLSESSION WLSession = NULL;
HWND hwndSASWindow = NULL;
/* FUNCTIONS *****************************************************************/
static void
PrintString (WCHAR* fmt,...)
static INT_PTR CALLBACK
ShutdownComputerWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
WCHAR buffer[512];
va_list ap;
va_start(ap, fmt);
wsprintf(buffer, fmt, ap);
va_end(ap);
OutputDebugString(buffer);
switch (uMsg)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
break;
}
break;
}
case WM_INITDIALOG:
{
RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
break;
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
INT_PTR CALLBACK
ShutdownComputerProc (HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
break;
}
break;
}
case WM_INITDIALOG:
{
RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
break;
}
}
return FALSE;
}
static BOOLEAN
StartServices (VOID)
static BOOL
StartServicesManager(void)
{
HANDLE ServicesInitEvent;
BOOLEAN Result;
@ -96,7 +71,7 @@ StartServices (VOID)
StartupInfo.lpReserved2 = 0;
#if 0
PrintString(L"WL: Creating new process - \"services.exe\".\n");
DPRINT1(L"WL: Creating new process - \"services.exe\".\n");
#endif
Result = CreateProcess(NULL,
@ -111,7 +86,7 @@ StartServices (VOID)
&ProcessInformation);
if (!Result)
{
PrintString(L"WL: Failed to execute services\n");
DPRINT1("WL: Failed to execute services\n");
return FALSE;
}
@ -141,66 +116,75 @@ StartServices (VOID)
WaitForSingleObject(ServicesInitEvent, INFINITE);
DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
CloseHandle(ServicesInitEvent);
DPRINT("WL: StartServices() Done.\n");
DPRINT("WL: StartServicesManager() Done.\n");
return TRUE;
}
static BOOLEAN
StartLsass (VOID)
static BOOL
StartCustomService(
IN LPCWSTR ServiceName)
{
HANDLE LsassInitEvent;
BOOLEAN Result;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
WCHAR ServiceString[] = L"lsass.exe";
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
BOOL ret = FALSE;
LsassInitEvent = CreateEvent(NULL,
TRUE,
FALSE,
L"\\SECURITY_SERVICES_STARTED");
hSCManager = OpenSCManager(NULL, NULL, 0);
if (!hSCManager)
goto cleanup;
if (LsassInitEvent == NULL)
{
DPRINT1("WL: Failed to create lsass notification event\n");
return(FALSE);
}
hService = OpenService(hSCManager, ServiceName, SERVICE_START);
if (!hService)
goto cleanup;
#if 0
if (!StartService(hService, 0, NULL))
goto cleanup;
#endif
/* Start the local security authority subsystem (lsass.exe) */
ret = TRUE;
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
Result = CreateProcess(NULL,
ServiceString,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute lsass\n");
return(FALSE);
}
WaitForSingleObject(LsassInitEvent, INFINITE);
CloseHandle(LsassInitEvent);
return(TRUE);
cleanup:
if (hService)
CloseServiceHandle(hService);
if (hSCManager)
CloseServiceHandle(hSCManager);
return ret;
}
static BOOL
StartLsass(VOID)
{
HANDLE LsassInitEvent;
static BOOLEAN
OpenRegistryKey (HKEY *WinLogonKey)
LsassInitEvent = CreateEvent(
NULL,
TRUE,
FALSE,
L"Global\\SECURITY_SERVICES_STARTED");
if (!LsassInitEvent)
{
ERR("WL: Failed to create lsass notification event (error %lu)\n", GetLastError());
return FALSE;
}
/* Start the local security authority subsystem (Netlogon service) */
if (!StartCustomService(L"Netlogon"))
{
ERR("WL: Failed to start NetLogon service (error %lu)\n", GetLastError());
return FALSE;
}
#if 0
WaitForSingleObject(LsassInitEvent, INFINITE);
#endif
CloseHandle(LsassInitEvent);
return TRUE;
}
static BOOL
OpenRegistryKey(
OUT HKEY *WinLogonKey)
{
return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
@ -209,8 +193,10 @@ OpenRegistryKey (HKEY *WinLogonKey)
WinLogonKey);
}
static BOOLEAN StartProcess(PWCHAR ValueName)
#if 0
static BOOL
StartProcess(
IN PWCHAR ValueName)
{
BOOL StartIt;
HKEY WinLogonKey;
@ -239,6 +225,7 @@ static BOOLEAN StartProcess(PWCHAR ValueName)
return StartIt;
}
#endif
/*
static BOOL RestartShell(void)
@ -268,56 +255,10 @@ static BOOL RestartShell(void)
}
*/
VOID STDCALL
RegisterHotKeys(VOID)
{
RegisterHotKey(hwndSASWindow, 0, MOD_ALT | MOD_CONTROL, VK_DELETE);
}
VOID STDCALL
UnregisterHotKeys(VOID)
{
UnregisterHotKey(NULL, 0);
}
VOID STDCALL
HandleHotKey(MSG *Msg)
{
DPRINT1("HOTKEY: Got hot key (%d)\n", Msg->wParam);
/* CTRL-ALT-DEL */
if (Msg->wParam == 0)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
CreateProcessW(
L"taskmgr.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread);
}
}
static PWCHAR
GetUserInit (WCHAR *CommandLine)
GetUserInit(
OUT WCHAR *CommandLine,
IN DWORD BufferLength)
{
HKEY WinLogonKey;
BOOL GotCommandLine;
@ -360,9 +301,10 @@ GetUserInit (WCHAR *CommandLine)
}
static BOOL
DoLogonUser (PWCHAR Name,
PWCHAR Password)
BOOL
DoBrokenLogonUser(
IN PWLSESSION WLSession,
IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo)
{
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
@ -372,24 +314,14 @@ DoLogonUser (PWCHAR Name,
BOOL Result;
LPVOID lpEnvironment = NULL;
MSG Msg;
BOOLEAN Old;
Result = LogonUserW (Name,
NULL,
Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&WLSession->UserToken);
if (!Result)
{
DPRINT1 ("WL: LogonUserW() failed\n");
RtlDestroyEnvironment (lpEnvironment);
return FALSE;
}
SwitchDesktop(WLSession->ApplicationDesktop);
/* Load the user profile */
ProfileInfo.dwSize = sizeof(PROFILEINFOW);
ProfileInfo.dwFlags = 0;
ProfileInfo.lpUserName = Name;
ProfileInfo.lpUserName = pMprNotifyInfo->pszUserName;
ProfileInfo.lpProfilePath = NULL;
ProfileInfo.lpDefaultPath = NULL;
ProfileInfo.lpServerName = NULL;
@ -428,10 +360,14 @@ DoLogonUser (PWCHAR Name,
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
/* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
Result = CreateProcessAsUserW (WLSession->UserToken,
Result = CreateProcessAsUserW(
WLSession->UserToken,
NULL,
GetUserInit (CommandLine),
GetUserInit (CommandLine, MAX_PATH),
NULL,
NULL,
FALSE,
@ -442,7 +378,7 @@ DoLogonUser (PWCHAR Name,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute user shell %s\n", CommandLine);
DPRINT1("WL: Failed to execute user shell %ws\n", CommandLine);
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, FALSE);
@ -454,20 +390,20 @@ DoLogonUser (PWCHAR Name,
DestroyEnvironmentBlock (lpEnvironment);
return FALSE;
}
RegisterHotKeys();
/*WLSession->MsGina.Functions.WlxActivateUserShell(WLSession->MsGina.Context,
L"WinSta0\\Default",
NULL,
NULL);*/
while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
{
if (PeekMessage(&Msg, hwndSASWindow, 0, 0, PM_REMOVE))
if (PeekMessage(&Msg, WLSession->SASWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
UnregisterHotKeys();
CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread);
@ -488,264 +424,36 @@ DoLogonUser (PWCHAR Name,
return TRUE;
}
static LRESULT CALLBACK
SASWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
static BOOL
DisplayStatusMessage(
IN PWLSESSION Session,
IN HDESK hDesktop,
IN UINT ResourceId)
{
DbgBreakPoint();
switch (uMsg)
{
case WM_HOTKEY:
{
switch (lParam)
{
case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE):
{
DispatchSAS(WLSession, WLX_SAS_TYPE_CTRL_ALT_DEL);
return TRUE;
}
}
}
}
WCHAR StatusMsg[MAX_PATH];
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
if (Session->SuppressStatus)
return TRUE;
if (LoadString(hAppInstance, ResourceId, StatusMsg, MAX_PATH) == 0)
return FALSE;
return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, 0, NULL, StatusMsg);
}
int STDCALL
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
BOOLEAN Old;
WNDCLASS wndClass;
#if 0
LSA_STRING ProcessName, PackageName;
HANDLE LsaHandle;
LSA_OPERATIONAL_MODE Mode;
ULONG AuthenticationPackage;
#endif
hAppInstance = hInstance;
if(!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
{
DPRINT1("WL: Could not register logon process\n");
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
return 0;
}
/* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
if (StartProcess(L"StartLsass"))
{
if (!StartLsass())
{
DPRINT1("WL: Failed to start LSASS (0x%X)\n", GetLastError());
}
}
else
{
DPRINT1("WL: StartProcess() failed!\n");
}
if(!(WLSession = MsGinaInit()))
{
DPRINT1("WL: Failed to initialize msgina.dll\n");
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
return 0;
}
WLSession->LogonStatus = LOGON_INITIALIZING;
if(!WlxCreateWindowStationAndDesktops(WLSession))
{
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1);
return 1;
}
/*
* Switch to winlogon desktop
*/
/* FIXME: Do start up in the application desktop for now. */
SetThreadDesktop(WLSession->ApplicationDesktop);
if(!SwitchDesktop(WLSession->ApplicationDesktop))
{
DPRINT1("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError());
}
InitServices();
/* Check for pending setup */
if (GetSetupType () != 0)
{
DPRINT("Winlogon: CheckForSetup() in setup mode\n");
/* Run setup and reboot when done */
RunSetup();
NtShutdownSystem(ShutdownReboot);
ExitProcess(0);
return 0;
}
if(!InitializeSAS(WLSession))
{
DPRINT1("WL: Failed to initialize SAS\n");
ExitProcess(2);
return 2;
}
#if 0
/* real winlogon uses "Winlogon" */
RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon");
Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
if (!NT_SUCCESS(Status))
{
switch(Status)
{
case STATUS_PORT_CONNECTION_REFUSED:
/* FIXME - we don't have the 'SeTcbPrivilege' pivilege, so set it or call
LsaAddAccountRights() and try again */
DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_PORT_CONNECTION_REFUSED\n");
break;
case STATUS_NAME_TOO_LONG:
DPRINT1("WL: LsaRegisterLogonProcess() returned STATUS_NAME_TOO_LONG\n");
break;
default:
DPRINT1("WL: Failed to connect to LSASS\n");
break;
}
return(1);
}
RtlInitUnicodeString((PUNICODE_STRING)&PackageName, L"Kerberos");
Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage);
if (!NT_SUCCESS(Status))
{
LsaDeregisterLogonProcess(LsaHandle);
DPRINT1("WL: Failed to lookup authentication package\n");
return(1);
}
#endif
/* FIXME: Create a window class and associate a Winlogon
* window procedure with it.
* Register SAS with the window.
* Register for logoff notification
*/
/* Create a window class */
ZeroMemory(&wndClass, sizeof(WNDCLASS));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = SASWindowProc;
wndClass.hInstance = hInstance;
wndClass.lpszClassName = L"SAS Window class";
RegisterClass(&wndClass);
hwndSASWindow = CreateWindow(
L"SAS Window class", L"SAS window", 0,
0, 0, 0, 0,
NULL, NULL, hInstance, NULL);
/* Main loop */
#if 0
/* Display login prompt */
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
LoginPrompt,
strlen(LoginPrompt), // wcslen(LoginPrompt),
&Result,
NULL);
i = 0;
do
{
ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
&LoginName[i],
1,
&Result,
NULL);
i++;
} while (LoginName[i - 1] != '\n');
LoginName[i - 1] = 0;
/* Display password prompt */
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
PasswordPrompt,
strlen(PasswordPrompt), // wcslen(PasswordPrompt),
&Result,
NULL);
i = 0;
do
{
ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
&Password[i],
1,
&Result,
NULL);
i++;
} while (Password[i - 1] != '\n');
Password[i - 1] =0;
#endif
RegisterHotKeys();
SessionLoop(WLSession);
UnregisterHotKeys();
/* FIXME - Flush disks and registry, ... */
if(WLSession->LogonStatus == LOGON_SHUTDOWN)
{
/* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerProc))
{
case IDC_BTNSHTDOWNCOMPUTER:
NtShutdownSystem(ShutdownReboot);
break;
default:
NtShutdownSystem(ShutdownNoReboot);
break;
}
ExitProcess(0);
}
else
{
DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
ExitProcess(0);
}
return 0;
}
BOOL
DisplayStatusMessage(PWLSESSION Session, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
static BOOL
InitServices(VOID)
{
if(Session->SuppressStatus)
{
return TRUE;
}
return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage);
}
BOOL
InitServices(void)
{
WCHAR StatusMsg[256];
/*WCHAR StatusMsg[256];
LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR));
DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);
DisplayStatusMessage(WLSession, WLSession->ApplicationDesktop, 0, NULL, StatusMsg);*/
/* start system processes (services.exe & lsass.exe) */
if(StartProcess(L"StartServices"))
{
if(!StartServices())
if(!StartServicesManager())
{
DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError());
}
@ -757,9 +465,12 @@ InitServices(void)
return TRUE;
}
#endif
DWORD
DoLogin(PWLSESSION Session)
#if 0
static DWORD
DoLogin(
IN OUT PWLSESSION Session)
{
DWORD WlxAction, Options;
WLX_MPR_NOTIFY_INFO MprNotifyInfo;
@ -784,66 +495,38 @@ DoLogin(PWLSESSION Session)
&MprNotifyInfo,
(PVOID*)&Profile);
if (WlxAction == WLX_SAS_ACTION_LOGON)
{
Session->UserToken = Token;
if (!DoBrokenLogonUser(Session, &MprNotifyInfo))
WlxAction = WLX_SAS_ACTION_NONE;
}
return WlxAction;
}
#endif
void
SessionLoop(PWLSESSION Session)
static VOID
SessionLoop(
IN OUT PWLSESSION Session)
{
//WCHAR StatusMsg[256];
// HANDLE hShutdownEvent;
DWORD WlxAction;
MSG Msg;
//WCHAR StatusMsg[256];
//HANDLE hShutdownEvent;
MSG Msg;
WlxAction = WLX_SAS_ACTION_NONE;
Session->LogonStatus = LOGON_NONE;
while(WlxAction == WLX_SAS_ACTION_NONE)
{
RemoveStatusMessage(Session);
if(Session->LogonStatus == LOGON_NONE)
{
Session->LogonStatus = LOGON_SHOWINGLOGON;
/* we're ready to display a logon window,
don't timeout dialogboxes here */
WlxSetTimeout(Session->MsGina.Context, 0);
Session->SuppressStatus = TRUE;
/* tell msgina to show a window telling the user one can logon */
DisplaySASNotice(Session);
Session->SuppressStatus = FALSE;
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
RemoveStatusMessage(Session);
DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
{
/* the system wants to log off here */
Session->LogonStatus = LOGON_SHUTDOWN;
break;
}
}
/* Message loop for the SAS window */
while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
WlxAction = DoLogin(Session);
if (WlxAction == WLX_SAS_ACTION_LOGON)
{
DoLogonUser(L"Administrator", L"Secret");
}
else if(WlxAction == WLX_SAS_ACTION_LOGOFF)
{
/* the user doesn't want to login, instead pressed cancel
we should display the window again so one can logon again */
/* FIXME - disconnect any connections in case we did a remote logon */
DPRINT1("WL: DoLogin failed\n");
WlxAction = WLX_SAS_ACTION_NONE;
}
if(WlxAction == WLX_SAS_ACTION_NONE)
{
if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
{
/* system is about to shut down, leave the main loop */
Session->LogonStatus = LOGON_SHUTDOWN;
break;
}
Session->LogonStatus = LOGON_NONE;
continue;
}
/* Don't go there! */
#if 0
/* FIXME - don't leave the loop when suspending the computer */
if(WLX_SUSPENDING(WlxAction))
{
@ -860,13 +543,7 @@ SessionLoop(PWLSESSION Session)
break;
}
/* Message loop for the SAS window */
while(GetMessage(&Msg, hwndSASWindow, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
#endif
/*
LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR));
MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context,
@ -958,3 +635,145 @@ SessionLoop(PWLSESSION Session)
*/
}
int WINAPI
WinMain(
IN HINSTANCE hInstance,
IN HINSTANCE hPrevInstance,
IN LPSTR lpCmdLine,
IN int nShowCmd)
{
#if 0
LSA_STRING ProcessName, PackageName;
HANDLE LsaHandle;
LSA_OPERATIONAL_MODE Mode;
BOOLEAN Old;
ULONG AuthenticationPackage;
NTSTATUS Status;
#endif
hAppInstance = hInstance;
if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE))
{
ERR("WL: Could not register logon process\n");
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
return 0;
}
WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION));
if (!WLSession)
{
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1);
return 1;
}
if (!CreateWindowStationAndDesktops(WLSession))
{
NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0);
ExitProcess(1);
return 1;
}
/* Check for pending setup */
if (GetSetupType() != 0)
{
DPRINT("Winlogon: CheckForSetup() in setup mode\n");
/* Run setup and reboot when done */
SwitchDesktop(WLSession->ApplicationDesktop);
RunSetup();
NtShutdownSystem(ShutdownReboot);
ExitProcess(0);
return 0;
}
/* Load and initialize gina */
if (!GinaInit(WLSession))
{
ERR("WL: Failed to initialize Gina\n");
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
return 0;
}
DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
if (!StartServicesManager())
{
ERR("WL: Could not start services.exe\n");
NtShutdownSystem(ShutdownNoReboot);
ExitProcess(0);
return 0;
}
if (!StartLsass())
{
DPRINT1("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError());
return 1;
}
#if 0
/* Connect to NetLogon service (lsass.exe) */
/* Real winlogon uses "Winlogon" */
RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon");
Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
if (Status == STATUS_PORT_CONNECTION_REFUSED)
{
/* Add the 'SeTcbPrivilege' privilege and try again */
RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old);
Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
}
if (!NT_SUCCESS(Status))
{
ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status));
return 1;
}
RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W);
Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage);
if (!NT_SUCCESS(Status))
{
ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status));
LsaDeregisterLogonProcess(LsaHandle);
return 1;
}
#endif
/* Create a hidden window to get SAS notifications */
if (!InitializeSAS(WLSession))
{
ERR("WL: Failed to initialize SAS\n");
ExitProcess(2);
return 2;
}
/* Main loop */
SessionLoop(WLSession);
/* FIXME - Flush disks and registry, ... */
if(WLSession->LogonStatus == 0)
{
/* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
switch(DialogBox(hInstance, MAKEINTRESOURCE(IDD_SHUTDOWNCOMPUTER), 0, ShutdownComputerWindowProc))
{
case IDC_BTNSHTDOWNCOMPUTER:
NtShutdownSystem(ShutdownReboot);
break;
default:
NtShutdownSystem(ShutdownNoReboot);
break;
}
ExitProcess(0);
}
else
{
DPRINT1("WL: LogonStatus != LOGON_SHUTDOWN!!!\n");
ExitProcess(0);
}
return 0;
}

View file

@ -34,40 +34,13 @@
#include <rtlfuncs.h>
#include <exfuncs.h>
#include <setypes.h>
#include <ntsecapi.h>
#include <reactos/winlogon.h>
#include "setup.h"
#include "resource.h"
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);
VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext);
VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType);
BOOL WINAPI WlxSetTimeout(HANDLE hWlx, DWORD Timeout);
int WINAPI WlxAssignShellProtection(HANDLE hWlx, HANDLE hToken, HANDLE hProcess, HANDLE hThread);
int WINAPI WlxMessageBox(HANDLE hWlx, HWND hwndOwner, LPWSTR lpszText, LPWSTR lpszTitle, UINT fuStyle);
int WINAPI WlxDialogBox(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc);
int WINAPI WlxDialogBoxParam(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam);
int WINAPI WlxDialogBoxIndirect(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc);
int WINAPI WlxDialogBoxIndirectParam(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam);
int WINAPI WlxSwitchDesktopToUser(HANDLE hWlx);
int WINAPI WlxSwitchDesktopToWinlogon(HANDLE hWlx);
int WINAPI WlxChangePasswordNotify(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo);
BOOL WINAPI WlxGetSourceDesktop(HANDLE hWlx, PWLX_DESKTOP* ppDesktop);
BOOL WINAPI WlxSetReturnDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop);
BOOL WINAPI WlxCreateUserDesktop(HANDLE hWlx, HANDLE hToken, DWORD Flags, PWSTR pszDesktopName, PWLX_DESKTOP* ppDesktop);
int WINAPI WlxChangePasswordNotifyEx(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo, PWSTR ProviderName, PVOID Reserved);
BOOL WINAPI WlxCloseUserDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop, HANDLE hToken);
BOOL WINAPI WlxSetOption(HANDLE hWlx, DWORD Option, ULONG_PTR Value, ULONG_PTR* OldValue);
BOOL WINAPI WlxGetOption(HANDLE hWlx, DWORD Option, ULONG_PTR* Value);
VOID WINAPI WlxWin31Migrate(HANDLE hWlx);
BOOL WINAPI WlxQueryClientCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred);
BOOL WINAPI WlxQueryInetConnectorCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred);
DWORD WINAPI WlxQueryConsoleSwitchCredentials(PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred);
BOOL WINAPI WlxQueryTsLogonCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred);
BOOL WINAPI WlxDisconnect(void);
DWORD WINAPI WlxQueryTerminalServicesData(HANDLE hWlx, PWLX_TERMINAL_SERVICES_DATA pTSData, WCHAR* UserName, WCHAR* Domain);
typedef BOOL (WINAPI * PFWLXNEGOTIATE) (DWORD, DWORD *);
typedef BOOL (WINAPI * PFWLXINITIALIZE) (LPWSTR, HANDLE, PVOID, PVOID, PVOID *);
typedef VOID (WINAPI * PFWLXDISPLAYSASNOTICE) (PVOID);
@ -97,36 +70,50 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID);
typedef struct _MSGINAFUNCTIONS
{
PFWLXNEGOTIATE WlxNegotiate;
PFWLXINITIALIZE WlxInitialize;
PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice;
PFWLXLOGGEDOUTSAS WlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL WlxActivateUserShell;
PFWLXLOGGEDONSAS WlxLoggedOnSAS;
PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice;
PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS;
PFWLXISLOCKOK WlxIsLockOk;
PFWLXISLOGOFFOK WlxIsLogoffOk;
PFWLXLOGOFF WlxLogoff;
PFWLXSHUTDOWN WlxShutdown;
/* Functions always available for a valid GINA */
PFWLXNEGOTIATE WlxNegotiate;
PFWLXINITIALIZE WlxInitialize;
PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify;
PFWLXSTARTAPPLICATION WlxStartApplication;
/* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */
PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice;
PFWLXLOGGEDOUTSAS WlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL WlxActivateUserShell;
PFWLXLOGGEDONSAS WlxLoggedOnSAS;
PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice;
PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS;
PFWLXISLOCKOK WlxIsLockOk;
PFWLXISLOGOFFOK WlxIsLogoffOk;
PFWLXLOGOFF WlxLogoff;
PFWLXSHUTDOWN WlxShutdown;
PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad;
PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage;
PFWLXGETSTATUSMESSAGE WlxGetStatusMessage;
PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage;
/* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */
PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify;
PFWLXSTARTAPPLICATION WlxStartApplication;
/* Functions available if WlxVersion >= WLX_VERSION_1_2 (MS Windows NT 4.0) */
/* Functions available if WlxVersion >= WLX_VERSION_1_3 (MS Windows 2000) */
PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad;
PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage;
PFWLXGETSTATUSMESSAGE WlxGetStatusMessage;
PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage;
/* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */
} MSGINAFUNCTIONS, *PMSGINAFUNCTIONS;
typedef struct _MSGINAINSTANCE
{
HMODULE hDllInstance;
MSGINAFUNCTIONS Functions;
PVOID Context;
DWORD Version;
HMODULE hDllInstance;
MSGINAFUNCTIONS Functions;
PVOID Context;
DWORD Version;
} MSGINAINSTANCE, *PMSGINAINSTANCE;
/* FIXME: put in an enum */
#define WKSTA_IS_LOGGED_OFF 0
#define WKSTA_IS_LOGGED_ON 1
#define WKSTA_IS_LOCKED 2
typedef struct _WLSESSION
{
MSGINAINSTANCE MsGina;
@ -142,22 +129,16 @@ typedef struct _WLSESSION
HDESK ScreenSaverDesktop;
LUID LogonId;
HANDLE UserToken;
/* Logon informations */
DWORD Options;
WLX_MPR_NOTIFY_INFO MprNotifyInfo;
WLX_PROFILE_V2_0 Profile;
} WLSESSION, *PWLSESSION;
extern HINSTANCE hAppInstance;
extern PWLSESSION WLSession;
BOOL
InitializeSAS(PWLSESSION Session);
void
DispatchSAS(PWLSESSION Session, DWORD dwSasType);
#define LOGON_INITIALIZING 1
#define LOGON_NONE 2
#define LOGON_SHOWINGLOGON 3
#define LOGON_SHUTDOWN 9
#define WLX_SHUTTINGDOWN(Status) \
(((Status) == WLX_SAS_ACTION_SHUTDOWN) || \
((Status) == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) || \
@ -180,6 +161,51 @@ BOOL WINAPI
UpdatePerUserSystemParameters(DWORD dwUnknown,
DWORD dwReserved);
/* sas.c */
VOID
DispatchSAS(
IN OUT PWLSESSION Session,
IN DWORD dwSasType);
BOOL
InitializeSAS(
IN OUT PWLSESSION Session);
/* wlx.c */
BOOL
GinaInit(
IN OUT PWLSESSION Session);
BOOL
CreateWindowStationAndDesktops(
IN OUT PWLSESSION Session);
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);
VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext);
VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType);
BOOL WINAPI WlxSetTimeout(HANDLE hWlx, DWORD Timeout);
int WINAPI WlxAssignShellProtection(HANDLE hWlx, HANDLE hToken, HANDLE hProcess, HANDLE hThread);
int WINAPI WlxMessageBox(HANDLE hWlx, HWND hwndOwner, LPWSTR lpszText, LPWSTR lpszTitle, UINT fuStyle);
int WINAPI WlxDialogBox(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc);
int WINAPI WlxDialogBoxParam(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam);
int WINAPI WlxDialogBoxIndirect(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc);
int WINAPI WlxDialogBoxIndirectParam(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam);
int WINAPI WlxSwitchDesktopToUser(HANDLE hWlx);
int WINAPI WlxSwitchDesktopToWinlogon(HANDLE hWlx);
int WINAPI WlxChangePasswordNotify(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo);
BOOL WINAPI WlxGetSourceDesktop(HANDLE hWlx, PWLX_DESKTOP* ppDesktop);
BOOL WINAPI WlxSetReturnDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop);
BOOL WINAPI WlxCreateUserDesktop(HANDLE hWlx, HANDLE hToken, DWORD Flags, PWSTR pszDesktopName, PWLX_DESKTOP* ppDesktop);
int WINAPI WlxChangePasswordNotifyEx(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo, PWSTR ProviderName, PVOID Reserved);
BOOL WINAPI WlxCloseUserDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop, HANDLE hToken);
BOOL WINAPI WlxSetOption(HANDLE hWlx, DWORD Option, ULONG_PTR Value, ULONG_PTR* OldValue);
BOOL WINAPI WlxGetOption(HANDLE hWlx, DWORD Option, ULONG_PTR* Value);
VOID WINAPI WlxWin31Migrate(HANDLE hWlx);
BOOL WINAPI WlxQueryClientCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred);
BOOL WINAPI WlxQueryInetConnectorCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred);
DWORD WINAPI WlxQueryConsoleSwitchCredentials(PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred);
BOOL WINAPI WlxQueryTsLogonCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred);
BOOL WINAPI WlxDisconnect(VOID);
DWORD WINAPI WlxQueryTerminalServicesData(HANDLE hWlx, PWLX_TERMINAL_SERVICES_DATA pTSData, WCHAR* UserName, WCHAR* Domain);
#endif /* __WINLOGON_MAIN_H__ */
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,380 @@
/*
* PROJECT: ReactOS msgina.dll
* FILE: dll/win32/msgina/gui.c
* PURPOSE: ReactOS Logon GINA DLL
* PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
*/
#include "msgina.h"
#include <debug.h>
#define TRACE DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#define FIXME DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#define WARN DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#undef DPRINT
#undef DPRINT1
typedef struct _DISPLAYSTATUSMSG
{
PGINA_CONTEXT Context;
HDESK hDesktop;
DWORD dwOptions;
PWSTR pTitle;
PWSTR pMessage;
HANDLE StartupEvent;
} DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG;
static BOOL
GUIInitialize(
IN OUT PGINA_CONTEXT pgContext)
{
TRACE("GUIInitialize(%p)\n", pgContext);
return TRUE;
}
static BOOL CALLBACK
StatusMessageWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam;
if (!msg)
return FALSE;
msg->Context->hStatusWindow = hwndDlg;
if (msg->pTitle)
SetWindowText(hwndDlg, msg->pTitle);
SetDlgItemText(hwndDlg, IDC_STATUSLABEL, msg->pMessage);
if (!msg->Context->SignaledStatusWindowCreated)
{
msg->Context->SignaledStatusWindowCreated = TRUE;
SetEvent(msg->StartupEvent);
}
break;
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
static DWORD WINAPI
StartupWindowThread(LPVOID lpParam)
{
HDESK OldDesk;
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam;
OldDesk = GetThreadDesktop(GetCurrentThreadId());
if(!SetThreadDesktop(msg->hDesktop))
{
HeapFree(GetProcessHeap(), 0, lpParam);
return FALSE;
}
DialogBoxParam(
hDllInstance,
MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG),
0,
StatusMessageWindowProc,
(LPARAM)lpParam);
SetThreadDesktop(OldDesk);
msg->Context->hStatusWindow = 0;
msg->Context->SignaledStatusWindowCreated = FALSE;
HeapFree(GetProcessHeap(), 0, lpParam);
return TRUE;
}
static BOOL
GUIDisplayStatusMessage(
IN PGINA_CONTEXT pgContext,
IN HDESK hDesktop,
IN DWORD dwOptions,
IN PWSTR pTitle,
IN PWSTR pMessage)
{
PDISPLAYSTATUSMSG msg;
HANDLE Thread;
DWORD ThreadId;
TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage);
if (!pgContext->hStatusWindow)
{
msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG));
if(!msg)
return FALSE;
msg->Context = pgContext;
msg->dwOptions = dwOptions;
msg->pTitle = pTitle;
msg->pMessage = pMessage;
msg->hDesktop = hDesktop;
msg->StartupEvent = CreateEvent(
NULL,
TRUE,
FALSE,
NULL);
if (!msg->StartupEvent)
return FALSE;
Thread = CreateThread(
NULL,
0,
StartupWindowThread,
(PVOID)msg,
0,
&ThreadId);
if (Thread)
{
CloseHandle(Thread);
WaitForSingleObject(msg->StartupEvent, INFINITE);
CloseHandle(msg->StartupEvent);
return TRUE;
}
return FALSE;
}
if(pTitle)
SetWindowText(pgContext->hStatusWindow, pTitle);
SetDlgItemText(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage);
return TRUE;
}
static VOID
GUIDisplaySASNotice(
IN OUT PGINA_CONTEXT pgContext)
{
int result;
TRACE("GUIDisplaySASNotice()\n");
/* Display the notice window */
result = pgContext->pWlxFuncs->WlxDialogBoxParam(
pgContext->hWlx,
pgContext->hDllInstance,
MAKEINTRESOURCE(IDD_NOTICE_DLG),
NULL,
(DLGPROC)DefWindowProc,
(LPARAM)NULL);
if (result == -1)
{
/* Failed to display the window. Do as if the user
* already has pressed CTRL+ALT+DELETE */
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
}
}
/* Get the text contained in a textbox. Allocates memory in pText
* to contain the text. Returns TRUE in case of success */
static BOOL
GetTextboxText(
IN HWND hwndDlg,
IN INT TextboxId,
OUT LPWSTR *pText)
{
LPWSTR Text;
int Count;
Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId));
Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR));
if (!Text)
return FALSE;
if (Count != GetWindowText(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1))
{
HeapFree(GetProcessHeap(), 0, Text);
return FALSE;
}
*pText = Text;
return TRUE;
}
static INT_PTR CALLBACK
LoggedOutWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
/* FIXME: take care of DontDisplayLastUserName, NoDomainUI, ShutdownWithoutLogon */
SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)lParam);
SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME));
break;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDOK:
{
PGINA_CONTEXT pgContext;
LPWSTR UserName = NULL, Password = NULL;
INT result = WLX_SAS_ACTION_NONE;
pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
break;
if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
DoLoginTasks(pgContext, UserName, NULL, Password))
{
result = WLX_SAS_ACTION_LOGON;
}
HeapFree(GetProcessHeap(), 0, UserName);
HeapFree(GetProcessHeap(), 0, Password);
EndDialog(hwndDlg, result);
return TRUE;
}
case IDCANCEL:
{
EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
return TRUE;
}
case IDC_SHUTDOWN:
{
EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
return TRUE;
}
}
break;
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
static INT_PTR CALLBACK
LoggedOnWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDYES:
case IDNO:
{
EndDialog(hwndDlg, LOWORD(wParam));
break;
}
}
return TRUE;
}
case WM_INITDIALOG:
{
SetFocus(GetDlgItem(hwndDlg, IDNO));
break;
}
case WM_CLOSE:
{
EndDialog(hwndDlg, IDNO);
return TRUE;
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
static INT
GUILoggedOnSAS(
IN OUT PGINA_CONTEXT pgContext,
IN DWORD dwSasType)
{
INT SasAction = WLX_SAS_ACTION_NONE;
TRACE("GUILoggedOnSAS()\n");
switch (dwSasType)
{
case WLX_SAS_TYPE_CTRL_ALT_DEL:
{
INT result;
/* Display "Are you sure you want to log off?" dialog */
result = pgContext->pWlxFuncs->WlxDialogBoxParam(
pgContext->hWlx,
pgContext->hDllInstance,
MAKEINTRESOURCE(IDD_LOGGEDON_DLG),
NULL,
LoggedOnWindowProc,
(LPARAM)pgContext);
if (result == IDOK)
SasAction = WLX_SAS_ACTION_LOCK_WKSTA;
break;
}
case WLX_SAS_TYPE_SC_INSERT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
break;
}
case WLX_SAS_TYPE_SC_REMOVE:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
break;
}
case WLX_SAS_TYPE_TIMEOUT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
break;
}
default:
{
WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
break;
}
}
return SasAction;
}
static INT
GUILoggedOutSAS(
IN OUT PGINA_CONTEXT pgContext)
{
int result;
TRACE("GUILoggedOutSAS()\n");
result = pgContext->pWlxFuncs->WlxDialogBoxParam(
pgContext->hWlx,
pgContext->hDllInstance,
MAKEINTRESOURCE(IDD_LOGGEDOUT_DLG),
NULL,
LoggedOutWindowProc,
(LPARAM)pgContext);
if (result >= WLX_SAS_ACTION_LOGON &&
result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
{
WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
return result;
}
WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
return WLX_SAS_ACTION_NONE;
}
GINA_UI GinaGraphicalUI = {
GUIInitialize,
GUIDisplayStatusMessage,
GUIDisplaySASNotice,
GUILoggedOnSAS,
GUILoggedOutSAS,
};

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
* ReactOS GINA
* Copyright (C) 2003-2004, 2006 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
@ -16,88 +16,78 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
/*
* PROJECT: ReactOS msgina.dll
* FILE: lib/msgina/msgina.c
* FILE: dll/win32/msgina/msgina.c
* PURPOSE: ReactOS Logon GINA DLL
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY:
* 24-11-2003 Created
* Hervé Poussineau (hpoussin@reactos.org)
*/
#include <windows.h>
#include <winwlx.h>
#include "msgina.h"
#include "resource.h"
#include <wine/debug.h>
extern HINSTANCE hDllInstance;
typedef struct _DISPLAYSTATUSMSG
{
PGINA_CONTEXT Context;
HDESK hDesktop;
DWORD dwOptions;
PWSTR pTitle;
PWSTR pMessage;
HANDLE StartupEvent;
} DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG;
INT_PTR CALLBACK
LoggedOnDlgProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDYES:
case IDNO:
{
EndDialog(hwndDlg, LOWORD(wParam));
break;
}
}
return FALSE;
}
case WM_INITDIALOG:
{
SetFocus(GetDlgItem(hwndDlg, IDNO));
break;
}
case WM_CLOSE:
{
EndDialog(hwndDlg, IDNO);
return TRUE;
}
}
return FALSE;
}
extern GINA_UI GinaGraphicalUI;
extern GINA_UI GinaTextUI;
static PGINA_UI pGinaUI = &GinaGraphicalUI; /* Default value */
/*
* @implemented
*/
BOOL WINAPI
WlxNegotiate(
DWORD dwWinlogonVersion,
PDWORD pdwDllVersion)
IN DWORD dwWinlogonVersion,
OUT PDWORD pdwDllVersion)
{
if(!pdwDllVersion || (dwWinlogonVersion < GINA_VERSION))
return FALSE;
*pdwDllVersion = GINA_VERSION;
return TRUE;
DPRINT1("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion);
if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3))
return FALSE;
*pdwDllVersion = WLX_VERSION_1_3;
return TRUE;
}
static BOOL
ChooseGinaUI(VOID)
{
HKEY WinLogonKey = NULL;
DWORD Type, Size, Value;
LONG rc;
rc = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
0,
KEY_QUERY_VALUE,
&WinLogonKey);
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;
if (Value != 0)
pGinaUI = &GinaGraphicalUI;
else
pGinaUI = &GinaTextUI;
cleanup:
if (WinLogonKey != NULL)
RegCloseKey(WinLogonKey);
}
/*
* @implemented
@ -122,7 +112,7 @@ WlxInitialize(
pgContext->hDllInstance = hDllInstance;
/* save pointer to dispatch table */
pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION)pWinlogonFunctions;
pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions;
/* save the winlogon handle used to call the dispatch functions */
pgContext->hWlx = hWlx;
@ -136,7 +126,13 @@ WlxInitialize(
/* notify winlogon that we will use the default SAS */
pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);
return TRUE;
/* Locates the authentification package */
//LsaRegisterLogonProcess(...);
pgContext->DoAutoLogonOnce = FALSE;
ChooseGinaUI();
return pGinaUI->Initialize(pgContext);
}
@ -193,13 +189,14 @@ WlxActivateUserShell(
PVOID pEnvironment)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
STARTUPINFO si;
PROCESS_INFORMATION pi;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
HKEY hKey;
DWORD BufSize, ValueType;
WCHAR pszUserInitApp[MAX_PATH];
WCHAR pszExpUserInitApp[MAX_PATH];
BOOL Ret;
WCHAR CurrentDirectory[MAX_PATH];
/* get the path of userinit */
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
@ -222,31 +219,34 @@ WlxActivateUserShell(
/* start userinit */
/* FIXME - allow to start more applications that are comma-separated */
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = L"userinit";
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0;
si.dwFlags = 0;
si.wShowWindow = SW_SHOW;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
si.lpDesktop = pszDesktopName;
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = pszDesktopName;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.lpReserved2 = NULL;
StartupInfo.cbReserved2 = 0;
StartupInfo.dwX = StartupInfo.dwY = StartupInfo.dwXSize = StartupInfo.dwYSize = 0;
StartupInfo.wShowWindow = SW_SHOW;
ExpandEnvironmentStrings(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
Ret = CreateProcessAsUser(pgContext->UserToken,
pszExpUserInitApp,
NULL,
pszExpUserInitApp,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
pEnvironment,
NULL,
&si,
&pi);
if(!Ret) ERR("GINA: Failed: 3\n");
CurrentDirectory,
&StartupInfo,
&ProcessInformation);
if(!Ret) ERR("GINA: Failed: 3, error %lu\n", GetLastError());
VirtualFree(pEnvironment, 0, MEM_RELEASE);
Ret = pgContext->pWlxFuncs->WlxSwitchDesktopToUser(pgContext->hWlx);
if(!Ret) ERR("GINA: Failed: 4, error %lu\n", GetLastError());
return Ret;
}
@ -260,303 +260,295 @@ WlxLoggedOnSAS(
DWORD dwSasType,
PVOID pReserved)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
int SasAction = WLX_SAS_ACTION_NONE;
switch(dwSasType)
{
case WLX_SAS_TYPE_CTRL_ALT_DEL:
{
int Result;
/* display "Are you sure you want to log off?" dialog */
Result = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
pgContext->hDllInstance,
(LPTSTR)IDD_LOGOFF_DLG,
NULL,
LoggedOnDlgProc,
(LPARAM)pgContext);
if(Result == IDOK)
{
SasAction = WLX_SAS_ACTION_LOCK_WKSTA;
}
break;
}
case WLX_SAS_TYPE_SC_INSERT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
break;
}
case WLX_SAS_TYPE_SC_REMOVE:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
break;
}
case WLX_SAS_TYPE_TIMEOUT:
{
FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
break;
}
default:
{
WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
break;
}
}
return SasAction;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
DPRINT1("WlxLoggedOnSAS(0x%lx)\n", dwSasType);
return pGinaUI->LoggedOnSAS(pgContext, dwSasType);
}
BOOL
CALLBACK
StatusMessageWindowProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam;
if(!msg)
return FALSE;
msg->Context->hStatusWindow = hwndDlg;
if(msg->pTitle)
SetWindowText(hwndDlg, msg->pTitle);
SetDlgItemText(hwndDlg, IDC_STATUSLABEL, msg->pMessage);
if(!msg->Context->SignaledStatusWindowCreated)
{
msg->Context->SignaledStatusWindowCreated = TRUE;
SetEvent(msg->StartupEvent);
}
break;
}
}
return FALSE;
}
DWORD WINAPI
StartupWindowThread(LPVOID lpParam)
{
HDESK OldDesk;
PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam;
OldDesk = GetThreadDesktop(GetCurrentThreadId());
if(!SetThreadDesktop(msg->hDesktop))
{
HeapFree(GetProcessHeap(), 0, lpParam);
return FALSE;
}
DialogBoxParam(hDllInstance,
MAKEINTRESOURCE(IDD_STATUSWINDOW),
0,
StatusMessageWindowProc,
(LPARAM)lpParam);
SetThreadDesktop(OldDesk);
msg->Context->hStatusWindow = 0;
msg->Context->SignaledStatusWindowCreated = FALSE;
HeapFree(GetProcessHeap(), 0, lpParam);
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
WlxDisplayStatusMessage(
PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage)
IN PVOID pWlxContext,
IN HDESK hDesktop,
IN DWORD dwOptions,
IN PWSTR pTitle,
IN PWSTR pMessage)
{
PDISPLAYSTATUSMSG msg;
HANDLE Thread;
DWORD ThreadId;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(!pgContext->hStatusWindow)
{
msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG));
if(!msg)
return FALSE;
msg->Context = pgContext;
msg->dwOptions = dwOptions;
msg->pTitle = pTitle;
msg->pMessage = pMessage;
msg->hDesktop = hDesktop;
msg->StartupEvent = CreateEvent(NULL,
TRUE,
FALSE,
NULL);
if(!msg->StartupEvent)
return FALSE;
Thread = CreateThread(NULL,
0,
StartupWindowThread,
(PVOID)msg,
0,
&ThreadId);
if(Thread)
{
CloseHandle(Thread);
WaitForSingleObject(msg->StartupEvent, INFINITE);
CloseHandle(msg->StartupEvent);
return TRUE;
}
return FALSE;
}
if(pTitle)
SetWindowText(pgContext->hStatusWindow, pTitle);
SetDlgItemText(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage);
return TRUE;
}
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
DPRINT1("WlxDisplayStatusMessage(\"%S\")\n", pMessage);
return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage);
}
/*
* @implemented
*/
BOOL WINAPI
WlxRemoveStatusMessage(
PVOID pWlxContext)
IN PVOID pWlxContext)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(pgContext->hStatusWindow)
{
EndDialog(pgContext->hStatusWindow, 0);
pgContext->hStatusWindow = 0;
}
return TRUE;
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';
*pValue = Value;
return ERROR_SUCCESS;
}
static PWSTR
DuplicationString(PWSTR Str)
{
DWORD cb;
PWSTR NewStr;
if (Str == NULL) return NULL;
cb = (wcslen(Str) + 1) * sizeof(WCHAR);
if ((NewStr = LocalAlloc(LMEM_FIXED, cb)))
memcpy(NewStr, Str, cb);
return NewStr;
}
BOOL
DoLoginTasks(
IN OUT PGINA_CONTEXT pgContext,
IN PWSTR UserName,
IN PWSTR Domain,
IN PWSTR Password)
{
TOKEN_STATISTICS Stats;
DWORD cbStats;
if(!LogonUserW(UserName, Domain, Password,
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
LOGON32_PROVIDER_DEFAULT,
pgContext->phToken))
{
WARN("GINA: Logonuser() failed\n");
return FALSE;
}
if(!(*pgContext->phToken))
{
WARN("GINA: *phToken == NULL!\n");
return FALSE;
}
pgContext->UserToken =*pgContext->phToken;
*pgContext->pdwOptions = 0;
*pgContext->pProfile =NULL;
if(!GetTokenInformation(*pgContext->phToken,
TokenStatistics,
(PVOID)&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("GINA: Couldn't get Authentication id from user token!\n");
return FALSE;
}
*pgContext->pAuthenticationId = Stats.AuthenticationId;
pgContext->pNprNotifyInfo->pszUserName = DuplicationString(UserName);
pgContext->pNprNotifyInfo->pszDomain = DuplicationString(Domain);
pgContext->pNprNotifyInfo->pszPassword = DuplicationString(Password);
pgContext->pNprNotifyInfo->pszOldPassword = NULL;
return TRUE;
}
static BOOL
DoAutoLogon(
IN PGINA_CONTEXT pgContext,
IN BOOL CheckOnly)
{
HKEY WinLogonKey = NULL;
LPWSTR AutoLogon = NULL;
LPWSTR AutoCount = NULL;
LPWSTR IgnoreShiftOverride = NULL;
LPWSTR UserName = NULL;
LPWSTR DomainName = NULL;
LPWSTR Password = NULL;
BOOL result = FALSE;
LONG rc;
rc = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
0,
KEY_QUERY_VALUE,
&WinLogonKey);
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;
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"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;
}
if (CheckOnly)
{
result = TRUE;
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);
cleanup:
if (WinLogonKey != NULL)
RegCloseKey(WinLogonKey);
HeapFree(GetProcessHeap(), 0, AutoLogon);
HeapFree(GetProcessHeap(), 0, AutoCount);
HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride);
HeapFree(GetProcessHeap(), 0, UserName);
HeapFree(GetProcessHeap(), 0, DomainName);
HeapFree(GetProcessHeap(), 0, Password);
return result;
}
/*
* @implemented
*/
VOID WINAPI
WlxDisplaySASNotice(
PVOID pWlxContext)
IN PVOID pWlxContext)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
DPRINT1("WlxDisplaySASNotice(%p)\n", pWlxContext);
if (GetSystemMetrics(SM_REMOTESESSION))
{
/* User is remotely logged on. Don't display a notice */
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
return;
}
if (DoAutoLogon(NULL, TRUE))
{
/* Don't display the window, we want to do an automatic logon */
pgContext->DoAutoLogonOnce = TRUE;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
return;
}
pGinaUI->DisplaySASNotice(pgContext);
DPRINT1("WlxDisplaySASNotice() done\n");
}
static PWSTR
DuplicationString(PWSTR Str)
{
DWORD cb;
PWSTR NewStr;
cb = (wcslen(Str) + 1) * sizeof(WCHAR);
if((NewStr = LocalAlloc(LMEM_FIXED, cb)))
{
memcpy(NewStr, Str, cb);
}
return NewStr;
}
/*
* @unimplemented
* @implemented
*/
int WINAPI
INT WINAPI
WlxLoggedOutSAS(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile)
IN PVOID pWlxContext,
IN DWORD dwSasType,
OUT PLUID pAuthenticationId,
IN OUT PSID pLogonSid,
OUT PDWORD pdwOptions,
OUT PHANDLE phToken,
OUT PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
OUT PVOID *pProfile)
{
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
TOKEN_STATISTICS Stats;
DWORD cbStats;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(!phToken)
{
WARN("msgina: phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
DPRINT1("WlxLoggedOutSAS()\n");
if(!LogonUser(L"Administrator", NULL, L"Secrect",
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
LOGON32_PROVIDER_DEFAULT,
phToken))
{
WARN("msgina: Logonuser() failed\n");
return WLX_SAS_ACTION_NONE;
}
if(!(*phToken))
{
WARN("msgina: *phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
pgContext->pAuthenticationId = pAuthenticationId;
pgContext->pdwOptions = pdwOptions;
pgContext->phToken = phToken;
pgContext->pNprNotifyInfo = pNprNotifyInfo;
pgContext->pProfile = pProfile;
pgContext->UserToken =*phToken;
*pdwOptions = 0;
*pProfile =NULL;
if(!GetTokenInformation(*phToken,
TokenStatistics,
(PVOID)&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("msgina: Couldn't get Autentication id from user token!\n");
return WLX_SAS_ACTION_NONE;
}
*pAuthenticationId = Stats.AuthenticationId;
pNprNotifyInfo->pszUserName = DuplicationString(L"Administrator");
pNprNotifyInfo->pszDomain = NULL;
pNprNotifyInfo->pszPassword = DuplicationString(L"Secret");
pNprNotifyInfo->pszOldPassword = NULL;
if (!GetSystemMetrics(SM_REMOTESESSION) &&
pgContext->DoAutoLogonOnce &&
DoAutoLogon(pgContext, FALSE))
{
/* User is local and registry contains information
* to log on him automatically */
pgContext->DoAutoLogonOnce = FALSE;
return WLX_SAS_ACTION_LOGON;
}
return WLX_SAS_ACTION_LOGON;
return pGinaUI->LoggedOutSAS(pgContext);
}
BOOL STDCALL
BOOL WINAPI
DllMain(
HINSTANCE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
IN HINSTANCE hinstDLL,
IN DWORD dwReason,
IN LPVOID lpvReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
/* fall through */
case DLL_THREAD_ATTACH:
hDllInstance = hinstDLL;
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH)
hDllInstance = hinstDLL;
return TRUE;
}

View file

@ -1,22 +1,53 @@
#ifndef __MSGINA_H
#define __MSGINA_H
#define GINA_VERSION (WLX_VERSION_1_3)
#define PWLX_DISPATCH_VERSION PWLX_DISPATCH_VERSION_1_3
#include <windows.h>
#include <winwlx.h>
#include "resource.h"
typedef struct {
HANDLE hWlx;
LPWSTR station;
PWLX_DISPATCH_VERSION pWlxFuncs;
HANDLE hDllInstance;
HANDLE UserToken;
HWND hStatusWindow;
BOOL SignaledStatusWindowCreated;
HANDLE hWlx;
LPWSTR station;
PWLX_DISPATCH_VERSION_1_3 pWlxFuncs;
HANDLE hDllInstance;
HANDLE UserToken;
HWND hStatusWindow;
BOOL SignaledStatusWindowCreated;
BOOL DoAutoLogonOnce;
/* Informations to be filled during logon */
PLUID pAuthenticationId;
PDWORD pdwOptions;
PHANDLE phToken;
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo;
PVOID *pProfile;
} GINA_CONTEXT, *PGINA_CONTEXT;
HINSTANCE hDllInstance;
typedef BOOL (*PFGINA_INITIALIZE)(PGINA_CONTEXT);
typedef BOOL (*PFGINA_DISPLAYSTATUSMESSAGE)(PGINA_CONTEXT, HDESK, DWORD, PWSTR, PWSTR);
typedef VOID (*PFGINA_DISPLAYSASNOTICE)(PGINA_CONTEXT);
typedef INT (*PFGINA_LOGGEDONSAS)(PGINA_CONTEXT, DWORD);
typedef INT (*PFGINA_LOGGEDOUTSAS)(PGINA_CONTEXT);
typedef struct _GINA_UI
{
PFGINA_INITIALIZE Initialize;
PFGINA_DISPLAYSTATUSMESSAGE DisplayStatusMessage;
PFGINA_DISPLAYSASNOTICE DisplaySASNotice;
PFGINA_LOGGEDONSAS LoggedOnSAS;
PFGINA_LOGGEDOUTSAS LoggedOutSAS;
} GINA_UI, *PGINA_UI;
/* msgina.c */
BOOL
DoLoginTasks(
IN OUT PGINA_CONTEXT pgContext,
IN PWSTR UserName,
IN PWSTR Domain,
IN PWSTR Password);
#endif /* __MSGINA_H */
/* EOF */

View file

@ -10,7 +10,9 @@
<library>kernel32</library>
<library>advapi32</library>
<library>user32</library>
<file>gui.c</file>
<file>msgina.c</file>
<file>stubs.c</file>
<file>tui.c</file>
<file>msgina.rc</file>
</module>

View file

@ -9,26 +9,51 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_LOGOFFICON ICON "resources/ico_logoff.ico"
IDD_LOGOFF_DLG DIALOG 0, 0, 188, 60
STYLE DS_FIXEDSYS | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Log Off ReactOS"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 8, "MS Shell Dlg"
{
ICON IDI_LOGOFFICON, IDC_LOGOFFICON, 7, 7, 21, 21, SS_ICON | WS_CHILD | WS_VISIBLE
LTEXT "Are you sure you want to log off?", -1, 35, 16, 146, 8, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP
PUSHBUTTON "&Log Off", 1, 41, 39, 50, 14, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "&No", 2, 95, 39, 50, 14, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP
}
IDD_STATUSWINDOW DIALOG 0, 0, 274, 26
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION
IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26
STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP
CAPTION "Please wait..."
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 8, "MS Shell Dlg"
{
LTEXT "", IDC_STATUSLABEL, 7, 8, 234, 12, SS_ENDELLIPSIS
}
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS
END
IDD_NOTICE_DLG DIALOGEX 0,0,186,59
STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP
CAPTION "Welcome to ReactOS"
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
LTEXT "Press Control-Alt-Delete key combination",IDC_STATIC,16,18,144,14
END
IDD_LOGGEDOUT_DLG DIALOGEX 0,0,245,77
STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP
CAPTION "Logon"
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
PUSHBUTTON "OK",IDOK,31,52,50,14,BS_DEFPUSHBUTTON
PUSHBUTTON "Cancel",IDCANCEL,95,52,50,14
PUSHBUTTON "Shutdown",IDC_SHUTDOWN,159,52,50,14
LTEXT "User name:",IDC_STATIC,16,15,40,8
LTEXT "Password:",IDC_STATIC,16,33,42,8
EDITTEXT IDC_USERNAME,64,12,169,14,ES_AUTOHSCROLL
EDITTEXT IDC_PASSWORD,64,31,169,14,ES_AUTOHSCROLL | ES_PASSWORD
END
IDD_LOGGEDON_DLG DIALOGEX 0,0,186,52
STYLE NOT WS_VISIBLE | DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | DS_FIXEDSYS | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU
CAPTION "Security"
FONT 8,"MS Shell Dlg 2",400,0,1
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,125,31,50,14
PUSHBUTTON "Log off",IDC_LOGOFF,11,31,50,14
PUSHBUTTON "Shutdown",IDC_SHUTDOWN,69,31,50,14
LTEXT "What do you want to do?",IDC_STATIC,50,18,87,8
END
STRINGTABLE
BEGIN
IDS_PRESSCTRLALTDELETE "Press CONTROL+ALT+DELETE key combination\n"
IDS_ASKFORUSER "User name: "
IDS_ASKFORPASSWORD "Password: "
END

View file

@ -1,13 +1,19 @@
#ifndef __MSGINA_RESOURCE_H
#define __MSGINA_RESOURCE_H
#define IDD_LOGOFF_DLG 2250
#define IDD_STATUSWINDOW 2450
#define IDC_LOGOFFICON 21
#define IDC_STATUSLABEL 2451
#define IDI_LOGOFFICON 2251
#define IDC_STATIC -1
#define IDD_STATUSWINDOW_DLG 100
#define IDD_NOTICE_DLG 101
#define IDD_LOGGEDON_DLG 102
#define IDD_LOGGEDOUT_DLG 103
#define IDC_LOGOFF 1001
#define IDC_USERNAME 1002
#define IDC_PASSWORD 1003
#define IDC_SHUTDOWN 1004
#define IDC_STATUSLABEL 1005
#define IDS_ASKFORUSER 40000
#define IDS_PRESSCTRLALTDELETE 40001
#define IDS_ASKFORPASSWORD 40002
#endif /* __MSGINA_RESOURCE_H */

View file

@ -0,0 +1,148 @@
/*
* PROJECT: ReactOS msgina.dll
* FILE: dll/win32/msgina/tui.c
* PURPOSE: ReactOS Logon GINA DLL
* PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
*/
#include "msgina.h"
#include <debug.h>
#define TRACE DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#define FIXME DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#define WARN DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
#undef DPRINT
#undef DPRINT1
static BOOL
TUIInitialize(
IN OUT PGINA_CONTEXT pgContext)
{
TRACE("TUIInitialize(%p)\n", pgContext);
return AllocConsole();
}
static BOOL
TUIDisplayStatusMessage(
IN PGINA_CONTEXT pgContext,
IN HDESK hDesktop,
IN DWORD dwOptions,
IN PWSTR pTitle,
IN PWSTR pMessage)
{
static LPCWSTR newLine = L"\n";
DWORD result;
TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage);
return
WriteConsole(
GetStdHandle(STD_OUTPUT_HANDLE),
pMessage,
wcslen(pMessage),
&result,
NULL) &&
WriteConsole(
GetStdHandle(STD_OUTPUT_HANDLE),
newLine,
wcslen(newLine),
&result,
NULL);
}
static VOID
TUIDisplaySASNotice(
IN OUT PGINA_CONTEXT pgContext)
{
WCHAR CtrlAltDelPrompt[256];
DWORD count;
TRACE("TUIDisplaySASNotice()\n");
if (LoadString(hDllInstance, IDS_PRESSCTRLALTDELETE, CtrlAltDelPrompt, 256))
{
WriteConsole(
GetStdHandle(STD_OUTPUT_HANDLE),
CtrlAltDelPrompt,
wcslen(CtrlAltDelPrompt),
&count,
NULL);
}
}
static INT
TUILoggedOnSAS(
IN OUT PGINA_CONTEXT pgContext,
IN DWORD dwSasType)
{
TRACE("TUILoggedOnSAS()\n");
for (;;) FIXME("FIXME!\n");
return 0;
}
static BOOL
ReadString(
IN PGINA_CONTEXT pgContext,
IN UINT uIdResourcePrompt,
IN OUT PWSTR Buffer,
IN DWORD BufferLength,
IN BOOL ShowString)
{
WCHAR Prompt[256];
DWORD count, i;
if (!SetConsoleMode(
GetStdHandle(STD_INPUT_HANDLE),
ShowString ? ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT: ENABLE_LINE_INPUT))
{
return FALSE;
}
if (!LoadString(hDllInstance, uIdResourcePrompt, Prompt, 256))
return FALSE;
if (!WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), Prompt, wcslen(Prompt), &count, NULL))
return FALSE;
i = 0;
do
{
if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &Buffer[i], 1, &count, NULL))
return FALSE;
i++;
/* FIXME: buffer overflow if the user writes too many chars! */
/* FIXME: handle backspace */
} while (Buffer[i - 1] != '\n');
Buffer[i - 1] = 0;
return TRUE;
}
static INT
TUILoggedOutSAS(
IN OUT PGINA_CONTEXT pgContext)
{
WCHAR User[256];
WCHAR Password[256];
TRACE("TUILoggedOutSAS()\n");
/* Ask the user for credentials */
if (!ReadString(pgContext, IDS_ASKFORUSER, User, 256, TRUE))
return WLX_SAS_ACTION_NONE;
if (!ReadString(pgContext, IDS_ASKFORPASSWORD, Password, 256, FALSE))
return WLX_SAS_ACTION_NONE;
if (DoLoginTasks(pgContext, User, NULL, Password))
return WLX_SAS_ACTION_LOGON;
else
return WLX_SAS_ACTION_NONE;
}
GINA_UI GinaTextUI = {
TUIInitialize,
TUIDisplayStatusMessage,
TUIDisplaySASNotice,
TUILoggedOnSAS,
TUILoggedOutSAS,
};