diff options
Diffstat (limited to 'src/VBox/Main/src-client/ConsoleVRDPServer.cpp')
-rw-r--r-- | src/VBox/Main/src-client/ConsoleVRDPServer.cpp | 872 |
1 files changed, 721 insertions, 151 deletions
diff --git a/src/VBox/Main/src-client/ConsoleVRDPServer.cpp b/src/VBox/Main/src-client/ConsoleVRDPServer.cpp index f907b189..4247f2fb 100644 --- a/src/VBox/Main/src-client/ConsoleVRDPServer.cpp +++ b/src/VBox/Main/src-client/ConsoleVRDPServer.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -28,6 +28,7 @@ #ifdef VBOX_WITH_USB_CARDREADER # include "UsbCardReader.h" #endif +#include "UsbWebcamInterface.h" #include "Global.h" #include "AutoCaller.h" @@ -666,7 +667,6 @@ DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackQueryProperty(void *pvCallback *pcbOut = (uint32_t)cbPortRange; } break; -#ifdef VBOX_WITH_VRDP_VIDEO_CHANNEL case VRDE_QP_VIDEO_CHANNEL: { com::Bstr bstr; @@ -750,7 +750,6 @@ DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackQueryProperty(void *pvCallback *pcbOut = sizeof(uint32_t); } break; -#endif /* VBOX_WITH_VRDP_VIDEO_CHANNEL */ case VRDE_QP_FEATURE: { @@ -924,6 +923,16 @@ DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackClientConnect(void *pvCallback ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback); server->mConsole->VRDPClientConnect(u32ClientId); + + /* Should the server report usage of an interface for each client? + * Similar to Intercept. + */ + int c = ASMAtomicIncS32(&server->mcClients); + if (c == 1) + { + /* Features which should be enabled only if there is a client. */ + server->remote3DRedirect(true); + } } DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackClientDisconnect(void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercepted) @@ -947,6 +956,13 @@ DECLCALLBACK(void) ConsoleVRDPServer::VRDPCallbackClientDisconnect(void *pvCallb AssertFailed(); } } + + int c = ASMAtomicDecS32(&server->mcClients); + if (c == 0) + { + /* Features which should be enabled only if there is a client. */ + server->remote3DRedirect(false); + } } DECLCALLBACK(int) ConsoleVRDPServer::VRDPCallbackIntercept(void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercept, void **ppvIntercept) @@ -1332,6 +1348,8 @@ ConsoleVRDPServer::ConsoleVRDPServer(Console *console) mhServer = 0; mServerInterfaceVersion = 0; + mcInResize = 0; + m_fGuestWantsAbsolute = false; m_mousex = 0; m_mousey = 0; @@ -1347,7 +1365,7 @@ ConsoleVRDPServer::ConsoleVRDPServer(Console *console) m_InputSynch.fClientCapsLock = false; m_InputSynch.fClientScrollLock = false; - memset(maFramebuffers, 0, sizeof(maFramebuffers)); + RT_ZERO(maFramebuffers); { ComPtr<IEventSource> es; @@ -1368,18 +1386,29 @@ ConsoleVRDPServer::ConsoleVRDPServer(Console *console) mAuthLibrary = 0; mu32AudioInputClientId = 0; + mcClients = 0; /* * Optional interfaces. */ m_fInterfaceImage = false; - memset(&m_interfaceImage, 0, sizeof (m_interfaceImage)); - memset(&m_interfaceCallbacksImage, 0, sizeof (m_interfaceCallbacksImage)); + RT_ZERO(m_interfaceImage); + RT_ZERO(m_interfaceCallbacksImage); RT_ZERO(m_interfaceMousePtr); RT_ZERO(m_interfaceSCard); RT_ZERO(m_interfaceCallbacksSCard); RT_ZERO(m_interfaceTSMF); RT_ZERO(m_interfaceCallbacksTSMF); + RT_ZERO(m_interfaceVideoIn); + RT_ZERO(m_interfaceCallbacksVideoIn); + RT_ZERO(m_interfaceInput); + RT_ZERO(m_interfaceCallbacksInput); + + rc = RTCritSectInit(&mTSMFLock); + AssertRC(rc); + + mEmWebcam = new EmWebcam(this); + AssertPtr(mEmWebcam); } ConsoleVRDPServer::~ConsoleVRDPServer() @@ -1404,10 +1433,22 @@ ConsoleVRDPServer::~ConsoleVRDPServer() } } + if (mEmWebcam) + { + delete mEmWebcam; + mEmWebcam = NULL; + } + if (RTCritSectIsInitialized(&mCritSect)) { RTCritSectDelete(&mCritSect); - memset(&mCritSect, 0, sizeof(mCritSect)); + RT_ZERO(mCritSect); + } + + if (RTCritSectIsInitialized(&mTSMFLock)) + { + RTCritSectDelete(&mTSMFLock); + RT_ZERO(mTSMFLock); } } @@ -1654,6 +1695,54 @@ int ConsoleVRDPServer::Launch(void) RT_ZERO(m_interfaceTSMF); } + /* VideoIn interface. */ + m_interfaceVideoIn.header.u64Version = 1; + m_interfaceVideoIn.header.u64Size = sizeof(m_interfaceVideoIn); + + m_interfaceCallbacksVideoIn.header.u64Version = 1; + m_interfaceCallbacksVideoIn.header.u64Size = sizeof(m_interfaceCallbacksVideoIn); + m_interfaceCallbacksVideoIn.VRDECallbackVideoInNotify = VRDECallbackVideoInNotify; + m_interfaceCallbacksVideoIn.VRDECallbackVideoInDeviceDesc = VRDECallbackVideoInDeviceDesc; + m_interfaceCallbacksVideoIn.VRDECallbackVideoInControl = VRDECallbackVideoInControl; + m_interfaceCallbacksVideoIn.VRDECallbackVideoInFrame = VRDECallbackVideoInFrame; + + vrc = mpEntryPoints->VRDEGetInterface(mhServer, + VRDE_VIDEOIN_INTERFACE_NAME, + &m_interfaceVideoIn.header, + &m_interfaceCallbacksVideoIn.header, + this); + if (RT_SUCCESS(vrc)) + { + LogRel(("VRDE: [%s]\n", VRDE_VIDEOIN_INTERFACE_NAME)); + } + else + { + RT_ZERO(m_interfaceVideoIn); + } + + /* Input interface. */ + m_interfaceInput.header.u64Version = 1; + m_interfaceInput.header.u64Size = sizeof(m_interfaceInput); + + m_interfaceCallbacksInput.header.u64Version = 1; + m_interfaceCallbacksInput.header.u64Size = sizeof(m_interfaceCallbacksInput); + m_interfaceCallbacksInput.VRDECallbackInputSetup = VRDECallbackInputSetup; + m_interfaceCallbacksInput.VRDECallbackInputEvent = VRDECallbackInputEvent; + + vrc = mpEntryPoints->VRDEGetInterface(mhServer, + VRDE_INPUT_INTERFACE_NAME, + &m_interfaceInput.header, + &m_interfaceCallbacksInput.header, + this); + if (RT_SUCCESS(vrc)) + { + LogRel(("VRDE: [%s]\n", VRDE_INPUT_INTERFACE_NAME)); + } + else + { + RT_ZERO(m_interfaceInput); + } + /* Since these interfaces are optional, it is always a success here. */ vrc = VINF_SUCCESS; } @@ -1683,14 +1772,17 @@ typedef struct H3DORInstance uint32_t w; uint32_t h; bool fCreated; + bool fFallback; } H3DORInstance; +#define H3DORLOG Log + /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORBegin(const void *pvContext, void **ppvInstance, const char *pszFormat) { - LogFlowFunc(("ctx %p\n", pvContext)); + H3DORLOG(("H3DORBegin: ctx %p [%s]\n", pvContext, pszFormat)); - H3DORInstance *p = (H3DORInstance *)RTMemAlloc(sizeof (H3DORInstance)); + H3DORInstance *p = (H3DORInstance *)RTMemAlloc(sizeof(H3DORInstance)); if (p) { @@ -1701,6 +1793,7 @@ typedef struct H3DORInstance p->w = 0; p->h = 0; p->fCreated = false; + p->fFallback = false; /* Host 3D service passes the actual format of data in this redirect instance. * That is what will be in the H3DORFrame's parameters pvData and cbData. @@ -1716,14 +1809,16 @@ typedef struct H3DORInstance } } - /* Caller check this for NULL. */ + H3DORLOG(("H3DORBegin: ins %p\n", p)); + + /* Caller checks this for NULL. */ *ppvInstance = p; } /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORGeometry(void *pvInstance, int32_t x, int32_t y, uint32_t w, uint32_t h) { - LogFlowFunc(("ins %p %d,%d %dx%d\n", pvInstance, x, y, w, h)); + H3DORLOG(("H3DORGeometry: ins %p %d,%d %dx%d\n", pvInstance, x, y, w, h)); H3DORInstance *p = (H3DORInstance *)pvInstance; Assert(p); @@ -1752,12 +1847,14 @@ typedef struct H3DORInstance && p->w == w && p->h == h) { - LogFlowFunc(("geometry not changed\n")); + H3DORLOG(("H3DORGeometry: geometry not changed\n")); /* Do nothing. Continue using the existing handle. */ } else { - int rc = p->pThis->m_interfaceImage.VRDEImageGeometrySet(p->hImageBitmap, &rect); + int rc = p->fFallback? + VERR_NOT_SUPPORTED: /* Try to go out of fallback mode. */ + p->pThis->m_interfaceImage.VRDEImageGeometrySet(p->hImageBitmap, &rect); if (RT_SUCCESS(rc)) { p->x = x; @@ -1786,6 +1883,7 @@ typedef struct H3DORInstance * the clipping must be done here in ConsoleVRDPServer */ uint32_t fu32CompletionFlags = 0; + p->fFallback = false; int rc = p->pThis->m_interfaceImage.VRDEImageHandleCreate(p->pThis->mhServer, &p->hImageBitmap, p, @@ -1800,7 +1898,9 @@ typedef struct H3DORInstance if (RT_FAILURE(rc)) { /* No support for a 3D + WINDOW. Try bitmap updates. */ + H3DORLOG(("H3DORGeometry: Fallback to bitmaps\n")); fu32CompletionFlags = 0; + p->fFallback = true; rc = p->pThis->m_interfaceImage.VRDEImageHandleCreate(p->pThis->mhServer, &p->hImageBitmap, p, @@ -1813,6 +1913,8 @@ typedef struct H3DORInstance &fu32CompletionFlags); } + H3DORLOG(("H3DORGeometry: Image handle create %Rrc, flags 0x%RX32\n", rc, fu32CompletionFlags)); + if (RT_SUCCESS(rc)) { p->x = x; @@ -1832,12 +1934,14 @@ typedef struct H3DORInstance p->h = 0; } } + + H3DORLOG(("H3DORGeometry: ins %p completed\n", pvInstance)); } /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORVisibleRegion(void *pvInstance, - uint32_t cRects, RTRECT *paRects) + uint32_t cRects, const RTRECT *paRects) { - LogFlowFunc(("ins %p %d\n", pvInstance, cRects)); + H3DORLOG(("H3DORVisibleRegion: ins %p %d\n", pvInstance, cRects)); H3DORInstance *p = (H3DORInstance *)pvInstance; Assert(p); @@ -1861,12 +1965,14 @@ typedef struct H3DORInstance cRects, paRects); } + + H3DORLOG(("H3DORVisibleRegion: ins %p completed\n", pvInstance)); } /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DORFrame(void *pvInstance, void *pvData, uint32_t cbData) { - LogFlowFunc(("ins %p %p %d\n", pvInstance, pvData, cbData)); + H3DORLOG(("H3DORFrame: ins %p %p %d\n", pvInstance, pvData, cbData)); H3DORInstance *p = (H3DORInstance *)pvInstance; Assert(p); @@ -1889,11 +1995,13 @@ typedef struct H3DORInstance p->h, &image, sizeof(VRDEIMAGEBITMAP)); + + H3DORLOG(("H3DORFrame: ins %p completed\n", pvInstance)); } /* static */ DECLCALLBACK(void) ConsoleVRDPServer::H3DOREnd(void *pvInstance) { - LogFlowFunc(("ins %p\n", pvInstance)); + H3DORLOG(("H3DOREnd: ins %p\n", pvInstance)); H3DORInstance *p = (H3DORInstance *)pvInstance; Assert(p); @@ -1902,6 +2010,8 @@ typedef struct H3DORInstance p->pThis->m_interfaceImage.VRDEImageHandleClose(p->hImageBitmap); RTMemFree(p); + + H3DORLOG(("H3DOREnd: ins %p completed\n", pvInstance)); } /* static */ DECLCALLBACK(int) ConsoleVRDPServer::H3DORContextProperty(const void *pvContext, uint32_t index, @@ -1909,6 +2019,8 @@ typedef struct H3DORInstance { int rc = VINF_SUCCESS; + H3DORLOG(("H3DORContextProperty: index %d\n", index)); + if (index == H3DOR_PROP_FORMATS) { /* Return a comma separated list of supported formats. */ @@ -1929,10 +2041,11 @@ typedef struct H3DORInstance rc = VERR_NOT_SUPPORTED; } + H3DORLOG(("H3DORContextProperty: %Rrc\n", rc)); return rc; } -void ConsoleVRDPServer::remote3DRedirect(void) +void ConsoleVRDPServer::remote3DRedirect(bool fEnable) { if (!m_fInterfaceImage) { @@ -1940,21 +2053,17 @@ void ConsoleVRDPServer::remote3DRedirect(void) return; } - /* Check if 3D redirection has been enabled. */ + /* Check if 3D redirection has been enabled. It is enabled by default. */ com::Bstr bstr; HRESULT hrc = mConsole->getVRDEServer()->GetVRDEProperty(Bstr("H3DRedirect/Enabled").raw(), bstr.asOutParam()); - if (hrc != S_OK) - { - bstr = ""; - } - - com::Utf8Str value = bstr; + com::Utf8Str value = hrc == S_OK? bstr: ""; - bool fEnabled = RTStrICmp(value.c_str(), "true") == 0 - || RTStrICmp(value.c_str(), "1") == 0; + bool fAllowed = RTStrICmp(value.c_str(), "true") == 0 + || RTStrICmp(value.c_str(), "1") == 0 + || value.c_str()[0] == 0; - if (!fEnabled) + if (!fAllowed && fEnable) { return; } @@ -1971,6 +2080,12 @@ void ConsoleVRDPServer::remote3DRedirect(void) H3DORContextProperty }; + if (!fEnable) + { + /* This will tell the service to disable rediection. */ + RT_ZERO(outputRedirect); + } + VBOXHGCMSVCPARM parm; parm.type = VBOX_HGCM_SVC_PARM_PTR; @@ -1992,11 +2107,11 @@ void ConsoleVRDPServer::remote3DRedirect(void) if (!RT_SUCCESS(rc)) { - AssertMsgFailed(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc)); + Log(("SHCRGL_HOST_FN_SET_CONSOLE failed with %Rrc\n", rc)); return; } - LogRel(("VRDE: Enabled 3D redirect.\n")); + LogRel(("VRDE: %s 3D redirect.\n", fEnable? "Enabled": "Disabled")); return; } @@ -2008,8 +2123,8 @@ void ConsoleVRDPServer::remote3DRedirect(void) void *pvData, uint32_t cbData) { - LogFlowFunc(("pvContext %p, pvUser %p, hVideo %p, u32Id %u, pvData %p, cbData %d\n", - pvContext, pvUser, hVideo, u32Id, pvData, cbData)); + H3DORLOG(("H3DOR: VRDEImageCbNotify: pvContext %p, pvUser %p, hVideo %p, u32Id %u, pvData %p, cbData %d\n", + pvContext, pvUser, hVideo, u32Id, pvData, cbData)); ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvContext); H3DORInstance *p = (H3DORInstance *)pvUser; @@ -2026,8 +2141,8 @@ void ConsoleVRDPServer::remote3DRedirect(void) } uint32_t u32StreamId = *(uint32_t *)pvData; - LogFlowFunc(("VRDE_IMAGE_NOTIFY_HANDLE_CREATE u32StreamId %d\n", - u32StreamId)); + H3DORLOG(("H3DOR: VRDE_IMAGE_NOTIFY_HANDLE_CREATE u32StreamId %d\n", + u32StreamId)); if (u32StreamId != 0) { @@ -2042,6 +2157,8 @@ void ConsoleVRDPServer::remote3DRedirect(void) return VINF_SUCCESS; } +#undef H3DORLOG + /* static */ DECLCALLBACK(int) ConsoleVRDPServer::VRDESCardCbNotify(void *pvContext, uint32_t u32Id, void *pvData, @@ -2098,19 +2215,64 @@ int ConsoleVRDPServer::SCardRequest(void *pvUser, uint32_t u32Function, const vo return rc; } -typedef struct TSMFHOSTCHANNELCTX + +struct TSMFHOSTCHCTX; +struct TSMFVRDPCTX; + +typedef struct TSMFHOSTCHCTX +{ + ConsoleVRDPServer *pThis; + + struct TSMFVRDPCTX *pVRDPCtx; /* NULL if no corresponding host channel context. */ + + void *pvDataReceived; + uint32_t cbDataReceived; + uint32_t cbDataAllocated; +} TSMFHOSTCHCTX; + +typedef struct TSMFVRDPCTX { ConsoleVRDPServer *pThis; VBOXHOSTCHANNELCALLBACKS *pCallbacks; void *pvCallbacks; + TSMFHOSTCHCTX *pHostChCtx; /* NULL if no corresponding host channel context. */ + uint32_t u32ChannelHandle; +} TSMFVRDPCTX; - void *pvDataReceived; - uint32_t cbDataReceived; - uint32_t cbDataAllocated; -} TSMFHOSTCHANNELCTX; +static int tsmfContextsAlloc(TSMFHOSTCHCTX **ppHostChCtx, TSMFVRDPCTX **ppVRDPCtx) +{ + TSMFHOSTCHCTX *pHostChCtx = (TSMFHOSTCHCTX *)RTMemAllocZ(sizeof(TSMFHOSTCHCTX)); + if (!pHostChCtx) + { + return VERR_NO_MEMORY; + } + + TSMFVRDPCTX *pVRDPCtx = (TSMFVRDPCTX *)RTMemAllocZ(sizeof(TSMFVRDPCTX)); + if (!pVRDPCtx) + { + RTMemFree(pHostChCtx); + return VERR_NO_MEMORY; + } + + *ppHostChCtx = pHostChCtx; + *ppVRDPCtx = pVRDPCtx; + return VINF_SUCCESS; +} + +int ConsoleVRDPServer::tsmfLock(void) +{ + int rc = RTCritSectEnter(&mTSMFLock); + AssertRC(rc); + return rc; +} + +void ConsoleVRDPServer::tsmfUnlock(void) +{ + RTCritSectLeave(&mTSMFLock); +} /* static */ DECLCALLBACK(int) ConsoleVRDPServer::tsmfHostChannelAttach(void *pvProvider, void **ppvChannel, @@ -2122,26 +2284,35 @@ typedef struct TSMFHOSTCHANNELCTX ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvProvider); - TSMFHOSTCHANNELCTX *pCtx = (TSMFHOSTCHANNELCTX *)RTMemAllocZ(sizeof(TSMFHOSTCHANNELCTX)); - if (!pCtx) + /* Create 2 context structures: for the VRDP server and for the host service. */ + TSMFHOSTCHCTX *pHostChCtx = NULL; + TSMFVRDPCTX *pVRDPCtx = NULL; + + int rc = tsmfContextsAlloc(&pHostChCtx, &pVRDPCtx); + if (RT_FAILURE(rc)) { - return VERR_NO_MEMORY; + return rc; } - pCtx->pThis = pThis; - pCtx->pCallbacks = pCallbacks; - pCtx->pvCallbacks = pvCallbacks; + pHostChCtx->pThis = pThis; + pHostChCtx->pVRDPCtx = pVRDPCtx; - int rc = pThis->m_interfaceTSMF.VRDETSMFChannelCreate(pThis->mhServer, pCtx, u32Flags); + pVRDPCtx->pThis = pThis; + pVRDPCtx->pCallbacks = pCallbacks; + pVRDPCtx->pvCallbacks = pvCallbacks; + pVRDPCtx->pHostChCtx = pHostChCtx; + + rc = pThis->m_interfaceTSMF.VRDETSMFChannelCreate(pThis->mhServer, pVRDPCtx, u32Flags); if (RT_SUCCESS(rc)) { /* @todo contexts should be in a list for accounting. */ - *ppvChannel = pCtx; + *ppvChannel = pHostChCtx; } else { - RTMemFree(pCtx); + RTMemFree(pHostChCtx); + RTMemFree(pVRDPCtx); } return rc; @@ -2151,21 +2322,69 @@ typedef struct TSMFHOSTCHANNELCTX { LogFlowFunc(("\n")); - TSMFHOSTCHANNELCTX *pCtx = (TSMFHOSTCHANNELCTX *)pvChannel; + TSMFHOSTCHCTX *pHostChCtx = (TSMFHOSTCHCTX *)pvChannel; + ConsoleVRDPServer *pThis = pHostChCtx->pThis; + + int rc = pThis->tsmfLock(); + if (RT_SUCCESS(rc)) + { + bool fClose = false; + uint32_t u32ChannelHandle = 0; + + if (pHostChCtx->pVRDPCtx) + { + /* There is still a VRDP context for this channel. */ + pHostChCtx->pVRDPCtx->pHostChCtx = NULL; + u32ChannelHandle = pHostChCtx->pVRDPCtx->u32ChannelHandle; + fClose = true; + } + + pThis->tsmfUnlock(); - pCtx->pThis->m_interfaceTSMF.VRDETSMFChannelClose(pCtx->pThis->mhServer, pCtx->u32ChannelHandle); - /* @todo */ + RTMemFree(pHostChCtx); + + if (fClose) + { + LogFlowFunc(("Closing VRDE channel %d.\n", u32ChannelHandle)); + pThis->m_interfaceTSMF.VRDETSMFChannelClose(pThis->mhServer, u32ChannelHandle); + } + else + { + LogFlowFunc(("No VRDE channel.\n")); + } + } } /* static */ DECLCALLBACK(int) ConsoleVRDPServer::tsmfHostChannelSend(void *pvChannel, const void *pvData, uint32_t cbData) { - LogFlowFunc(("\n")); - TSMFHOSTCHANNELCTX *pCtx = (TSMFHOSTCHANNELCTX *)pvChannel; + LogFlowFunc(("cbData %d\n", cbData)); + + TSMFHOSTCHCTX *pHostChCtx = (TSMFHOSTCHCTX *)pvChannel; + ConsoleVRDPServer *pThis = pHostChCtx->pThis; + + int rc = pThis->tsmfLock(); + if (RT_SUCCESS(rc)) + { + bool fSend = false; + uint32_t u32ChannelHandle = 0; + + if (pHostChCtx->pVRDPCtx) + { + u32ChannelHandle = pHostChCtx->pVRDPCtx->u32ChannelHandle; + fSend = true; + } - int rc = pCtx->pThis->m_interfaceTSMF.VRDETSMFChannelSend(pCtx->pThis->mhServer, pCtx->u32ChannelHandle, - pvData, cbData); + pThis->tsmfUnlock(); + + if (fSend) + { + LogFlowFunc(("Send to VRDE channel %d.\n", u32ChannelHandle)); + rc = pThis->m_interfaceTSMF.VRDETSMFChannelSend(pThis->mhServer, u32ChannelHandle, + pvData, cbData); + } + } return rc; } @@ -2176,32 +2395,38 @@ typedef struct TSMFHOSTCHANNELCTX uint32_t *pcbReceived, uint32_t *pcbRemaining) { - LogFlowFunc(("\n")); - - TSMFHOSTCHANNELCTX *pCtx = (TSMFHOSTCHANNELCTX *)pvChannel; - int rc = VINF_SUCCESS; + LogFlowFunc(("cbData %d\n", cbData)); - uint32_t cbToCopy = RT_MIN(cbData, pCtx->cbDataReceived); - uint32_t cbRemaining = pCtx->cbDataReceived - cbToCopy; + TSMFHOSTCHCTX *pHostChCtx = (TSMFHOSTCHCTX *)pvChannel; + ConsoleVRDPServer *pThis = pHostChCtx->pThis; - LogFlowFunc(("cbToCopy %d, cbRemaining %d\n", cbToCopy, cbRemaining)); - - if (cbToCopy != 0) + int rc = pThis->tsmfLock(); + if (RT_SUCCESS(rc)) { - memcpy(pvData, pCtx->pvDataReceived, cbToCopy); + uint32_t cbToCopy = RT_MIN(cbData, pHostChCtx->cbDataReceived); + uint32_t cbRemaining = pHostChCtx->cbDataReceived - cbToCopy; + + LogFlowFunc(("cbToCopy %d, cbRemaining %d\n", cbToCopy, cbRemaining)); - if (cbRemaining != 0) + if (cbToCopy != 0) { - memmove(pCtx->pvDataReceived, (uint8_t *)pCtx->pvDataReceived + cbToCopy, cbRemaining); + memcpy(pvData, pHostChCtx->pvDataReceived, cbToCopy); + + if (cbRemaining != 0) + { + memmove(pHostChCtx->pvDataReceived, (uint8_t *)pHostChCtx->pvDataReceived + cbToCopy, cbRemaining); + } + + pHostChCtx->cbDataReceived = cbRemaining; } - pCtx->cbDataReceived = cbRemaining; - } + pThis->tsmfUnlock(); - *pcbRemaining = cbRemaining; - *pcbReceived = cbToCopy; + *pcbRemaining = cbRemaining; + *pcbReceived = cbToCopy; + } - return VINF_SUCCESS; + return rc; } /* static */ DECLCALLBACK(int) ConsoleVRDPServer::tsmfHostChannelControl(void *pvChannel, @@ -2212,7 +2437,8 @@ typedef struct TSMFHOSTCHANNELCTX uint32_t cbData, uint32_t *pcbDataReturned) { - LogFlowFunc(("\n")); + LogFlowFunc(("u32Code %u\n", u32Code)); + if (!pvChannel) { /* Special case, the provider must answer rather than a channel instance. */ @@ -2295,33 +2521,44 @@ void ConsoleVRDPServer::setupTSMF(void) const void *pvParm, uint32_t cbParm) { + int rc = VINF_SUCCESS; + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvContext); - TSMFHOSTCHANNELCTX *pCtx = (TSMFHOSTCHANNELCTX *)pvChannel; + TSMFVRDPCTX *pVRDPCtx = (TSMFVRDPCTX *)pvChannel; - Assert(pCtx->pThis == pThis); + Assert(pVRDPCtx->pThis == pThis); - switch(u32Notification) + if (pVRDPCtx->pCallbacks == NULL) + { + LogFlowFunc(("tsmfHostChannel: Channel disconnected. Skipping.\n")); + return; + } + + switch (u32Notification) { case VRDE_TSMF_N_CREATE_ACCEPTED: { VRDETSMFNOTIFYCREATEACCEPTED *p = (VRDETSMFNOTIFYCREATEACCEPTED *)pvParm; Assert(cbParm == sizeof(VRDETSMFNOTIFYCREATEACCEPTED)); - LogFlowFunc(("VRDE_TSMF_N_CREATE_ACCEPTED: p->u32ChannelHandle %d\n", p->u32ChannelHandle)); + LogFlowFunc(("tsmfHostChannel: VRDE_TSMF_N_CREATE_ACCEPTED(%p): p->u32ChannelHandle %d\n", + pVRDPCtx, p->u32ChannelHandle)); - pCtx->u32ChannelHandle = p->u32ChannelHandle; + pVRDPCtx->u32ChannelHandle = p->u32ChannelHandle; - pCtx->pCallbacks->HostChannelCallbackEvent(pCtx->pvCallbacks, pCtx, - VBOX_TSMF_HCH_CREATE_ACCEPTED, - NULL, 0); + pVRDPCtx->pCallbacks->HostChannelCallbackEvent(pVRDPCtx->pvCallbacks, pVRDPCtx->pHostChCtx, + VBOX_TSMF_HCH_CREATE_ACCEPTED, + NULL, 0); } break; case VRDE_TSMF_N_CREATE_DECLINED: { - pCtx->pCallbacks->HostChannelCallbackEvent(pCtx->pvCallbacks, pCtx, - VBOX_TSMF_HCH_CREATE_DECLINED, - NULL, 0); + LogFlowFunc(("tsmfHostChannel: VRDE_TSMF_N_CREATE_DECLINED(%p)\n", pVRDPCtx)); + + pVRDPCtx->pCallbacks->HostChannelCallbackEvent(pVRDPCtx->pvCallbacks, pVRDPCtx->pHostChCtx, + VBOX_TSMF_HCH_CREATE_DECLINED, + NULL, 0); } break; case VRDE_TSMF_N_DATA: @@ -2330,39 +2567,79 @@ void ConsoleVRDPServer::setupTSMF(void) VRDETSMFNOTIFYDATA *p = (VRDETSMFNOTIFYDATA *)pvParm; Assert(cbParm == sizeof(VRDETSMFNOTIFYDATA)); - LogFlowFunc(("VRDE_TSMF_N_DATA: p->cbData %d\n", p->cbData)); + LogFlowFunc(("tsmfHostChannel: VRDE_TSMF_N_DATA(%p): p->cbData %d\n", pVRDPCtx, p->cbData)); - if (pCtx->pvDataReceived) - { - uint32_t cbAlloc = p->cbData + pCtx->cbDataReceived; - pCtx->pvDataReceived = RTMemRealloc(pCtx->pvDataReceived, cbAlloc); - memcpy((uint8_t *)pCtx->pvDataReceived + pCtx->cbDataReceived, p->pvData, p->cbData); + VBOXHOSTCHANNELEVENTRECV ev; + ev.u32SizeAvailable = 0; - pCtx->cbDataReceived += p->cbData; - pCtx->cbDataAllocated = cbAlloc; - } - else + rc = pThis->tsmfLock(); + + if (RT_SUCCESS(rc)) { - pCtx->pvDataReceived = RTMemAlloc(p->cbData); - memcpy(pCtx->pvDataReceived, p->pvData, p->cbData); + TSMFHOSTCHCTX *pHostChCtx = pVRDPCtx->pHostChCtx; - pCtx->cbDataReceived = p->cbData; - pCtx->cbDataAllocated = p->cbData; - } + if (pHostChCtx) + { + if (pHostChCtx->pvDataReceived) + { + uint32_t cbAlloc = p->cbData + pHostChCtx->cbDataReceived; + pHostChCtx->pvDataReceived = RTMemRealloc(pHostChCtx->pvDataReceived, cbAlloc); + memcpy((uint8_t *)pHostChCtx->pvDataReceived + pHostChCtx->cbDataReceived, p->pvData, p->cbData); - VBOXHOSTCHANNELEVENTRECV ev; - ev.u32SizeAvailable = p->cbData; + pHostChCtx->cbDataReceived += p->cbData; + pHostChCtx->cbDataAllocated = cbAlloc; + } + else + { + pHostChCtx->pvDataReceived = RTMemAlloc(p->cbData); + memcpy(pHostChCtx->pvDataReceived, p->pvData, p->cbData); - pCtx->pCallbacks->HostChannelCallbackEvent(pCtx->pvCallbacks, pCtx, - VBOX_HOST_CHANNEL_EVENT_RECV, - &ev, sizeof(ev)); + pHostChCtx->cbDataReceived = p->cbData; + pHostChCtx->cbDataAllocated = p->cbData; + } + + ev.u32SizeAvailable = p->cbData; + } + else + { + LogFlowFunc(("tsmfHostChannel: VRDE_TSMF_N_DATA: no host channel. Skipping\n")); + } + + pThis->tsmfUnlock(); + } + + pVRDPCtx->pCallbacks->HostChannelCallbackEvent(pVRDPCtx->pvCallbacks, pVRDPCtx->pHostChCtx, + VBOX_HOST_CHANNEL_EVENT_RECV, + &ev, sizeof(ev)); } break; case VRDE_TSMF_N_DISCONNECTED: { - pCtx->pCallbacks->HostChannelCallbackEvent(pCtx->pvCallbacks, pCtx, - VBOX_TSMF_HCH_DISCONNECTED, - NULL, 0); + LogFlowFunc(("tsmfHostChannel: VRDE_TSMF_N_DISCONNECTED(%p)\n", pVRDPCtx)); + + pVRDPCtx->pCallbacks->HostChannelCallbackEvent(pVRDPCtx->pvCallbacks, pVRDPCtx->pHostChCtx, + VBOX_TSMF_HCH_DISCONNECTED, + NULL, 0); + + /* The callback context will not be used anymore. */ + pVRDPCtx->pCallbacks->HostChannelCallbackDeleted(pVRDPCtx->pvCallbacks, pVRDPCtx->pHostChCtx); + pVRDPCtx->pCallbacks = NULL; + pVRDPCtx->pvCallbacks = NULL; + + rc = pThis->tsmfLock(); + if (RT_SUCCESS(rc)) + { + if (pVRDPCtx->pHostChCtx) + { + /* There is still a host channel context for this channel. */ + pVRDPCtx->pHostChCtx->pVRDPCtx = NULL; + } + + pThis->tsmfUnlock(); + + RT_ZERO(*pVRDPCtx); + RTMemFree(pVRDPCtx); + } } break; default: @@ -2372,15 +2649,222 @@ void ConsoleVRDPServer::setupTSMF(void) } } +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackVideoInNotify(void *pvCallback, + uint32_t u32Id, + const void *pvData, + uint32_t cbData) +{ + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvCallback); + if (pThis->mEmWebcam) + { + pThis->mEmWebcam->EmWebcamCbNotify(u32Id, pvData, cbData); + } +} + +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackVideoInDeviceDesc(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINDEVICEDESC *pDeviceDesc, + uint32_t cbDevice) +{ + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvCallback); + if (pThis->mEmWebcam) + { + pThis->mEmWebcam->EmWebcamCbDeviceDesc(rcRequest, pDeviceCtx, pvUser, pDeviceDesc, cbDevice); + } +} + +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackVideoInControl(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINCTRLHDR *pControl, + uint32_t cbControl) +{ + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvCallback); + if (pThis->mEmWebcam) + { + pThis->mEmWebcam->EmWebcamCbControl(rcRequest, pDeviceCtx, pvUser, pControl, cbControl); + } +} + +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackVideoInFrame(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + const VRDEVIDEOINPAYLOADHDR *pFrame, + uint32_t cbFrame) +{ + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvCallback); + if (pThis->mEmWebcam) + { + pThis->mEmWebcam->EmWebcamCbFrame(rcRequest, pDeviceCtx, pFrame, cbFrame); + } +} + +int ConsoleVRDPServer::VideoInDeviceAttach(const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, void *pvDeviceCtx) +{ + int rc; + + if (mhServer && mpEntryPoints && m_interfaceVideoIn.VRDEVideoInDeviceAttach) + { + rc = m_interfaceVideoIn.VRDEVideoInDeviceAttach(mhServer, pDeviceHandle, pvDeviceCtx); + } + else + { + rc = VERR_NOT_SUPPORTED; + } + + return rc; +} + +int ConsoleVRDPServer::VideoInDeviceDetach(const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle) +{ + int rc; + + if (mhServer && mpEntryPoints && m_interfaceVideoIn.VRDEVideoInDeviceDetach) + { + rc = m_interfaceVideoIn.VRDEVideoInDeviceDetach(mhServer, pDeviceHandle); + } + else + { + rc = VERR_NOT_SUPPORTED; + } + + return rc; +} + +int ConsoleVRDPServer::VideoInGetDeviceDesc(void *pvUser, const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle) +{ + int rc; + + if (mhServer && mpEntryPoints && m_interfaceVideoIn.VRDEVideoInGetDeviceDesc) + { + rc = m_interfaceVideoIn.VRDEVideoInGetDeviceDesc(mhServer, pvUser, pDeviceHandle); + } + else + { + rc = VERR_NOT_SUPPORTED; + } + + return rc; +} + +int ConsoleVRDPServer::VideoInControl(void *pvUser, const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, + const VRDEVIDEOINCTRLHDR *pReq, uint32_t cbReq) +{ + int rc; + + if (mhServer && mpEntryPoints && m_interfaceVideoIn.VRDEVideoInControl) + { + rc = m_interfaceVideoIn.VRDEVideoInControl(mhServer, pvUser, pDeviceHandle, pReq, cbReq); + } + else + { + rc = VERR_NOT_SUPPORTED; + } + + return rc; +} + + +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackInputSetup(void *pvCallback, + int rcRequest, + uint32_t u32Method, + const void *pvResult, + uint32_t cbResult) +{ + NOREF(pvCallback); + NOREF(rcRequest); + NOREF(u32Method); + NOREF(pvResult); + NOREF(cbResult); +} + +/* static */ DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackInputEvent(void *pvCallback, + uint32_t u32Method, + const void *pvEvent, + uint32_t cbEvent) +{ + ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvCallback); + + if (u32Method == VRDE_INPUT_METHOD_TOUCH) + { + if (cbEvent >= sizeof(VRDEINPUTHEADER)) + { + VRDEINPUTHEADER *pHeader = (VRDEINPUTHEADER *)pvEvent; + + if (pHeader->u16EventId == VRDEINPUT_EVENTID_TOUCH) + { + IMouse *pMouse = pThis->mConsole->getMouse(); + + VRDEINPUT_TOUCH_EVENT_PDU *p = (VRDEINPUT_TOUCH_EVENT_PDU *)pHeader; + + uint16_t iFrame; + for (iFrame = 0; iFrame < p->u16FrameCount; iFrame++) + { + VRDEINPUT_TOUCH_FRAME *pFrame = &p->aFrames[iFrame]; + + com::SafeArray<LONG64> aContacts(pFrame->u16ContactCount); + + uint16_t iContact; + for (iContact = 0; iContact < pFrame->u16ContactCount; iContact++) + { + VRDEINPUT_CONTACT_DATA *pContact = &pFrame->aContacts[iContact]; + + int16_t x = (int16_t)(pContact->i32X + 1); + int16_t y = (int16_t)(pContact->i32Y + 1); + uint8_t contactId = pContact->u8ContactId; + uint8_t contactState = TouchContactState_None; + + if (pContact->u32ContactFlags & VRDEINPUT_CONTACT_FLAG_INRANGE) + { + contactState |= TouchContactState_InRange; + } + if (pContact->u32ContactFlags & VRDEINPUT_CONTACT_FLAG_INCONTACT) + { + contactState |= TouchContactState_InContact; + } + + aContacts[iContact] = RT_MAKE_U64_FROM_U16((uint16_t)x, + (uint16_t)y, + RT_MAKE_U16(contactId, contactState), + 0); + } + + if (pFrame->u64FrameOffset == 0) + { + pThis->mu64TouchInputTimestampMCS = 0; + } + else + { + pThis->mu64TouchInputTimestampMCS += pFrame->u64FrameOffset; + } + + pMouse->PutEventMultiTouch(pFrame->u16ContactCount, + ComSafeArrayAsInParam(aContacts), + (ULONG)(pThis->mu64TouchInputTimestampMCS / 1000)); /* Micro->milliseconds. */ + } + } + else if (pHeader->u16EventId == VRDEINPUT_EVENTID_DISMISS_HOVERING_CONTACT) + { + /* @todo */ + } + else + { + AssertMsgFailed(("EventId %d\n", pHeader->u16EventId)); + } + } + } +} + + void ConsoleVRDPServer::EnableConnections(void) { if (mpEntryPoints && mhServer) { mpEntryPoints->VRDEEnableConnections(mhServer, true); - /* Redirect 3D output if it is enabled. */ - remote3DRedirect(); - /* Setup the generic TSMF channel. */ setupTSMF(); } @@ -2471,6 +2955,11 @@ void ConsoleVRDPServer::Stop(void) { Assert(VALID_PTR(this)); /** @todo r=bird: there are(/was) some odd cases where this buster was invalid on * linux. Just remove this when it's 100% sure that problem has been fixed. */ + +#ifdef VBOX_WITH_USB + remoteUSBThreadStop(); +#endif /* VBOX_WITH_USB */ + if (mhServer) { HVRDESERVER hServer = mhServer; @@ -2478,16 +2967,29 @@ void ConsoleVRDPServer::Stop(void) /* Reset the handle to avoid further calls to the server. */ mhServer = 0; + /* Workaround for VM process hangs on termination. + * + * Make sure that the server is not currently processing a resize. + * mhServer 0 will not allow to enter the server again. + * Wait until any current resize returns from the server. + */ + if (mcInResize) + { + LogRel(("VRDP: waiting for resize %d\n", mcInResize)); + + int i = 0; + while (mcInResize && ++i < 100) + { + RTThreadSleep(10); + } + } + if (mpEntryPoints && hServer) { mpEntryPoints->VRDEDestroy(hServer); } } -#ifdef VBOX_WITH_USB - remoteUSBThreadStop(); -#endif /* VBOX_WITH_USB */ - mpfnAuthEntry = NULL; mpfnAuthEntry2 = NULL; mpfnAuthEntry3 = NULL; @@ -2615,6 +3117,77 @@ void ConsoleVRDPServer::remoteUSBThreadStop(void) } #endif /* VBOX_WITH_USB */ +typedef struct AuthCtx +{ + AuthResult result; + + PAUTHENTRY3 pfnAuthEntry3; + PAUTHENTRY2 pfnAuthEntry2; + PAUTHENTRY pfnAuthEntry; + + const char *pszCaller; + PAUTHUUID pUuid; + AuthGuestJudgement guestJudgement; + const char *pszUser; + const char *pszPassword; + const char *pszDomain; + int fLogon; + unsigned clientId; +} AuthCtx; + +static DECLCALLBACK(int) authThread(RTTHREAD self, void *pvUser) +{ + AuthCtx *pCtx = (AuthCtx *)pvUser; + + if (pCtx->pfnAuthEntry3) + { + pCtx->result = pCtx->pfnAuthEntry3(pCtx->pszCaller, pCtx->pUuid, pCtx->guestJudgement, + pCtx->pszUser, pCtx->pszPassword, pCtx->pszDomain, + pCtx->fLogon, pCtx->clientId); + } + else if (pCtx->pfnAuthEntry2) + { + pCtx->result = pCtx->pfnAuthEntry2(pCtx->pUuid, pCtx->guestJudgement, + pCtx->pszUser, pCtx->pszPassword, pCtx->pszDomain, + pCtx->fLogon, pCtx->clientId); + } + else if (pCtx->pfnAuthEntry) + { + pCtx->result = pCtx->pfnAuthEntry(pCtx->pUuid, pCtx->guestJudgement, + pCtx->pszUser, pCtx->pszPassword, pCtx->pszDomain); + } + return VINF_SUCCESS; +} + +static AuthResult authCall(AuthCtx *pCtx) +{ + AuthResult result = AuthResultAccessDenied; + + /* Use a separate thread because external modules might need a lot of stack space. */ + RTTHREAD thread = NIL_RTTHREAD; + int rc = RTThreadCreate(&thread, authThread, pCtx, 512*_1K, + RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VRDEAuth"); + LogFlow(("authCall: RTThreadCreate %Rrc\n", rc)); + + if (RT_SUCCESS(rc)) + { + rc = RTThreadWait(thread, RT_INDEFINITE_WAIT, NULL); + LogFlow(("authCall: RTThreadWait %Rrc\n", rc)); + } + + if (RT_SUCCESS(rc)) + { + /* Only update the result if the thread finished without errors. */ + result = pCtx->result; + } + else + { + LogRel(("AUTH: unable to execute the auth thread %Rrc\n", rc)); + } + + return result; +} + AuthResult ConsoleVRDPServer::Authenticate(const Guid &uuid, AuthGuestJudgement guestJudgement, const char *pszUser, const char *pszPassword, const char *pszDomain, uint32_t u32ClientId) @@ -2638,7 +3211,7 @@ AuthResult ConsoleVRDPServer::Authenticate(const Guid &uuid, AuthGuestJudgement Utf8Str filename = authLibrary; - LogRel(("AUTH: ConsoleVRDPServer::Authenticate: loading external authentication library '%ls'\n", authLibrary.raw())); + LogRel(("AUTH: loading external authentication library '%ls'\n", authLibrary.raw())); int rc; if (RTPathHavePath(filename.c_str())) @@ -2726,19 +3299,21 @@ AuthResult ConsoleVRDPServer::Authenticate(const Guid &uuid, AuthGuestJudgement Assert(mAuthLibrary && (mpfnAuthEntry || mpfnAuthEntry2 || mpfnAuthEntry3)); - AuthResult result = AuthResultAccessDenied; - if (mpfnAuthEntry3) - { - result = mpfnAuthEntry3("vrde", &rawuuid, guestJudgement, pszUser, pszPassword, pszDomain, true, u32ClientId); - } - else if (mpfnAuthEntry2) - { - result = mpfnAuthEntry2(&rawuuid, guestJudgement, pszUser, pszPassword, pszDomain, true, u32ClientId); - } - else if (mpfnAuthEntry) - { - result = mpfnAuthEntry(&rawuuid, guestJudgement, pszUser, pszPassword, pszDomain); - } + AuthCtx ctx; + ctx.result = AuthResultAccessDenied; /* Denied by default. */ + ctx.pfnAuthEntry3 = mpfnAuthEntry3; + ctx.pfnAuthEntry2 = mpfnAuthEntry2; + ctx.pfnAuthEntry = mpfnAuthEntry; + ctx.pszCaller = "vrde"; + ctx.pUuid = &rawuuid; + ctx.guestJudgement = guestJudgement; + ctx.pszUser = pszUser; + ctx.pszPassword = pszPassword; + ctx.pszDomain = pszDomain; + ctx.fLogon = true; + ctx.clientId = u32ClientId; + + AuthResult result = authCall(&ctx); switch (result) { @@ -2772,10 +3347,21 @@ void ConsoleVRDPServer::AuthDisconnect(const Guid &uuid, uint32_t u32ClientId) Assert(mAuthLibrary && (mpfnAuthEntry || mpfnAuthEntry2 || mpfnAuthEntry3)); - if (mpfnAuthEntry3) - mpfnAuthEntry3("vrde", &rawuuid, AuthGuestNotAsked, NULL, NULL, NULL, false, u32ClientId); - else if (mpfnAuthEntry2) - mpfnAuthEntry2(&rawuuid, AuthGuestNotAsked, NULL, NULL, NULL, false, u32ClientId); + AuthCtx ctx; + ctx.result = AuthResultAccessDenied; /* Not used. */ + ctx.pfnAuthEntry3 = mpfnAuthEntry3; + ctx.pfnAuthEntry2 = mpfnAuthEntry2; + ctx.pfnAuthEntry = NULL; /* Does not use disconnect notification. */ + ctx.pszCaller = "vrde"; + ctx.pUuid = &rawuuid; + ctx.guestJudgement = AuthGuestNotAsked; + ctx.pszUser = NULL; + ctx.pszPassword = NULL; + ctx.pszDomain = NULL; + ctx.fLogon = false; + ctx.clientId = u32ClientId; + + authCall(&ctx); } int ConsoleVRDPServer::lockConsoleVRDPServer(void) @@ -3210,11 +3796,13 @@ void ConsoleVRDPServer::SendUpdate(unsigned uScreenId, void *pvUpdate, uint32_t } } -void ConsoleVRDPServer::SendResize(void) const +void ConsoleVRDPServer::SendResize(void) { if (mpEntryPoints && mhServer) { + ++mcInResize; mpEntryPoints->VRDEResize(mhServer); + --mcInResize; } } @@ -3297,24 +3885,6 @@ void ConsoleVRDPServer::SendAudioInputEnd(void *pvUserCtx) } } -#ifdef VBOX_WITH_USB_VIDEO -int ConsoleVRDPServer::GetVideoFrameDimensions(uint16_t *pu16Heigh, uint16_t *pu16Width) -{ - *pu16Heigh = 640; - *pu16Width = 480; - return VINF_SUCCESS; -} - -int ConsoleVRDPServer::SendVideoSreamOn(bool fFetch) -{ - /* Here we inform server that guest is starting/stopping - * the stream - */ - return VINF_SUCCESS; -} -#endif - - void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const { |