VirtualBox

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

Last change on this file since 27709 was 25864, checked in by vboxsync, 15 years ago

VBoxGINA: Made UI handling more modular, added new handling also to timer-based credential polling, wipe credentials on logout.

  • 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#include <VBox/VBoxGuestLib.h>
28
29/*
30 * Global variables
31 */
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/**
76 * DLL entry point.
77 */
78BOOL WINAPI DllMain(HINSTANCE hInstance,
79 DWORD dwReason,
80 LPVOID lpReserved)
81{
82 switch (dwReason)
83 {
84 case DLL_PROCESS_ATTACH:
85 {
86 RTR3Init();
87 VbglR3Init();
88 LogRel(("VBoxGina: DLL loaded.\n"));
89
90 DisableThreadLibraryCalls(hInstance);
91 hDllInstance = hInstance;
92 break;
93 }
94
95 case DLL_PROCESS_DETACH:
96 {
97 LogRel(("VBoxGina: DLL unloaded.\n"));
98 VbglR3Term();
99 /// @todo RTR3Term();
100 break;
101 }
102
103 default:
104 break;
105 }
106 return TRUE;
107}
108
109BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion,
110 DWORD *pdwDllVersion)
111{
112 HINSTANCE hDll;
113
114#ifdef DEBUG
115 /* enable full log output */
116 RTLogGroupSettings(RTLogDefaultInstance(), "all=~0");
117#endif
118
119 Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %d\n", dwWinlogonVersion));
120
121 /* load the standard Microsoft GINA DLL */
122 if (!(hDll = LoadLibrary(TEXT("MSGINA.DLL"))))
123 {
124 Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! last error = %d\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 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
135 return FALSE;
136 }
137 GWlxInitialize = (PGWLXINITIALIZE)GetProcAddress(hDll, "WlxInitialize");
138 if (!GWlxInitialize)
139 {
140 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
141 return FALSE;
142 }
143 GWlxDisplaySASNotice =
144 (PGWLXDISPLAYSASNOTICE)GetProcAddress(hDll, "WlxDisplaySASNotice");
145 if (!GWlxDisplaySASNotice)
146 {
147 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
148 return FALSE;
149 }
150 GWlxLoggedOutSAS =
151 (PGWLXLOGGEDOUTSAS)GetProcAddress(hDll, "WlxLoggedOutSAS");
152 if (!GWlxLoggedOutSAS)
153 {
154 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
155 return FALSE;
156 }
157 GWlxActivateUserShell =
158 (PGWLXACTIVATEUSERSHELL)GetProcAddress(hDll, "WlxActivateUserShell");
159 if (!GWlxActivateUserShell)
160 {
161 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
162 return FALSE;
163 }
164 GWlxLoggedOnSAS =
165 (PGWLXLOGGEDONSAS)GetProcAddress(hDll, "WlxLoggedOnSAS");
166 if (!GWlxLoggedOnSAS)
167 {
168 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
169 return FALSE;
170 }
171 GWlxDisplayLockedNotice =
172 (PGWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hDll, "WlxDisplayLockedNotice");
173 if (!GWlxDisplayLockedNotice)
174 {
175 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
176 return FALSE;
177 }
178 GWlxIsLockOk = (PGWLXISLOCKOK)GetProcAddress(hDll, "WlxIsLockOk");
179 if (!GWlxIsLockOk)
180 {
181 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
182 return FALSE;
183 }
184 GWlxWkstaLockedSAS =
185 (PGWLXWKSTALOCKEDSAS)GetProcAddress(hDll, "WlxWkstaLockedSAS");
186 if (!GWlxWkstaLockedSAS)
187 {
188 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
189 return FALSE;
190 }
191 GWlxIsLogoffOk = (PGWLXISLOGOFFOK)GetProcAddress(hDll, "WlxIsLogoffOk");
192 if (!GWlxIsLogoffOk)
193 {
194 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
195 return FALSE;
196 }
197 GWlxLogoff = (PGWLXLOGOFF)GetProcAddress(hDll, "WlxLogoff");
198 if (!GWlxLogoff)
199 {
200 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
201 return FALSE;
202 }
203 GWlxShutdown = (PGWLXSHUTDOWN)GetProcAddress(hDll, "WlxShutdown");
204 if (!GWlxShutdown)
205 {
206 Log(("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 Log(("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 /* forward call */
239 return GWlxNegotiate(dwWinlogonVersion, pdwDllVersion);
240}
241
242
243BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
244 PVOID pWinlogonFunctions, PVOID *pWlxContext)
245{
246 Log(("VBoxGINA::WlxInitialize\n"));
247
248 /* store Winlogon function table */
249 pWlxFuncs = (PWLX_DISPATCH_VERSION_1_1)pWinlogonFunctions;
250
251 /* store handle to Winlogon service*/
252 hGinaWlx = hWlx;
253
254 /* hook the dialogs */
255 hookDialogBoxes(pWlxFuncs, wlxVersion);
256
257 /* forward call */
258 return GWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
259}
260
261
262VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
263{
264 Log(("VBoxGINA::WlxDisplaySASNotice\n"));
265
266 /* check if there are credentials for us, if so simulat C-A-D */
267 if (credentialsAvailable())
268 {
269 Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
270 /* automatic C-A-D */
271 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
272 }
273 else
274 {
275 Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
276 /* start the credentials poller thread */
277 credentialsPollerCreate();
278 /* forward call to MSGINA */
279 GWlxDisplaySASNotice(pWlxContext);
280 }
281}
282
283
284int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId,
285 PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken,
286 PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
287{
288 Log(("VBoxGINA::WlxLoggedOutSAS\n"));
289
290 /* when performing a direct logon without C-A-D, our poller might not be running */
291 if (!credentialsAvailable())
292 {
293 credentialsPollerCreate();
294 }
295
296 int iRet;
297 iRet = GWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,
298 pdwOptions, phToken, pMprNotifyInfo, pProfile);
299
300 if (iRet == WLX_SAS_ACTION_LOGON)
301 {
302 //
303 // copy pMprNotifyInfo and pLogonSid for later use
304 //
305
306 // pMprNotifyInfo->pszUserName
307 // pMprNotifyInfo->pszDomain
308 // pMprNotifyInfo->pszPassword
309 // pMprNotifyInfo->pszOldPassword
310
311 }
312
313 return iRet;
314}
315
316
317BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
318 PWSTR pszMprLogonScript, PVOID pEnvironment)
319{
320 Log(("VBoxGINA::WlxActivateUserShell\n"));
321
322 /* forward call to MSGINA */
323 return GWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
324}
325
326
327int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
328{
329 HKEY hKey;
330 DWORD dwValue = 1;
331 DWORD dwSize = 0;
332 DWORD dwType = 0;
333 int iRet = WLX_SAS_ACTION_NONE;
334
335 Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
336
337 /* Winlogon registry path */
338 static TCHAR szPath[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
339
340 if (!RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey))
341 {
342 dwSize = sizeof(DWORD);
343 RegQueryValueEx(hKey, TEXT("SAS_S"), 0, &dwType, (PBYTE)&dwValue, &dwSize);
344 RegCloseKey(hKey);
345 }
346 else
347 {
348 Log(("VBoxGINA::WlxLoggedOnSAS: Could not open registry key! Last error: %d\n", GetLastError()));
349 }
350
351 if (dwValue)
352 {
353 switch (dwSasType)
354 {
355
356 case WLX_SAS_TYPE_CTRL_ALT_DEL: /* User pressed CTRL-ALT-DEL. */
357
358 /* Show the task list (or whatever the OS wants to do here). */
359 iRet = WLX_SAS_ACTION_TASKLIST;
360 break;
361
362 default:
363 break;
364 }
365 }
366 else
367 {
368 /* Forward call to MSGINA. */
369 Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
370 return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
371 }
372
373 return iRet;
374}
375
376VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
377{
378 Log(("VBoxGINA::WlxDisplayLockedNotice\n"));
379 /* forward call to MSGINA */
380 GWlxDisplayLockedNotice(pWlxContext);
381}
382
383
384BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
385{
386 Log(("VBoxGINA::WlxIsLockOk\n"));
387 /* forward call to MSGINA */
388 return GWlxIsLockOk(pWlxContext);
389}
390
391int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
392{
393 Log(("VBoxGINA::WlxWkstaLockedSAS\n"));
394 /* forward call to MSGINA */
395 return GWlxWkstaLockedSAS(pWlxContext, dwSasType);
396}
397
398BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
399{
400 BOOL bSuccess;
401
402 Log(("VBoxGINA::WlxIsLogoffOk\n"));
403
404 bSuccess = GWlxIsLogoffOk(pWlxContext);
405
406 if (bSuccess)
407 {
408 //
409 // if it's ok to logoff, finish with the stored credentials
410 // and scrub the buffers
411 //
412 credentialsReset();
413
414 }
415 return bSuccess;
416}
417
418
419VOID WINAPI WlxLogoff(PVOID pWlxContext)
420{
421 Log(("VBoxGINA::WlxLogoff\n"));
422
423 /* forward call to MSGINA */
424 GWlxLogoff(pWlxContext);
425}
426
427
428VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
429{
430 Log(("VBoxGINA::WlxShutdown\n"));
431
432 /* forward call to MSGINA */
433 GWlxShutdown(pWlxContext, ShutdownType);
434}
435
436
437/*
438 * GINA 1.1 entry points
439 */
440
441BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
442{
443 Log(("VBoxGINA::WlxScreenSaverNotify\n"));
444
445 /* forward to MSGINA if present */
446 if (GWlxScreenSaverNotify)
447 return GWlxScreenSaverNotify(pWlxContext, pSecure);
448 /* return something intelligent */
449 *pSecure = TRUE;
450 return TRUE;
451}
452
453BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
454 PVOID pEnvironment, PWSTR pszCmdLine)
455{
456 Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
457 pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
458
459 /* forward to MSGINA if present */
460 if (GWlxStartApplication)
461 return GWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
462 return FALSE;
463}
464
465/*
466 * GINA 1.3 entry points
467 */
468BOOL WINAPI WlxNetworkProviderLoad (PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
469{
470 Log(("VBoxGINA::WlxNetworkProviderLoad\n"));
471
472 /* forward to MSGINA if present */
473 if (GWlxNetworkProviderLoad)
474 return GWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
475 return FALSE;
476}
477
478
479BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions,
480 PWSTR pTitle, PWSTR pMessage)
481{
482 Log(("VBoxGINA::WlxDisplayStatusMessage\n"));
483
484 /* forward to MSGINA if present */
485 if (GWlxDisplayStatusMessage)
486 return GWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
487 return FALSE;
488}
489
490
491BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions,
492 PWSTR pMessage, DWORD dwBufferSize)
493{
494 Log(("VBoxGINA::WlxGetStatusMessage\n"));
495
496 /* forward to MSGINA if present */
497 if (GWlxGetStatusMessage)
498 return GWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
499 return FALSE;
500}
501
502
503BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
504{
505 Log(("VBoxGINA::WlxRemoveStatusMessage\n"));
506
507 /* forward to MSGINA if present */
508 if (GWlxRemoveStatusMessage)
509 return GWlxRemoveStatusMessage(pWlxContext);
510 return FALSE;
511}
512
513
514/*
515 * GINA 1.4 entry points
516 */
517
518BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
519{
520 Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
521
522 /* forward call to MSGINA if present */
523 if (GWlxGetConsoleSwitchCredentials)
524 return GWlxGetConsoleSwitchCredentials(pWlxContext,pCredInfo);
525 return FALSE;
526}
527
528VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
529{
530 Log(("VBoxGINA::WlxReconnectNotify\n"));
531
532 /* forward to MSGINA if present */
533 if (GWlxReconnectNotify)
534 GWlxReconnectNotify(pWlxContext);
535}
536
537VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
538{
539 Log(("VBoxGINA::WlxDisconnectNotify\n"));
540
541 /* forward to MSGINA if present */
542 if (GWlxDisconnectNotify)
543 GWlxDisconnectNotify(pWlxContext);
544}
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