[69360] | 1 | /* $Id: VBoxGINA.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
| 3 | * VBoxGINA -- Windows Logon DLL for VirtualBox
|
---|
[69360] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[1] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
[1] | 26 | */
|
---|
| 27 |
|
---|
[95874] | 28 |
|
---|
| 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
[62679] | 32 | #include <iprt/win/windows.h>
|
---|
[40214] | 33 |
|
---|
| 34 | #include <iprt/buildconfig.h>
|
---|
| 35 | #include <iprt/initterm.h>
|
---|
[46593] | 36 | #include <iprt/ldr.h>
|
---|
[76474] | 37 | #include <iprt/errcore.h>
|
---|
[40214] | 38 |
|
---|
| 39 | #include <VBox/VBoxGuestLib.h>
|
---|
| 40 |
|
---|
[1] | 41 | #include "winwlx.h"
|
---|
| 42 | #include "VBoxGINA.h"
|
---|
| 43 | #include "Helper.h"
|
---|
| 44 | #include "Dialog.h"
|
---|
| 45 |
|
---|
[95891] | 46 |
|
---|
[95874] | 47 | /*********************************************************************************************************************************
|
---|
| 48 | * Global Variables *
|
---|
| 49 | *********************************************************************************************************************************/
|
---|
[36258] | 50 | /** DLL instance handle. */
|
---|
[1] | 51 | HINSTANCE hDllInstance;
|
---|
| 52 |
|
---|
[36258] | 53 | /** Version of Winlogon. */
|
---|
[1] | 54 | DWORD wlxVersion;
|
---|
| 55 |
|
---|
[36258] | 56 | /** Handle to Winlogon service. */
|
---|
[1] | 57 | HANDLE hGinaWlx;
|
---|
[36258] | 58 | /** Winlog function dispatch table. */
|
---|
[1] | 59 | PWLX_DISPATCH_VERSION_1_1 pWlxFuncs;
|
---|
| 60 |
|
---|
| 61 | /**
|
---|
[36258] | 62 | * Function pointers to MSGINA entry points.
|
---|
[1] | 63 | */
|
---|
| 64 | PGWLXNEGOTIATE GWlxNegotiate;
|
---|
| 65 | PGWLXINITIALIZE GWlxInitialize;
|
---|
| 66 | PGWLXDISPLAYSASNOTICE GWlxDisplaySASNotice;
|
---|
| 67 | PGWLXLOGGEDOUTSAS GWlxLoggedOutSAS;
|
---|
| 68 | PGWLXACTIVATEUSERSHELL GWlxActivateUserShell;
|
---|
| 69 | PGWLXLOGGEDONSAS GWlxLoggedOnSAS;
|
---|
| 70 | PGWLXDISPLAYLOCKEDNOTICE GWlxDisplayLockedNotice;
|
---|
| 71 | PGWLXWKSTALOCKEDSAS GWlxWkstaLockedSAS;
|
---|
| 72 | PGWLXISLOCKOK GWlxIsLockOk;
|
---|
| 73 | PGWLXISLOGOFFOK GWlxIsLogoffOk;
|
---|
| 74 | PGWLXLOGOFF GWlxLogoff;
|
---|
| 75 | PGWLXSHUTDOWN GWlxShutdown;
|
---|
[36258] | 76 | /* GINA 1.1. */
|
---|
[1] | 77 | PGWLXSTARTAPPLICATION GWlxStartApplication;
|
---|
| 78 | PGWLXSCREENSAVERNOTIFY GWlxScreenSaverNotify;
|
---|
[36258] | 79 | /* GINA 1.3. */
|
---|
[1] | 80 | PGWLXNETWORKPROVIDERLOAD GWlxNetworkProviderLoad;
|
---|
| 81 | PGWLXDISPLAYSTATUSMESSAGE GWlxDisplayStatusMessage;
|
---|
| 82 | PGWLXGETSTATUSMESSAGE GWlxGetStatusMessage;
|
---|
| 83 | PGWLXREMOVESTATUSMESSAGE GWlxRemoveStatusMessage;
|
---|
[36258] | 84 | /* GINA 1.4. */
|
---|
[1] | 85 | PGWLXGETCONSOLESWITCHCREDENTIALS GWlxGetConsoleSwitchCredentials;
|
---|
| 86 | PGWLXRECONNECTNOTIFY GWlxReconnectNotify;
|
---|
| 87 | PGWLXDISCONNECTNOTIFY GWlxDisconnectNotify;
|
---|
| 88 |
|
---|
| 89 |
|
---|
| 90 | /**
|
---|
| 91 | * DLL entry point.
|
---|
| 92 | */
|
---|
| 93 | BOOL WINAPI DllMain(HINSTANCE hInstance,
|
---|
| 94 | DWORD dwReason,
|
---|
[63093] | 95 | LPVOID pReserved)
|
---|
[1] | 96 | {
|
---|
[63093] | 97 | RT_NOREF(pReserved);
|
---|
[1] | 98 | switch (dwReason)
|
---|
| 99 | {
|
---|
| 100 | case DLL_PROCESS_ATTACH:
|
---|
| 101 | {
|
---|
[46593] | 102 | RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
|
---|
[16138] | 103 | VbglR3Init();
|
---|
| 104 |
|
---|
[40214] | 105 | VBoxGINALoadConfiguration();
|
---|
| 106 |
|
---|
| 107 | VBoxGINAVerbose(0, "VBoxGINA: v%s r%s (%s %s) loaded\n",
|
---|
| 108 | RTBldCfgVersion(), RTBldCfgRevisionStr(),
|
---|
| 109 | __DATE__, __TIME__);
|
---|
| 110 |
|
---|
[1] | 111 | DisableThreadLibraryCalls(hInstance);
|
---|
| 112 | hDllInstance = hInstance;
|
---|
| 113 | break;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | case DLL_PROCESS_DETACH:
|
---|
[16138] | 117 | {
|
---|
[40214] | 118 | VBoxGINAVerbose(0, "VBoxGINA: Unloaded\n");
|
---|
[16138] | 119 | VbglR3Term();
|
---|
| 120 | /// @todo RTR3Term();
|
---|
| 121 | break;
|
---|
| 122 | }
|
---|
| 123 |
|
---|
[1] | 124 | default:
|
---|
| 125 | break;
|
---|
| 126 | }
|
---|
| 127 | return TRUE;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
[36258] | 130 |
|
---|
[1] | 131 | BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion,
|
---|
| 132 | DWORD *pdwDllVersion)
|
---|
| 133 | {
|
---|
[40214] | 134 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion);
|
---|
[1] | 135 |
|
---|
[36446] | 136 | /* Load the standard Microsoft GINA DLL. */
|
---|
[46593] | 137 | RTLDRMOD hLdrMod;
|
---|
| 138 | int rc = RTLdrLoadSystem("MSGINA.DLL", true /*fNoUnload*/, &hLdrMod);
|
---|
| 139 | if (RT_FAILURE(rc))
|
---|
[1] | 140 | {
|
---|
[46593] | 141 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed loading MSGINA! rc=%Rrc\n", rc);
|
---|
[1] | 142 | return FALSE;
|
---|
| 143 | }
|
---|
| 144 |
|
---|
| 145 | /*
|
---|
| 146 | * Now get the entry points of the MSGINA
|
---|
| 147 | */
|
---|
[46593] | 148 | GWlxNegotiate = (PGWLXNEGOTIATE)RTLdrGetFunction(hLdrMod, "WlxNegotiate");
|
---|
[1] | 149 | if (!GWlxNegotiate)
|
---|
| 150 | {
|
---|
[40214] | 151 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n");
|
---|
[1] | 152 | return FALSE;
|
---|
| 153 | }
|
---|
[46593] | 154 | GWlxInitialize = (PGWLXINITIALIZE)RTLdrGetFunction(hLdrMod, "WlxInitialize");
|
---|
[1] | 155 | if (!GWlxInitialize)
|
---|
| 156 | {
|
---|
[40214] | 157 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n");
|
---|
[1] | 158 | return FALSE;
|
---|
| 159 | }
|
---|
| 160 | GWlxDisplaySASNotice =
|
---|
[46593] | 161 | (PGWLXDISPLAYSASNOTICE)RTLdrGetFunction(hLdrMod, "WlxDisplaySASNotice");
|
---|
[1] | 162 | if (!GWlxDisplaySASNotice)
|
---|
| 163 | {
|
---|
[40214] | 164 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n");
|
---|
[1] | 165 | return FALSE;
|
---|
| 166 | }
|
---|
| 167 | GWlxLoggedOutSAS =
|
---|
[46593] | 168 | (PGWLXLOGGEDOUTSAS)RTLdrGetFunction(hLdrMod, "WlxLoggedOutSAS");
|
---|
[1] | 169 | if (!GWlxLoggedOutSAS)
|
---|
| 170 | {
|
---|
[40214] | 171 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n");
|
---|
[1] | 172 | return FALSE;
|
---|
| 173 | }
|
---|
| 174 | GWlxActivateUserShell =
|
---|
[46593] | 175 | (PGWLXACTIVATEUSERSHELL)RTLdrGetFunction(hLdrMod, "WlxActivateUserShell");
|
---|
[1] | 176 | if (!GWlxActivateUserShell)
|
---|
| 177 | {
|
---|
[40214] | 178 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n");
|
---|
[1] | 179 | return FALSE;
|
---|
| 180 | }
|
---|
| 181 | GWlxLoggedOnSAS =
|
---|
[46593] | 182 | (PGWLXLOGGEDONSAS)RTLdrGetFunction(hLdrMod, "WlxLoggedOnSAS");
|
---|
[1] | 183 | if (!GWlxLoggedOnSAS)
|
---|
| 184 | {
|
---|
[40214] | 185 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n");
|
---|
[1] | 186 | return FALSE;
|
---|
| 187 | }
|
---|
| 188 | GWlxDisplayLockedNotice =
|
---|
[46593] | 189 | (PGWLXDISPLAYLOCKEDNOTICE)RTLdrGetFunction(hLdrMod, "WlxDisplayLockedNotice");
|
---|
[1] | 190 | if (!GWlxDisplayLockedNotice)
|
---|
| 191 | {
|
---|
[40214] | 192 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n");
|
---|
[1] | 193 | return FALSE;
|
---|
| 194 | }
|
---|
[46593] | 195 | GWlxIsLockOk = (PGWLXISLOCKOK)RTLdrGetFunction(hLdrMod, "WlxIsLockOk");
|
---|
[1] | 196 | if (!GWlxIsLockOk)
|
---|
| 197 | {
|
---|
[40214] | 198 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n");
|
---|
[1] | 199 | return FALSE;
|
---|
| 200 | }
|
---|
| 201 | GWlxWkstaLockedSAS =
|
---|
[46593] | 202 | (PGWLXWKSTALOCKEDSAS)RTLdrGetFunction(hLdrMod, "WlxWkstaLockedSAS");
|
---|
[1] | 203 | if (!GWlxWkstaLockedSAS)
|
---|
| 204 | {
|
---|
[40214] | 205 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n");
|
---|
[1] | 206 | return FALSE;
|
---|
| 207 | }
|
---|
[46593] | 208 | GWlxIsLogoffOk = (PGWLXISLOGOFFOK)RTLdrGetFunction(hLdrMod, "WlxIsLogoffOk");
|
---|
[1] | 209 | if (!GWlxIsLogoffOk)
|
---|
| 210 | {
|
---|
[40214] | 211 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n");
|
---|
[1] | 212 | return FALSE;
|
---|
| 213 | }
|
---|
[46593] | 214 | GWlxLogoff = (PGWLXLOGOFF)RTLdrGetFunction(hLdrMod, "WlxLogoff");
|
---|
[1] | 215 | if (!GWlxLogoff)
|
---|
| 216 | {
|
---|
[40214] | 217 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n");
|
---|
[1] | 218 | return FALSE;
|
---|
| 219 | }
|
---|
[46593] | 220 | GWlxShutdown = (PGWLXSHUTDOWN)RTLdrGetFunction(hLdrMod, "WlxShutdown");
|
---|
[1] | 221 | if (!GWlxShutdown)
|
---|
| 222 | {
|
---|
[40214] | 223 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n");
|
---|
[1] | 224 | return FALSE;
|
---|
| 225 | }
|
---|
| 226 | /* GINA 1.1, optional */
|
---|
[46593] | 227 | GWlxStartApplication = (PGWLXSTARTAPPLICATION)RTLdrGetFunction(hLdrMod, "WlxStartApplication");
|
---|
| 228 | GWlxScreenSaverNotify = (PGWLXSCREENSAVERNOTIFY)RTLdrGetFunction(hLdrMod, "WlxScreenSaverNotify");
|
---|
[1] | 229 | /* GINA 1.3, optional */
|
---|
[46593] | 230 | GWlxNetworkProviderLoad = (PGWLXNETWORKPROVIDERLOAD)RTLdrGetFunction(hLdrMod, "WlxNetworkProviderLoad");
|
---|
| 231 | GWlxDisplayStatusMessage = (PGWLXDISPLAYSTATUSMESSAGE)RTLdrGetFunction(hLdrMod, "WlxDisplayStatusMessage");
|
---|
| 232 | GWlxGetStatusMessage = (PGWLXGETSTATUSMESSAGE)RTLdrGetFunction(hLdrMod, "WlxGetStatusMessage");
|
---|
| 233 | GWlxRemoveStatusMessage = (PGWLXREMOVESTATUSMESSAGE)RTLdrGetFunction(hLdrMod, "WlxRemoveStatusMessage");
|
---|
[1] | 234 | /* GINA 1.4, optional */
|
---|
| 235 | GWlxGetConsoleSwitchCredentials =
|
---|
[46593] | 236 | (PGWLXGETCONSOLESWITCHCREDENTIALS)RTLdrGetFunction(hLdrMod, "WlxGetConsoleSwitchCredentials");
|
---|
| 237 | GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)RTLdrGetFunction(hLdrMod, "WlxReconnectNotify");
|
---|
| 238 | GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)RTLdrGetFunction(hLdrMod, "WlxDisconnectNotify");
|
---|
[40214] | 239 | VBoxGINAVerbose(0, "VBoxGINA::WlxNegotiate: optional function pointers:\n"
|
---|
| 240 | " WlxStartApplication: %p\n"
|
---|
| 241 | " WlxScreenSaverNotify: %p\n"
|
---|
| 242 | " WlxNetworkProviderLoad: %p\n"
|
---|
| 243 | " WlxDisplayStatusMessage: %p\n"
|
---|
| 244 | " WlxGetStatusMessage: %p\n"
|
---|
| 245 | " WlxRemoveStatusMessage: %p\n"
|
---|
| 246 | " WlxGetConsoleSwitchCredentials: %p\n"
|
---|
| 247 | " WlxReconnectNotify: %p\n"
|
---|
| 248 | " WlxDisconnectNotify: %p\n",
|
---|
| 249 | GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
|
---|
| 250 | GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
|
---|
| 251 | GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify);
|
---|
[1] | 252 |
|
---|
| 253 | wlxVersion = dwWinlogonVersion;
|
---|
| 254 |
|
---|
[38313] | 255 | /* Acknowledge interface version. */
|
---|
| 256 | if (pdwDllVersion)
|
---|
| 257 | *pdwDllVersion = dwWinlogonVersion;
|
---|
| 258 |
|
---|
| 259 | return TRUE; /* We're ready to rumble! */
|
---|
[1] | 260 | }
|
---|
| 261 |
|
---|
| 262 |
|
---|
| 263 | BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
|
---|
| 264 | PVOID pWinlogonFunctions, PVOID *pWlxContext)
|
---|
| 265 | {
|
---|
[40214] | 266 | VBoxGINAVerbose(0, "VBoxGINA::WlxInitialize\n");
|
---|
[1] | 267 |
|
---|
[38313] | 268 | /* Store Winlogon function table */
|
---|
[1] | 269 | pWlxFuncs = (PWLX_DISPATCH_VERSION_1_1)pWinlogonFunctions;
|
---|
| 270 |
|
---|
[38313] | 271 | /* Store handle to Winlogon service*/
|
---|
[1] | 272 | hGinaWlx = hWlx;
|
---|
| 273 |
|
---|
[40214] | 274 | VBoxGINAReportStatus(VBoxGuestFacilityStatus_Init);
|
---|
| 275 |
|
---|
[38313] | 276 | /* Hook the dialogs */
|
---|
[1] | 277 | hookDialogBoxes(pWlxFuncs, wlxVersion);
|
---|
| 278 |
|
---|
[38313] | 279 | /* Forward call */
|
---|
[40768] | 280 | if (GWlxInitialize)
|
---|
| 281 | return GWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
|
---|
| 282 | return TRUE;
|
---|
[1] | 283 | }
|
---|
| 284 |
|
---|
| 285 |
|
---|
| 286 | VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
|
---|
| 287 | {
|
---|
[40214] | 288 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice\n");
|
---|
[1] | 289 |
|
---|
[38313] | 290 | /* Check if there are credentials for us, if so simulate C-A-D */
|
---|
[40214] | 291 | int rc = VbglR3CredentialsQueryAvailability();
|
---|
| 292 | if (RT_SUCCESS(rc))
|
---|
[1] | 293 | {
|
---|
[40214] | 294 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n");
|
---|
[38313] | 295 | /* Wutomatic C-A-D */
|
---|
[1] | 296 | pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
|
---|
| 297 | }
|
---|
| 298 | else
|
---|
| 299 | {
|
---|
[40214] | 300 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n");
|
---|
[1] | 301 | /* start the credentials poller thread */
|
---|
[40214] | 302 | VBoxGINACredentialsPollerCreate();
|
---|
[36258] | 303 | /* Forward call to MSGINA. */
|
---|
[40768] | 304 | if (GWlxDisplaySASNotice)
|
---|
| 305 | GWlxDisplaySASNotice(pWlxContext);
|
---|
[1] | 306 | }
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 |
|
---|
| 310 | int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId,
|
---|
| 311 | PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken,
|
---|
| 312 | PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
|
---|
| 313 | {
|
---|
[40214] | 314 | VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOutSAS\n");
|
---|
[1] | 315 |
|
---|
[38313] | 316 | /* When performing a direct logon without C-A-D, our poller might not be running */
|
---|
[40214] | 317 | int rc = VbglR3CredentialsQueryAvailability();
|
---|
| 318 | if (RT_FAILURE(rc))
|
---|
| 319 | VBoxGINACredentialsPollerCreate();
|
---|
[1] | 320 |
|
---|
[40768] | 321 | if (GWlxLoggedOutSAS)
|
---|
[1] | 322 | {
|
---|
[40768] | 323 | int iRet;
|
---|
| 324 | iRet = GWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,
|
---|
| 325 | pdwOptions, phToken, pMprNotifyInfo, pProfile);
|
---|
[1] | 326 |
|
---|
[40768] | 327 | if (iRet == WLX_SAS_ACTION_LOGON)
|
---|
| 328 | {
|
---|
| 329 | //
|
---|
| 330 | // Copy pMprNotifyInfo and pLogonSid for later use
|
---|
| 331 | //
|
---|
| 332 |
|
---|
| 333 | // pMprNotifyInfo->pszUserName
|
---|
| 334 | // pMprNotifyInfo->pszDomain
|
---|
| 335 | // pMprNotifyInfo->pszPassword
|
---|
| 336 | // pMprNotifyInfo->pszOldPassword
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | return iRet;
|
---|
[1] | 340 | }
|
---|
| 341 |
|
---|
[40768] | 342 | return WLX_SAS_ACTION_NONE;
|
---|
[1] | 343 | }
|
---|
| 344 |
|
---|
| 345 |
|
---|
[40214] | 346 | /**
|
---|
| 347 | * WinLogon calls this function following a successful logon to request that the GINA activate the user's shell program.
|
---|
| 348 | */
|
---|
[1] | 349 | BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
|
---|
| 350 | PWSTR pszMprLogonScript, PVOID pEnvironment)
|
---|
| 351 | {
|
---|
[40214] | 352 | VBoxGINAVerbose(0, "VBoxGINA::WlxActivateUserShell\n");
|
---|
[1] | 353 |
|
---|
[40214] | 354 | /*
|
---|
| 355 | * Report status "terminated" to the host -- this means that a user
|
---|
| 356 | * got logged in (either manually or automatically using the provided credentials).
|
---|
| 357 | */
|
---|
| 358 | VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
|
---|
| 359 |
|
---|
[36258] | 360 | /* Forward call to MSGINA. */
|
---|
[40768] | 361 | if (GWlxActivateUserShell)
|
---|
| 362 | return GWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
|
---|
| 363 | return TRUE; /* Activate the user shell. */
|
---|
[1] | 364 | }
|
---|
| 365 |
|
---|
| 366 |
|
---|
| 367 | int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
|
---|
| 368 | {
|
---|
[40214] | 369 | VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: dwSasType=%ld\n", dwSasType);
|
---|
[1] | 370 |
|
---|
[36012] | 371 | /*
|
---|
| 372 | * We don't want to do anything special here since the OS should behave
|
---|
| 373 | * as VBoxGINA wouldn't have been installed. So pass all calls down
|
---|
| 374 | * to the original MSGINA.
|
---|
| 375 | */
|
---|
[1] | 376 |
|
---|
[36012] | 377 | /* Forward call to MSGINA. */
|
---|
[40214] | 378 | VBoxGINAVerbose(0, "VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n");
|
---|
[40768] | 379 | if (GWlxLoggedOnSAS)
|
---|
| 380 | return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
|
---|
| 381 | return WLX_SAS_ACTION_NONE;
|
---|
[1] | 382 | }
|
---|
| 383 |
|
---|
| 384 | VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
|
---|
| 385 | {
|
---|
[40214] | 386 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice\n");
|
---|
[36283] | 387 |
|
---|
[38313] | 388 | /* Check if there are credentials for us, if so simulate C-A-D */
|
---|
[40214] | 389 | int rc = VbglR3CredentialsQueryAvailability();
|
---|
| 390 | if (RT_SUCCESS(rc))
|
---|
[36283] | 391 | {
|
---|
[40214] | 392 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n");
|
---|
[38313] | 393 | /* Automatic C-A-D */
|
---|
[36283] | 394 | pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
|
---|
| 395 | }
|
---|
| 396 | else
|
---|
| 397 | {
|
---|
[40214] | 398 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n");
|
---|
[36283] | 399 | /* start the credentials poller thread */
|
---|
[40214] | 400 | VBoxGINACredentialsPollerCreate();
|
---|
[36283] | 401 | /* Forward call to MSGINA. */
|
---|
[40768] | 402 | if (GWlxDisplayLockedNotice)
|
---|
| 403 | GWlxDisplayLockedNotice(pWlxContext);
|
---|
[36283] | 404 | }
|
---|
[1] | 405 | }
|
---|
| 406 |
|
---|
| 407 |
|
---|
[40214] | 408 | /*
|
---|
| 409 | * Winlogon calls this function before it attempts to lock the workstation.
|
---|
| 410 | */
|
---|
[1] | 411 | BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
|
---|
| 412 | {
|
---|
[40214] | 413 | VBoxGINAVerbose(0, "VBoxGINA::WlxIsLockOk\n");
|
---|
[40768] | 414 |
|
---|
[36258] | 415 | /* Forward call to MSGINA. */
|
---|
[40768] | 416 | if (GWlxIsLockOk)
|
---|
| 417 | return GWlxIsLockOk(pWlxContext);
|
---|
| 418 | return TRUE; /* Locking is OK. */
|
---|
[1] | 419 | }
|
---|
| 420 |
|
---|
[40214] | 421 |
|
---|
[1] | 422 | int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
|
---|
| 423 | {
|
---|
[40214] | 424 | VBoxGINAVerbose(0, "VBoxGINA::WlxWkstaLockedSAS, dwSasType=%ld\n", dwSasType);
|
---|
[36258] | 425 |
|
---|
[38313] | 426 | /* When performing a direct logon without C-A-D, our poller might not be running */
|
---|
[40214] | 427 | int rc = VbglR3CredentialsQueryAvailability();
|
---|
| 428 | if (RT_FAILURE(rc))
|
---|
| 429 | VBoxGINACredentialsPollerCreate();
|
---|
[36258] | 430 |
|
---|
| 431 | /* Forward call to MSGINA. */
|
---|
[40768] | 432 | if (GWlxWkstaLockedSAS)
|
---|
| 433 | return GWlxWkstaLockedSAS(pWlxContext, dwSasType);
|
---|
| 434 | return WLX_SAS_ACTION_NONE;
|
---|
[1] | 435 | }
|
---|
| 436 |
|
---|
[40214] | 437 |
|
---|
[1] | 438 | BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
|
---|
| 439 | {
|
---|
[40214] | 440 | VBoxGINAVerbose(0, "VBoxGINA::WlxIsLogoffOk\n");
|
---|
[1] | 441 |
|
---|
[40768] | 442 | if (GWlxIsLogoffOk)
|
---|
| 443 | return GWlxIsLogoffOk(pWlxContext);
|
---|
| 444 | return TRUE; /* Log off is OK. */
|
---|
[1] | 445 | }
|
---|
| 446 |
|
---|
| 447 |
|
---|
[40214] | 448 | /*
|
---|
| 449 | * Winlogon calls this function to notify the GINA of a logoff operation on this
|
---|
| 450 | * workstation. This allows the GINA to perform any logoff operations that may be required.
|
---|
| 451 | */
|
---|
[1] | 452 | VOID WINAPI WlxLogoff(PVOID pWlxContext)
|
---|
| 453 | {
|
---|
[40214] | 454 | VBoxGINAVerbose(0, "VBoxGINA::WlxLogoff\n");
|
---|
[1] | 455 |
|
---|
[40214] | 456 | /* No need to report the "active" status to the host here -- this will be done
|
---|
| 457 | * when VBoxGINA gets the chance to hook the dialogs (again). */
|
---|
| 458 |
|
---|
[36258] | 459 | /* Forward call to MSGINA. */
|
---|
[40768] | 460 | if (GWlxLogoff)
|
---|
| 461 | GWlxLogoff(pWlxContext);
|
---|
[1] | 462 | }
|
---|
| 463 |
|
---|
| 464 |
|
---|
[40214] | 465 | /*
|
---|
| 466 | * Winlogon calls this function just before shutting down.
|
---|
| 467 | * This allows the GINA to perform any necessary shutdown tasks.
|
---|
| 468 | * Will be called *after* WlxLogoff!
|
---|
| 469 | */
|
---|
[1] | 470 | VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
|
---|
| 471 | {
|
---|
[40214] | 472 | VBoxGINAVerbose(0, "VBoxGINA::WlxShutdown\n");
|
---|
[1] | 473 |
|
---|
[40214] | 474 | /*
|
---|
| 475 | * Report status "inactive" to the host -- this means the
|
---|
| 476 | * auto-logon feature won't be active anymore at this point
|
---|
| 477 | * (until it maybe gets loaded again after a reboot).
|
---|
| 478 | */
|
---|
| 479 | VBoxGINAReportStatus(VBoxGuestFacilityStatus_Inactive);
|
---|
| 480 |
|
---|
[36258] | 481 | /* Forward call to MSGINA. */
|
---|
[40768] | 482 | if (GWlxShutdown)
|
---|
| 483 | GWlxShutdown(pWlxContext, ShutdownType);
|
---|
[1] | 484 | }
|
---|
| 485 |
|
---|
| 486 |
|
---|
| 487 | /*
|
---|
| 488 | * GINA 1.1 entry points
|
---|
| 489 | */
|
---|
| 490 | BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
|
---|
| 491 | {
|
---|
[63093] | 492 | RT_NOREF(pWlxContext);
|
---|
[40760] | 493 | VBoxGINAVerbose(0, "VBoxGINA::WlxScreenSaverNotify, pSecure=%d\n",
|
---|
| 494 | pSecure ? *pSecure : 0);
|
---|
[1] | 495 |
|
---|
[40768] | 496 | /* Report the status to "init" since the screensaver
|
---|
| 497 | * (Winlogon) does not give VBoxGINA yet the chance to hook into dialogs
|
---|
[40760] | 498 | * which only then in turn would set the status to "active" -- so
|
---|
[40768] | 499 | * at least set some status here. */
|
---|
| 500 | VBoxGINAReportStatus(VBoxGuestFacilityStatus_Init);
|
---|
[40760] | 501 |
|
---|
| 502 | /* Note: Disabling the screensaver's grace period is necessary to get
|
---|
| 503 | * VBoxGINA loaded and set the status to "terminated" again properly
|
---|
| 504 | * after the logging-in handling was done. To do this:
|
---|
| 505 | * - on a non-domain machine, set:
|
---|
| 506 | * HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ScreenSaverGracePeriod (REG_SZ)
|
---|
| 507 | * to "0"
|
---|
| 508 | * - on a machine joined a domain:
|
---|
| 509 | * use the group policy preferences and/or the registry key above,
|
---|
| 510 | * depending on the domain's policies.
|
---|
| 511 | */
|
---|
| 512 |
|
---|
| 513 | /* Indicate that the workstation should be locked. */
|
---|
[1] | 514 | *pSecure = TRUE;
|
---|
[40760] | 515 |
|
---|
| 516 | return TRUE; /* Screensaver should be activated. */
|
---|
[1] | 517 | }
|
---|
| 518 |
|
---|
[36258] | 519 |
|
---|
[1] | 520 | BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
|
---|
| 521 | PVOID pEnvironment, PWSTR pszCmdLine)
|
---|
| 522 | {
|
---|
[40214] | 523 | VBoxGINAVerbose(0, "VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
|
---|
| 524 | pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
|
---|
[1] | 525 |
|
---|
[36258] | 526 | /* Forward to MSGINA if present. */
|
---|
[1] | 527 | if (GWlxStartApplication)
|
---|
| 528 | return GWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
|
---|
| 529 | return FALSE;
|
---|
| 530 | }
|
---|
| 531 |
|
---|
[36258] | 532 |
|
---|
[1] | 533 | /*
|
---|
| 534 | * GINA 1.3 entry points
|
---|
| 535 | */
|
---|
[36446] | 536 | BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
|
---|
[1] | 537 | {
|
---|
[40214] | 538 | VBoxGINAVerbose(0, "VBoxGINA::WlxNetworkProviderLoad\n");
|
---|
[1] | 539 |
|
---|
[36258] | 540 | /* Forward to MSGINA if present. */
|
---|
[1] | 541 | if (GWlxNetworkProviderLoad)
|
---|
| 542 | return GWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
|
---|
| 543 | return FALSE;
|
---|
| 544 | }
|
---|
| 545 |
|
---|
| 546 |
|
---|
| 547 | BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions,
|
---|
| 548 | PWSTR pTitle, PWSTR pMessage)
|
---|
| 549 | {
|
---|
[40214] | 550 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisplayStatusMessage\n");
|
---|
[1] | 551 |
|
---|
[36258] | 552 | /* Forward to MSGINA if present. */
|
---|
[1] | 553 | if (GWlxDisplayStatusMessage)
|
---|
| 554 | return GWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
|
---|
| 555 | return FALSE;
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 |
|
---|
| 559 | BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions,
|
---|
| 560 | PWSTR pMessage, DWORD dwBufferSize)
|
---|
| 561 | {
|
---|
[40214] | 562 | VBoxGINAVerbose(0, "VBoxGINA::WlxGetStatusMessage\n");
|
---|
[1] | 563 |
|
---|
[36258] | 564 | /* Forward to MSGINA if present. */
|
---|
[1] | 565 | if (GWlxGetStatusMessage)
|
---|
| 566 | return GWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
|
---|
| 567 | return FALSE;
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 |
|
---|
| 571 | BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
|
---|
| 572 | {
|
---|
[40214] | 573 | VBoxGINAVerbose(0, "VBoxGINA::WlxRemoveStatusMessage\n");
|
---|
[1] | 574 |
|
---|
[36258] | 575 | /* Forward to MSGINA if present. */
|
---|
[1] | 576 | if (GWlxRemoveStatusMessage)
|
---|
| 577 | return GWlxRemoveStatusMessage(pWlxContext);
|
---|
| 578 | return FALSE;
|
---|
| 579 | }
|
---|
| 580 |
|
---|
| 581 |
|
---|
| 582 | /*
|
---|
| 583 | * GINA 1.4 entry points
|
---|
| 584 | */
|
---|
| 585 | BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
|
---|
| 586 | {
|
---|
[40214] | 587 | VBoxGINAVerbose(0, "VBoxGINA::WlxGetConsoleSwitchCredentials\n");
|
---|
[1] | 588 |
|
---|
[38313] | 589 | /* Forward call to MSGINA if present */
|
---|
[1] | 590 | if (GWlxGetConsoleSwitchCredentials)
|
---|
| 591 | return GWlxGetConsoleSwitchCredentials(pWlxContext,pCredInfo);
|
---|
| 592 | return FALSE;
|
---|
| 593 | }
|
---|
| 594 |
|
---|
[36258] | 595 |
|
---|
[1] | 596 | VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
|
---|
| 597 | {
|
---|
[40214] | 598 | VBoxGINAVerbose(0, "VBoxGINA::WlxReconnectNotify\n");
|
---|
[1] | 599 |
|
---|
[36258] | 600 | /* Forward to MSGINA if present. */
|
---|
[1] | 601 | if (GWlxReconnectNotify)
|
---|
| 602 | GWlxReconnectNotify(pWlxContext);
|
---|
| 603 | }
|
---|
| 604 |
|
---|
[36258] | 605 |
|
---|
[1] | 606 | VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
|
---|
| 607 | {
|
---|
[40214] | 608 | VBoxGINAVerbose(0, "VBoxGINA::WlxDisconnectNotify\n");
|
---|
[1] | 609 |
|
---|
[36258] | 610 | /* Forward to MSGINA if present. */
|
---|
[1] | 611 | if (GWlxDisconnectNotify)
|
---|
| 612 | GWlxDisconnectNotify(pWlxContext);
|
---|
| 613 | }
|
---|
[36258] | 614 |
|
---|
[40214] | 615 |
|
---|
[40768] | 616 | /*
|
---|
| 617 | * Windows Notification Package callbacks
|
---|
| 618 | */
|
---|
| 619 | void WnpScreenSaverStop(PWLX_NOTIFICATION_INFO pInfo)
|
---|
| 620 | {
|
---|
[63093] | 621 | RT_NOREF(pInfo);
|
---|
[40768] | 622 | VBoxGINAVerbose(0, "VBoxGINA::WnpScreenSaverStop\n");
|
---|
| 623 |
|
---|
| 624 | /*
|
---|
| 625 | * Because we set the status to "init" in WlxScreenSaverNotify when
|
---|
| 626 | * the screensaver becomes active we also have to take into account
|
---|
| 627 | * that in case the screensaver terminates (either within the grace
|
---|
| 628 | * period or because the lock screen appears) we have to set the
|
---|
| 629 | * status accordingly.
|
---|
| 630 | */
|
---|
| 631 | VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminated);
|
---|
| 632 | }
|
---|
| 633 |
|
---|
| 634 |
|
---|
[40214] | 635 | DWORD WINAPI VBoxGINADebug(void)
|
---|
| 636 | {
|
---|
| 637 | #ifdef DEBUG
|
---|
| 638 | DWORD dwVersion;
|
---|
| 639 | BOOL fRes = WlxNegotiate(WLX_VERSION_1_4, &dwVersion);
|
---|
| 640 | if (!fRes)
|
---|
| 641 | return 1;
|
---|
| 642 |
|
---|
| 643 | void* pWlxContext = NULL;
|
---|
| 644 | WLX_DISPATCH_VERSION_1_4 wlxDispatch;
|
---|
| 645 | ZeroMemory(&wlxDispatch, sizeof(WLX_DISPATCH_VERSION_1_4));
|
---|
| 646 |
|
---|
| 647 | fRes = WlxInitialize(0, 0,
|
---|
| 648 | NULL /* Reserved */,
|
---|
| 649 | NULL /* Winlogon functions */,
|
---|
| 650 | &pWlxContext);
|
---|
| 651 | if (!fRes)
|
---|
| 652 | return 2;
|
---|
| 653 |
|
---|
| 654 | WlxDisplaySASNotice(pWlxContext);
|
---|
| 655 |
|
---|
| 656 | char szSID[MAX_PATH];
|
---|
| 657 | LUID luidAuth;
|
---|
| 658 | DWORD dwOpts;
|
---|
| 659 | WLX_MPR_NOTIFY_INFO wlxNotifyInfo;
|
---|
| 660 | void* pvProfile;
|
---|
| 661 | HANDLE hToken;
|
---|
| 662 | int iRes = WlxLoggedOutSAS(pWlxContext, WLX_SAS_TYPE_CTRL_ALT_DEL,
|
---|
| 663 | &luidAuth, szSID,
|
---|
| 664 | &dwOpts, &hToken, &wlxNotifyInfo, &pvProfile);
|
---|
| 665 | return iRes;
|
---|
| 666 | #else
|
---|
| 667 | return 0;
|
---|
| 668 | #endif
|
---|
| 669 | }
|
---|
| 670 |
|
---|