ConsoleVRDPServer.cpp revision 775be17bb9ed432d9873f5b9a3852361846abee2
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * VBox Console VRDP Helper class
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * Copyright (C) 2006-2013 Oracle Corporation
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * available from http://www.virtualbox.org. This file is free software;
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * you can redistribute it and/or modify it under the terms of the GNU
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * General Public License (GPL) as published by the Free Software
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b6b07507d11e2bea02bbba193ba367ea479a2fcfvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
switch (aType)
if (m_server)
if (m_server)
AssertFailed();
return S_OK;
#ifdef DEBUG_sunlover
for (i = 0; i < height; i++)
pu8And++;
if (fXorMaskRGB32)
for (i = 0; i < height; i++)
for (j = 0; j < width; j++)
for (i = 0; i < height; i++)
for (j = 0; j < width; j++)
#define dumpPointer(a, b, c, d) do {} while (0)
static void findTopLeftBorder(const uint8_t *pu8AndMask, const uint8_t *pu8XorMask, uint32_t width, uint32_t height, uint32_t *pxSkip, uint32_t *pySkip)
ySkipAnd = y;
ySkipAnd = y;
ySkipAnd = 0;
xSkipAnd = x;
xSkipAnd = 0;
for (x = 0; x < width; x++)
if (pu32Xor[x] != 0)
ySkipXor = y;
ySkipXor = 0;
if (*pu32Xor != 0)
xSkipXor = x;
xSkipXor = 0;
static void mousePointerGenerateANDMask(uint8_t *pu8DstAndMask, int cbDstAndMask, const uint8_t *pu8SrcAlpha, int w, int h)
if (bitmask == 0)
LogSunlover(("VRDPConsoleListener::OnMousePointerShapeChange: %d, %d, %lux%lu, @%lu,%lu\n", visible, alpha, width, height, xHot, yHot));
if (m_server)
if (!visible)
return S_OK;
if (alpha)
if (pointer)
for (y = 0; y < minheight; y++)
for (x = 0; x < minwidth; x++)
if (!bit)
for (y = 0; y < minheight ; y++)
for (x = 0; x < minwidth; x++)
return S_OK;
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackQueryProperty(void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut)
switch (index)
case VRDE_QP_NETWORK_PORT:
case VRDE_QP_NETWORK_ADDRESS:
case VRDE_QP_NUMBER_MONITORS:
HRESULT hrc = server->mConsole->getVRDEServer()->GetVRDEProperty(Bstr("TCP/Ports").raw(), bstr.asOutParam());
case VRDE_QP_VIDEO_CHANNEL:
HRESULT hrc = server->mConsole->getVRDEServer()->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), bstr.asOutParam());
HRESULT hrc = server->mConsole->getVRDEServer()->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), bstr.asOutParam());
case VRDE_QP_FEATURE:
HRESULT hrc = server->mConsole->getVRDEServer()->GetVRDEProperty(Bstr(pszPropertyName).raw(), bstrValue.asOutParam());
if (pcbOut)
case VRDE_SP_CLIENT_STATUS:
if (pcbOut)
return rc;
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackClientLogon(void *pvCallback, uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain)
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackClientConnect(void *pvCallback, uint32_t u32ClientId)
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackClientDisconnect(void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercepted)
if (pPort)
AssertFailed();
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackIntercept(void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercept, void **ppvIntercept)
switch (fu32Intercept)
if (ppvIntercept)
if (ppvIntercept)
if (pPort)
if (ppvIntercept)
AssertFailed();
Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, server->mu32AudioInputClientId));
return rc;
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackUSB(void *pvCallback, void *pvIntercept, uint32_t u32ClientId, uint8_t u8Code, const void *pvRet, uint32_t cbRet)
#ifdef VBOX_WITH_USB
return VERR_NOT_SUPPORTED;
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackClipboard(void *pvCallback, void *pvIntercept, uint32_t u32ClientId, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData)
DECLCALLBACK(bool) ConsoleVRDPServer::VRDPCallbackFramebufferQuery(void *pvCallback, unsigned uScreenId, VRDEFRAMEBUFFERINFO *pInfo)
bool fAvailable = false;
if (pfb)
fAvailable = true;
return fAvailable;
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackFramebufferLock(void *pvCallback, unsigned uScreenId)
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackFramebufferUnlock(void *pvCallback, unsigned uScreenId)
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackInput(void *pvCallback, int type, const void *pvInput, unsigned cbInput)
switch (type)
case VRDE_INPUT_SCANCODE:
case VRDE_INPUT_POINT:
int mouseButtons = 0;
int iWheel = 0;
pConsole->getMouse()->PutMouseEventAbsolute(pInputPoint->x + 1, pInputPoint->y + 1, iWheel, 0 /* Horizontal wheel */, mouseButtons);
case VRDE_INPUT_CAD:
case VRDE_INPUT_RESET:
case VRDE_INPUT_SYNCH:
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackVideoModeHint(void *pvCallback, unsigned cWidth, unsigned cHeight, unsigned cBitsPerPixel, unsigned uScreenId)
void *pvCtx,
const void *pvData,
switch (u32Event)
case VRDE_AUDIOIN_BEGIN:
case VRDE_AUDIOIN_DATA:
case VRDE_AUDIOIN_END:
mcClipboardRefs = 0;
#ifdef VBOX_WITH_USB
mhServer = 0;
mcInResize = 0;
m_fGuestWantsAbsolute = false;
m_mousex = 0;
m_mousey = 0;
mAuthLibrary = 0;
mcClients = 0;
m_fInterfaceImage = false;
Stop();
if (mConsoleListener)
if (maFramebuffers[i])
if (!fEnabled)
return VINF_SUCCESS;
return VINF_NOT_SUPPORTED;
#ifdef VBOX_WITH_EXTPACK
vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints4, &mhServer);
vrc = mpfnVRDECreateServer(&sCallbacks3.header, this, (VRDEINTERFACEHDR **)&pEntryPoints3, &mhServer);
vrc = mpfnVRDECreateServer(&sCallbacks1.header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer);
m_fInterfaceImage = true;
NULL,
#ifdef VBOX_WITH_USB
return vrc;
typedef struct H3DORInstance
int32_t x;
int32_t y;
uint32_t w;
uint32_t h;
bool fCreated;
bool fFallback;
/* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORBegin(const void *pvContext, void **ppvInstance,
const char *pszFormat)
p->fCreated = false;
p->fFallback = false;
RTMemFree(p);
p = NULL;
*ppvInstance = p;
Assert(p);
if (p->hImageBitmap)
if (!p->hImageBitmap)
p->fFallback = false;
&p->hImageBitmap,
&rect,
NULL,
fu32CompletionFlags = 0;
p->fFallback = true;
&p->hImageBitmap,
&rect,
NULL,
p->fCreated = true;
Assert(p);
if (cRects == 0)
&rect);
paRects);
Assert(p);
&image,
sizeof(VRDEIMAGEBITMAP));
Assert(p);
RTMemFree(p);
/* static */ DECLCALLBACK(int) ConsoleVRDPServer::H3DORContextProperty(const void *pvContext, uint32_t index,
return rc;
if (!m_fInterfaceImage)
HRESULT hrc = mConsole->getVRDEServer()->GetVRDEProperty(Bstr("H3DRedirect/Enabled").raw(), bstr.asOutParam());
if (!fEnable)
if (!pVMMDev)
&parm);
void *pvUser,
void *pvData,
H3DORLOG(("H3DOR: VRDEImageCbNotify: pvContext %p, pvUser %p, hVideo %p, u32Id %u, pvData %p, cbData %d\n",
Assert(p);
AssertFailed();
return VERR_INVALID_PARAMETER;
u32StreamId));
if (u32StreamId != 0)
return VINF_SUCCESS;
void *pvData,
#ifdef VBOX_WITH_USB_CARDREADER
return VERR_NOT_SUPPORTED;
int rcRequest,
void *pvUser,
void *pvData,
#ifdef VBOX_WITH_USB_CARDREADER
return VERR_NOT_SUPPORTED;
int ConsoleVRDPServer::SCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData)
return rc;
struct TSMFHOSTCHCTX;
struct TSMFVRDPCTX;
typedef struct TSMFHOSTCHCTX
void *pvDataReceived;
typedef struct TSMFVRDPCTX
void *pvCallbacks;
} TSMFVRDPCTX;
if (!pHostChCtx)
return VERR_NO_MEMORY;
if (!pVRDPCtx)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
return rc;
void **ppvChannel,
void *pvCallbacks)
return rc;
return rc;
bool fClose = false;
fClose = true;
if (fClose)
const void *pvData,
bool fSend = false;
fSend = true;
if (fSend)
return rc;
void *pvData,
if (cbToCopy != 0)
if (cbRemaining != 0)
return rc;
const void *pvParm,
const void *pvData,
if (!pvChannel)
*pcbDataReturned = 0;
return VINF_SUCCESS;
return VERR_NOT_IMPLEMENTED;
return VERR_NOT_IMPLEMENTED;
if (!pVMMDev)
void *pvChannel,
const void *pvParm,
switch (u32Notification)
NULL, 0);
NULL, 0);
case VRDE_TSMF_N_DATA:
if (pHostChCtx)
case VRDE_TSMF_N_DISCONNECTED:
NULL, 0);
AssertFailed();
const void *pvData,
#ifdef VBOX_WITH_USB_VIDEO
int rcRequest,
void *pDeviceCtx,
void *pvUser,
#ifdef VBOX_WITH_USB_VIDEO
int rcRequest,
void *pDeviceCtx,
void *pvUser,
#ifdef VBOX_WITH_USB_VIDEO
int rcRequest,
void *pDeviceCtx,
#ifdef VBOX_WITH_USB_VIDEO
int ConsoleVRDPServer::VideoInDeviceAttach(const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, void *pvDeviceCtx)
int rc;
return rc;
int rc;
return rc;
int ConsoleVRDPServer::VideoInGetDeviceDesc(void *pvUser, const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle)
int rc;
return rc;
int rc;
return rc;
int rcRequest,
const void *pvResult,
const void *pvEvent,
setupTSMF();
if (cbDstMask)
return rc;
Assert(VALID_PTR(this)); /** @todo r=bird: there are(/was) some odd cases where this buster was invalid on
#ifdef VBOX_WITH_USB
if (mhServer)
mhServer = 0;
if (mcInResize)
if (mAuthLibrary)
mAuthLibrary = 0;
#ifdef VBOX_WITH_USB
return VINF_SUCCESS;
AssertFailed();
typedef struct AuthCtx
const char *pszCaller;
const char *pszUser;
const char *pszPassword;
const char *pszDomain;
int fLogon;
unsigned clientId;
} AuthCtx;
return VINF_SUCCESS;
return result;
LogFlow(("ConsoleVRDPServer::Authenticate: uuid = %RTuuid, guestJudgement = %d, pszUser = %s, pszPassword = %s, pszDomain = %s, u32ClientId = %d\n",
if (!mAuthLibrary)
int rc;
LogRel(("AUTH: ConsoleVRDPServer::Authenticate: loading external authentication library VBoxAuth\n"));
typedef struct AuthEntryInfoStruct
const char *pszName;
void **ppvAddress;
pEntryInfo++;
rc);
if (mAuthLibrary)
mAuthLibrary = 0;
return AuthResultAccessDenied;
switch (result)
case AuthResultAccessDenied:
case AuthResultAccessGranted:
return result;
return rc;
const void *pvData,
LogFlowFunc(("pvCallback = %p, u32ClientId = %d, u32Function = %d, u32Format = 0x%08X, pvData = %p, cbData = %d\n",
switch (u32Function)
(void *)pvData,
cbData);
(void *)pvData,
cbData);
return rc;
void *pvParms,
switch (u32Function)
NULL,
NULL);
NULL);
return rc;
if (mcClipboardRefs == 0)
rc = HGCMHostRegisterServiceExtension(&mhClipboard, "VBoxSharedClipboard", ClipboardServiceExtension, this);
if (mcClipboardRefs == 0)
#ifdef VBOX_WITH_USB
if (pRemoteUSBBackend)
if (ppvIntercept)
#ifdef VBOX_WITH_USB
if (pRemoteUSBBackend)
if (pRemoteUSBBackend)
#ifdef VBOX_WITH_USB
if (pRemoteUSBBackend)
if (fAdded)
if (pRemoteUSBBackend)
return NULL;
#ifdef VBOX_WITH_USB
if (pRemoteUSBBackend)
if (pRemoteUSBBackend)
#ifdef VBOX_WITH_USB
if (pRemoteUSBBackend)
return pNextRemoteUSBBackend;
#ifdef VBOX_WITH_USB
while (pRemoteUSBBackend)
return pRemoteUSBBackend;
while (pRemoteUSBBackend)
return pRemoteUSBBackend;
#ifdef VBOX_WITH_USB
++mcInResize;
--mcInResize;
void ConsoleVRDPServer::SendUpdateBitmap(unsigned uScreenId, uint32_t x, uint32_t y, uint32_t w, uint32_t h) const
update.x = x;
update.y = y;
update.w = w;
update.h = h;
void ConsoleVRDPServer::SendAudioSamples(void *pvSamples, uint32_t cSamples, VRDEAUDIOFORMAT format) const
void *pvContext,
cSamples);
return VINF_SUCCESS;
return VERR_NOT_SUPPORTED;
#ifdef VBOX_WITH_USB_VIDEO
return VINF_SUCCESS;
return VINF_SUCCESS;
void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const
rc = SUPR3HardenedLdrLoadAppPriv(pszLibraryName, &mVRDPLibrary, RTLDRLOAD_FLAGS_LOCAL, &ErrInfo.Core);
struct SymbolEntry
const char *name;
void **ppfn;
LogRel(("VRDE: Error loading the library '%s': %s (%Rrc)\n", pszLibraryName, ErrInfo.Core.pszMsg, rc));
return rc;
return BaseFinalConstruct();
uninit();
return S_OK;
if (!a##_aName) \
return E_POINTER; \
return S_OK; \
extern void IMPL_GETTER_BOOL_DUMMY(void)
if (!a##_aName) \
return E_POINTER; \
return S_OK; \
extern void IMPL_GETTER_SCALAR_DUMMY(void)
if (!a##_aName) \
return E_POINTER; \
if (cbOut == 0) \
return S_OK; \
if (!pchBuffer) \
#_aName \
return E_OUTOFMEMORY; \
return S_OK; \
extern void IMPL_GETTER_BSTR_DUMMY(void)