mirror of
https://github.com/reactos/reactos.git
synced 2024-10-30 19:41:57 +00:00
f96c39f6b0
Refactor the security related code of Winlogon and move it to its own dedicated place, security.c. This includes code for preparation of security descriptors for window station and desktop objects when their created, helper functions which give allow access to such objects for the logged in user and whatnot. ==== DO NOTE ==== Currently new desktop security assignment fails because for whatever reason the system thinks the application desktop has no prior security even though a descriptor has been created for it before. See the FIXME comment on code for information.
1108 lines
25 KiB
C
1108 lines
25 KiB
C
/*
|
|
* 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é 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;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|