reactos/base/system/winlogon/wlx.c

1108 lines
25 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Winlogon
* FILE: base/system/winlogon/wlx.c
* PURPOSE: Logon
* PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* Ge van Geldorp (gvg@reactos.com)
* Herv<EFBFBD> Poussineau (hpoussin@reactos.org)
*/
/* INCLUDES *****************************************************************/
#include "winlogon.h"
typedef struct _DIALOG_LIST_ENTRY
{
LIST_ENTRY Entry;
HWND hWnd;
DLGPROC DlgProc;
LPARAM lParam;
} DIALOG_LIST_ENTRY, *PDIALOG_LIST_ENTRY;
/* GLOBALS ******************************************************************/
//static UINT_PTR IdTimer;
static LIST_ENTRY DialogListHead;
/* FUNCTIONS ****************************************************************/
VOID
InitDialogListHead(VOID)
{
InitializeListHead(&DialogListHead);
}
static
PDIALOG_LIST_ENTRY
AddDialogListEntry(VOID)
{
PDIALOG_LIST_ENTRY ListEntry;
ListEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIALOG_LIST_ENTRY));
if (ListEntry == NULL)
return NULL;
TRACE("Add entry %p\n", ListEntry);
InsertHeadList(&DialogListHead,
&ListEntry->Entry);
return ListEntry;
}
static
VOID
RemoveDialogListEntry(PDIALOG_LIST_ENTRY ListEntry)
{
TRACE("Remove entry %p\n", ListEntry);
RemoveEntryList(&ListEntry->Entry);
RtlFreeHeap(RtlGetProcessHeap(), 0, ListEntry);
}
static
PDIALOG_LIST_ENTRY
GetDialogListEntry(HWND hwndDlg)
{
PDIALOG_LIST_ENTRY Current;
PLIST_ENTRY ListEntry;
ListEntry = DialogListHead.Flink;
while (ListEntry != &DialogListHead)
{
Current = CONTAINING_RECORD(ListEntry,
DIALOG_LIST_ENTRY,
Entry);
if (Current->hWnd == hwndDlg)
{
TRACE("Found entry: %p\n", Current);
return Current;
}
ListEntry = ListEntry->Flink;
}
TRACE("Found no entry!\n");
return NULL;
}
2018-05-21 09:33:02 +00:00
VOID
CloseAllDialogWindows(VOID)
{
PDIALOG_LIST_ENTRY Current;
PLIST_ENTRY ListEntry;
ListEntry = DialogListHead.Flink;
while (ListEntry != &DialogListHead)
{
Current = CONTAINING_RECORD(ListEntry,
DIALOG_LIST_ENTRY,
Entry);
PostMessage(Current->hWnd, WLX_WM_SAS, 0, 0);
ListEntry = ListEntry->Flink;
}
}
static
INT_PTR
CALLBACK
DefaultWlxWindowProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PDIALOG_LIST_ENTRY ListEntry;
INT_PTR ret;
if (uMsg == WM_INITDIALOG)
{
ListEntry = (PDIALOG_LIST_ENTRY)lParam;
TRACE("Set dialog handle: %p\n", hwndDlg);
ListEntry->hWnd = hwndDlg;
lParam = ListEntry->lParam;
// SetTopTimeout(hWnd);
}
else
{
ListEntry = GetDialogListEntry(hwndDlg);
if (ListEntry == NULL)
return FALSE;
}
if (uMsg == WLX_WM_SAS)
{
EndDialog(hwndDlg, WLX_DLG_SAS);
return 0;
}
ret = ListEntry->DlgProc(hwndDlg, uMsg, wParam, lParam);
return ret;
/*
if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer)
{
EndDialog(hwndDlg, -1);
KillTimer(hwndDlg, IdTimer);
return TRUE;
}
else if (uMsg == WM_INITDIALOG)
{
IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL);
return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
}
else if (uMsg == WM_NCDESTROY)
{
BOOL ret;
ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
PreviousWindowProc = NULL;
return ret;
}
else
{
return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
}
*/
}
/*
* @implemented
*/
VOID
WINAPI
WlxUseCtrlAltDel(
HANDLE hWlx)
{
ULONG_PTR OldValue;
TRACE("WlxUseCtrlAltDel()\n");
WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, &OldValue);
}
/*
* @implemented
*/
VOID
WINAPI
WlxSetContextPointer(
HANDLE hWlx,
PVOID pWlxContext)
{
ULONG_PTR OldValue;
TRACE("WlxSetContextPointer(%p)\n", pWlxContext);
WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, &OldValue);
}
/*
* @implemented
*/
VOID
WINAPI
WlxSasNotify(
HANDLE hWlx,
DWORD dwSasType)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxSasNotify(0x%lx)\n", dwSasType);
if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL || dwSasType > WLX_SAS_TYPE_MAX_MSFT_VALUE)
PostMessageW(Session->SASWindow, WLX_WM_SAS, dwSasType, 0);
}
/*
* @implemented
*/
BOOL
WINAPI
WlxSetTimeout(
HANDLE hWlx,
DWORD Timeout)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxSetTimeout(%lu)\n", Timeout);
Session->DialogTimeout = Timeout;
return TRUE;
}
/*
* @unimplemented
*/
int
WINAPI
WlxAssignShellProtection(
HANDLE hWlx,
HANDLE hToken,
HANDLE hProcess,
HANDLE hThread)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(hToken);
UNREFERENCED_PARAMETER(hProcess);
UNREFERENCED_PARAMETER(hThread);
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/
int
WINAPI
WlxMessageBox(
HANDLE hWlx,
HWND hwndOwner,
LPWSTR lpszText,
LPWSTR lpszTitle,
UINT fuStyle)
{
UNREFERENCED_PARAMETER(hWlx);
TRACE("WlxMessageBox()\n");
/* FIXME: Provide a custom window proc to be able to handle timeout */
return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle);
}
/*
* @implemented
*/
int
WINAPI
WlxDialogBox(
HANDLE hWlx,
HANDLE hInst,
LPWSTR lpszTemplate,
HWND hwndOwner,
DLGPROC dlgprc)
{
UNREFERENCED_PARAMETER(hWlx);
TRACE("WlxDialogBox()\n");
return (int)WlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc, 0);
}
/*
* @implemented
*/
int
WINAPI
WlxDialogBoxParam(
HANDLE hWlx,
HANDLE hInst,
LPWSTR lpszTemplate,
HWND hwndOwner,
DLGPROC dlgprc,
LPARAM dwInitParam)
{
PDIALOG_LIST_ENTRY ListEntry;
int ret;
UNREFERENCED_PARAMETER(hWlx);
TRACE("WlxDialogBoxParam()\n");
ListEntry = AddDialogListEntry();
if (ListEntry == NULL)
return -1;
ListEntry->DlgProc = dlgprc;
ListEntry->lParam = dwInitParam;
ret = (int)DialogBoxParamW(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry);
RemoveDialogListEntry(ListEntry);
return ret;
}
/*
* @implemented
*/
int
WINAPI
WlxDialogBoxIndirect(
HANDLE hWlx,
HANDLE hInst,
LPCDLGTEMPLATE hDialogTemplate,
HWND hwndOwner,
DLGPROC dlgprc)
{
UNREFERENCED_PARAMETER(hWlx);
TRACE("WlxDialogBoxIndirect()\n");
return (int)WlxDialogBoxIndirectParam(hWlx, hInst, hDialogTemplate, hwndOwner, dlgprc, 0);
}
/*
* @implemented
*/
int
WINAPI
WlxDialogBoxIndirectParam(
HANDLE hWlx,
HANDLE hInst,
LPCDLGTEMPLATE hDialogTemplate,
HWND hwndOwner,
DLGPROC dlgprc,
LPARAM dwInitParam)
{
PDIALOG_LIST_ENTRY ListEntry;
int ret;
UNREFERENCED_PARAMETER(hWlx);
TRACE("WlxDialogBoxIndirectParam()\n");
ListEntry = AddDialogListEntry();
if (ListEntry == NULL)
return -1;
ListEntry->DlgProc = dlgprc;
ListEntry->lParam = dwInitParam;
ret = (int)DialogBoxIndirectParamW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry);
RemoveDialogListEntry(ListEntry);
return ret;
}
/*
* @implemented
*/
int
WINAPI
WlxSwitchDesktopToUser(
HANDLE hWlx)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxSwitchDesktopToUser()\n");
return (int)SwitchDesktop(Session->ApplicationDesktop);
}
/*
* @implemented
*/
int
WINAPI
WlxSwitchDesktopToWinlogon(
HANDLE hWlx)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxSwitchDesktopToWinlogon()\n");
return (int)SwitchDesktop(Session->WinlogonDesktop);
}
/*
* @unimplemented
*/
int
WINAPI
WlxChangePasswordNotify(
HANDLE hWlx,
PWLX_MPR_NOTIFY_INFO pMprInfo,
DWORD dwChangeInfo)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(pMprInfo);
UNREFERENCED_PARAMETER(dwChangeInfo);
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxGetSourceDesktop(
HANDLE hWlx,
PWLX_DESKTOP* ppDesktop)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(ppDesktop);
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxSetReturnDesktop(
HANDLE hWlx,
PWLX_DESKTOP pDesktop)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(pDesktop);
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxCreateUserDesktop(
HANDLE hWlx,
HANDLE hToken,
DWORD Flags,
PWSTR pszDesktopName,
PWLX_DESKTOP* ppDesktop)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(hToken);
UNREFERENCED_PARAMETER(Flags);
UNREFERENCED_PARAMETER(pszDesktopName);
UNREFERENCED_PARAMETER(ppDesktop);
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
int
WINAPI
WlxChangePasswordNotifyEx(
HANDLE hWlx,
PWLX_MPR_NOTIFY_INFO pMprInfo,
DWORD dwChangeInfo,
PWSTR ProviderName,
PVOID Reserved)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(pMprInfo);
UNREFERENCED_PARAMETER(dwChangeInfo);
UNREFERENCED_PARAMETER(ProviderName);
UNREFERENCED_PARAMETER(Reserved);
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxCloseUserDesktop(
HANDLE hWlx,
PWLX_DESKTOP pDesktop,
HANDLE hToken)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(pDesktop);
UNREFERENCED_PARAMETER(hToken);
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
WlxSetOption(
HANDLE hWlx,
DWORD Option,
ULONG_PTR Value,
ULONG_PTR* OldValue)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxSetOption(%lu)\n", Option);
switch (Option)
{
case WLX_OPTION_USE_CTRL_ALT_DEL:
*OldValue = (ULONG_PTR)Session->Gina.UseCtrlAltDelete;
Session->Gina.UseCtrlAltDelete = (BOOL)Value;
return TRUE;
case WLX_OPTION_CONTEXT_POINTER:
*OldValue = (ULONG_PTR)Session->Gina.Context;
Session->Gina.Context = (PVOID)Value;
return TRUE;
case WLX_OPTION_USE_SMART_CARD:
UNIMPLEMENTED;
return FALSE;
}
return FALSE;
}
/*
* @implemented
*/
BOOL
WINAPI
WlxGetOption(
HANDLE hWlx,
DWORD Option,
ULONG_PTR* Value)
{
PWLSESSION Session = (PWLSESSION)hWlx;
TRACE("WlxGetOption(%lu)\n", Option);
switch (Option)
{
case WLX_OPTION_USE_CTRL_ALT_DEL:
*Value = (ULONG_PTR)Session->Gina.UseCtrlAltDelete;
return TRUE;
case WLX_OPTION_CONTEXT_POINTER:
{
*Value = (ULONG_PTR)Session->Gina.Context;
return TRUE;
}
case WLX_OPTION_USE_SMART_CARD:
case WLX_OPTION_SMART_CARD_PRESENT:
case WLX_OPTION_SMART_CARD_INFO:
UNIMPLEMENTED;
return FALSE;
case WLX_OPTION_DISPATCH_TABLE_SIZE:
{
switch (Session->Gina.Version)
{
case WLX_VERSION_1_0:
*Value = sizeof(WLX_DISPATCH_VERSION_1_0);
break;
case WLX_VERSION_1_1:
*Value = sizeof(WLX_DISPATCH_VERSION_1_1);
break;
case WLX_VERSION_1_2:
*Value = sizeof(WLX_DISPATCH_VERSION_1_2);
break;
case WLX_VERSION_1_3:
*Value = sizeof(WLX_DISPATCH_VERSION_1_3);
break;
case WLX_VERSION_1_4:
*Value = sizeof(WLX_DISPATCH_VERSION_1_4);
break;
default:
return FALSE;
}
return TRUE;
}
}
return FALSE;
}
/*
* @unimplemented
*/
VOID
WINAPI
WlxWin31Migrate(
HANDLE hWlx)
{
UNREFERENCED_PARAMETER(hWlx);
UNIMPLEMENTED;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxQueryClientCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
{
UNREFERENCED_PARAMETER(pCred);
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxQueryInetConnectorCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
{
UNREFERENCED_PARAMETER(pCred);
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxDisconnect(VOID)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
DWORD
WINAPI
WlxQueryTerminalServicesData(
HANDLE hWlx,
PWLX_TERMINAL_SERVICES_DATA pTSData,
WCHAR* UserName,
WCHAR* Domain)
{
UNREFERENCED_PARAMETER(hWlx);
UNREFERENCED_PARAMETER(pTSData);
UNREFERENCED_PARAMETER(UserName);
UNREFERENCED_PARAMETER(Domain);
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
DWORD
WINAPI
WlxQueryConsoleSwitchCredentials(
PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred)
{
UNREFERENCED_PARAMETER(pCred);
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
BOOL
WINAPI
WlxQueryTsLogonCredentials(
PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred)
{
UNREFERENCED_PARAMETER(pCred);
UNIMPLEMENTED;
return FALSE;
}
static
WLX_DISPATCH_VERSION_1_4 FunctionTable = {
WlxUseCtrlAltDel,
WlxSetContextPointer,
WlxSasNotify,
WlxSetTimeout,
WlxAssignShellProtection,
WlxMessageBox,
WlxDialogBox,
WlxDialogBoxParam,
WlxDialogBoxIndirect,
WlxDialogBoxIndirectParam,
WlxSwitchDesktopToUser,
WlxSwitchDesktopToWinlogon,
WlxChangePasswordNotify,
WlxGetSourceDesktop,
WlxSetReturnDesktop,
WlxCreateUserDesktop,
WlxChangePasswordNotifyEx,
WlxCloseUserDesktop,
WlxSetOption,
WlxGetOption,
WlxWin31Migrate,
WlxQueryClientCredentials,
WlxQueryInetConnectorCredentials,
WlxDisconnect,
WlxQueryTerminalServicesData,
WlxQueryConsoleSwitchCredentials,
WlxQueryTsLogonCredentials
};
/******************************************************************************/
static
BOOL
GetGinaPath(
OUT LPWSTR Path,
IN DWORD Len)
{
LONG Status;
DWORD Type, Size;
HKEY hKey;
Status = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
0,
KEY_QUERY_VALUE,
&hKey);
if (Status != ERROR_SUCCESS)
{
/* Default value */
wcsncpy(Path, L"msgina.dll", Len);
return TRUE;
}
Size = Len * sizeof(WCHAR);
Status = RegQueryValueExW(
hKey,
L"GinaDLL",
NULL,
&Type,
(LPBYTE)Path,
&Size);
if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0)
wcsncpy(Path, L"msgina.dll", Len);
RegCloseKey(hKey);
return TRUE;
}
static
BOOL
WINAPI
DefaultWlxScreenSaverNotify(
IN PVOID pWlxContext,
IN OUT BOOL *pSecure)
{
if (*pSecure)
*pSecure = WLSession->Gina.Functions.WlxIsLogoffOk(pWlxContext);
return TRUE;
}
static
BOOL
LoadGina(
IN OUT PGINAFUNCTIONS Functions,
OUT DWORD *DllVersion,
OUT HMODULE *GinaInstance)
{
HMODULE hGina = NULL;
WCHAR GinaDll[MAX_PATH + 1];
BOOL ret = FALSE;
GinaDll[0] = '\0';
if (!GetGinaPath(GinaDll, MAX_PATH))
goto cleanup;
/* Terminate string */
GinaDll[MAX_PATH] = '\0';
hGina = LoadLibraryW(GinaDll);
if (!hGina)
goto cleanup;
Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate");
Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize");
if (!Functions->WlxInitialize)
goto cleanup;
if (!Functions->WlxNegotiate)
{
/* Assume current version */
*DllVersion = WLX_CURRENT_VERSION;
}
else
{
TRACE("About to negotiate with Gina %S. Winlogon uses version %x\n",
GinaDll, WLX_CURRENT_VERSION);
if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion))
goto cleanup;
}
TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion);
if (*DllVersion >= WLX_VERSION_1_0)
{
Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell");
if (!Functions->WlxActivateUserShell) goto cleanup;
Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice");
if (!Functions->WlxDisplayLockedNotice) goto cleanup;
Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice");
if (!Functions->WlxDisplaySASNotice) goto cleanup;
Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk");
if (!Functions->WlxIsLockOk) goto cleanup;
Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk");
if (!Functions->WlxIsLogoffOk) goto cleanup;
Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
if (!Functions->WlxLoggedOnSAS) goto cleanup;
Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
if (!Functions->WlxLoggedOutSAS) goto cleanup;
Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff");
if (!Functions->WlxLogoff) goto cleanup;
Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown");
if (!Functions->WlxShutdown) goto cleanup;
Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
if (!Functions->WlxWkstaLockedSAS) goto cleanup;
}
if (*DllVersion >= WLX_VERSION_1_1)
{
Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify");
Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication");
}
if (*DllVersion >= WLX_VERSION_1_3)
{
Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage");
if (!Functions->WlxDisplayStatusMessage) goto cleanup;
Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage");
if (!Functions->WlxGetStatusMessage) goto cleanup;
Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad");
if (!Functions->WlxNetworkProviderLoad) goto cleanup;
Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage");
if (!Functions->WlxRemoveStatusMessage) goto cleanup;
}
/* Provide some default functions */
if (!Functions->WlxScreenSaverNotify)
Functions->WlxScreenSaverNotify = DefaultWlxScreenSaverNotify;
ret = TRUE;
cleanup:
if (!ret)
{
if (hGina)
FreeLibrary(hGina);
}
else
*GinaInstance = hGina;
return ret;
}
BOOL
GinaInit(
IN OUT PWLSESSION Session)
{
DWORD GinaDllVersion;
if (!LoadGina(&Session->Gina.Functions, &GinaDllVersion, &Session->Gina.hDllInstance))
return FALSE;
Session->Gina.Context = NULL;
Session->Gina.Version = GinaDllVersion;
Session->Gina.UseCtrlAltDelete = FALSE;
Session->SuppressStatus = FALSE;
TRACE("Calling WlxInitialize(\"%S\")\n", Session->InteractiveWindowStationName);
return Session->Gina.Functions.WlxInitialize(
Session->InteractiveWindowStationName,
(HANDLE)Session,
NULL,
(PVOID)&FunctionTable,
&Session->Gina.Context);
}
BOOL
CreateWindowStationAndDesktops(
_Inout_ PWLSESSION Session)
{
SECURITY_ATTRIBUTES WinstaSecurity;
SECURITY_ATTRIBUTES ApplicationDesktopSecurity;
SECURITY_ATTRIBUTES WinlogonDesktopSecurity;
SECURITY_ATTRIBUTES ScreenSaverDesktopSecurity;
PSECURITY_DESCRIPTOR WlWinstaSecurityDescriptor;
PSECURITY_DESCRIPTOR WlApplicationDesktopSecurityDescriptor;
PSECURITY_DESCRIPTOR WlWinlogonDesktopSecurityDescriptor;
PSECURITY_DESCRIPTOR WlScreenSaverDesktopSecurityDescriptor;
BOOL ret = FALSE;
if (!CreateWinstaSecurity(&WlWinstaSecurityDescriptor))
{
ERR("WL: Failed to create winsta security!\n");
return ret;
}
WinstaSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
WinstaSecurity.lpSecurityDescriptor = WlWinstaSecurityDescriptor;
WinstaSecurity.bInheritHandle = TRUE;
if (!CreateApplicationDesktopSecurity(&WlApplicationDesktopSecurityDescriptor))
{
ERR("WL: Failed to create application desktop security!\n");
goto cleanup;
}
ApplicationDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
ApplicationDesktopSecurity.lpSecurityDescriptor = WlApplicationDesktopSecurityDescriptor;
ApplicationDesktopSecurity.bInheritHandle = TRUE;
if (!CreateWinlogonDesktopSecurity(&WlWinlogonDesktopSecurityDescriptor))
{
ERR("WL: Failed to create winlogon desktop security!\n");
goto cleanup;
}
WinlogonDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
WinlogonDesktopSecurity.lpSecurityDescriptor = WlWinlogonDesktopSecurityDescriptor;
WinlogonDesktopSecurity.bInheritHandle = FALSE;
if (!CreateScreenSaverSecurity(&WlScreenSaverDesktopSecurityDescriptor))
{
ERR("WL: Failed to create winlogon desktop security!\n");
goto cleanup;
}
ScreenSaverDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
ScreenSaverDesktopSecurity.lpSecurityDescriptor = WlScreenSaverDesktopSecurityDescriptor;
ScreenSaverDesktopSecurity.bInheritHandle = TRUE;
/*
* Create the interactive window station
*/
Session->InteractiveWindowStationName = L"WinSta0";
Session->InteractiveWindowStation = CreateWindowStationW(
Session->InteractiveWindowStationName,
0,
MAXIMUM_ALLOWED,
&WinstaSecurity);
if (!Session->InteractiveWindowStation)
{
ERR("WL: Failed to create window station (%lu)\n", GetLastError());
goto cleanup;
}
if (!SetProcessWindowStation(Session->InteractiveWindowStation))
{
ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/*
* Create the application desktop
*/
Session->ApplicationDesktop = CreateDesktopW(
L"Default",
NULL,
NULL,
0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
MAXIMUM_ALLOWED,
&ApplicationDesktopSecurity);
if (!Session->ApplicationDesktop)
{
ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
goto cleanup;
}
/*
* Create the winlogon desktop
*/
Session->WinlogonDesktop = CreateDesktopW(
L"Winlogon",
NULL,
NULL,
0,
MAXIMUM_ALLOWED,
&WinlogonDesktopSecurity);
if (!Session->WinlogonDesktop)
{
ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
goto cleanup;
}
/*
* Create the screen saver desktop
*/
Session->ScreenSaverDesktop = CreateDesktopW(
L"Screen-Saver",
NULL,
NULL,
0,
MAXIMUM_ALLOWED,
&ScreenSaverDesktopSecurity);
if(!Session->ScreenSaverDesktop)
{
ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
goto cleanup;
}
/*
* Switch to winlogon desktop
*/
if (!SetThreadDesktop(Session->WinlogonDesktop) ||
!SwitchDesktop(Session->WinlogonDesktop))
{
ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
goto cleanup;
}
SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0);
ret = TRUE;
cleanup:
if (!ret)
{
if (Session->ApplicationDesktop)
{
CloseDesktop(Session->ApplicationDesktop);
Session->ApplicationDesktop = NULL;
}
if (Session->WinlogonDesktop)
{
CloseDesktop(Session->WinlogonDesktop);
Session->WinlogonDesktop = NULL;
}
if (Session->ScreenSaverDesktop)
{
CloseDesktop(Session->ScreenSaverDesktop);
Session->ScreenSaverDesktop = NULL;
}
if (Session->InteractiveWindowStation)
{
CloseWindowStation(Session->InteractiveWindowStation);
Session->InteractiveWindowStation = NULL;
}
if (WlWinstaSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinstaSecurityDescriptor);
}
if (WlApplicationDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlApplicationDesktopSecurityDescriptor);
}
if (WlWinlogonDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinlogonDesktopSecurityDescriptor);
}
if (WlScreenSaverDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlScreenSaverDesktopSecurityDescriptor);
}
}
return ret;
}