VirtualBox

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

Last change on this file since 60337 was 50323, checked in by vboxsync, 11 years ago

Vbox => VBox

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/* $Id: Helper.cpp 50323 2014-02-05 10:20:04Z vboxsync $ */
2/** @file
3 * VBoxGINA - Windows Logon DLL for VirtualBox, Helper Functions.
4 */
5
6/*
7 * Copyright (C) 2006-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <windows.h>
19
20#include <iprt/semaphore.h>
21#include <iprt/string.h>
22#include <iprt/thread.h>
23
24#include "winwlx.h"
25#include "Helper.h"
26#include "VBoxGINA.h"
27
28#include <VBox/log.h>
29#include <VBox/VBoxGuestLib.h>
30
31/** Flag indicating whether remote sessions (over MSRDP) should be
32 * handled or not. Default is disabled. */
33static DWORD g_dwHandleRemoteSessions = 0;
34/** Verbosity flag for guest logging. */
35static DWORD g_dwVerbosity = 0;
36
37/**
38 * Displays a verbose message.
39 *
40 * @param iLevel Minimum log level required to display this message.
41 * @param pszFormat The message text.
42 * @param ... Format arguments.
43 */
44void VBoxGINAVerbose(DWORD dwLevel, const char *pszFormat, ...)
45{
46 if (dwLevel <= g_dwVerbosity)
47 {
48 va_list args;
49 va_start(args, pszFormat);
50 char *psz = NULL;
51 RTStrAPrintfV(&psz, pszFormat, args);
52 va_end(args);
53
54 AssertPtr(psz);
55 LogRel(("%s", psz));
56
57 RTStrFree(psz);
58 }
59}
60
61/**
62 * Loads the global configuration from registry.
63 *
64 * @return IPRT status code.
65 */
66int VBoxGINALoadConfiguration(void)
67{
68 HKEY hKey;
69 /** @todo Add some registry wrapper function(s) as soon as we got more values to retrieve. */
70 DWORD dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions\\AutoLogon",
71 0L, KEY_QUERY_VALUE, &hKey);
72 if (dwRet == ERROR_SUCCESS)
73 {
74 DWORD dwValue;
75 DWORD dwType = REG_DWORD;
76 DWORD dwSize = sizeof(DWORD);
77
78 dwRet = RegQueryValueEx(hKey, L"HandleRemoteSessions", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
79 if ( dwRet == ERROR_SUCCESS
80 && dwType == REG_DWORD
81 && dwSize == sizeof(DWORD))
82 {
83 g_dwHandleRemoteSessions = dwValue;
84 }
85
86 dwRet = RegQueryValueEx(hKey, L"LoggingEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
87 if ( dwRet == ERROR_SUCCESS
88 && dwType == REG_DWORD
89 && dwSize == sizeof(DWORD))
90 {
91 g_dwVerbosity = 1; /* Default logging level. */
92 }
93
94 if (g_dwVerbosity) /* Do we want logging at all? */
95 {
96 dwRet = RegQueryValueEx(hKey, L"LoggingLevel", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
97 if ( dwRet == ERROR_SUCCESS
98 && dwType == REG_DWORD
99 && dwSize == sizeof(DWORD))
100 {
101 g_dwVerbosity = dwValue;
102 }
103 }
104
105 RegCloseKey(hKey);
106 }
107 /* Do not report back an error here yet. */
108 return VINF_SUCCESS;
109}
110
111/**
112 * Determines whether we should handle the current session or not.
113 *
114 * @return bool true if we should handle this session, false if not.
115 */
116bool VBoxGINAHandleCurrentSession(void)
117{
118 /* Load global configuration from registry. */
119 int rc = VBoxGINALoadConfiguration();
120 if (RT_FAILURE(rc))
121 VBoxGINAVerbose(0, "VBoxGINA::handleCurrentSession: Error loading global configuration, rc=%Rrc\n",
122 rc);
123
124 bool fHandle = false;
125 if (VbglR3AutoLogonIsRemoteSession())
126 {
127 if (g_dwHandleRemoteSessions) /* Force remote session handling. */
128 fHandle = true;
129 }
130 else /* No remote session. */
131 fHandle = true;
132
133#ifdef DEBUG
134 VBoxGINAVerbose(3, "VBoxGINA::handleCurrentSession: Handling current session=%RTbool\n", fHandle);
135#endif
136 return fHandle;
137}
138
139/* handle of the poller thread */
140RTTHREAD gThreadPoller = NIL_RTTHREAD;
141
142/**
143 * Poller thread. Checks periodically whether there are credentials.
144 */
145static DECLCALLBACK(int) credentialsPoller(RTTHREAD ThreadSelf, void *pvUser)
146{
147 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller\n");
148
149 do
150 {
151 int rc = VbglR3CredentialsQueryAvailability();
152 if (RT_SUCCESS(rc))
153 {
154 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n");
155 /* tell WinLogon to start the attestation process */
156 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
157 /* time to say goodbye */
158 return 0;
159 }
160
161 if ( RT_FAILURE(rc)
162 && rc != VERR_NOT_FOUND)
163 {
164 static int s_cBitchedQueryAvail = 0;
165 if (s_cBitchedQueryAvail++ < 5)
166 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: querying for credentials failed with rc=%Rrc\n", rc);
167 }
168
169 /* wait a bit */
170 if (RTThreadUserWait(ThreadSelf, 500) == VINF_SUCCESS)
171 {
172 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: we were asked to terminate\n");
173 /* we were asked to terminate, do that instantly! */
174 return 0;
175 }
176 }
177 while (1);
178
179 return 0;
180}
181
182int VBoxGINACredentialsPollerCreate(void)
183{
184 if (!VBoxGINAHandleCurrentSession())
185 return VINF_SUCCESS;
186
187 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate\n");
188
189 /* don't create more than one of them */
190 if (gThreadPoller != NIL_RTTHREAD)
191 {
192 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: thread already running, returning!\n");
193 return VINF_SUCCESS;
194 }
195
196 /* create the poller thread */
197 int rc = RTThreadCreate(&gThreadPoller, credentialsPoller, NULL, 0, RTTHREADTYPE_INFREQUENT_POLLER,
198 RTTHREADFLAGS_WAITABLE, "creds");
199 if (RT_FAILURE(rc))
200 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc);
201
202 return rc;
203}
204
205int VBoxGINACredentialsPollerTerminate(void)
206{
207 if (gThreadPoller == NIL_RTTHREAD)
208 return VINF_SUCCESS;
209
210 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate\n");
211
212 /* post termination event semaphore */
213 int rc = RTThreadUserSignal(gThreadPoller);
214 if (RT_SUCCESS(rc))
215 {
216 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n");
217 rc = RTThreadWait(gThreadPoller, RT_INDEFINITE_WAIT, NULL);
218 }
219 else
220 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: thread has terminated? wait rc = %Rrc\n", rc);
221
222 if (RT_SUCCESS(rc))
223 {
224 gThreadPoller = NIL_RTTHREAD;
225 }
226
227 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: returned with rc=%Rrc)\n", rc);
228 return rc;
229}
230
231/**
232 * Reports VBoxGINA's status to the host (treated as a guest facility).
233 *
234 * @return IPRT status code.
235 * @param enmStatus Status to report to the host.
236 */
237int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus)
238{
239 VBoxGINAVerbose(0, "VBoxGINA: reporting status %d\n", enmStatus);
240
241 int rc = VbglR3AutoLogonReportStatus(enmStatus);
242 if (RT_FAILURE(rc))
243 VBoxGINAVerbose(0, "VBoxGINA: failed to report status %d, rc=%Rrc\n", enmStatus, rc);
244 return rc;
245}
246
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