[21219] | 1 | /* $Id: VBoxVRDP.cpp 99828 2023-05-17 13:48:57Z vboxsync $ */
|
---|
[4795] | 2 | /** @file
|
---|
| 3 | * VBoxVRDP - VBox VRDP connection notification
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[4795] | 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
|
---|
[4795] | 26 | */
|
---|
| 27 |
|
---|
[95960] | 28 | #include <iprt/assert.h>
|
---|
| 29 | #include <iprt/ldr.h>
|
---|
[95961] | 30 | #include <VBox/log.h>
|
---|
[95960] | 31 |
|
---|
[4795] | 32 | /* 0x0501 for SPI_SETDROPSHADOW */
|
---|
| 33 | #define _WIN32_WINNT 0x0501
|
---|
[62679] | 34 | #include <iprt/win/windows.h>
|
---|
[95960] | 35 |
|
---|
| 36 | #include <VBox/VMMDev.h> /* for VMMDEV_EVENT_VRDP and VRDP_EXPERIENCE_LEVEL_XXX */
|
---|
| 37 |
|
---|
[8850] | 38 | #include "VBoxTray.h"
|
---|
[33966] | 39 | #include "VBoxHelpers.h"
|
---|
[4795] | 40 | #include "VBoxVRDP.h"
|
---|
[51469] | 41 |
|
---|
| 42 |
|
---|
[4795] | 43 |
|
---|
| 44 | /* The guest receives VRDP_ACTIVE/VRDP_INACTIVE notifications.
|
---|
| 45 | *
|
---|
| 46 | * When VRDP_ACTIVE is received, the guest asks host about the experience level.
|
---|
| 47 | * The experience level is an integer value, different values disable some GUI effects.
|
---|
| 48 | *
|
---|
| 49 | * On VRDP_INACTIVE the original values are restored.
|
---|
| 50 | *
|
---|
| 51 | * Note: that this is not controlled from the client, that is a per VM settings.
|
---|
| 52 | *
|
---|
| 53 | * Note: theming is disabled separately by EnableTheming.
|
---|
| 54 | */
|
---|
| 55 |
|
---|
| 56 | #define VBOX_SPI_STRING 0
|
---|
| 57 | #define VBOX_SPI_BOOL_PTR 1
|
---|
| 58 | #define VBOX_SPI_BOOL 2
|
---|
| 59 | #define VBOX_SPI_PTR 3
|
---|
| 60 |
|
---|
| 61 | static ANIMATIONINFO animationInfoDisable =
|
---|
| 62 | {
|
---|
| 63 | sizeof (ANIMATIONINFO),
|
---|
| 64 | FALSE
|
---|
| 65 | };
|
---|
| 66 |
|
---|
[99828] | 67 | typedef struct VBOXVRDPEXPPARAM
|
---|
[4795] | 68 | {
|
---|
| 69 | const char *name;
|
---|
| 70 | UINT uActionSet;
|
---|
| 71 | UINT uActionGet;
|
---|
| 72 | uint32_t level; /* The parameter remain enabled at this or higher level. */
|
---|
| 73 | int type;
|
---|
| 74 | void *pvDisable;
|
---|
| 75 | UINT cbSavedValue;
|
---|
| 76 | char achSavedValue[2 * MAX_PATH]; /* Large enough to save the bitmap path. */
|
---|
[57741] | 77 | } VBOXVRDPEXPPARAM, *PVBOXVRDPEXPPARAM;
|
---|
[4795] | 78 |
|
---|
[99828] | 79 | typedef struct VBOXVRDPCONTEXT
|
---|
[57741] | 80 | {
|
---|
| 81 | const VBOXSERVICEENV *pEnv;
|
---|
| 82 |
|
---|
| 83 | uint32_t level;
|
---|
| 84 | BOOL fSavedThemeEnabled;
|
---|
| 85 |
|
---|
| 86 | RTLDRMOD hModUxTheme;
|
---|
| 87 |
|
---|
| 88 | HRESULT (* pfnEnableTheming)(BOOL fEnable);
|
---|
| 89 | BOOL (* pfnIsThemeActive)(VOID);
|
---|
| 90 | } VBOXVRDPCONTEXT, *PVBOXVRDPCONTEXT;
|
---|
| 91 |
|
---|
| 92 | static VBOXVRDPCONTEXT g_Ctx = { 0 };
|
---|
| 93 |
|
---|
[4795] | 94 | #define SPI_(l, a) #a, SPI_SET##a, SPI_GET##a, VRDP_EXPERIENCE_LEVEL_##l
|
---|
| 95 |
|
---|
[57741] | 96 | static VBOXVRDPEXPPARAM s_aSPIParams[] =
|
---|
[4795] | 97 | {
|
---|
[99828] | 98 | { SPI_(MEDIUM, DESKWALLPAPER), VBOX_SPI_STRING, (void *)"" },
|
---|
[4795] | 99 | { SPI_(FULL, DROPSHADOW), VBOX_SPI_BOOL_PTR, },
|
---|
| 100 | { SPI_(HIGH, FONTSMOOTHING), VBOX_SPI_BOOL, },
|
---|
| 101 | { SPI_(FULL, MENUFADE), VBOX_SPI_BOOL_PTR, },
|
---|
| 102 | { SPI_(FULL, COMBOBOXANIMATION), VBOX_SPI_BOOL_PTR, },
|
---|
| 103 | { SPI_(FULL, CURSORSHADOW), VBOX_SPI_BOOL_PTR, },
|
---|
| 104 | { SPI_(HIGH, GRADIENTCAPTIONS), VBOX_SPI_BOOL_PTR, },
|
---|
| 105 | { SPI_(FULL, LISTBOXSMOOTHSCROLLING), VBOX_SPI_BOOL_PTR, },
|
---|
| 106 | { SPI_(FULL, MENUANIMATION), VBOX_SPI_BOOL_PTR, },
|
---|
| 107 | { SPI_(FULL, SELECTIONFADE), VBOX_SPI_BOOL_PTR, },
|
---|
| 108 | { SPI_(FULL, TOOLTIPANIMATION), VBOX_SPI_BOOL_PTR, },
|
---|
| 109 | { SPI_(FULL, ANIMATION), VBOX_SPI_PTR, &animationInfoDisable, sizeof (ANIMATIONINFO) },
|
---|
| 110 | { SPI_(MEDIUM, DRAGFULLWINDOWS), VBOX_SPI_BOOL, }
|
---|
| 111 | };
|
---|
| 112 |
|
---|
| 113 | #undef SPI_
|
---|
| 114 |
|
---|
[57741] | 115 | static void vboxExperienceSet(uint32_t uLevel)
|
---|
[4795] | 116 | {
|
---|
[57741] | 117 | for (size_t i = 0; i < RT_ELEMENTS(s_aSPIParams); i++)
|
---|
[4795] | 118 | {
|
---|
[57741] | 119 | PVBOXVRDPEXPPARAM pParam = &s_aSPIParams[i];
|
---|
| 120 | if (pParam->level > uLevel)
|
---|
[4795] | 121 | {
|
---|
| 122 | /*
|
---|
| 123 | * The parameter has to be disabled.
|
---|
| 124 | */
|
---|
[57741] | 125 | LogFlowFunc(("Saving %s\n", pParam->name));
|
---|
[13836] | 126 |
|
---|
[4795] | 127 | /* Save the current value. */
|
---|
[57741] | 128 | switch (pParam->type)
|
---|
[4795] | 129 | {
|
---|
| 130 | case VBOX_SPI_STRING:
|
---|
| 131 | {
|
---|
| 132 | /* The 2nd parameter is size in characters of the buffer.
|
---|
[13836] | 133 | * The 3rd parameter points to the buffer.
|
---|
[4795] | 134 | */
|
---|
[57741] | 135 | SystemParametersInfo (pParam->uActionGet,
|
---|
[4795] | 136 | MAX_PATH,
|
---|
[57741] | 137 | pParam->achSavedValue,
|
---|
[4795] | 138 | 0);
|
---|
| 139 | } break;
|
---|
| 140 |
|
---|
| 141 | case VBOX_SPI_BOOL:
|
---|
| 142 | case VBOX_SPI_BOOL_PTR:
|
---|
| 143 | {
|
---|
| 144 | /* The 3rd parameter points to BOOL. */
|
---|
[57741] | 145 | SystemParametersInfo (pParam->uActionGet,
|
---|
[4795] | 146 | 0,
|
---|
[57741] | 147 | pParam->achSavedValue,
|
---|
[4795] | 148 | 0);
|
---|
| 149 | } break;
|
---|
| 150 |
|
---|
| 151 | case VBOX_SPI_PTR:
|
---|
| 152 | {
|
---|
[13836] | 153 | /* The 3rd parameter points to the structure.
|
---|
[4795] | 154 | * The cbSize member of this structure must be set.
|
---|
| 155 | * The uiParam parameter must alos be set.
|
---|
| 156 | */
|
---|
[57741] | 157 | if (pParam->cbSavedValue > sizeof (pParam->achSavedValue))
|
---|
[4795] | 158 | {
|
---|
[57741] | 159 | LogFlowFunc(("Not enough space %d > %d\n", pParam->cbSavedValue, sizeof (pParam->achSavedValue)));
|
---|
[4795] | 160 | break;
|
---|
| 161 | }
|
---|
[13836] | 162 |
|
---|
[57741] | 163 | *(UINT *)&pParam->achSavedValue[0] = pParam->cbSavedValue;
|
---|
[13836] | 164 |
|
---|
[57741] | 165 | SystemParametersInfo (s_aSPIParams[i].uActionGet,
|
---|
| 166 | s_aSPIParams[i].cbSavedValue,
|
---|
| 167 | s_aSPIParams[i].achSavedValue,
|
---|
[4795] | 168 | 0);
|
---|
| 169 | } break;
|
---|
| 170 |
|
---|
| 171 | default:
|
---|
| 172 | break;
|
---|
| 173 | }
|
---|
[13836] | 174 |
|
---|
[57741] | 175 | LogFlowFunc(("Disabling %s\n", pParam->name));
|
---|
[13836] | 176 |
|
---|
[4795] | 177 | /* Disable the feature. */
|
---|
[57741] | 178 | switch (pParam->type)
|
---|
[4795] | 179 | {
|
---|
| 180 | case VBOX_SPI_STRING:
|
---|
| 181 | {
|
---|
| 182 | /* The 3rd parameter points to the string. */
|
---|
[57741] | 183 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 184 | 0,
|
---|
[57741] | 185 | pParam->pvDisable,
|
---|
[4795] | 186 | SPIF_SENDCHANGE);
|
---|
| 187 | } break;
|
---|
| 188 |
|
---|
| 189 | case VBOX_SPI_BOOL:
|
---|
| 190 | {
|
---|
| 191 | /* The 2nd parameter is BOOL. */
|
---|
[57741] | 192 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 193 | FALSE,
|
---|
| 194 | NULL,
|
---|
| 195 | SPIF_SENDCHANGE);
|
---|
| 196 | } break;
|
---|
| 197 |
|
---|
| 198 | case VBOX_SPI_BOOL_PTR:
|
---|
| 199 | {
|
---|
| 200 | /* The 3rd parameter is NULL to disable. */
|
---|
[57741] | 201 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 202 | 0,
|
---|
| 203 | NULL,
|
---|
| 204 | SPIF_SENDCHANGE);
|
---|
| 205 | } break;
|
---|
| 206 |
|
---|
| 207 | case VBOX_SPI_PTR:
|
---|
| 208 | {
|
---|
| 209 | /* The 3rd parameter points to the structure. */
|
---|
[57741] | 210 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 211 | 0,
|
---|
[57741] | 212 | pParam->pvDisable,
|
---|
[4795] | 213 | SPIF_SENDCHANGE);
|
---|
| 214 | } break;
|
---|
| 215 |
|
---|
| 216 | default:
|
---|
| 217 | break;
|
---|
| 218 | }
|
---|
| 219 | }
|
---|
| 220 | }
|
---|
| 221 | }
|
---|
| 222 |
|
---|
[57741] | 223 | static void vboxExperienceRestore(uint32_t uLevel)
|
---|
[4795] | 224 | {
|
---|
| 225 | int i;
|
---|
[57741] | 226 | for (i = 0; i < RT_ELEMENTS(s_aSPIParams); i++)
|
---|
[4795] | 227 | {
|
---|
[57741] | 228 | PVBOXVRDPEXPPARAM pParam = &s_aSPIParams[i];
|
---|
| 229 | if (pParam->level > uLevel)
|
---|
[4795] | 230 | {
|
---|
[57741] | 231 | LogFlowFunc(("Restoring %s\n", pParam->name));
|
---|
[13836] | 232 |
|
---|
[4795] | 233 | /* Restore the feature. */
|
---|
[57741] | 234 | switch (pParam->type)
|
---|
[4795] | 235 | {
|
---|
| 236 | case VBOX_SPI_STRING:
|
---|
| 237 | {
|
---|
| 238 | /* The 3rd parameter points to the string. */
|
---|
[57741] | 239 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 240 | 0,
|
---|
[57741] | 241 | pParam->achSavedValue,
|
---|
[4795] | 242 | SPIF_SENDCHANGE);
|
---|
| 243 | } break;
|
---|
| 244 |
|
---|
| 245 | case VBOX_SPI_BOOL:
|
---|
| 246 | {
|
---|
| 247 | /* The 2nd parameter is BOOL. */
|
---|
[57741] | 248 | SystemParametersInfo (pParam->uActionSet,
|
---|
| 249 | *(BOOL *)&pParam->achSavedValue[0],
|
---|
[4795] | 250 | NULL,
|
---|
| 251 | SPIF_SENDCHANGE);
|
---|
| 252 | } break;
|
---|
| 253 |
|
---|
| 254 | case VBOX_SPI_BOOL_PTR:
|
---|
| 255 | {
|
---|
| 256 | /* The 3rd parameter is NULL to disable. */
|
---|
[57741] | 257 | BOOL fSaved = *(BOOL *)&pParam->achSavedValue[0];
|
---|
[4795] | 258 |
|
---|
[57741] | 259 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 260 | 0,
|
---|
| 261 | fSaved? &fSaved: NULL,
|
---|
| 262 | SPIF_SENDCHANGE);
|
---|
| 263 | } break;
|
---|
| 264 |
|
---|
| 265 | case VBOX_SPI_PTR:
|
---|
| 266 | {
|
---|
| 267 | /* The 3rd parameter points to the structure. */
|
---|
[57741] | 268 | SystemParametersInfo (pParam->uActionSet,
|
---|
[4795] | 269 | 0,
|
---|
[57741] | 270 | pParam->achSavedValue,
|
---|
[4795] | 271 | SPIF_SENDCHANGE);
|
---|
| 272 | } break;
|
---|
| 273 |
|
---|
| 274 | default:
|
---|
| 275 | break;
|
---|
| 276 | }
|
---|
| 277 | }
|
---|
| 278 | }
|
---|
| 279 | }
|
---|
| 280 |
|
---|
[57741] | 281 | static DECLCALLBACK(int) VBoxVRDPInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
|
---|
[4795] | 282 | {
|
---|
[57741] | 283 | AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
|
---|
| 284 | AssertPtrReturn(ppInstance, VERR_INVALID_POINTER);
|
---|
[4795] | 285 |
|
---|
[57741] | 286 | LogFlowFuncEnter();
|
---|
[13836] | 287 |
|
---|
[57741] | 288 | PVBOXVRDPCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
|
---|
| 289 | AssertPtr(pCtx);
|
---|
[4795] | 290 |
|
---|
[57741] | 291 | pCtx->pEnv = pEnv;
|
---|
| 292 | pCtx->level = VRDP_EXPERIENCE_LEVEL_FULL;
|
---|
| 293 | pCtx->fSavedThemeEnabled = FALSE;
|
---|
[4795] | 294 |
|
---|
[57741] | 295 | int rc = RTLdrLoadSystem("UxTheme.dll", false /*fNoUnload*/, &g_Ctx.hModUxTheme);
|
---|
[46593] | 296 | if (RT_SUCCESS(rc))
|
---|
[4795] | 297 | {
|
---|
[57741] | 298 | *(PFNRT *)&pCtx->pfnEnableTheming = RTLdrGetFunction(g_Ctx.hModUxTheme, "EnableTheming");
|
---|
| 299 | *(PFNRT *)&pCtx->pfnIsThemeActive = RTLdrGetFunction(g_Ctx.hModUxTheme, "IsThemeActive");
|
---|
| 300 |
|
---|
| 301 | *ppInstance = &g_Ctx;
|
---|
[4795] | 302 | }
|
---|
| 303 | else
|
---|
| 304 | {
|
---|
[57741] | 305 | g_Ctx.hModUxTheme = NIL_RTLDRMOD;
|
---|
| 306 | g_Ctx.pfnEnableTheming = NULL;
|
---|
| 307 | g_Ctx.pfnIsThemeActive = NULL;
|
---|
[4795] | 308 | }
|
---|
[13836] | 309 |
|
---|
[62135] | 310 | /* Tell the caller that the service does not work but it is OK to continue. */
|
---|
| 311 | if (RT_FAILURE(rc))
|
---|
| 312 | rc = VERR_NOT_SUPPORTED;
|
---|
| 313 |
|
---|
[57741] | 314 | LogFlowFuncLeaveRC(rc);
|
---|
| 315 | return rc;
|
---|
[4795] | 316 | }
|
---|
| 317 |
|
---|
[57741] | 318 | static DECLCALLBACK(void) VBoxVRDPDestroy(void *pInstance)
|
---|
| 319 | {
|
---|
| 320 | AssertPtrReturnVoid(pInstance);
|
---|
[4795] | 321 |
|
---|
[57741] | 322 | LogFlowFuncEnter();
|
---|
| 323 |
|
---|
| 324 | PVBOXVRDPCONTEXT pCtx = (PVBOXVRDPCONTEXT)pInstance;
|
---|
| 325 |
|
---|
[4795] | 326 | vboxExperienceRestore (pCtx->level);
|
---|
[57741] | 327 | if (pCtx->hModUxTheme != NIL_RTLDRMOD)
|
---|
[46593] | 328 | {
|
---|
[57741] | 329 | RTLdrClose(g_Ctx.hModUxTheme);
|
---|
| 330 | pCtx->hModUxTheme = NIL_RTLDRMOD;
|
---|
[46593] | 331 | }
|
---|
[57741] | 332 |
|
---|
[4795] | 333 | return;
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | /**
|
---|
| 337 | * Thread function to wait for and process mode change requests
|
---|
| 338 | */
|
---|
[68437] | 339 | static DECLCALLBACK(int) VBoxVRDPWorker(void *pvInstance, bool volatile *pfShutdown)
|
---|
[4795] | 340 | {
|
---|
[68437] | 341 | AssertPtrReturn(pvInstance, VERR_INVALID_POINTER);
|
---|
| 342 | PVBOXVRDPCONTEXT pCtx = (PVBOXVRDPCONTEXT)pvInstance;
|
---|
[57741] | 343 |
|
---|
| 344 | LogFlowFuncEnter();
|
---|
| 345 |
|
---|
| 346 | /*
|
---|
[68437] | 347 | * Tell the control thread that it can continue spawning services.
|
---|
[57741] | 348 | */
|
---|
| 349 | RTThreadUserSignal(RTThreadSelf());
|
---|
| 350 |
|
---|
[68437] | 351 | int rc = VbglR3CtlFilterMask(VMMDEV_EVENT_VRDP, 0 /*fNot*/);
|
---|
| 352 | if (RT_FAILURE(rc))
|
---|
[4795] | 353 | {
|
---|
[68437] | 354 | LogRel(("VbglR3CtlFilterMask(VMMDEV_EVENT_VRDP, 0) failed with %Rrc, exiting...\n"));
|
---|
| 355 | return rc;
|
---|
[4795] | 356 | }
|
---|
| 357 |
|
---|
[57741] | 358 | for (;;)
|
---|
[4795] | 359 | {
|
---|
[68437] | 360 | /*
|
---|
| 361 | * Wait for the event, checking the shutdown flag both before and after the call.
|
---|
| 362 | */
|
---|
| 363 | if (*pfShutdown)
|
---|
[4795] | 364 | {
|
---|
[68437] | 365 | rc = VINF_SUCCESS;
|
---|
| 366 | break;
|
---|
| 367 | }
|
---|
[4795] | 368 |
|
---|
[68437] | 369 | uint32_t fEvent = 0;
|
---|
| 370 | rc = VbglR3WaitEvent(VMMDEV_EVENT_VRDP, 5000 /*ms*/, &fEvent);
|
---|
| 371 |
|
---|
| 372 | if (*pfShutdown)
|
---|
| 373 | {
|
---|
| 374 | rc = VINF_SUCCESS;
|
---|
| 375 | break;
|
---|
| 376 | }
|
---|
| 377 |
|
---|
| 378 | if (RT_SUCCESS(rc))
|
---|
| 379 | {
|
---|
[4795] | 380 | /* did we get the right event? */
|
---|
[68437] | 381 | if (fEvent & VMMDEV_EVENT_VRDP)
|
---|
[4795] | 382 | {
|
---|
[68437] | 383 | bool fActive = false;
|
---|
| 384 | uint32_t uExperienceLevel = 0;
|
---|
| 385 | rc = VbglR3VrdpGetChangeRequest(&fActive, &uExperienceLevel);
|
---|
| 386 | if (RT_SUCCESS(rc))
|
---|
[4795] | 387 | {
|
---|
[68437] | 388 | LogFlowFunc(("u8VRDPActive = %d, level %d\n", fActive, uExperienceLevel));
|
---|
[13836] | 389 |
|
---|
[68437] | 390 | if (fActive)
|
---|
[4795] | 391 | {
|
---|
[68437] | 392 | pCtx->level = uExperienceLevel;
|
---|
[4795] | 393 | vboxExperienceSet (pCtx->level);
|
---|
[13836] | 394 |
|
---|
[4795] | 395 | if (pCtx->level == VRDP_EXPERIENCE_LEVEL_ZERO
|
---|
| 396 | && pCtx->pfnEnableTheming
|
---|
| 397 | && pCtx->pfnIsThemeActive)
|
---|
| 398 | {
|
---|
| 399 | pCtx->fSavedThemeEnabled = pCtx->pfnIsThemeActive ();
|
---|
[13836] | 400 |
|
---|
[51469] | 401 | LogFlowFunc(("pCtx->fSavedThemeEnabled = %d\n", pCtx->fSavedThemeEnabled));
|
---|
[13836] | 402 |
|
---|
[4795] | 403 | if (pCtx->fSavedThemeEnabled)
|
---|
| 404 | {
|
---|
| 405 | pCtx->pfnEnableTheming (FALSE);
|
---|
| 406 | }
|
---|
| 407 | }
|
---|
| 408 | }
|
---|
| 409 | else
|
---|
| 410 | {
|
---|
| 411 | if (pCtx->level == VRDP_EXPERIENCE_LEVEL_ZERO
|
---|
| 412 | && pCtx->pfnEnableTheming
|
---|
| 413 | && pCtx->pfnIsThemeActive)
|
---|
| 414 | {
|
---|
| 415 | if (pCtx->fSavedThemeEnabled)
|
---|
| 416 | {
|
---|
[63100] | 417 | /** @todo the call returns S_OK but theming remains disabled. */
|
---|
[4795] | 418 | HRESULT hrc = pCtx->pfnEnableTheming (TRUE);
|
---|
[63100] | 419 | LogFlowFunc(("enabling theme rc = 0x%08X\n", hrc)); NOREF(hrc);
|
---|
[4795] | 420 | pCtx->fSavedThemeEnabled = FALSE;
|
---|
| 421 | }
|
---|
| 422 | }
|
---|
[13836] | 423 |
|
---|
[4795] | 424 | vboxExperienceRestore (pCtx->level);
|
---|
[13836] | 425 |
|
---|
[4795] | 426 | pCtx->level = VRDP_EXPERIENCE_LEVEL_FULL;
|
---|
| 427 | }
|
---|
| 428 | }
|
---|
| 429 | else
|
---|
| 430 | {
|
---|
| 431 | /* sleep a bit to not eat too much CPU in case the above call always fails */
|
---|
[57741] | 432 | RTThreadSleep(10);
|
---|
[4795] | 433 | }
|
---|
| 434 | }
|
---|
[13836] | 435 | }
|
---|
[68437] | 436 | /* sleep a bit to not eat too much CPU in case the above call always fails */
|
---|
[4795] | 437 | else
|
---|
[57741] | 438 | RTThreadSleep(50);
|
---|
| 439 | }
|
---|
[4795] | 440 |
|
---|
[68437] | 441 | int rc2 = VbglR3CtlFilterMask(0 /*fOr*/, VMMDEV_EVENT_VRDP);
|
---|
| 442 | if (RT_FAILURE(rc2))
|
---|
| 443 | LogRel(("VbglR3CtlFilterMask(0 /*fOr*/, VMMDEV_EVENT_VRDP) failed with %Rrc\n", rc));
|
---|
[4795] | 444 |
|
---|
[57741] | 445 | LogFlowFuncLeaveRC(rc);
|
---|
| 446 | return rc;
|
---|
[4795] | 447 | }
|
---|
| 448 |
|
---|
[57741] | 449 | /**
|
---|
| 450 | * The service description.
|
---|
| 451 | */
|
---|
| 452 | VBOXSERVICEDESC g_SvcDescVRDP =
|
---|
| 453 | {
|
---|
| 454 | /* pszName. */
|
---|
| 455 | "VRDP",
|
---|
| 456 | /* pszDescription. */
|
---|
| 457 | "VRDP Connection Notification",
|
---|
| 458 | /* methods */
|
---|
| 459 | VBoxVRDPInit,
|
---|
| 460 | VBoxVRDPWorker,
|
---|
| 461 | NULL /* pfnStop */,
|
---|
| 462 | VBoxVRDPDestroy
|
---|
| 463 | };
|
---|
| 464 |
|
---|