VirtualBox

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

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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