VirtualBox

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

Last change on this file since 39300 was 38646, checked in by vboxsync, 13 years ago

Burn fix.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1/** @file
2 *
3 * VBoxGINA -- Windows Logon DLL for VirtualBox
4 *
5 * Copyright (C) 2006-2011 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/** 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 * DLL entry point.
71 */
72BOOL WINAPI DllMain(HINSTANCE hInstance,
73 DWORD dwReason,
74 LPVOID lpReserved)
75{
76 switch (dwReason)
77 {
78 case DLL_PROCESS_ATTACH:
79 {
80 RTR3InitDll(0);
81 VbglR3Init();
82 LogRel(("VBoxGINA: DLL loaded.\n"));
83
84 DisableThreadLibraryCalls(hInstance);
85 hDllInstance = hInstance;
86 break;
87 }
88
89 case DLL_PROCESS_DETACH:
90 {
91 LogRel(("VBoxGINA: DLL unloaded.\n"));
92 VbglR3Term();
93 /// @todo RTR3Term();
94 break;
95 }
96
97 default:
98 break;
99 }
100 return TRUE;
101}
102
103
104BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion,
105 DWORD *pdwDllVersion)
106{
107 HINSTANCE hDll;
108
109#ifdef DEBUG_andy
110 /* Enable full log output. */
111 RTLogGroupSettings(0, "+autologon.e.l.f.l2.l3");
112#endif
113
114 Log(("VBoxGINA::WlxNegotiate: dwWinlogonVersion: %ld\n", dwWinlogonVersion));
115
116 /* Load the standard Microsoft GINA DLL. */
117 if (!(hDll = LoadLibrary(TEXT("MSGINA.DLL"))))
118 {
119 Log(("VBoxGINA::WlxNegotiate: failed loading MSGINA! Last error=%ld\n", GetLastError()));
120 return FALSE;
121 }
122
123 /*
124 * Now get the entry points of the MSGINA
125 */
126 GWlxNegotiate = (PGWLXNEGOTIATE)GetProcAddress(hDll, "WlxNegotiate");
127 if (!GWlxNegotiate)
128 {
129 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxNegotiate\n"));
130 return FALSE;
131 }
132 GWlxInitialize = (PGWLXINITIALIZE)GetProcAddress(hDll, "WlxInitialize");
133 if (!GWlxInitialize)
134 {
135 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxInitialize\n"));
136 return FALSE;
137 }
138 GWlxDisplaySASNotice =
139 (PGWLXDISPLAYSASNOTICE)GetProcAddress(hDll, "WlxDisplaySASNotice");
140 if (!GWlxDisplaySASNotice)
141 {
142 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplaySASNotice\n"));
143 return FALSE;
144 }
145 GWlxLoggedOutSAS =
146 (PGWLXLOGGEDOUTSAS)GetProcAddress(hDll, "WlxLoggedOutSAS");
147 if (!GWlxLoggedOutSAS)
148 {
149 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOutSAS\n"));
150 return FALSE;
151 }
152 GWlxActivateUserShell =
153 (PGWLXACTIVATEUSERSHELL)GetProcAddress(hDll, "WlxActivateUserShell");
154 if (!GWlxActivateUserShell)
155 {
156 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxActivateUserShell\n"));
157 return FALSE;
158 }
159 GWlxLoggedOnSAS =
160 (PGWLXLOGGEDONSAS)GetProcAddress(hDll, "WlxLoggedOnSAS");
161 if (!GWlxLoggedOnSAS)
162 {
163 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLoggedOnSAS\n"));
164 return FALSE;
165 }
166 GWlxDisplayLockedNotice =
167 (PGWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hDll, "WlxDisplayLockedNotice");
168 if (!GWlxDisplayLockedNotice)
169 {
170 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxDisplayLockedNotice\n"));
171 return FALSE;
172 }
173 GWlxIsLockOk = (PGWLXISLOCKOK)GetProcAddress(hDll, "WlxIsLockOk");
174 if (!GWlxIsLockOk)
175 {
176 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLockOk\n"));
177 return FALSE;
178 }
179 GWlxWkstaLockedSAS =
180 (PGWLXWKSTALOCKEDSAS)GetProcAddress(hDll, "WlxWkstaLockedSAS");
181 if (!GWlxWkstaLockedSAS)
182 {
183 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxWkstaLockedSAS\n"));
184 return FALSE;
185 }
186 GWlxIsLogoffOk = (PGWLXISLOGOFFOK)GetProcAddress(hDll, "WlxIsLogoffOk");
187 if (!GWlxIsLogoffOk)
188 {
189 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxIsLogoffOk\n"));
190 return FALSE;
191 }
192 GWlxLogoff = (PGWLXLOGOFF)GetProcAddress(hDll, "WlxLogoff");
193 if (!GWlxLogoff)
194 {
195 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxLogoff\n"));
196 return FALSE;
197 }
198 GWlxShutdown = (PGWLXSHUTDOWN)GetProcAddress(hDll, "WlxShutdown");
199 if (!GWlxShutdown)
200 {
201 Log(("VBoxGINA::WlxNegotiate: failed resolving WlxShutdown\n"));
202 return FALSE;
203 }
204 /* GINA 1.1, optional */
205 GWlxStartApplication = (PGWLXSTARTAPPLICATION)GetProcAddress(hDll, "WlxStartApplication");
206 GWlxScreenSaverNotify = (PGWLXSCREENSAVERNOTIFY)GetProcAddress(hDll, "WlxScreenSaverNotify");
207 /* GINA 1.3, optional */
208 GWlxNetworkProviderLoad = (PGWLXNETWORKPROVIDERLOAD)GetProcAddress( hDll, "WlxNetworkProviderLoad");
209 GWlxDisplayStatusMessage = (PGWLXDISPLAYSTATUSMESSAGE)GetProcAddress( hDll, "WlxDisplayStatusMessage");
210 GWlxGetStatusMessage = (PGWLXGETSTATUSMESSAGE)GetProcAddress( hDll, "WlxGetStatusMessage");
211 GWlxRemoveStatusMessage = (PGWLXREMOVESTATUSMESSAGE)GetProcAddress( hDll, "WlxRemoveStatusMessage");
212 /* GINA 1.4, optional */
213 GWlxGetConsoleSwitchCredentials =
214 (PGWLXGETCONSOLESWITCHCREDENTIALS)GetProcAddress(hDll, "WlxGetConsoleSwitchCredentials");
215 GWlxReconnectNotify = (PGWLXRECONNECTNOTIFY)GetProcAddress(hDll, "WlxReconnectNotify");
216 GWlxDisconnectNotify = (PGWLXDISCONNECTNOTIFY)GetProcAddress(hDll, "WlxDisconnectNotify");
217 Log(("VBoxGINA::WlxNegotiate: optional function pointers:\n"
218 " WlxStartApplication: %p\n"
219 " WlxScreenSaverNotify: %p\n"
220 " WlxNetworkProviderLoad: %p\n"
221 " WlxDisplayStatusMessage: %p\n"
222 " WlxGetStatusMessage: %p\n"
223 " WlxRemoveStatusMessage: %p\n"
224 " WlxGetConsoleSwitchCredentials: %p\n"
225 " WlxReconnectNotify: %p\n"
226 " WlxDisconnectNotify: %p\n",
227 GWlxStartApplication, GWlxScreenSaverNotify, GWlxNetworkProviderLoad,
228 GWlxDisplayStatusMessage, GWlxGetStatusMessage, GWlxRemoveStatusMessage,
229 GWlxGetConsoleSwitchCredentials, GWlxReconnectNotify, GWlxDisconnectNotify));
230
231 wlxVersion = dwWinlogonVersion;
232
233 /* Acknowledge interface version. */
234 if (pdwDllVersion)
235 *pdwDllVersion = dwWinlogonVersion;
236
237 return TRUE; /* We're ready to rumble! */
238}
239
240
241BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
242 PVOID pWinlogonFunctions, PVOID *pWlxContext)
243{
244 Log(("VBoxGINA::WlxInitialize\n"));
245
246 /* Store Winlogon function table */
247 pWlxFuncs = (PWLX_DISPATCH_VERSION_1_1)pWinlogonFunctions;
248
249 /* Store handle to Winlogon service*/
250 hGinaWlx = hWlx;
251
252 /* Hook the dialogs */
253 hookDialogBoxes(pWlxFuncs, wlxVersion);
254
255 /* Forward call */
256 return GWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
257}
258
259
260VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
261{
262 Log(("VBoxGINA::WlxDisplaySASNotice\n"));
263
264 /* Check if there are credentials for us, if so simulate C-A-D */
265 if (credentialsAvailable())
266 {
267 Log(("VBoxGINA::WlxDisplaySASNotice: simulating C-A-D\n"));
268 /* Wutomatic C-A-D */
269 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
270 }
271 else
272 {
273 Log(("VBoxGINA::WlxDisplaySASNotice: starting credentials poller\n"));
274 /* start the credentials poller thread */
275 credentialsPollerCreate();
276 /* Forward call to MSGINA. */
277 GWlxDisplaySASNotice(pWlxContext);
278 }
279}
280
281
282int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId,
283 PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken,
284 PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
285{
286 Log(("VBoxGINA::WlxLoggedOutSAS\n"));
287
288 /* When performing a direct logon without C-A-D, our poller might not be running */
289 if (!credentialsAvailable())
290 credentialsPollerCreate();
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 return iRet;
309}
310
311
312BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
313 PWSTR pszMprLogonScript, PVOID pEnvironment)
314{
315 Log(("VBoxGINA::WlxActivateUserShell\n"));
316
317 /* Forward call to MSGINA. */
318 return GWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
319}
320
321
322int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
323{
324 Log(("VBoxGINA::WlxLoggedOnSAS: SaSType = %ld\n", dwSasType));
325
326 /*
327 * We don't want to do anything special here since the OS should behave
328 * as VBoxGINA wouldn't have been installed. So pass all calls down
329 * to the original MSGINA.
330 */
331
332 /* Forward call to MSGINA. */
333 Log(("VBoxGINA::WlxLoggedOnSAS: Forwarding call to MSGINA ...\n"));
334 return GWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
335}
336
337VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
338{
339 Log(("VBoxGINA::WlxDisplayLockedNotice\n"));
340
341 /* Check if there are credentials for us, if so simulate C-A-D */
342 if (credentialsAvailable())
343 {
344 Log(("VBoxGINA::WlxDisplayLockedNotice: simulating C-A-D\n"));
345 /* Automatic C-A-D */
346 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
347 }
348 else
349 {
350 Log(("VBoxGINA::WlxDisplayLockedNotice: starting credentials poller\n"));
351 /* start the credentials poller thread */
352 credentialsPollerCreate();
353 /* Forward call to MSGINA. */
354 GWlxDisplayLockedNotice(pWlxContext);
355 }
356}
357
358
359BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
360{
361 Log(("VBoxGINA::WlxIsLockOk\n"));
362 /* Forward call to MSGINA. */
363 return GWlxIsLockOk(pWlxContext);
364}
365
366int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
367{
368 Log(("VBoxGINA::WlxWkstaLockedSAS\n"));
369
370 /* When performing a direct logon without C-A-D, our poller might not be running */
371 if (!credentialsAvailable())
372 credentialsPollerCreate();
373
374 /* Forward call to MSGINA. */
375 return GWlxWkstaLockedSAS(pWlxContext, dwSasType);
376}
377
378BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
379{
380 Log(("VBoxGINA::WlxIsLogoffOk\n"));
381
382 BOOL bSuccess = GWlxIsLogoffOk(pWlxContext);
383 if (bSuccess)
384 {
385 //
386 // if it's ok to logoff, finish with the stored credentials
387 // and scrub the buffers
388 //
389 credentialsReset();
390
391 }
392 return bSuccess;
393}
394
395
396VOID WINAPI WlxLogoff(PVOID pWlxContext)
397{
398 Log(("VBoxGINA::WlxLogoff\n"));
399
400 /* Forward call to MSGINA. */
401 GWlxLogoff(pWlxContext);
402}
403
404
405VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
406{
407 Log(("VBoxGINA::WlxShutdown\n"));
408
409 /* Forward call to MSGINA. */
410 GWlxShutdown(pWlxContext, ShutdownType);
411}
412
413
414/*
415 * GINA 1.1 entry points
416 */
417BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
418{
419 Log(("VBoxGINA::WlxScreenSaverNotify\n"));
420
421 /* Forward to MSGINA if present. */
422 if (GWlxScreenSaverNotify)
423 return GWlxScreenSaverNotify(pWlxContext, pSecure);
424 /* Return something intelligent */
425 *pSecure = TRUE;
426 return TRUE;
427}
428
429
430BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
431 PVOID pEnvironment, PWSTR pszCmdLine)
432{
433 Log(("VBoxGINA::WlxStartApplication: pWlxCtx=%p, pszDesktopName=%ls, pEnvironment=%p, pszCmdLine=%ls\n",
434 pWlxContext, pszDesktopName, pEnvironment, pszCmdLine));
435
436 /* Forward to MSGINA if present. */
437 if (GWlxStartApplication)
438 return GWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
439 return FALSE;
440}
441
442
443/*
444 * GINA 1.3 entry points
445 */
446BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
447{
448 Log(("VBoxGINA::WlxNetworkProviderLoad\n"));
449
450 /* Forward to MSGINA if present. */
451 if (GWlxNetworkProviderLoad)
452 return GWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
453 return FALSE;
454}
455
456
457BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions,
458 PWSTR pTitle, PWSTR pMessage)
459{
460 Log(("VBoxGINA::WlxDisplayStatusMessage\n"));
461
462 /* Forward to MSGINA if present. */
463 if (GWlxDisplayStatusMessage)
464 return GWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
465 return FALSE;
466}
467
468
469BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions,
470 PWSTR pMessage, DWORD dwBufferSize)
471{
472 Log(("VBoxGINA::WlxGetStatusMessage\n"));
473
474 /* Forward to MSGINA if present. */
475 if (GWlxGetStatusMessage)
476 return GWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
477 return FALSE;
478}
479
480
481BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
482{
483 Log(("VBoxGINA::WlxRemoveStatusMessage\n"));
484
485 /* Forward to MSGINA if present. */
486 if (GWlxRemoveStatusMessage)
487 return GWlxRemoveStatusMessage(pWlxContext);
488 return FALSE;
489}
490
491
492/*
493 * GINA 1.4 entry points
494 */
495BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext,PVOID pCredInfo)
496{
497 Log(("VBoxGINA::WlxGetConsoleSwitchCredentials\n"));
498
499 /* Forward call to MSGINA if present */
500 if (GWlxGetConsoleSwitchCredentials)
501 return GWlxGetConsoleSwitchCredentials(pWlxContext,pCredInfo);
502 return FALSE;
503}
504
505
506VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
507{
508 Log(("VBoxGINA::WlxReconnectNotify\n"));
509
510 /* Forward to MSGINA if present. */
511 if (GWlxReconnectNotify)
512 GWlxReconnectNotify(pWlxContext);
513}
514
515
516VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
517{
518 Log(("VBoxGINA::WlxDisconnectNotify\n"));
519
520 /* Forward to MSGINA if present. */
521 if (GWlxDisconnectNotify)
522 GWlxDisconnectNotify(pWlxContext);
523}
524
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