VirtualBox

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

Last change on this file since 86996 was 82968, checked in by vboxsync, 5 years 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.3 KB
Line 
1/* $Id: Helper.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * VBoxGINA - Windows Logon DLL for VirtualBox, Helper Functions.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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 <iprt/win/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 dwLevel 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 RT_NOREF(pvUser);
148 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller\n");
149
150 do
151 {
152 int rc = VbglR3CredentialsQueryAvailability();
153 if (RT_SUCCESS(rc))
154 {
155 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: got credentials, simulating C-A-D\n");
156 /* tell WinLogon to start the attestation process */
157 pWlxFuncs->WlxSasNotify(hGinaWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
158 /* time to say goodbye */
159 return 0;
160 }
161
162 if ( RT_FAILURE(rc)
163 && rc != VERR_NOT_FOUND)
164 {
165 static int s_cBitchedQueryAvail = 0;
166 if (s_cBitchedQueryAvail++ < 5)
167 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: querying for credentials failed with rc=%Rrc\n", rc);
168 }
169
170 /* wait a bit */
171 if (RTThreadUserWait(ThreadSelf, 500) == VINF_SUCCESS)
172 {
173 VBoxGINAVerbose(0, "VBoxGINA::credentialsPoller: we were asked to terminate\n");
174 /* we were asked to terminate, do that instantly! */
175 return 0;
176 }
177 }
178 while (1);
179
180 return 0;
181}
182
183int VBoxGINACredentialsPollerCreate(void)
184{
185 if (!VBoxGINAHandleCurrentSession())
186 return VINF_SUCCESS;
187
188 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate\n");
189
190 /* don't create more than one of them */
191 if (gThreadPoller != NIL_RTTHREAD)
192 {
193 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: thread already running, returning!\n");
194 return VINF_SUCCESS;
195 }
196
197 /* create the poller thread */
198 int rc = RTThreadCreate(&gThreadPoller, credentialsPoller, NULL, 0, RTTHREADTYPE_INFREQUENT_POLLER,
199 RTTHREADFLAGS_WAITABLE, "creds");
200 if (RT_FAILURE(rc))
201 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerCreate: failed to create thread, rc = %Rrc\n", rc);
202
203 return rc;
204}
205
206int VBoxGINACredentialsPollerTerminate(void)
207{
208 if (gThreadPoller == NIL_RTTHREAD)
209 return VINF_SUCCESS;
210
211 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate\n");
212
213 /* post termination event semaphore */
214 int rc = RTThreadUserSignal(gThreadPoller);
215 if (RT_SUCCESS(rc))
216 {
217 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: waiting for thread to terminate\n");
218 rc = RTThreadWait(gThreadPoller, RT_INDEFINITE_WAIT, NULL);
219 }
220 else
221 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: thread has terminated? wait rc = %Rrc\n", rc);
222
223 if (RT_SUCCESS(rc))
224 {
225 gThreadPoller = NIL_RTTHREAD;
226 }
227
228 VBoxGINAVerbose(0, "VBoxGINA::credentialsPollerTerminate: returned with rc=%Rrc)\n", rc);
229 return rc;
230}
231
232/**
233 * Reports VBoxGINA's status to the host (treated as a guest facility).
234 *
235 * @return IPRT status code.
236 * @param enmStatus Status to report to the host.
237 */
238int VBoxGINAReportStatus(VBoxGuestFacilityStatus enmStatus)
239{
240 VBoxGINAVerbose(0, "VBoxGINA: reporting status %d\n", enmStatus);
241
242 int rc = VbglR3AutoLogonReportStatus(enmStatus);
243 if (RT_FAILURE(rc))
244 VBoxGINAVerbose(0, "VBoxGINA: failed to report status %d, rc=%Rrc\n", enmStatus, rc);
245 return rc;
246}
247
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