VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxGINA/VBoxGINA.cpp@ 40388

Last change on this file since 40388 was 40214, checked in by vboxsync, 13 years ago

VBoxGINA: Added support for auto-logon facility, added guest log support, misc. refactoring, added basic testcase.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette