VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use