VirtualBox

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

Last change on this file since 16684 was 16143, checked in by vboxsync, 16 years ago

VBoxGINA: Fixed CTRL-ALT-DEL handling: Now works as expected. Also added some more diagnostic info for further debugging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1/** @file
2 *
3 * VBoxGINA -- Windows Logon DLL for VirtualBox
4 *
5 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
16 * Clara, CA 95054 USA or visit http://www.sun.com if you need
17 * additional information or have any questions.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <windows.h>
23#include "winwlx.h"
24#include "VBoxGINA.h"
25#include "Helper.h"
26#include "Dialog.h"
27
28/*
29 * Global variables
30 */
31
32
33/** DLL instance handle */
34HINSTANCE hDllInstance;
35
36/** Version of Winlogon */
37DWORD wlxVersion;
38
39/** Handle to Winlogon service */
40HANDLE hGinaWlx;
41/** Winlog function dispatch table */
42PWLX_DISPATCH_VERSION_1_1 pWlxFuncs;
43
44/**
45 * Function pointers to MSGINA entry points
46 */
47PGWLXNEGOTIATE GWlxNegotiate;
48PGWLXINITIALIZE GWlxInitialize;
49PGWLXDISPLAYSASNOTICE GWlxDisplaySASNotice;
50PGWLXLOGGEDOUTSAS GWlxLoggedOutSAS;
51PGWLXACTIVATEUSERSHELL GWlxActivateUserShell;
52PGWLXLOGGEDONSAS GWlxLoggedOnSAS;
53PGWLXDISPLAYLOCKEDNOTICE GWlxDisplayLockedNotice;
54PGWLXWKSTALOCKEDSAS GWlxWkstaLockedSAS;
55PGWLXISLOCKOK GWlxIsLockOk;
56PGWLXISLOGOFFOK GWlxIsLogoffOk;
57PGWLXLOGOFF GWlxLogoff;
58PGWLXSHUTDOWN GWlxShutdown;
59/* GINA 1.1 */
60PGWLXSTARTAPPLICATION GWlxStartApplication;
61PGWLXSCREENSAVERNOTIFY GWlxScreenSaverNotify;
62/* GINA 1.3 */
63PGWLXNETWORKPROVIDERLOAD GWlxNetworkProviderLoad;
64PGWLXDISPLAYSTATUSMESSAGE GWlxDisplayStatusMessage;
65PGWLXGETSTATUSMESSAGE GWlxGetStatusMessage;
66PGWLXREMOVESTATUSMESSAGE GWlxRemoveStatusMessage;
67/* GINA 1.4 */
68PGWLXGETCONSOLESWITCHCREDENTIALS GWlxGetConsoleSwitchCredentials;
69PGWLXRECONNECTNOTIFY GWlxReconnectNotify;
70PGWLXDISCONNECTNOTIFY GWlxDisconnectNotify;
71
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 RTR3Init();
86 VbglR3Init();
87 LogRel(("VBoxGina: DLL loaded.\n"));
88
89 DisableThreadLibraryCalls(hInstance);
90 hDllInstance = hInstance;
91 break;
92 }
93
94 case DLL_PROCESS_DETACH:
95 {
96 LogRel(("VBoxGina: DLL unloaded.\n"));
97 VbglR3Term();
98 /// @todo RTR3Term();
99 break;
100 }
101
102 default:
103 break;
104 }
105 return TRUE;
106}
107
108BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion,
109 DWORD *pdwDllVersion)
110{
111 HINSTANCE hDll;
112
113#ifdef DEBUG
114 /* enable full log output */
115 RTLogGroupSettings(RTLogDefaultInstance(), "all=~0");
116#endif
117
118 Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %d\n", dwWinlogonVersion));
119
120 /* load the standard Microsoft GINA DLL */
121 if (!(hDll = LoadLibrary(TEXT("MSGINA.DLL"))))
122 {
123 Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! last error = %d\n", GetLastError()));
124 return FALSE;
125 }
126
127 /*
128 * Now get the entry points of the MSGINA
129 */
130 GWlxNegotiate = (PGWLXNEGOTIATE)GetProcAddress(hDll, "WlxNegotiate");
131 if (!GWlxNegotiate)
132 {
133 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
134 return FALSE;
135 }
136 GWlxInitialize = (PGWLXINITIALIZE)GetProcAddress(hDll, "WlxInitialize");
137 if (!GWlxInitialize)
138 {
139 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
140 return FALSE;
141 }
142 GWlxDisplaySASNotice =
143 (PGWLXDISPLAYSASNOTICE)GetProcAddress(hDll, "WlxDisplaySASNotice");
144 if (!GWlxDisplaySASNotice)
145 {
146 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
147 return FALSE;
148 }
149 GWlxLoggedOutSAS =
150 (PGWLXLOGGEDOUTSAS)GetProcAddress(hDll, "WlxLoggedOutSAS");
151 if (!GWlxLoggedOutSAS)
152 {
153 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
154 return FALSE;
155 }
156 GWlxActivateUserShell =
157 (PGWLXACTIVATEUSERSHELL)GetProcAddress(hDll, "WlxActivateUserShell");
158 if (!GWlxActivateUserShell)
159 {
160 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
161 return FALSE;
162 }
163 GWlxLoggedOnSAS =
164 (PGWLXLOGGEDONSAS)GetProcAddress(hDll, "WlxLoggedOnSAS");
165 if (!GWlxLoggedOnSAS)
166 {
167 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
168 return FALSE;
169 }
170 GWlxDisplayLockedNotice =
171 (PGWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hDll, "WlxDisplayLockedNotice");
172 if (!GWlxDisplayLockedNotice)
173 {
174 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
175 return FALSE;
176 }
177 GWlxIsLockOk = (PGWLXISLOCKOK)GetProcAddress(hDll, "WlxIsLockOk");
178 if (!GWlxIsLockOk)
179 {
180 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
181 return FALSE;
182 }
183 GWlxWkstaLockedSAS =
184 (PGWLXWKSTALOCKEDSAS)GetProcAddress(hDll, "WlxWkstaLockedSAS");
185 if (!GWlxWkstaLockedSAS)
186 {
187 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
188 return FALSE;
189 }
190 GWlxIsLogoffOk = (PGWLXISLOGOFFOK)GetProcAddress(hDll, "WlxIsLogoffOk");
191 if (!GWlxIsLogoffOk)
192 {
193 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
194 return FALSE;
195 }
196 GWlxLogoff = (PGWLXLOGOFF)GetProcAddress(hDll, "WlxLogoff");
197 if (!GWlxLogoff)
198 {
199 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
200 return FALSE;
201 }
202 GWlxShutdown = (PGWLXSHUTDOWN)GetProcAddress(hDll, "WlxShutdown");
203 if (!GWlxShutdown)
204 {
205 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n"));
206 return FALSE;
207 }
208 /* GINA 1.1, optional */
209 GWlxStartApplication = (PGWLXSTARTAPPLICATION)GetProcAddress(hDll, "WlxStartApplication");
210 GWlxScreenSaverNotify = (PGWLXSCREENSAVERNOTIFY)GetProcAddress(hDll, "WlxScreenSaverNotify");
211 /* GINA 1.3, optional */
212 GWlxNetworkProviderLoad = (PGWLXNETWORKPROVIDERLOAD)GetProcAddress( hDll, "WlxNetworkProviderLoad");
213 GWlxDisplayStatusMessage = (PGWLXDISPLAYSTATUSMESSAGE)GetProcAddress( hDll, "WlxDisplayStatusMessage");
214 GWlxGetStatusMessage = (PGWLXGETSTATUSMESSAGE)GetProcAddress( hDll, "WlxGetStatusMessage");
215 GWlxRemoveStatusMessage = (PGWLXREMOVESTATUSMESSAGE)GetProcAddress( hDll, "WlxRemoveStatusMessage");
216 /* GINA 1.4, optional */
217 GWlxGetConsoleSwitchCredentials =
218 (PGWLXGETCONSOLESWITCHCREDENTIALS)GetProcAddress(hDll, "WlxGetConsoleSwitchCredentials");
219 GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)GetProcAddress(hDll, "WlxReconnectNotify");
220 GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)GetProcAddress(hDll, "WlxDisconnectNotify");
221 Log(("VBoxGINA::WlxNegotiate: optional function pointers:\n"
222 " WlxStartApplication: %p\n"
223 " WlxScreenSaverNotify: %p\n"
224 " WlxNetworkProviderLoad: %p\n"
225 " WlxDisplayStatusMessage: %p\n"
226 " WlxGetStatusMessage: %p\n"
227 " WlxRemoveStatusMessage: %p\n"
228 " WlxGetConsoleSwitchCredentials: %p\n"
229 " WlxReconnectNotify: %p\n"
230 " WlxDisconnectNotify: %p\n",
231 GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
232 GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
233 GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify));
234
235 wlxVersion = dwWinlogonVersion;
236
237 /* forward call */
238 return GWlxNegotiate(dwWinlogonVersion, pdwDllVersion);
239}
240
241
242BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
243 PVOID pWinlogonFunctions, PVOID *pWlxContext)
244{
245 Log(("VBoxGINA::WlxInitialize\n"));
246
247 /* store Winlogon function table */
248 pWlxFuncs = (PWLX_DISPATCH_VERSION_1_1)pWinlogonFunctions;
249
250 /* store handle to Winlogon service*/
251 hGinaWlx = hWlx;
252
253 /* hook the dialogs */
254 hookDialogBoxes(pWlxFuncs, wlxVersion);
255
256 /* forward call */
257 return GWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
258}
259
260
261VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
262{
263 Log(("VBoxGINA::WlxDisplaySASNotice\n"));
264
265 /* check if there are credentials for us, if so simulat C-A-D */
266 if (credentialsAvailable())
267 {
268 Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
269 /* automatic C-A-D */
270 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
271 }
272 else
273 {
274 Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
275 /* start the credentials poller thread */
276 credentialsPollerCreate();
277 /* forward call to MSGINA */
278 GWlxDisplaySASNotice(pWlxContext);
279 }
280}
281
282
283int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId,
284 PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken,
285 PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
286{
287 Log(("VBoxGINA::WlxLoggedOutSAS\n"));
288
289 /* when performing a direct logon without C-A-D, our poller might not be running */
290 if (!credentialsAvailable())
291 {
292 credentialsPollerCreate();
293 }
294
295 int iRet;
296 iRet = GWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,
297 pdwOptions, phToken, pMprNotifyInfo, pProfile);
298
299 if (iRet == WLX_SAS_ACTION_LOGON)
300 {
301 //
302 // copy pMprNotifyInfo and pLogonSid for later use
303 //
304
305 // pMprNotifyInfo->pszUserName
306 // pMprNotifyInfo->pszDomain
307 // pMprNotifyInfo->pszPassword
308 // pMprNotifyInfo->pszOldPassword
309
310 }
311
312 return iRet;
313}
314
315
316BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
317 PWSTR pszMprLogonScript, PVOID pEnvironment)
318{
319 Log(("VBoxGINA::WlxActivateUserShell\n"));
320
321 /* forward call to MSGINA */
322 return GWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
323}
324
325
326int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
327{
328 HKEY hKey;
329 DWORD dwValue = 1;
330 DWORD dwSize = 0;
331 DWORD dwType = 0;
332 int iRet = WLX_SAS_ACTION_NONE;
333
334 Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
335
336 /* Winlogon registry path */
337 static TCHAR szPath[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
338
339 if (!RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey))
340 {
341 dwSize = sizeof(DWORD);
342 RegQueryValueEx(hKey, TEXT("SAS_S"), 0, &dwType, (PBYTE)&dwValue, &dwSize);
343 RegCloseKey(hKey);
344 }
345 else
346 {
347 Log(("VBoxGINA::WlxLoggedOnSAS: Could not open registry key! Last error: %d\n", GetLastError()));
348 }
349
350 if (dwValue)
351 {
352 switch (dwSasType)
353 {
354
355 case WLX_SAS_TYPE_CTRL_ALT_DEL: /* User pressed CTRL-ALT-DEL. */
356
357 /* Show the task list (or whatever the OS wants to do here). */
358 iRet = WLX_SAS_ACTION_TASKLIST;
359 break;
360
361 default:
362 break;
363 }
364 }
365 else
366 {
367 /* Forward call to MSGINA. */
368 Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
369 return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
370 }
371
372 return iRet;
373}
374
375VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
376{
377 Log(("VBoxGINA::WlxDisplayLockedNotice\n"));
378 /* forward call to MSGINA */
379 GWlxDisplayLockedNotice(pWlxContext);
380}
381
382
383BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
384{
385 Log(("VBoxGINA::WlxIsLockOk\n"));
386 /* forward call to MSGINA */
387 return GWlxIsLockOk(pWlxContext);
388}
389
390int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
391{
392 Log(("VBoxGINA::WlxWkstaLockedSAS\n"));
393 /* forward call to MSGINA */
394 return GWlxWkstaLockedSAS(pWlxContext, dwSasType);
395}
396
397BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
398{
399 BOOL bSuccess;
400
401 Log(("VBoxGINA::WlxIsLogoffOk\n"));
402
403 bSuccess = GWlxIsLogoffOk(pWlxContext);
404
405 if (bSuccess)
406 {
407 //
408 // if it's ok to logoff, finish with the stored credentials
409 // and scrub the buffers
410 //
411
412 }
413 return bSuccess;
414}
415
416
417VOID WINAPI WlxLogoff(PVOID pWlxContext)
418{
419 Log(("VBoxGINA::WlxLogoff\n"));
420
421 /* forward call to MSGINA */
422 GWlxLogoff(pWlxContext);
423}
424
425
426VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
427{
428 Log(("VBoxGINA::WlxShutdown\n"));
429
430 /* forward call to MSGINA */
431 GWlxShutdown(pWlxContext, ShutdownType);
432}
433
434
435/*
436 * GINA 1.1 entry points
437 */
438
439BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
440{
441 Log(("VBoxGINA::WlxScreenSaverNotify\n"));
442
443 /* forward to MSGINA if present */
444 if (GWlxScreenSaverNotify)
445 return GWlxScreenSaverNotify(pWlxContext, pSecure);
446 /* return something intelligent */
447 *pSecure = TRUE;
448 return TRUE;
449}
450
451BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
452 PVOID pEnvironment, PWSTR pszCmdLine)
453{
454 Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
455 pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
456
457 /* forward to MSGINA if present */
458 if (GWlxStartApplication)
459 return GWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
460 return FALSE;
461}
462
463/*
464 * GINA 1.3 entry points
465 */
466BOOL WINAPI WlxNetworkProviderLoad (PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
467{
468 Log(("VBoxGINA::WlxNetworkProviderLoad\n"));
469
470 /* forward to MSGINA if present */
471 if (GWlxNetworkProviderLoad)
472 return GWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
473 return FALSE;
474}
475
476
477BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions,
478 PWSTR pTitle, PWSTR pMessage)
479{
480 Log(("VBoxGINA::WlxDisplayStatusMessage\n"));
481
482 /* forward to MSGINA if present */
483 if (GWlxDisplayStatusMessage)
484 return GWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
485 return FALSE;
486}
487
488
489BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions,
490 PWSTR pMessage, DWORD dwBufferSize)
491{
492 Log(("VBoxGINA::WlxGetStatusMessage\n"));
493
494 /* forward to MSGINA if present */
495 if (GWlxGetStatusMessage)
496 return GWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
497 return FALSE;
498}
499
500
501BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
502{
503 Log(("VBoxGINA::WlxRemoveStatusMessage\n"));
504
505 /* forward to MSGINA if present */
506 if (GWlxRemoveStatusMessage)
507 return GWlxRemoveStatusMessage(pWlxContext);
508 return FALSE;
509}
510
511
512/*
513 * GINA 1.4 entry points
514 */
515
516BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
517{
518 Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
519
520 /* forward call to MSGINA if present */
521 if (GWlxGetConsoleSwitchCredentials)
522 return GWlxGetConsoleSwitchCredentials(pWlxContext,pCredInfo);
523 return FALSE;
524}
525
526VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
527{
528 Log(("VBoxGINA::WlxReconnectNotify\n"));
529
530 /* forward to MSGINA if present */
531 if (GWlxReconnectNotify)
532 GWlxReconnectNotify(pWlxContext);
533}
534
535VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
536{
537 Log(("VBoxGINA::WlxDisconnectNotify\n"));
538
539 /* forward to MSGINA if present */
540 if (GWlxDisconnectNotify)
541 GWlxDisconnectNotify(pWlxContext);
542}
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