ConsoleVRDPServer.cpp revision e214bb78026c1d64078b34ca9504d3f5abbc52ef
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff * VBox Console VRDP Helper class
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * Copyright (C) 2006-2008 Sun Microsystems, Inc.
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * This file is part of VirtualBox Open Source Edition (OSE), as
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * available from http://www.virtualbox.org. This file is free software;
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * you can redistribute it and/or modify it under the terms of the GNU
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * General Public License (GPL) as published by the Free Software
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * Foundation, in version 2 as it comes in the "COPYING" file of the
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * Clara, CA 95054 USA or visit http://www.sun.com if you need
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos * additional information or have any questions.
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff#endif /* VBOX_WITH_VRDP */
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloffclass VRDPConsoleCallback : public IConsoleCallback
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff VRDPConsoleCallback (ConsoleVRDPServer *server) :
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos#endif /* !VBOX_WITH_XPCOM */
2081314b176ae84d6402503c4af3963f02de201dChris Drake delete this;
2081314b176ae84d6402503c4af3963f02de201dChris Drake STDMETHOD(QueryInterface) (REFIID riid , void **ppObj)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff#endif /* !VBOX_WITH_XPCOM */
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos STDMETHOD(OnMousePointerShapeChange)(BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff STDMETHOD(OnMouseCapabilityChange)(BOOL supportsAbsolute, BOOL needsHostCursor)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff m_server->NotifyAbsoluteMouse(!!supportsAbsolute);
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff STDMETHOD(OnKeyboardLedsChange)(BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff m_server->NotifyKeyboardLedsChange (fNumLock, fCapsLock, fScrollLock);
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff STDMETHOD(OnStateChange)(MachineState_T machineState)
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos STDMETHOD(OnNetworkAdapterChange) (INetworkAdapter *aNetworkAdapter)
794fdb0c9612e917e5e265df805421736072634dJim Mitchener STDMETHOD(OnSerialPortChange) (ISerialPort *aSerialPort)
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos STDMETHOD(OnParallelPortChange) (IParallelPort *aParallelPort)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff STDMETHOD(OnUSBDeviceStateChange)(IUSBDevice *aDevice, BOOL aAttached,
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff STDMETHOD(OnSharedFolderChange) (Scope_T aScope)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff STDMETHOD(OnRuntimeError)(BOOL fatal, IN_BSTR id, IN_BSTR message)
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos /* we don't manage window activation here: always agree */
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos /* we don't manage window activation here */
67b6d55fac6eaaf8c7b50cb11a746fcd9a83006bLaszlo Hordos#endif /* !VBOX_WITH_XPCOM */
adf530d70e0ee974cd0bace4db9967617819cec1Andi EgloffNS_IMPL_THREADSAFE_ISUPPORTS1_CI(VRDPConsoleCallback, IConsoleCallback)
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloff#endif /* VBOX_WITH_XPCOM */
adf530d70e0ee974cd0bace4db9967617819cec1Andi Egloffvoid dumpPointer (const uint8_t *pu8Shape, uint32_t width, uint32_t height, bool fXorMaskRGB32)
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff for (i = 0; i < height; i++)
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff for (k = 0; k < 8; k++)
0ca1588b42c5f41ecf02c05579f66fa8d2539e77Andi Egloff LOGDUMPPTR(("%d", ((*pu8And) & (1 << (7 - k)))? 1: 0));
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(("VRDPConsoleCallback::OnMousePointerShapeChange: %d, %d, %lux%lu, @%lu,%lu\n", visible, alpha, width, height, xHot, yHot));
if (m_server)
if (!shape)
if (!visible)
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;
#ifdef VBOX_WITH_VRDP
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackQueryProperty (void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut)
switch (index)
case VRDP_QP_NETWORK_PORT:
if (port == 0)
case VRDP_QP_NETWORK_ADDRESS:
if (cbAddress > 0)
case VRDP_QP_NUMBER_MONITORS:
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)
DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackIntercept (void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercept, void **ppvIntercept)
switch (fu32Intercept)
if (ppvIntercept)
if (ppvIntercept)
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, VRDPFRAMEBUFFERINFO *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 VRDP_INPUT_SCANCODE:
case VRDP_INPUT_POINT:
int mouseButtons = 0;
int iWheel = 0;
pConsole->getMouse()->PutMouseEventAbsolute (pInputPoint->x + 1, pInputPoint->y + 1, iWheel, mouseButtons);
case VRDP_INPUT_CAD:
case VRDP_INPUT_RESET:
case VRDP_INPUT_SYNCH:
DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackVideoModeHint (void *pvCallback, unsigned cWidth, unsigned cHeight, unsigned cBitsPerPixel, unsigned uScreenId)
mcClipboardRefs = 0;
#ifdef VBOX_WITH_USB
#ifdef VBOX_WITH_VRDP
mhServer = 0;
m_fGuestWantsAbsolute = false;
m_mousex = 0;
m_mousey = 0;
mAuthLibrary = 0;
Stop ();
#ifdef VBOX_WITH_VRDP
if (mConsoleCallback)
if (maFramebuffers[i])
#ifdef VBOX_WITH_VRDP
if (loadVRDPLibrary ())
rc = mpfnVRDPCreateServer (&mCallbacks.header, this, (VRDPINTERFACEHDR **)&mpEntryPoints, &mhServer);
#ifdef VBOX_WITH_USB
return rc;
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
Assert(VALID_PTR(this)); /** @todo r=bird: there are(/was) some odd cases where this buster was invalid on
#ifdef VBOX_WITH_VRDP
if (mhServer)
mhServer = 0;
#ifdef VBOX_WITH_USB
if (mAuthLibrary)
mAuthLibrary = 0;
#ifdef VBOX_WITH_USB
return VINF_SUCCESS;
AssertFailed ();
VRDPAuthResult ConsoleVRDPServer::Authenticate (const Guid &uuid, VRDPAuthGuestJudgement guestJudgement,
LogFlow(("ConsoleVRDPServer::Authenticate: uuid = %RTuuid, guestJudgement = %d, pszUser = %s, pszPassword = %s, pszDomain = %s, u32ClientId = %d\n",
if (!mAuthLibrary)
LogRel(("VRDPAUTH: ConsoleVRDPServer::Authenticate: loading external authentication library '%ls'\n", authLibrary.raw()));
if (mAuthLibrary)
mAuthLibrary = 0;
return VRDPAuthAccessDenied;
switch (result)
case VRDPAuthAccessDenied:
case VRDPAuthAccessGranted:
case VRDPAuthDelegateToGuest:
return result;
if (mpfnAuthEntry2)
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,
#ifdef VBOX_WITH_VRDP
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
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
void ConsoleVRDPServer::SendUpdateBitmap (unsigned uScreenId, uint32_t x, uint32_t y, uint32_t w, uint32_t h) const
#ifdef VBOX_WITH_VRDP
update.x = x;
update.y = y;
update.w = w;
update.h = h;
void ConsoleVRDPServer::SendAudioSamples (void *pvSamples, uint32_t cSamples, VRDPAUDIOFORMAT format) const
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
void ConsoleVRDPServer::SendUSBRequest (uint32_t u32ClientId, void *pvParms, uint32_t cbParms) const
#ifdef VBOX_WITH_VRDP
void ConsoleVRDPServer::QueryInfo (uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const
#ifdef VBOX_WITH_VRDP
#ifdef VBOX_WITH_VRDP
if (!mVRDPLibrary)
struct SymbolEntry
const char *name;
void **ppfn;
LogRel(("VRDPServer::loadLibrary(): failed to load VRDP library! VRDP not available: rc = %Rrc\n", rc));
if (mVRDPLibrary)
return S_OK;
uninit ();
return S_OK;
if (!a##_aName) \
return E_POINTER; \
return S_OK; \
if (!a##_aName) \
return E_POINTER; \
return S_OK; \
if (!a##_aName) \
return E_POINTER; \
if (cbOut == 0) \
return S_OK; \
if (!pchBuffer) \
#_aName \
return E_OUTOFMEMORY; \
return S_OK; \