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 * PROJECT: ReactOS kernel
* FILE: services/winlogon/sas.c * FILE: services/winlogon/sas.c
* PURPOSE: Secure Attention Sequence * 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: * UPDATE HISTORY:
* Created 28/03/2004 * Created 28/03/2004
*/ */
#include "winlogon.h" #include "winlogon.h"
#define NDEBUG #define YDEBUG
#include <debug.h> #include <wine/debug.h>
#define WINLOGON_SAS_CLASS L"SAS window class" #define WINLOGON_SAS_CLASS L"SAS Window class"
#define WINLOGON_SAS_TITLE L"SAS" #define WINLOGON_SAS_TITLE L"SAS window"
#define HK_CTRL_ALT_DEL 0 #define HK_CTRL_ALT_DEL 0
#define HK_CTRL_SHIFT_ESC 1 #define HK_CTRL_SHIFT_ESC 1
#ifdef __USE_W32API #ifdef __USE_W32API
extern BOOL STDCALL SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta); extern BOOL STDCALL SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta);
#endif #endif
void static BOOL
DispatchSAS(PWLSESSION Session, DWORD dwSasType) 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 static BOOL
UninitSAS(PWLSESSION Session) HandleLogon(
IN OUT PWLSESSION Session)
{ {
if(Session->SASWindow) PROFILEINFOW ProfileInfo;
{ LPVOID lpEnvironment = NULL;
DestroyWindow(Session->SASWindow); BOOLEAN Old;
Session->SASWindow = NULL;
} 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 static BOOL
SetupSAS(PWLSESSION Session, HWND hwndSAS) HandleLogoff(
IN OUT PWLSESSION Session)
{ {
/* Register Ctrl+Alt+Del Hotkey */ FIXME("FIXME: HandleLogoff() unimplemented\n");
if(!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE)) return FALSE;
{
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;
} }
BOOL static BOOL
DestroySAS(PWLSESSION Session, HWND hwndSAS) 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) VOID
{ DispatchSAS(
UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC); 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 #define EWX_ACTION_MASK 0xffffffeb
@ -196,95 +377,115 @@ HandleExitWindows(PWLSESSION Session, DWORD RequestingProcessId, UINT Flags)
return 1; return 1;
} }
LRESULT CALLBACK static LRESULT CALLBACK
SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SASWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{ {
PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA); PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwndDlg, 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;
/* Save the Session pointer */ switch (uMsg)
SetWindowLongPtr(Session->SASWindow, GWLP_USERDATA, (DWORD_PTR)Session); {
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)) /* Save the Session pointer */
{ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)Session);
/* Fail! */
return 1; return RegisterHotKeys(Session, hwndDlg);
} }
return 0; case WM_DESTROY:
} {
case PM_WINLOGON_EXITWINDOWS: UnregisterHotKeys(Session, hwndDlg);
{ return TRUE;
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam); }
} case PM_WINLOGON_EXITWINDOWS:
case WM_DESTROY: {
{ return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam);
DestroySAS(Session, hwnd); }
return 0; }
}
} return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
return DefWindowProc(hwnd, uMsg, wParam, lParam); }
static VOID
UninitializeSAS(
IN OUT PWLSESSION Session)
{
if (Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
} }
BOOL BOOL
InitializeSAS(PWLSESSION Session) InitializeSAS(
IN OUT PWLSESSION Session)
{ {
WNDCLASSEX swc; WNDCLASSEX swc;
/* register SAS window class. /* register SAS window class.
WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */ * WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */
swc.cbSize = sizeof(WNDCLASSEXW); swc.cbSize = sizeof(WNDCLASSEXW);
swc.style = CS_SAVEBITS; swc.style = CS_SAVEBITS;
swc.lpfnWndProc = SASProc; swc.lpfnWndProc = SASWindowProc;
swc.cbClsExtra = 0; swc.cbClsExtra = 0;
swc.cbWndExtra = 0; swc.cbWndExtra = 0;
swc.hInstance = hAppInstance; swc.hInstance = hAppInstance;
swc.hIcon = NULL; swc.hIcon = NULL;
swc.hCursor = NULL; swc.hCursor = NULL;
swc.hbrBackground = NULL; swc.hbrBackground = NULL;
swc.lpszMenuName = NULL; swc.lpszMenuName = NULL;
swc.lpszClassName = WINLOGON_SAS_CLASS; swc.lpszClassName = WINLOGON_SAS_CLASS;
swc.hIconSm = NULL; swc.hIconSm = NULL;
RegisterClassEx(&swc); RegisterClassEx(&swc); /* FIXME: check return code */
/* create invisible SAS window */ /* create invisible SAS window */
Session->SASWindow = CreateWindowEx(0, WINLOGON_SAS_CLASS, WINLOGON_SAS_TITLE, WS_POPUP, DPRINT1("Session %p\n", Session);
0, 0, 0, 0, 0, 0, hAppInstance, Session); Session->SASWindow = CreateWindowEx(
if(!Session->SASWindow) 0,
{ WINLOGON_SAS_CLASS,
DPRINT1("WL: Failed to create SAS window\n"); WINLOGON_SAS_TITLE,
return FALSE; 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 */ /* Register SAS window to receive SAS notifications */
if(!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation)) if (!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation))
{ {
UninitSAS(Session); UninitializeSAS(Session);
DPRINT1("WL: Failed to register SAS window\n"); ERR("WL: Failed to register SAS window\n");
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }

View file

@ -3,80 +3,55 @@
* PROJECT: ReactOS Winlogon * PROJECT: ReactOS Winlogon
* FILE: services/winlogon/winlogon.c * FILE: services/winlogon/winlogon.c
* PURPOSE: Logon * PURPOSE: Logon
* PROGRAMMER: David Welch (welch@cwcom.net) * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY: * Filip Navara
* Created 22/05/98 * Hervé Poussineau (hpoussin@reactos.org)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include "winlogon.h" #include "winlogon.h"
#define NDEBUG #define YDEBUG
#include <debug.h> #include <wine/debug.h>
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
BOOL
LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion);
PWLSESSION
MsGinaInit(void);
void
SessionLoop(PWLSESSION Session);
BOOL
InitServices(void);
BOOL
WlxCreateWindowStationAndDesktops(PWLSESSION Session);
HINSTANCE hAppInstance; HINSTANCE hAppInstance;
PWLSESSION WLSession = NULL; PWLSESSION WLSession = NULL;
HWND hwndSASWindow = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static void static INT_PTR CALLBACK
PrintString (WCHAR* fmt,...) ShutdownComputerWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{ {
WCHAR buffer[512]; switch (uMsg)
va_list ap; {
case WM_COMMAND:
va_start(ap, fmt); {
wsprintf(buffer, fmt, ap); switch (LOWORD(wParam))
va_end(ap); {
case IDC_BTNSHTDOWNCOMPUTER:
OutputDebugString(buffer); 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);
} }
static BOOL
INT_PTR CALLBACK StartServicesManager(void)
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)
{ {
HANDLE ServicesInitEvent; HANDLE ServicesInitEvent;
BOOLEAN Result; BOOLEAN Result;
@ -96,7 +71,7 @@ StartServices (VOID)
StartupInfo.lpReserved2 = 0; StartupInfo.lpReserved2 = 0;
#if 0 #if 0
PrintString(L"WL: Creating new process - \"services.exe\".\n"); DPRINT1(L"WL: Creating new process - \"services.exe\".\n");
#endif #endif
Result = CreateProcess(NULL, Result = CreateProcess(NULL,
@ -111,7 +86,7 @@ StartServices (VOID)
&ProcessInformation); &ProcessInformation);
if (!Result) if (!Result)
{ {
PrintString(L"WL: Failed to execute services\n"); DPRINT1("WL: Failed to execute services\n");
return FALSE; return FALSE;
} }
@ -141,66 +116,75 @@ StartServices (VOID)
WaitForSingleObject(ServicesInitEvent, INFINITE); WaitForSingleObject(ServicesInitEvent, INFINITE);
DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n"); DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
CloseHandle(ServicesInitEvent); CloseHandle(ServicesInitEvent);
DPRINT("WL: StartServices() Done.\n"); DPRINT("WL: StartServicesManager() Done.\n");
return TRUE; return TRUE;
} }
static BOOLEAN static BOOL
StartLsass (VOID) StartCustomService(
IN LPCWSTR ServiceName)
{ {
HANDLE LsassInitEvent; SC_HANDLE hSCManager = NULL;
BOOLEAN Result; SC_HANDLE hService = NULL;
STARTUPINFO StartupInfo; BOOL ret = FALSE;
PROCESS_INFORMATION ProcessInformation;
WCHAR ServiceString[] = L"lsass.exe";
LsassInitEvent = CreateEvent(NULL, hSCManager = OpenSCManager(NULL, NULL, 0);
TRUE, if (!hSCManager)
FALSE, goto cleanup;
L"\\SECURITY_SERVICES_STARTED");
if (LsassInitEvent == NULL) hService = OpenService(hSCManager, ServiceName, SERVICE_START);
{ if (!hService)
DPRINT1("WL: Failed to create lsass notification event\n"); goto cleanup;
return(FALSE); #if 0
} if (!StartService(hService, 0, NULL))
goto cleanup;
#endif
/* Start the local security authority subsystem (lsass.exe) */ ret = TRUE;
StartupInfo.cb = sizeof(StartupInfo); cleanup:
StartupInfo.lpReserved = NULL; if (hService)
StartupInfo.lpDesktop = NULL; CloseServiceHandle(hService);
StartupInfo.lpTitle = NULL; if (hSCManager)
StartupInfo.dwFlags = 0; CloseServiceHandle(hSCManager);
StartupInfo.cbReserved2 = 0; return ret;
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);
} }
static BOOL
StartLsass(VOID)
{
HANDLE LsassInitEvent;
static BOOLEAN LsassInitEvent = CreateEvent(
OpenRegistryKey (HKEY *WinLogonKey) 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, return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon", L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
@ -209,8 +193,10 @@ OpenRegistryKey (HKEY *WinLogonKey)
WinLogonKey); WinLogonKey);
} }
#if 0
static BOOLEAN StartProcess(PWCHAR ValueName) static BOOL
StartProcess(
IN PWCHAR ValueName)
{ {
BOOL StartIt; BOOL StartIt;
HKEY WinLogonKey; HKEY WinLogonKey;
@ -239,6 +225,7 @@ static BOOLEAN StartProcess(PWCHAR ValueName)
return StartIt; return StartIt;
} }
#endif
/* /*
static BOOL RestartShell(void) 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 static PWCHAR
GetUserInit (WCHAR *CommandLine) GetUserInit(
OUT WCHAR *CommandLine,
IN DWORD BufferLength)
{ {
HKEY WinLogonKey; HKEY WinLogonKey;
BOOL GotCommandLine; BOOL GotCommandLine;
@ -360,9 +301,10 @@ GetUserInit (WCHAR *CommandLine)
} }
static BOOL BOOL
DoLogonUser (PWCHAR Name, DoBrokenLogonUser(
PWCHAR Password) IN PWLSESSION WLSession,
IN PWLX_MPR_NOTIFY_INFO pMprNotifyInfo)
{ {
PROCESS_INFORMATION ProcessInformation; PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo; STARTUPINFO StartupInfo;
@ -372,24 +314,14 @@ DoLogonUser (PWCHAR Name,
BOOL Result; BOOL Result;
LPVOID lpEnvironment = NULL; LPVOID lpEnvironment = NULL;
MSG Msg; MSG Msg;
BOOLEAN Old;
Result = LogonUserW (Name, SwitchDesktop(WLSession->ApplicationDesktop);
NULL,
Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&WLSession->UserToken);
if (!Result)
{
DPRINT1 ("WL: LogonUserW() failed\n");
RtlDestroyEnvironment (lpEnvironment);
return FALSE;
}
/* Load the user profile */ /* Load the user profile */
ProfileInfo.dwSize = sizeof(PROFILEINFOW); ProfileInfo.dwSize = sizeof(PROFILEINFOW);
ProfileInfo.dwFlags = 0; ProfileInfo.dwFlags = 0;
ProfileInfo.lpUserName = Name; ProfileInfo.lpUserName = pMprNotifyInfo->pszUserName;
ProfileInfo.lpProfilePath = NULL; ProfileInfo.lpProfilePath = NULL;
ProfileInfo.lpDefaultPath = NULL; ProfileInfo.lpDefaultPath = NULL;
ProfileInfo.lpServerName = NULL; ProfileInfo.lpServerName = NULL;
@ -428,10 +360,14 @@ DoLogonUser (PWCHAR Name,
StartupInfo.dwFlags = 0; StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0; StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0; StartupInfo.lpReserved2 = 0;
/* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
Result = CreateProcessAsUserW (WLSession->UserToken, Result = CreateProcessAsUserW(
WLSession->UserToken,
NULL, NULL,
GetUserInit (CommandLine), GetUserInit (CommandLine, MAX_PATH),
NULL, NULL,
NULL, NULL,
FALSE, FALSE,
@ -442,7 +378,7 @@ DoLogonUser (PWCHAR Name,
&ProcessInformation); &ProcessInformation);
if (!Result) 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)) if (ImpersonateLoggedOnUser(WLSession->UserToken))
{ {
UpdatePerUserSystemParameters(0, FALSE); UpdatePerUserSystemParameters(0, FALSE);
@ -454,20 +390,20 @@ DoLogonUser (PWCHAR Name,
DestroyEnvironmentBlock (lpEnvironment); DestroyEnvironmentBlock (lpEnvironment);
return FALSE; return FALSE;
} }
/*WLSession->MsGina.Functions.WlxActivateUserShell(WLSession->MsGina.Context,
RegisterHotKeys(); L"WinSta0\\Default",
NULL,
NULL);*/
while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0) 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); TranslateMessage(&Msg);
DispatchMessage(&Msg); DispatchMessage(&Msg);
} }
} }
UnregisterHotKeys();
CloseHandle (ProcessInformation.hProcess); CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread); CloseHandle (ProcessInformation.hThread);
@ -488,264 +424,36 @@ DoLogonUser (PWCHAR Name,
return TRUE; return TRUE;
} }
static LRESULT CALLBACK static BOOL
SASWindowProc( DisplayStatusMessage(
IN HWND hwndDlg, IN PWLSESSION Session,
IN UINT uMsg, IN HDESK hDesktop,
IN WPARAM wParam, IN UINT ResourceId)
IN LPARAM lParam)
{ {
DbgBreakPoint(); WCHAR StatusMsg[MAX_PATH];
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;
}
}
}
}
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 #if 0
LSA_STRING ProcessName, PackageName; static BOOL
HANDLE LsaHandle; InitServices(VOID)
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)
{ {
if(Session->SuppressStatus) /*WCHAR StatusMsg[256];
{
return TRUE;
}
return Session->MsGina.Functions.WlxDisplayStatusMessage(Session->MsGina.Context, hDesktop, dwOptions, pTitle, pMessage);
}
BOOL
InitServices(void)
{
WCHAR StatusMsg[256];
LoadString(hAppInstance, IDS_REACTOSISSTARTINGUP, StatusMsg, 256 * sizeof(WCHAR)); 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) */ /* start system processes (services.exe & lsass.exe) */
if(StartProcess(L"StartServices")) if(StartProcess(L"StartServices"))
{ {
if(!StartServices()) if(!StartServicesManager())
{ {
DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError()); DPRINT1("WL: Failed to start Services (0x%X)\n", GetLastError());
} }
@ -757,9 +465,12 @@ InitServices(void)
return TRUE; return TRUE;
} }
#endif
DWORD #if 0
DoLogin(PWLSESSION Session) static DWORD
DoLogin(
IN OUT PWLSESSION Session)
{ {
DWORD WlxAction, Options; DWORD WlxAction, Options;
WLX_MPR_NOTIFY_INFO MprNotifyInfo; WLX_MPR_NOTIFY_INFO MprNotifyInfo;
@ -784,66 +495,38 @@ DoLogin(PWLSESSION Session)
&MprNotifyInfo, &MprNotifyInfo,
(PVOID*)&Profile); (PVOID*)&Profile);
if (WlxAction == WLX_SAS_ACTION_LOGON)
{
Session->UserToken = Token;
if (!DoBrokenLogonUser(Session, &MprNotifyInfo))
WlxAction = WLX_SAS_ACTION_NONE;
}
return WlxAction; return WlxAction;
} }
#endif
void static VOID
SessionLoop(PWLSESSION Session) SessionLoop(
IN OUT PWLSESSION Session)
{ {
//WCHAR StatusMsg[256]; //WCHAR StatusMsg[256];
// HANDLE hShutdownEvent; //HANDLE hShutdownEvent;
DWORD WlxAction; MSG Msg;
MSG Msg;
WlxAction = WLX_SAS_ACTION_NONE; Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
Session->LogonStatus = LOGON_NONE; RemoveStatusMessage(Session);
while(WlxAction == WLX_SAS_ACTION_NONE) DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
{
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;
if(Session->SASAction == WLX_SAS_ACTION_LOGOFF) /* Message loop for the SAS window */
{ while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
/* the system wants to log off here */ {
Session->LogonStatus = LOGON_SHUTDOWN; TranslateMessage(&Msg);
break; DispatchMessage(&Msg);
} }
}
WlxAction = DoLogin(Session); /* Don't go there! */
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;
}
#if 0
/* FIXME - don't leave the loop when suspending the computer */ /* FIXME - don't leave the loop when suspending the computer */
if(WLX_SUSPENDING(WlxAction)) if(WLX_SUSPENDING(WlxAction))
{ {
@ -860,13 +543,7 @@ SessionLoop(PWLSESSION Session)
break; break;
} }
/* Message loop for the SAS window */ #endif
while(GetMessage(&Msg, hwndSASWindow, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
/* /*
LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR)); LoadString(hAppInstance, IDS_PREPARENETWORKCONNECTIONS, StatusMsg, 256 * sizeof(WCHAR));
MsGinaInst->Functions->WlxDisplayStatusMessage(MsGinaInst->Context, 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 <rtlfuncs.h>
#include <exfuncs.h> #include <exfuncs.h>
#include <setypes.h> #include <setypes.h>
#include <ntsecapi.h>
#include <reactos/winlogon.h> #include <reactos/winlogon.h>
#include "setup.h" #include "setup.h"
#include "resource.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 * PFWLXNEGOTIATE) (DWORD, DWORD *);
typedef BOOL (WINAPI * PFWLXINITIALIZE) (LPWSTR, HANDLE, PVOID, PVOID, PVOID *); typedef BOOL (WINAPI * PFWLXINITIALIZE) (LPWSTR, HANDLE, PVOID, PVOID, PVOID *);
typedef VOID (WINAPI * PFWLXDISPLAYSASNOTICE) (PVOID); typedef VOID (WINAPI * PFWLXDISPLAYSASNOTICE) (PVOID);
@ -97,36 +70,50 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID);
typedef struct _MSGINAFUNCTIONS typedef struct _MSGINAFUNCTIONS
{ {
PFWLXNEGOTIATE WlxNegotiate; /* Functions always available for a valid GINA */
PFWLXINITIALIZE WlxInitialize; PFWLXNEGOTIATE WlxNegotiate;
PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice; PFWLXINITIALIZE WlxInitialize;
PFWLXLOGGEDOUTSAS WlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL WlxActivateUserShell;
PFWLXLOGGEDONSAS WlxLoggedOnSAS;
PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice;
PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS;
PFWLXISLOCKOK WlxIsLockOk;
PFWLXISLOGOFFOK WlxIsLogoffOk;
PFWLXLOGOFF WlxLogoff;
PFWLXSHUTDOWN WlxShutdown;
PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; /* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */
PFWLXSTARTAPPLICATION WlxStartApplication; PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice;
PFWLXLOGGEDOUTSAS WlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL WlxActivateUserShell;
PFWLXLOGGEDONSAS WlxLoggedOnSAS;
PFWLXDISPLAYLOCKEDNOTICE WlxDisplayLockedNotice;
PFWLXWKSTALOCKEDSAS WlxWkstaLockedSAS;
PFWLXISLOCKOK WlxIsLockOk;
PFWLXISLOGOFFOK WlxIsLogoffOk;
PFWLXLOGOFF WlxLogoff;
PFWLXSHUTDOWN WlxShutdown;
PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad; /* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */
PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify;
PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; PFWLXSTARTAPPLICATION WlxStartApplication;
PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage;
/* 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; } MSGINAFUNCTIONS, *PMSGINAFUNCTIONS;
typedef struct _MSGINAINSTANCE typedef struct _MSGINAINSTANCE
{ {
HMODULE hDllInstance; HMODULE hDllInstance;
MSGINAFUNCTIONS Functions; MSGINAFUNCTIONS Functions;
PVOID Context; PVOID Context;
DWORD Version; DWORD Version;
} MSGINAINSTANCE, *PMSGINAINSTANCE; } 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 typedef struct _WLSESSION
{ {
MSGINAINSTANCE MsGina; MSGINAINSTANCE MsGina;
@ -142,22 +129,16 @@ typedef struct _WLSESSION
HDESK ScreenSaverDesktop; HDESK ScreenSaverDesktop;
LUID LogonId; LUID LogonId;
HANDLE UserToken; HANDLE UserToken;
/* Logon informations */
DWORD Options;
WLX_MPR_NOTIFY_INFO MprNotifyInfo;
WLX_PROFILE_V2_0 Profile;
} WLSESSION, *PWLSESSION; } WLSESSION, *PWLSESSION;
extern HINSTANCE hAppInstance; extern HINSTANCE hAppInstance;
extern PWLSESSION WLSession; 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) \ #define WLX_SHUTTINGDOWN(Status) \
(((Status) == WLX_SAS_ACTION_SHUTDOWN) || \ (((Status) == WLX_SAS_ACTION_SHUTDOWN) || \
((Status) == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) || \ ((Status) == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF) || \
@ -180,6 +161,51 @@ BOOL WINAPI
UpdatePerUserSystemParameters(DWORD dwUnknown, UpdatePerUserSystemParameters(DWORD dwUnknown,
DWORD dwReserved); 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__ */ #endif /* __WINLOGON_MAIN_H__ */
/* EOF */ /* 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 * ReactOS GINA
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * Copyright (C) 2003-2004, 2006 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id$ /*
*
* PROJECT: ReactOS msgina.dll * PROJECT: ReactOS msgina.dll
* FILE: lib/msgina/msgina.c * FILE: dll/win32/msgina/msgina.c
* PURPOSE: ReactOS Logon GINA DLL * PURPOSE: ReactOS Logon GINA DLL
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY: * Hervé Poussineau (hpoussin@reactos.org)
* 24-11-2003 Created
*/ */
#include <windows.h>
#include <winwlx.h>
#include "msgina.h" #include "msgina.h"
#include "resource.h"
#include <wine/debug.h> #include <wine/debug.h>
extern HINSTANCE hDllInstance; extern HINSTANCE hDllInstance;
typedef struct _DISPLAYSTATUSMSG extern GINA_UI GinaGraphicalUI;
{ extern GINA_UI GinaTextUI;
PGINA_CONTEXT Context; static PGINA_UI pGinaUI = &GinaGraphicalUI; /* Default value */
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;
}
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL WINAPI
WlxNegotiate( WlxNegotiate(
DWORD dwWinlogonVersion, IN DWORD dwWinlogonVersion,
PDWORD pdwDllVersion) OUT PDWORD pdwDllVersion)
{ {
if(!pdwDllVersion || (dwWinlogonVersion < GINA_VERSION)) DPRINT1("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion);
return FALSE;
if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3))
*pdwDllVersion = GINA_VERSION; return FALSE;
return TRUE; *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 * @implemented
@ -122,7 +112,7 @@ WlxInitialize(
pgContext->hDllInstance = hDllInstance; pgContext->hDllInstance = hDllInstance;
/* save pointer to dispatch table */ /* 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 */ /* save the winlogon handle used to call the dispatch functions */
pgContext->hWlx = hWlx; pgContext->hWlx = hWlx;
@ -136,7 +126,13 @@ WlxInitialize(
/* notify winlogon that we will use the default SAS */ /* notify winlogon that we will use the default SAS */
pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx); 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) PVOID pEnvironment)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
STARTUPINFO si; STARTUPINFO StartupInfo;
PROCESS_INFORMATION pi; PROCESS_INFORMATION ProcessInformation;
HKEY hKey; HKEY hKey;
DWORD BufSize, ValueType; DWORD BufSize, ValueType;
WCHAR pszUserInitApp[MAX_PATH]; WCHAR pszUserInitApp[MAX_PATH];
WCHAR pszExpUserInitApp[MAX_PATH]; WCHAR pszExpUserInitApp[MAX_PATH];
BOOL Ret; BOOL Ret;
WCHAR CurrentDirectory[MAX_PATH];
/* get the path of userinit */ /* get the path of userinit */
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
@ -222,31 +219,34 @@ WlxActivateUserShell(
/* start userinit */ /* start userinit */
/* FIXME - allow to start more applications that are comma-separated */ /* FIXME - allow to start more applications that are comma-separated */
si.cb = sizeof(STARTUPINFO); StartupInfo.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL; StartupInfo.lpReserved = NULL;
si.lpTitle = L"userinit"; StartupInfo.lpDesktop = pszDesktopName;
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0; StartupInfo.lpTitle = NULL;
si.dwFlags = 0; StartupInfo.dwFlags = 0;
si.wShowWindow = SW_SHOW; StartupInfo.lpReserved2 = NULL;
si.lpReserved2 = NULL; StartupInfo.cbReserved2 = 0;
si.cbReserved2 = 0; StartupInfo.dwX = StartupInfo.dwY = StartupInfo.dwXSize = StartupInfo.dwYSize = 0;
si.lpDesktop = pszDesktopName; StartupInfo.wShowWindow = SW_SHOW;
ExpandEnvironmentStrings(pszUserInitApp, pszExpUserInitApp, MAX_PATH); ExpandEnvironmentStrings(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
Ret = CreateProcessAsUser(pgContext->UserToken, Ret = CreateProcessAsUser(pgContext->UserToken,
pszExpUserInitApp,
NULL, NULL,
pszExpUserInitApp,
NULL, NULL,
NULL, NULL,
FALSE, FALSE,
CREATE_UNICODE_ENVIRONMENT, CREATE_UNICODE_ENVIRONMENT,
pEnvironment, pEnvironment,
NULL, CurrentDirectory,
&si, &StartupInfo,
&pi); &ProcessInformation);
if(!Ret) ERR("GINA: Failed: 3\n"); if(!Ret) ERR("GINA: Failed: 3, error %lu\n", GetLastError());
VirtualFree(pEnvironment, 0, MEM_RELEASE); VirtualFree(pEnvironment, 0, MEM_RELEASE);
Ret = pgContext->pWlxFuncs->WlxSwitchDesktopToUser(pgContext->hWlx);
if(!Ret) ERR("GINA: Failed: 4, error %lu\n", GetLastError());
return Ret; return Ret;
} }
@ -260,303 +260,295 @@ WlxLoggedOnSAS(
DWORD dwSasType, DWORD dwSasType,
PVOID pReserved) PVOID pReserved)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
int SasAction = WLX_SAS_ACTION_NONE;
DPRINT1("WlxLoggedOnSAS(0x%lx)\n", dwSasType);
switch(dwSasType)
{ return pGinaUI->LoggedOnSAS(pgContext, 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;
} }
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 * @implemented
*/ */
BOOL WINAPI BOOL WINAPI
WlxDisplayStatusMessage( WlxDisplayStatusMessage(
PVOID pWlxContext, IN PVOID pWlxContext,
HDESK hDesktop, IN HDESK hDesktop,
DWORD dwOptions, IN DWORD dwOptions,
PWSTR pTitle, IN PWSTR pTitle,
PWSTR pMessage) IN PWSTR pMessage)
{ {
PDISPLAYSTATUSMSG msg; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
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;
}
DPRINT1("WlxDisplayStatusMessage(\"%S\")\n", pMessage);
return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage);
}
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL WINAPI
WlxRemoveStatusMessage( WlxRemoveStatusMessage(
PVOID pWlxContext) IN PVOID pWlxContext)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(pgContext->hStatusWindow) if (pgContext->hStatusWindow)
{ {
EndDialog(pgContext->hStatusWindow, 0); EndDialog(pgContext->hStatusWindow, 0);
pgContext->hStatusWindow = 0; pgContext->hStatusWindow = 0;
} }
return TRUE; 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 * @implemented
*/ */
VOID WINAPI VOID WINAPI
WlxDisplaySASNotice( WlxDisplaySASNotice(
PVOID pWlxContext) IN PVOID pWlxContext)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
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( WlxLoggedOutSAS(
PVOID pWlxContext, IN PVOID pWlxContext,
DWORD dwSasType, IN DWORD dwSasType,
PLUID pAuthenticationId, OUT PLUID pAuthenticationId,
PSID pLogonSid, IN OUT PSID pLogonSid,
PDWORD pdwOptions, OUT PDWORD pdwOptions,
PHANDLE phToken, OUT PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo, OUT PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile) OUT PVOID *pProfile)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
TOKEN_STATISTICS Stats;
DWORD cbStats;
if(!phToken) DPRINT1("WlxLoggedOutSAS()\n");
{
WARN("msgina: phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
if(!LogonUser(L"Administrator", NULL, L"Secrect", pgContext->pAuthenticationId = pAuthenticationId;
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */ pgContext->pdwOptions = pdwOptions;
LOGON32_PROVIDER_DEFAULT, pgContext->phToken = phToken;
phToken)) pgContext->pNprNotifyInfo = pNprNotifyInfo;
{ pgContext->pProfile = pProfile;
WARN("msgina: Logonuser() failed\n");
return WLX_SAS_ACTION_NONE;
}
if(!(*phToken))
{
WARN("msgina: *phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
pgContext->UserToken =*phToken; if (!GetSystemMetrics(SM_REMOTESESSION) &&
pgContext->DoAutoLogonOnce &&
*pdwOptions = 0; DoAutoLogon(pgContext, FALSE))
*pProfile =NULL; {
/* User is local and registry contains information
if(!GetTokenInformation(*phToken, * to log on him automatically */
TokenStatistics, pgContext->DoAutoLogonOnce = FALSE;
(PVOID)&Stats, return WLX_SAS_ACTION_LOGON;
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;
return WLX_SAS_ACTION_LOGON; return pGinaUI->LoggedOutSAS(pgContext);
} }
BOOL WINAPI
BOOL STDCALL
DllMain( DllMain(
HINSTANCE hinstDLL, IN HINSTANCE hinstDLL,
DWORD dwReason, IN DWORD dwReason,
LPVOID lpvReserved) IN LPVOID lpvReserved)
{ {
switch (dwReason) if (dwReason == DLL_PROCESS_ATTACH)
{ hDllInstance = hinstDLL;
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;
}
return TRUE;
}

View file

@ -1,22 +1,53 @@
#ifndef __MSGINA_H #ifndef __MSGINA_H
#define __MSGINA_H #define __MSGINA_H
#define GINA_VERSION (WLX_VERSION_1_3) #include <windows.h>
#include <winwlx.h>
#define PWLX_DISPATCH_VERSION PWLX_DISPATCH_VERSION_1_3 #include "resource.h"
typedef struct { typedef struct {
HANDLE hWlx; HANDLE hWlx;
LPWSTR station; LPWSTR station;
PWLX_DISPATCH_VERSION pWlxFuncs; PWLX_DISPATCH_VERSION_1_3 pWlxFuncs;
HANDLE hDllInstance; HANDLE hDllInstance;
HANDLE UserToken; HANDLE UserToken;
HWND hStatusWindow; HWND hStatusWindow;
BOOL SignaledStatusWindowCreated; 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; } GINA_CONTEXT, *PGINA_CONTEXT;
HINSTANCE hDllInstance; 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 */ #endif /* __MSGINA_H */
/* EOF */ /* EOF */

View file

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

View file

@ -9,26 +9,51 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_LOGOFFICON ICON "resources/ico_logoff.ico" 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
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
CAPTION "Please wait..." CAPTION "Please wait..."
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US FONT 8,"MS Shell Dlg 2",400,0,1
FONT 8, "MS Shell Dlg" BEGIN
{ LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS
LTEXT "", IDC_STATUSLABEL, 7, 8, 234, 12, SS_ENDELLIPSIS 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 #ifndef __MSGINA_RESOURCE_H
#define __MSGINA_RESOURCE_H #define __MSGINA_RESOURCE_H
#define IDD_LOGOFF_DLG 2250 #define IDC_STATIC -1
#define IDD_STATUSWINDOW 2450 #define IDD_STATUSWINDOW_DLG 100
#define IDD_NOTICE_DLG 101
#define IDC_LOGOFFICON 21 #define IDD_LOGGEDON_DLG 102
#define IDC_STATUSLABEL 2451 #define IDD_LOGGEDOUT_DLG 103
#define IDC_LOGOFF 1001
#define IDI_LOGOFFICON 2251 #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 */ #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,
};