VBoxGINA.cpp revision 57b2f1f185eeb6808825be7eb90516b362f26ccd
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * VBoxGINA -- Windows Logon DLL for VirtualBox
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * Copyright (C) 2006-2011 Oracle Corporation
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * available from http://www.virtualbox.org. This file is free software;
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * General Public License (GPL) as published by the Free Software
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * Global variables.
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/** DLL instance handle. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/** Version of Winlogon. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/** Handle to Winlogon service. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/** Winlog function dispatch table. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * Function pointers to MSGINA entry points.
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/* GINA 1.1. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/* GINA 1.3. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync/* GINA 1.4. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncPGWLXGETCONSOLESWITCHCREDENTIALS GWlxGetConsoleSwitchCredentials;
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * DLL entry point.
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /// @todo RTR3Term();
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* enable full log output */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync RTLogGroupSettings(RTLogDefaultInstance(), "all=~0");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %d\n", dwWinlogonVersion));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* load the standard Microsoft GINA DLL */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! last error = %d\n", GetLastError()));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * Now get the entry points of the MSGINA
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxNegotiate = (PGWLXNEGOTIATE)GetProcAddress(hDll, "WlxNegotiate");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxInitialize = (PGWLXINITIALIZE)GetProcAddress(hDll, "WlxInitialize");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXDISPLAYSASNOTICE)GetProcAddress(hDll, "WlxDisplaySASNotice");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXLOGGEDOUTSAS)GetProcAddress(hDll, "WlxLoggedOutSAS");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXACTIVATEUSERSHELL)GetProcAddress(hDll, "WlxActivateUserShell");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXLOGGEDONSAS)GetProcAddress(hDll, "WlxLoggedOnSAS");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hDll, "WlxDisplayLockedNotice");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxIsLockOk = (PGWLXISLOCKOK)GetProcAddress(hDll, "WlxIsLockOk");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXWKSTALOCKEDSAS)GetProcAddress(hDll, "WlxWkstaLockedSAS");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxIsLogoffOk = (PGWLXISLOGOFFOK)GetProcAddress(hDll, "WlxIsLogoffOk");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxLogoff = (PGWLXLOGOFF)GetProcAddress(hDll, "WlxLogoff");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxShutdown = (PGWLXSHUTDOWN)GetProcAddress(hDll, "WlxShutdown");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* GINA 1.1, optional */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxStartApplication = (PGWLXSTARTAPPLICATION)GetProcAddress(hDll, "WlxStartApplication");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxScreenSaverNotify = (PGWLXSCREENSAVERNOTIFY)GetProcAddress(hDll, "WlxScreenSaverNotify");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* GINA 1.3, optional */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxNetworkProviderLoad = (PGWLXNETWORKPROVIDERLOAD)GetProcAddress( hDll, "WlxNetworkProviderLoad");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxDisplayStatusMessage = (PGWLXDISPLAYSTATUSMESSAGE)GetProcAddress( hDll, "WlxDisplayStatusMessage");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxGetStatusMessage = (PGWLXGETSTATUSMESSAGE)GetProcAddress( hDll, "WlxGetStatusMessage");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxRemoveStatusMessage = (PGWLXREMOVESTATUSMESSAGE)GetProcAddress( hDll, "WlxRemoveStatusMessage");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* GINA 1.4, optional */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync (PGWLXGETCONSOLESWITCHCREDENTIALS)GetProcAddress(hDll, "WlxGetConsoleSwitchCredentials");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)GetProcAddress(hDll, "WlxReconnectNotify");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)GetProcAddress(hDll, "WlxDisconnectNotify");
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxNegotiate: optional function pointers:\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxStartApplication: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxScreenSaverNotify: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxNetworkProviderLoad: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxDisplayStatusMessage: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxGetStatusMessage: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxRemoveStatusMessage: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxGetConsoleSwitchCredentials: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxReconnectNotify: %p\n"
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync " WlxDisconnectNotify: %p\n",
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* forward call */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxNegotiate(dwWinlogonVersion, pdwDllVersion);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* store Winlogon function table */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync pWlxFuncs = (PWLX_DISPATCH_VERSION_1_1)pWinlogonFunctions;
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* store handle to Winlogon service*/
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* hook the dialogs */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* forward call */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* check if there are credentials for us, if so simulate C-A-D */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* automatic C-A-D */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* start the credentials poller thread */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncint WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* when performing a direct logon without C-A-D, our poller might not be running */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync iRet = GWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // copy pMprNotifyInfo and pLogonSid for later use
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // pMprNotifyInfo->pszUserName
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // pMprNotifyInfo->pszDomain
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // pMprNotifyInfo->pszPassword
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // pMprNotifyInfo->pszOldPassword
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncint WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * We don't want to do anything special here since the OS should behave
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * as VBoxGINA wouldn't have been installed. So pass all calls down
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * to the original MSGINA.
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncVOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncint WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* when performing a direct logon without C-A-D, our poller might not be running */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // if it's ok to logoff, finish with the stored credentials
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync // and scrub the buffers
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncVOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward call to MSGINA. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * GINA 1.1 entry points
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxScreenSaverNotify(pWlxContext, pSecure);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* return something intelligent */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * GINA 1.3 entry points
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxNetworkProviderLoad (PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions,
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync * GINA 1.4 entry points
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsyncBOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* forward call to MSGINA if present */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync return GWlxGetConsoleSwitchCredentials(pWlxContext,pCredInfo);
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */
a5e7ae69e440f6816420fc99599f044e79e716b6vboxsync /* Forward to MSGINA if present. */