VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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