VirtualBox

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

Last change on this file since 31890 was 28800, checked in by vboxsync, 14 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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