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,18 +3,19 @@
* 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
@ -23,53 +24,233 @@
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)
void
UninitSAS(PWLSESSION Session)
{
if(Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
}
BOOL
SetupSAS(PWLSESSION Session, HWND hwndSAS)
{
/* 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; return FALSE;
}
/* Register Ctrl+Shift+Esc */ StartupInfo.cb = sizeof(StartupInfo);
Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE); StartupInfo.lpReserved = NULL;
if(!Session->TaskManHotkey) StartupInfo.lpDesktop = NULL;
{ StartupInfo.lpTitle = NULL;
DPRINT1("WL-SAS: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n"); 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; return TRUE;
} }
BOOL static BOOL
DestroySAS(PWLSESSION Session, HWND hwndSAS) HandleLogon(
IN OUT PWLSESSION Session)
{
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);
}
static BOOL
HandleLogoff(
IN OUT PWLSESSION Session)
{
FIXME("FIXME: HandleLogoff() unimplemented\n");
return FALSE;
}
static BOOL
HandleShutdown(
IN OUT PWLSESSION Session)
{
FIXME("FIXME: HandleShutdown() unimplemented\n");
return FALSE;
}
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);
}
}
VOID
DispatchSAS(
IN OUT PWLSESSION Session,
IN DWORD dwSasType)
{
DWORD wlxAction = WLX_SAS_ACTION_NONE;
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 */ /* Unregister hotkeys */
UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL); UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL);
if(Session->TaskManHotkey) if (Session->TaskManHotkey)
{
UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC); UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC);
}
return TRUE; return TRUE;
} }
@ -196,28 +377,35 @@ 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)
{ switch (uMsg)
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
switch(uMsg)
{ {
case WM_HOTKEY: case WM_HOTKEY:
{ {
switch(wParam) switch (lParam)
{ {
case HK_CTRL_ALT_DEL: case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE):
DPRINT1("SAS: CTR+ALT+DEL\n"); {
break; TRACE("SAS: CONTROL+ALT+DELETE\n");
case HK_CTRL_SHIFT_ESC: DispatchSAS(Session, WLX_SAS_TYPE_CTRL_ALT_DEL);
DPRINT1("SAS: CTR+SHIFT+ESC\n"); return TRUE;
break;
} }
return 0; 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: case WM_CREATE:
{ {
@ -225,38 +413,46 @@ SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams; Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
/* Save the Session pointer */ /* Save the Session pointer */
SetWindowLongPtr(Session->SASWindow, GWLP_USERDATA, (DWORD_PTR)Session); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)Session);
if(!SetupSAS(Session, hwnd)) return RegisterHotKeys(Session, hwndDlg);
{
/* Fail! */
return 1;
} }
return 0; case WM_DESTROY:
{
UnregisterHotKeys(Session, hwndDlg);
return TRUE;
} }
case PM_WINLOGON_EXITWINDOWS: case PM_WINLOGON_EXITWINDOWS:
{ {
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam); return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam);
} }
case WM_DESTROY: }
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
}
static VOID
UninitializeSAS(
IN OUT PWLSESSION Session)
{
if (Session->SASWindow)
{ {
DestroySAS(Session, hwnd); DestroyWindow(Session->SASWindow);
return 0; Session->SASWindow = NULL;
} }
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
} }
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;
@ -266,25 +462,30 @@ InitializeSAS(PWLSESSION Session)
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,
WINLOGON_SAS_TITLE,
WS_POPUP,
0, 0, 0, 0, 0, 0,
hAppInstance, Session);
if (!Session->SASWindow)
{ {
DPRINT1("WL: Failed to create SAS window\n"); ERR("WL: Failed to create SAS window\n");
return FALSE; 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,61 +3,36 @@
* 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;
va_start(ap, fmt);
wsprintf(buffer, fmt, ap);
va_end(ap);
OutputDebugString(buffer);
}
INT_PTR CALLBACK
ShutdownComputerProc (HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{ {
case WM_COMMAND: case WM_COMMAND:
{ {
switch(LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDC_BTNSHTDOWNCOMPUTER: case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER); EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
@ -72,11 +47,11 @@ ShutdownComputerProc (HWND hwndDlg,
break; break;
} }
} }
return FALSE; return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
} }
static BOOLEAN static BOOL
StartServices (VOID) StartServicesManager(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;
@ -429,9 +361,13 @@ DoLogonUser (PWCHAR Name,
StartupInfo.cbReserved2 = 0; StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0; StartupInfo.lpReserved2 = 0;
Result = CreateProcessAsUserW (WLSession->UserToken, /* Get privilege */
RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);
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)
{ if (Session->SuppressStatus)
case WM_HOTKEY:
{
switch (lParam)
{
case MAKELONG(MOD_CONTROL | MOD_ALT, VK_DELETE):
{
DispatchSAS(WLSession, WLX_SAS_TYPE_CTRL_ALT_DEL);
return TRUE; return TRUE;
}
}
}
}
return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 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);
return WlxAction;
}
void
SessionLoop(PWLSESSION Session)
{
//WCHAR StatusMsg[256];
// HANDLE hShutdownEvent;
DWORD WlxAction;
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;
if(Session->SASAction == WLX_SAS_ACTION_LOGOFF)
{
/* the system wants to log off here */
Session->LogonStatus = LOGON_SHUTDOWN;
break;
}
}
WlxAction = DoLogin(Session);
if (WlxAction == WLX_SAS_ACTION_LOGON) if (WlxAction == WLX_SAS_ACTION_LOGON)
{ {
DoLogonUser(L"Administrator", L"Secret"); Session->UserToken = Token;
} if (!DoBrokenLogonUser(Session, &MprNotifyInfo))
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; WlxAction = WLX_SAS_ACTION_NONE;
} }
if(WlxAction == WLX_SAS_ACTION_NONE) return WlxAction;
}
#endif
static VOID
SessionLoop(
IN OUT PWLSESSION Session)
{
//WCHAR StatusMsg[256];
//HANDLE hShutdownEvent;
MSG Msg;
Session->LogonStatus = WKSTA_IS_LOGGED_OFF;
RemoveStatusMessage(Session);
DispatchSAS(Session, WLX_SAS_TYPE_TIMEOUT);
/* Message loop for the SAS window */
while (GetMessage(&Msg, WLSession->SASWindow, 0, 0))
{ {
if(Session->SASAction == WLX_SAS_ACTION_LOGOFF) TranslateMessage(&Msg);
{ DispatchMessage(&Msg);
/* 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 */ /* 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,8 +70,11 @@ typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID);
typedef struct _MSGINAFUNCTIONS typedef struct _MSGINAFUNCTIONS
{ {
/* Functions always available for a valid GINA */
PFWLXNEGOTIATE WlxNegotiate; PFWLXNEGOTIATE WlxNegotiate;
PFWLXINITIALIZE WlxInitialize; PFWLXINITIALIZE WlxInitialize;
/* Functions available if WlxVersion >= WLX_VERSION_1_0 (MS Windows 3.5.0) */
PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice; PFWLXDISPLAYSASNOTICE WlxDisplaySASNotice;
PFWLXLOGGEDOUTSAS WlxLoggedOutSAS; PFWLXLOGGEDOUTSAS WlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL WlxActivateUserShell; PFWLXACTIVATEUSERSHELL WlxActivateUserShell;
@ -110,13 +86,19 @@ typedef struct _MSGINAFUNCTIONS
PFWLXLOGOFF WlxLogoff; PFWLXLOGOFF WlxLogoff;
PFWLXSHUTDOWN WlxShutdown; PFWLXSHUTDOWN WlxShutdown;
/* Functions available if WlxVersion >= WLX_VERSION_1_1 (MS Windows 3.5.1) */
PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify; PFWLXSCREENSAVERNOTIFY WlxScreenSaverNotify;
PFWLXSTARTAPPLICATION WlxStartApplication; 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; PFWLXNETWORKPROVIDERLOAD WlxNetworkProviderLoad;
PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage; PFWLXDISPLAYSTATUSMESSAGE WlxDisplayStatusMessage;
PFWLXGETSTATUSMESSAGE WlxGetStatusMessage; PFWLXGETSTATUSMESSAGE WlxGetStatusMessage;
PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage; PFWLXREMOVESTATUSMESSAGE WlxRemoveStatusMessage;
/* Functions available if WlxVersion >= WLX_VERSION_1_4 (MS Windows XP) */
} MSGINAFUNCTIONS, *PMSGINAFUNCTIONS; } MSGINAFUNCTIONS, *PMSGINAFUNCTIONS;
typedef struct _MSGINAINSTANCE typedef struct _MSGINAINSTANCE
@ -127,6 +109,11 @@ typedef struct _MSGINAINSTANCE
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 */

View file

@ -1,22 +1,21 @@
/* $Id$ /*
*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS Winlogon
* FILE: services/winlogon/wlx.c * FILE: services/winlogon/wlx.c
* PURPOSE: Logon * PURPOSE: Logon
* PROGRAMMER: David Welch (welch@cwcom.net) * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY: * Ge van Geldorp (gvg@reactos.com)
* 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>
#define Unimplemented DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__) //#define UNIMPLEMENTED DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__)
#define WINLOGON_DESKTOP L"Winlogon" #define WINLOGON_DESKTOP L"Winlogon"
@ -25,8 +24,7 @@
*/ */
VOID WINAPI VOID WINAPI
WlxUseCtrlAltDel( WlxUseCtrlAltDel(
HANDLE hWlx HANDLE hWlx)
)
{ {
WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL); WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL);
} }
@ -37,8 +35,7 @@ WlxUseCtrlAltDel(
VOID WINAPI VOID WINAPI
WlxSetContextPointer( WlxSetContextPointer(
HANDLE hWlx, HANDLE hWlx,
PVOID pWlxContext PVOID pWlxContext)
)
{ {
WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL); WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL);
} }
@ -49,8 +46,7 @@ WlxSetContextPointer(
VOID WINAPI VOID WINAPI
WlxSasNotify( WlxSasNotify(
HANDLE hWlx, HANDLE hWlx,
DWORD dwSasType DWORD dwSasType)
)
{ {
DispatchSAS((PWLSESSION)hWlx, dwSasType); DispatchSAS((PWLSESSION)hWlx, dwSasType);
} }
@ -61,10 +57,9 @@ WlxSasNotify(
BOOL WINAPI BOOL WINAPI
WlxSetTimeout( WlxSetTimeout(
HANDLE hWlx, HANDLE hWlx,
DWORD Timeout DWORD Timeout)
)
{ {
/* Unimplemented; */ UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -76,10 +71,9 @@ WlxAssignShellProtection(
HANDLE hWlx, HANDLE hWlx,
HANDLE hToken, HANDLE hToken,
HANDLE hProcess, HANDLE hProcess,
HANDLE hThread HANDLE hThread)
)
{ {
Unimplemented; UNIMPLEMENTED;
return 0; return 0;
} }
@ -92,8 +86,7 @@ WlxMessageBox(
HWND hwndOwner, HWND hwndOwner,
LPWSTR lpszText, LPWSTR lpszText,
LPWSTR lpszTitle, LPWSTR lpszTitle,
UINT fuStyle UINT fuStyle)
)
{ {
return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle);
} }
@ -107,8 +100,7 @@ WlxDialogBox(
HANDLE hInst, HANDLE hInst,
LPWSTR lpszTemplate, LPWSTR lpszTemplate,
HWND hwndOwner, HWND hwndOwner,
DLGPROC dlgprc DLGPROC dlgprc)
)
{ {
return (int)DialogBox(hInst, lpszTemplate, hwndOwner, dlgprc); return (int)DialogBox(hInst, lpszTemplate, hwndOwner, dlgprc);
} }
@ -123,14 +115,13 @@ WlxDialogBoxParam(
LPWSTR lpszTemplate, LPWSTR lpszTemplate,
HWND hwndOwner, HWND hwndOwner,
DLGPROC dlgprc, DLGPROC dlgprc,
LPARAM dwInitParam LPARAM dwInitParam)
)
{ {
return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam); return (int)DialogBoxParam(hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam);
} }
/* /*
* @unimplemented * @implemented
*/ */
int WINAPI int WINAPI
WlxDialogBoxIndirect( WlxDialogBoxIndirect(
@ -138,8 +129,7 @@ WlxDialogBoxIndirect(
HANDLE hInst, HANDLE hInst,
LPCDLGTEMPLATE hDialogTemplate, LPCDLGTEMPLATE hDialogTemplate,
HWND hwndOwner, HWND hwndOwner,
DLGPROC dlgprc DLGPROC dlgprc)
)
{ {
return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, dlgprc); return (int)DialogBoxIndirect(hInst, hDialogTemplate, hwndOwner, dlgprc);
} }
@ -154,34 +144,31 @@ WlxDialogBoxIndirectParam(
LPCDLGTEMPLATE hDialogTemplate, LPCDLGTEMPLATE hDialogTemplate,
HWND hwndOwner, HWND hwndOwner,
DLGPROC dlgprc, DLGPROC dlgprc,
LPARAM dwInitParam LPARAM dwInitParam)
)
{ {
return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, dlgprc, dwInitParam); return (int)DialogBoxIndirectParam(hInst, hDialogTemplate, hwndOwner, dlgprc, dwInitParam);
} }
/* /*
* @unimplemented * @implemented
*/ */
int WINAPI int WINAPI
WlxSwitchDesktopToUser( WlxSwitchDesktopToUser(
HANDLE hWlx HANDLE hWlx)
)
{ {
Unimplemented; PWLSESSION Session = (PWLSESSION)hWlx;
return 0; return (int)SwitchDesktop(Session->ApplicationDesktop);
} }
/* /*
* @unimplemented * @implemented
*/ */
int WINAPI int WINAPI
WlxSwitchDesktopToWinlogon( WlxSwitchDesktopToWinlogon(
HANDLE hWlx HANDLE hWlx)
)
{ {
Unimplemented; PWLSESSION Session = (PWLSESSION)hWlx;
return 0; return (int)SwitchDesktop(Session->WinlogonDesktop);
} }
/* /*
@ -191,10 +178,9 @@ int WINAPI
WlxChangePasswordNotify( WlxChangePasswordNotify(
HANDLE hWlx, HANDLE hWlx,
PWLX_MPR_NOTIFY_INFO pMprInfo, PWLX_MPR_NOTIFY_INFO pMprInfo,
DWORD dwChangeInfo DWORD dwChangeInfo)
)
{ {
Unimplemented; UNIMPLEMENTED;
return 0; return 0;
} }
@ -204,10 +190,9 @@ WlxChangePasswordNotify(
BOOL WINAPI BOOL WINAPI
WlxGetSourceDesktop( WlxGetSourceDesktop(
HANDLE hWlx, HANDLE hWlx,
PWLX_DESKTOP* ppDesktop PWLX_DESKTOP* ppDesktop)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -217,10 +202,9 @@ WlxGetSourceDesktop(
BOOL WINAPI BOOL WINAPI
WlxSetReturnDesktop( WlxSetReturnDesktop(
HANDLE hWlx, HANDLE hWlx,
PWLX_DESKTOP pDesktop PWLX_DESKTOP pDesktop)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -233,10 +217,9 @@ WlxCreateUserDesktop(
HANDLE hToken, HANDLE hToken,
DWORD Flags, DWORD Flags,
PWSTR pszDesktopName, PWSTR pszDesktopName,
PWLX_DESKTOP* ppDesktop PWLX_DESKTOP* ppDesktop)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -249,10 +232,9 @@ WlxChangePasswordNotifyEx(
PWLX_MPR_NOTIFY_INFO pMprInfo, PWLX_MPR_NOTIFY_INFO pMprInfo,
DWORD dwChangeInfo, DWORD dwChangeInfo,
PWSTR ProviderName, PWSTR ProviderName,
PVOID Reserved PVOID Reserved)
)
{ {
Unimplemented; UNIMPLEMENTED;
return 0; return 0;
} }
@ -263,10 +245,9 @@ BOOL WINAPI
WlxCloseUserDesktop( WlxCloseUserDesktop(
HANDLE hWlx, HANDLE hWlx,
PWLX_DESKTOP pDesktop, PWLX_DESKTOP pDesktop,
HANDLE hToken HANDLE hToken)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -278,14 +259,14 @@ WlxSetOption(
HANDLE hWlx, HANDLE hWlx,
DWORD Option, DWORD Option,
ULONG_PTR Value, ULONG_PTR Value,
ULONG_PTR* OldValue ULONG_PTR* OldValue)
)
{ {
PWLSESSION Session = (PWLSESSION)hWlx; PWLSESSION Session = (PWLSESSION)hWlx;
UNIMPLEMENTED;
if(Session || !Value) if (Session || !Value)
{ {
switch(Option) switch (Option)
{ {
case WLX_OPTION_USE_CTRL_ALT_DEL: case WLX_OPTION_USE_CTRL_ALT_DEL:
return TRUE; return TRUE;
@ -310,14 +291,14 @@ BOOL WINAPI
WlxGetOption( WlxGetOption(
HANDLE hWlx, HANDLE hWlx,
DWORD Option, DWORD Option,
ULONG_PTR* Value ULONG_PTR* Value)
)
{ {
PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx; PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx;
Unimplemented; UNIMPLEMENTED;
if(Instance || !Value)
if (Instance || !Value)
{ {
switch(Option) switch (Option)
{ {
case WLX_OPTION_USE_CTRL_ALT_DEL: case WLX_OPTION_USE_CTRL_ALT_DEL:
return TRUE; return TRUE;
@ -333,7 +314,7 @@ WlxGetOption(
return FALSE; return FALSE;
case WLX_OPTION_DISPATCH_TABLE_SIZE: case WLX_OPTION_DISPATCH_TABLE_SIZE:
{ {
switch(Instance->Version) switch (Instance->Version)
{ {
case WLX_VERSION_1_0: case WLX_VERSION_1_0:
*Value = sizeof(WLX_DISPATCH_VERSION_1_0); *Value = sizeof(WLX_DISPATCH_VERSION_1_0);
@ -351,7 +332,7 @@ WlxGetOption(
*Value = sizeof(WLX_DISPATCH_VERSION_1_4); *Value = sizeof(WLX_DISPATCH_VERSION_1_4);
break; break;
default: default:
return 0; return FALSE;
} }
return TRUE; return TRUE;
} }
@ -366,10 +347,9 @@ WlxGetOption(
*/ */
VOID WINAPI VOID WINAPI
WlxWin31Migrate( WlxWin31Migrate(
HANDLE hWlx HANDLE hWlx)
)
{ {
Unimplemented; UNIMPLEMENTED;
} }
/* /*
@ -377,10 +357,9 @@ WlxWin31Migrate(
*/ */
BOOL WINAPI BOOL WINAPI
WlxQueryClientCredentials( WlxQueryClientCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -389,34 +368,9 @@ WlxQueryClientCredentials(
*/ */
BOOL WINAPI BOOL WINAPI
WlxQueryInetConnectorCredentials( WlxQueryInetConnectorCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
DWORD WINAPI
WlxQueryConsoleSwitchCredentials(
PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred
)
{
Unimplemented;
return 0;
}
/*
* @unimplemented
*/
BOOL WINAPI
WlxQueryTsLogonCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred
)
{
Unimplemented;
return FALSE; return FALSE;
} }
@ -424,9 +378,9 @@ WlxQueryTsLogonCredentials(
* @unimplemented * @unimplemented
*/ */
BOOL WINAPI BOOL WINAPI
WlxDisconnect(void) WlxDisconnect(VOID)
{ {
Unimplemented; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -438,14 +392,35 @@ WlxQueryTerminalServicesData(
HANDLE hWlx, HANDLE hWlx,
PWLX_TERMINAL_SERVICES_DATA pTSData, PWLX_TERMINAL_SERVICES_DATA pTSData,
WCHAR* UserName, WCHAR* UserName,
WCHAR* Domain WCHAR* Domain)
)
{ {
Unimplemented; UNIMPLEMENTED;
return 0; return 0;
} }
const /*
* @unimplemented
*/
DWORD WINAPI
WlxQueryConsoleSwitchCredentials(
PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL WINAPI
WlxQueryTsLogonCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred)
{
UNIMPLEMENTED;
return FALSE;
}
static const
WLX_DISPATCH_VERSION_1_4 FunctionTable = { WLX_DISPATCH_VERSION_1_4 FunctionTable = {
WlxUseCtrlAltDel, WlxUseCtrlAltDel,
WlxSetContextPointer, WlxSetContextPointer,
@ -478,50 +453,54 @@ WLX_DISPATCH_VERSION_1_4 FunctionTable = {
/******************************************************************************/ /******************************************************************************/
static void static BOOL
GetMsGinaPath(WCHAR *path) GetGinaPath(
OUT LPWSTR Path,
IN DWORD Len)
{ {
DWORD Status, Type, Size; LONG Status;
DWORD Type, Size;
HKEY hKey; HKEY hKey;
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
0, 0,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
&hKey); &hKey);
if(Status != ERROR_SUCCESS) if (Status != ERROR_SUCCESS)
{ {
wcscpy(path, L"msgina.dll"); /* Default value */
return; wcsncpy(Path, L"msgina.dll", Len);
return TRUE;
} }
Size = MAX_PATH * sizeof(WCHAR); Size = Len * sizeof(WCHAR);
Status = RegQueryValueEx(hKey, Status = RegQueryValueEx(
hKey,
L"GinaDLL", L"GinaDLL",
NULL, NULL,
&Type, &Type,
(LPBYTE)path, (LPBYTE)Path,
&Size); &Size);
if((Status != ERROR_SUCCESS) || (Size != REG_SZ) || (Size == 0)) if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0)
{ wcsncpy(Path, L"msgina.dll", Len);
wcscpy(path, L"msgina.dll");
}
RegCloseKey(hKey); RegCloseKey(hKey);
return TRUE;
} }
INT_PTR CALLBACK static INT_PTR CALLBACK
GinaLoadFailedProc( GinaLoadFailedWindowProc(
HWND hwndDlg, IN HWND hwndDlg,
UINT uMsg, IN UINT uMsg,
WPARAM wParam, IN WPARAM wParam,
LPARAM lParam IN LPARAM lParam)
)
{ {
switch(uMsg) switch (uMsg)
{ {
case WM_COMMAND: case WM_COMMAND:
{ {
switch(LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDOK: case IDOK:
EndDialog(hwndDlg, IDOK); EndDialog(hwndDlg, IDOK);
@ -532,17 +511,13 @@ GinaLoadFailedProc(
case WM_INITDIALOG: case WM_INITDIALOG:
{ {
int len; int len;
WCHAR str[MAX_PATH], str2[MAX_PATH]; WCHAR templateText[MAX_PATH], text[MAX_PATH];
if(lParam) len = GetDlgItemText(hwndDlg, IDC_GINALOADFAILED, templateText, MAX_PATH);
if (len)
{ {
len = GetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str, MAX_PATH); wsprintf(text, templateText, (LPWSTR)lParam);
SetDlgItemText(hwndDlg, IDC_GINALOADFAILED, text);
if(len)
{
wsprintf(str2, str, (LPWSTR)lParam);
SetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str2);
}
} }
SetFocus(GetDlgItem(hwndDlg, IDOK)); SetFocus(GetDlgItem(hwndDlg, IDOK));
break; break;
@ -553,117 +528,129 @@ GinaLoadFailedProc(
return TRUE; return TRUE;
} }
} }
return FALSE;
return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
} }
BOOL #define FAIL_AND_RETURN() return DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedWindowProc, (LPARAM)GinaDll) && FALSE
LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion, HMODULE *GinaInstance) static BOOL
LoadGina(
IN OUT PMSGINAFUNCTIONS Functions,
OUT DWORD *DllVersion,
OUT HMODULE *GinaInstance)
{ {
HMODULE hGina; HMODULE hGina;
WCHAR GinaDll[MAX_PATH + 1]; WCHAR GinaDll[MAX_PATH + 1];
GetMsGinaPath(GinaDll); GinaDll[0] = '\0';
if (!GetGinaPath(GinaDll, MAX_PATH))
FAIL_AND_RETURN();
/* Terminate string */
GinaDll[MAX_PATH] = '\0';
if(!(hGina = LoadLibrary(GinaDll))) if (!(hGina = LoadLibrary(GinaDll)))
{ FAIL_AND_RETURN();
DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedProc, (LPARAM)&GinaDll);
return FALSE;
}
*GinaInstance = hGina; *GinaInstance = hGina;
Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate");
Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize");
if(Functions->WlxNegotiate) if (!Functions->WlxInitialize)
{ FAIL_AND_RETURN();
if(!Functions->WlxNegotiate(WLX_VERSION_1_3, DllVersion))
{
return FALSE;
}
if(*DllVersion >= WLX_VERSION_1_0) if (!Functions->WlxNegotiate)
{
/* Assume current version */
*DllVersion = WLX_CURRENT_VERSION;
}
else if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion))
FAIL_AND_RETURN();
if (*DllVersion >= WLX_VERSION_1_0)
{ {
Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell"); Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell");
if (!Functions->WlxActivateUserShell) FAIL_AND_RETURN();
Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice"); Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice");
if (!Functions->WlxDisplayLockedNotice) FAIL_AND_RETURN();
Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice"); Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice");
if (!Functions->WlxDisplaySASNotice) FAIL_AND_RETURN();
Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk"); Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk");
if (!Functions->WlxIsLockOk) FAIL_AND_RETURN();
Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk"); Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk");
if (!Functions->WlxIsLogoffOk) FAIL_AND_RETURN();
Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS"); Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
if (!Functions->WlxLoggedOnSAS) FAIL_AND_RETURN();
Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS"); Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
if (!Functions->WlxLoggedOutSAS) FAIL_AND_RETURN();
Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff"); Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff");
if (!Functions->WlxLogoff) FAIL_AND_RETURN();
Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown"); Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown");
if (!Functions->WlxShutdown) FAIL_AND_RETURN();
Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS"); Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
if (!Functions->WlxWkstaLockedSAS) FAIL_AND_RETURN();
} }
if(*DllVersion >= WLX_VERSION_1_1) if (*DllVersion >= WLX_VERSION_1_1)
{ {
Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify"); Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify");
if (!Functions->WlxScreenSaverNotify) FAIL_AND_RETURN();
Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication"); Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication");
if (!Functions->WlxStartApplication) FAIL_AND_RETURN();
} }
if(*DllVersion >= WLX_VERSION_1_3) if (*DllVersion >= WLX_VERSION_1_3)
{ {
Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage"); Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage");
if (!Functions->WlxDisplayStatusMessage) FAIL_AND_RETURN();
Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage"); Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage");
if (!Functions->WlxGetStatusMessage) FAIL_AND_RETURN();
Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad"); Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad");
if (!Functions->WlxNetworkProviderLoad) FAIL_AND_RETURN();
Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage"); Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage");
if (!Functions->WlxRemoveStatusMessage) FAIL_AND_RETURN();
} }
if(*DllVersion >= WLX_VERSION_1_4) return TRUE;
{
}
}
return (Functions->WlxNegotiate != NULL) && (Functions->WlxInitialize != NULL);
} }
#undef FAIL_AND_RETURN
PWLSESSION BOOL
MsGinaInit(void) GinaInit(
IN OUT PWLSESSION Session)
{ {
PWLSESSION WLSession;
DWORD GinaDllVersion; DWORD GinaDllVersion;
WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION)); if (!LoadGina(&Session->MsGina.Functions, &GinaDllVersion, &Session->MsGina.hDllInstance))
if(!WLSession) return FALSE;
{
return NULL;
}
if(!LoadGina(&WLSession->MsGina.Functions, &GinaDllVersion, &WLSession->MsGina.hDllInstance)) Session->MsGina.Context = NULL;
{ Session->MsGina.Version = GinaDllVersion;
HeapFree(GetProcessHeap(), 0, WLSession); Session->SuppressStatus = FALSE;
return NULL;
}
WLSession->MsGina.Context = NULL; return Session->MsGina.Functions.WlxInitialize(
WLSession->MsGina.Version = GinaDllVersion; Session->InteractiveWindowStationName,
WLSession->SuppressStatus = FALSE; (HANDLE)Session,
if(!WLSession->MsGina.Functions.WlxInitialize(WLSession->InteractiveWindowStationName,
(HANDLE)WLSession,
NULL, NULL,
(PVOID)&FunctionTable, (PVOID)&FunctionTable,
&WLSession->MsGina.Context)) &Session->MsGina.Context);
{
HeapFree(GetProcessHeap(), 0, WLSession);
return NULL;
}
return WLSession;
} }
BOOL BOOL
WlxCreateWindowStationAndDesktops(PWLSESSION Session) CreateWindowStationAndDesktops(
IN OUT PWLSESSION Session)
{ {
/* /*
* Create the interactive window station * Create the interactive window station
*/ */
Session->InteractiveWindowStationName = L"WinSta0"; Session->InteractiveWindowStationName = L"WinSta0";
Session->InteractiveWindowStation = CreateWindowStation(Session->InteractiveWindowStationName, Session->InteractiveWindowStation = CreateWindowStation(
0, GENERIC_ALL, NULL); Session->InteractiveWindowStationName,
if(!Session->InteractiveWindowStation) 0,
WINSTA_CREATEDESKTOP,
NULL);
if (!Session->InteractiveWindowStation)
{ {
DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError()); ERR("WL: Failed to create window station (%lu)\n", GetLastError());
return FALSE; return FALSE;
} }
SetProcessWindowStation(Session->InteractiveWindowStation); SetProcessWindowStation(Session->InteractiveWindowStation);
@ -671,37 +658,40 @@ WlxCreateWindowStationAndDesktops(PWLSESSION Session)
/* /*
* Create the application desktop * Create the application desktop
*/ */
Session->ApplicationDesktop = CreateDesktop(L"Default", Session->ApplicationDesktop = CreateDesktop(
L"Default",
NULL, NULL,
NULL, NULL,
0, /* FIXME: Set some flags */ 0, /* FIXME: Set some flags */
GENERIC_ALL, GENERIC_ALL,
NULL); NULL);
if(!Session->ApplicationDesktop) if (!Session->ApplicationDesktop)
{ {
DbgPrint("WL: Failed to create Default desktop (0x%X)\n", GetLastError()); ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
return FALSE; return FALSE;
} }
/* /*
* Create the winlogon desktop * Create the winlogon desktop
*/ */
Session->WinlogonDesktop = CreateDesktop(WINLOGON_DESKTOP, Session->WinlogonDesktop = CreateDesktop(
WINLOGON_DESKTOP,
NULL, NULL,
NULL, NULL,
0, /* FIXME: Set some flags */ 0, /* FIXME: Set some flags */
GENERIC_ALL, GENERIC_ALL,
NULL); NULL);
if(!Session->WinlogonDesktop) if (!Session->WinlogonDesktop)
{ {
DbgPrint("WL: Failed to create Winlogon desktop (0x%X)\n", GetLastError()); ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
return FALSE; return FALSE;
} }
/* /*
* Create the screen saver desktop * Create the screen saver desktop
*/ */
Session->ScreenSaverDesktop = CreateDesktop(L"Screen-Saver", Session->ScreenSaverDesktop = CreateDesktop(
L"Screen-Saver",
NULL, NULL,
NULL, NULL,
0, /* FIXME: Set some flags */ 0, /* FIXME: Set some flags */
@ -709,10 +699,22 @@ WlxCreateWindowStationAndDesktops(PWLSESSION Session)
NULL); NULL);
if(!Session->ScreenSaverDesktop) if(!Session->ScreenSaverDesktop)
{ {
DbgPrint("WL: Failed to create Screen-Saver desktop (0x%X)\n", GetLastError()); ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
return FALSE;
}
/* FIXME: big HACK */
Session->WinlogonDesktop = Session->ApplicationDesktop;
/*
* Switch to winlogon desktop
*/
if (!SetThreadDesktop(Session->WinlogonDesktop) ||
!SwitchDesktop(Session->WinlogonDesktop))
{
ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }

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);
if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3))
return FALSE; return FALSE;
*pdwDllVersion = GINA_VERSION; *pdwDllVersion = WLX_VERSION_1_3;
return TRUE; 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;
} }
@ -261,185 +261,39 @@ WlxLoggedOnSAS(
PVOID pReserved) PVOID pReserved)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
int SasAction = WLX_SAS_ACTION_NONE;
switch(dwSasType) DPRINT1("WlxLoggedOnSAS(0x%lx)\n", 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; 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 * @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;
HANDLE Thread;
DWORD ThreadId;
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
if(!pgContext->hStatusWindow) DPRINT1("WlxDisplayStatusMessage(\"%S\")\n", pMessage);
{
msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG));
if(!msg)
return FALSE;
msg->Context = pgContext; return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage);
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;
} }
/* /*
* @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;
@ -448,18 +302,37 @@ WlxRemoveStatusMessage(
return TRUE; return TRUE;
} }
static LONG
/* ReadRegSzKey(
* @implemented IN HKEY hKey,
*/ IN LPCWSTR pszKey,
VOID WINAPI OUT LPWSTR* pValue)
WlxDisplaySASNotice(
PVOID pWlxContext)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; LONG rc;
pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); 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 static PWSTR
DuplicationString(PWSTR Str) DuplicationString(PWSTR Str)
@ -467,96 +340,215 @@ DuplicationString(PWSTR Str)
DWORD cb; DWORD cb;
PWSTR NewStr; PWSTR NewStr;
if (Str == NULL) return NULL;
cb = (wcslen(Str) + 1) * sizeof(WCHAR); cb = (wcslen(Str) + 1) * sizeof(WCHAR);
if((NewStr = LocalAlloc(LMEM_FIXED, cb))) if ((NewStr = LocalAlloc(LMEM_FIXED, cb)))
{
memcpy(NewStr, Str, cb); memcpy(NewStr, Str, cb);
}
return NewStr; return NewStr;
} }
BOOL
/* DoLoginTasks(
* @unimplemented IN OUT PGINA_CONTEXT pgContext,
*/ IN PWSTR UserName,
int WINAPI IN PWSTR Domain,
WlxLoggedOutSAS( IN PWSTR Password)
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile)
{ {
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
TOKEN_STATISTICS Stats; TOKEN_STATISTICS Stats;
DWORD cbStats; DWORD cbStats;
if(!phToken) if(!LogonUserW(UserName, Domain, Password,
{
WARN("msgina: phToken == NULL!\n");
return WLX_SAS_ACTION_NONE;
}
if(!LogonUser(L"Administrator", NULL, L"Secrect",
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */ LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
LOGON32_PROVIDER_DEFAULT, LOGON32_PROVIDER_DEFAULT,
phToken)) pgContext->phToken))
{ {
WARN("msgina: Logonuser() failed\n"); WARN("GINA: Logonuser() failed\n");
return WLX_SAS_ACTION_NONE; return FALSE;
} }
if(!(*phToken)) if(!(*pgContext->phToken))
{ {
WARN("msgina: *phToken == NULL!\n"); WARN("GINA: *phToken == NULL!\n");
return WLX_SAS_ACTION_NONE; return FALSE;
} }
pgContext->UserToken =*phToken; pgContext->UserToken =*pgContext->phToken;
*pdwOptions = 0; *pgContext->pdwOptions = 0;
*pProfile =NULL; *pgContext->pProfile =NULL;
if(!GetTokenInformation(*phToken, if(!GetTokenInformation(*pgContext->phToken,
TokenStatistics, TokenStatistics,
(PVOID)&Stats, (PVOID)&Stats,
sizeof(TOKEN_STATISTICS), sizeof(TOKEN_STATISTICS),
&cbStats)) &cbStats))
{ {
WARN("msgina: Couldn't get Autentication id from user token!\n"); WARN("GINA: Couldn't get Authentication id from user token!\n");
return WLX_SAS_ACTION_NONE; return FALSE;
}
*pAuthenticationId = Stats.AuthenticationId;
pNprNotifyInfo->pszUserName = DuplicationString(L"Administrator");
pNprNotifyInfo->pszDomain = NULL;
pNprNotifyInfo->pszPassword = DuplicationString(L"Secret");
pNprNotifyInfo->pszOldPassword = NULL;
return WLX_SAS_ACTION_LOGON;
}
BOOL STDCALL
DllMain(
HINSTANCE hinstDLL,
DWORD dwReason,
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;
} }
*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; 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(
IN PVOID pWlxContext)
{
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");
}
/*
* @implemented
*/
INT WINAPI
WlxLoggedOutSAS(
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;
DPRINT1("WlxLoggedOutSAS()\n");
pgContext->pAuthenticationId = pAuthenticationId;
pgContext->pdwOptions = pdwOptions;
pgContext->phToken = phToken;
pgContext->pNprNotifyInfo = pNprNotifyInfo;
pgContext->pProfile = pProfile;
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 pGinaUI->LoggedOutSAS(pgContext);
}
BOOL WINAPI
DllMain(
IN HINSTANCE hinstDLL,
IN DWORD dwReason,
IN LPVOID lpvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
hDllInstance = hinstDLL;
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,
};