9fb5c93ff4449e19077128c07c080acbed35ceeavboxsync/* $Id$ */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/** @file
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * VBoxVRDP - VBox VRDP connection notification
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/*
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync * Copyright (C) 2006-2014 Oracle Corporation
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * available from http://www.virtualbox.org. This file is free software;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * General Public License (GPL) as published by the Free Software
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/* 0x0501 for SPI_SETDROPSHADOW */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define _WIN32_WINNT 0x0501
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include <windows.h>
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include "VBoxTray.h"
74804912a237136f06d0b49682a119577135902bvboxsync#include "VBoxHelpers.h"
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include "VBoxVRDP.h"
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync
9fb5c93ff4449e19077128c07c080acbed35ceeavboxsync#include <VBox/VMMDev.h>
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync#ifdef DEBUG
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync# define LOG_ENABLED
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync# define LOG_GROUP LOG_GROUP_DEFAULT
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync#endif
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync#include <VBox/log.h>
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include <VBoxGuestInternal.h>
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include <iprt/assert.h>
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync#include <iprt/ldr.h>
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/* The guest receives VRDP_ACTIVE/VRDP_INACTIVE notifications.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * When VRDP_ACTIVE is received, the guest asks host about the experience level.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * The experience level is an integer value, different values disable some GUI effects.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * On VRDP_INACTIVE the original values are restored.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Note: that this is not controlled from the client, that is a per VM settings.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Note: theming is disabled separately by EnableTheming.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define VBOX_SPI_STRING 0
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define VBOX_SPI_BOOL_PTR 1
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define VBOX_SPI_BOOL 2
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define VBOX_SPI_PTR 3
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic ANIMATIONINFO animationInfoDisable =
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync sizeof (ANIMATIONINFO),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync FALSE
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync};
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsynctypedef struct _VBoxExperienceParameter
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync const char *name;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT uActionSet;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT uActionGet;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t level; /* The parameter remain enabled at this or higher level. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int type;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync void *pvDisable;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT cbSavedValue;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync char achSavedValue[2 * MAX_PATH]; /* Large enough to save the bitmap path. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync} VBoxExperienceParameter;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define SPI_(l, a) #a, SPI_SET##a, SPI_GET##a, VRDP_EXPERIENCE_LEVEL_##l
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic VBoxExperienceParameter parameters[] =
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(MEDIUM, DESKWALLPAPER), VBOX_SPI_STRING, "" },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, DROPSHADOW), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(HIGH, FONTSMOOTHING), VBOX_SPI_BOOL, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, MENUFADE), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, COMBOBOXANIMATION), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, CURSORSHADOW), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(HIGH, GRADIENTCAPTIONS), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, LISTBOXSMOOTHSCROLLING), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, MENUANIMATION), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, SELECTIONFADE), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, TOOLTIPANIMATION), VBOX_SPI_BOOL_PTR, },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(FULL, ANIMATION), VBOX_SPI_PTR, &animationInfoDisable, sizeof (ANIMATIONINFO) },
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync { SPI_(MEDIUM, DRAGFULLWINDOWS), VBOX_SPI_BOOL, }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync};
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#undef SPI_
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void vboxExperienceSet (uint32_t level)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int i;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync for (i = 0; i < RT_ELEMENTS(parameters); i++)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (parameters[i].level > level)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /*
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * The parameter has to be disabled.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Saving %s\n", parameters[i].name));
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Save the current value. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (parameters[i].type)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_STRING:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 2nd parameter is size in characters of the buffer.
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync * The 3rd parameter points to the buffer.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionGet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync MAX_PATH,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].achSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter points to BOOL. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionGet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].achSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync /* The 3rd parameter points to the structure.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * The cbSize member of this structure must be set.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * The uiParam parameter must alos be set.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (parameters[i].cbSavedValue > sizeof (parameters[i].achSavedValue))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Not enough space %d > %d\n", parameters[i].cbSavedValue, sizeof (parameters[i].achSavedValue)));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *(UINT *)&parameters[i].achSavedValue[0] = parameters[i].cbSavedValue;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionGet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].cbSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].achSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Disabling %s\n", parameters[i].name));
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Disable the feature. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (parameters[i].type)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_STRING:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter points to the string. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].pvDisable,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 2nd parameter is BOOL. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync FALSE,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter is NULL to disable. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter points to the structure. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].pvDisable,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void vboxExperienceRestore (uint32_t level)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int i;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync for (i = 0; i < RT_ELEMENTS(parameters); i++)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (parameters[i].level > level)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Restoring %s\n", parameters[i].name));
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Restore the feature. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (parameters[i].type)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_STRING:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter points to the string. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].achSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 2nd parameter is BOOL. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *(BOOL *)&parameters[i].achSavedValue[0],
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_BOOL_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter is NULL to disable. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync BOOL fSaved = *(BOOL *)&parameters[i].achSavedValue[0];
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync fSaved? &fSaved: NULL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SPI_PTR:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The 3rd parameter points to the structure. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SystemParametersInfo (parameters[i].uActionSet,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync parameters[i].achSavedValue,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SPIF_SENDCHANGE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsynctypedef struct _VBOXVRDPCONTEXT
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync const VBOXSERVICEENV *pEnv;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t level;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync BOOL fSavedThemeEnabled;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync RTLDRMOD hModUxTheme;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HRESULT (* pfnEnableTheming)(BOOL fEnable);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync BOOL (* pfnIsThemeActive)(VOID);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync} VBOXVRDPCONTEXT;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic VBOXVRDPCONTEXT gCtx = {0};
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncint VBoxVRDPInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("VBoxVRDPInit\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync gCtx.pEnv = pEnv;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync gCtx.level = VRDP_EXPERIENCE_LEVEL_FULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync gCtx.fSavedThemeEnabled = FALSE;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync int rc = RTLdrLoadSystem("UxTheme.dll", false /*fNoUnload*/, &gCtx.hModUxTheme);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync if (RT_SUCCESS(rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync *(PFNRT *)&gCtx.pfnEnableTheming = RTLdrGetFunction(gCtx.hModUxTheme, "EnableTheming");
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync *(PFNRT *)&gCtx.pfnIsThemeActive = RTLdrGetFunction(gCtx.hModUxTheme, "IsThemeActive");
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync gCtx.hModUxTheme = NIL_RTLDRMOD;
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync gCtx.pfnEnableTheming = NULL;
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync gCtx.pfnIsThemeActive = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *pfStartThread = true;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *ppInstance = &gCtx;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncvoid VBoxVRDPDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("VBoxVRDPDestroy\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxExperienceRestore (pCtx->level);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync if (gCtx.hModUxTheme != NIL_RTLDRMOD)
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync {
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync RTLdrClose(gCtx.hModUxTheme);
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync gCtx.hModUxTheme = NIL_RTLDRMOD;
71955773a7f477f9a159a491f765ba97e1f00e1avboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/**
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Thread function to wait for and process mode change requests
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncunsigned __stdcall VBoxVRDPThread(void *pInstance)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync bool fTerminate = false;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxGuestFilterMaskInfo maskInfo;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DWORD cbReturned;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync maskInfo.u32OrMask = VMMDEV_EVENT_VRDP;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync maskInfo.u32NotMask = 0;
b357df727b216b85d4517efecf466a7b14c2e80cvboxsync if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("DeviceIOControl(CtlMask - or) succeeded\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("DeviceIOControl(CtlMask) failed\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync do
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* wait for the event */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxGuestWaitEventInfo waitEvent;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync waitEvent.u32TimeoutIn = 5000;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync waitEvent.u32EventMaskIn = VMMDEV_EVENT_VRDP;
b357df727b216b85d4517efecf466a7b14c2e80cvboxsync if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("DeviceIOControl succeeded\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* are we supposed to stop? */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("checking event\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* did we get the right event? */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_VRDP)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Call the host to get VRDP status and the experience level. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VMMDevVRDPChangeRequest vrdpChangeRequest = {0};
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vrdpChangeRequest.header.size = sizeof(VMMDevVRDPChangeRequest);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vrdpChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vrdpChangeRequest.header.requestType = VMMDevReq_GetVRDPChangeRequest;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vrdpChangeRequest.u8VRDPActive = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vrdpChangeRequest.u32VRDPExperienceLevel = 0;
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (DeviceIoControl (gVBoxDriver,
ba2e65ca2c6ee70366bca6b355a22b44899490e7vboxsync VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevVRDPChangeRequest)),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &vrdpChangeRequest,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync sizeof(VMMDevVRDPChangeRequest),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &vrdpChangeRequest,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync sizeof(VMMDevVRDPChangeRequest),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &cbReturned, NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("u8VRDPActive = %d, level %d\n", vrdpChangeRequest.u8VRDPActive, vrdpChangeRequest.u32VRDPExperienceLevel));
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (vrdpChangeRequest.u8VRDPActive)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->level = vrdpChangeRequest.u32VRDPExperienceLevel;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxExperienceSet (pCtx->level);
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->level == VRDP_EXPERIENCE_LEVEL_ZERO
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync && pCtx->pfnEnableTheming
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync && pCtx->pfnIsThemeActive)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->fSavedThemeEnabled = pCtx->pfnIsThemeActive ();
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("pCtx->fSavedThemeEnabled = %d\n", pCtx->fSavedThemeEnabled));
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->fSavedThemeEnabled)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->pfnEnableTheming (FALSE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->level == VRDP_EXPERIENCE_LEVEL_ZERO
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync && pCtx->pfnEnableTheming
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync && pCtx->pfnIsThemeActive)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->fSavedThemeEnabled)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* @todo the call returns S_OK but theming remains disabled. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HRESULT hrc = pCtx->pfnEnableTheming (TRUE);
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("enabling theme rc = 0x%08X\n", hrc));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->fSavedThemeEnabled = FALSE;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxExperienceRestore (pCtx->level);
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->level = VRDP_EXPERIENCE_LEVEL_FULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#ifndef DEBUG_andy /* Too noisy for me. */
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#endif
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* sleep a bit to not eat too much CPU in case the above call always fails */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync fTerminate = true;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e9a584ee0777ab2612e206eeec264ccb1a8ce333vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#ifndef DEBUG_andy
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#endif
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* sleep a bit to not eat too much CPU in case the above call always fails */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync fTerminate = true;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } while (!fTerminate);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync maskInfo.u32OrMask = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync maskInfo.u32NotMask = VMMDEV_EVENT_VRDP;
b357df727b216b85d4517efecf466a7b14c2e80cvboxsync if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("DeviceIOControl(CtlMask - not) succeeded\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("DeviceIOControl(CtlMask) failed\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
a29027bb2378172c7c88610ad5311548b66f96f6vboxsync LogFlowFunc(("Finished VRDP change request thread\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync