vboxhgcm.c revision f3f69e0e8d6a713566e129aa3ab321b1e6b07fbc
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * VBox HGCM connection
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * Copyright (C) 2008-2012 Oracle Corporation
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * available from http://www.virtualbox.org. This file is free software;
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * you can redistribute it and/or modify it under the terms of the GNU
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * General Public License (GPL) as published by the Free Software
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
fe02cc356f7bd01a7ffbcd6ceb8ca09bb1c35330vboxsync#if 1 /** @todo Try use the Vbgl interface instead of talking directly to the driver? */
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
#ifdef DEBUG_misha
#ifdef CRASSERT
#ifdef VBOX_WITH_CRHGSMIPROFILE
#include <stdio.h>
typedef struct VBOXCRHGSMIPROFILE
typedef struct VBOXCRHGSMIPROFILE_SCOPE
#ifdef VBOX_WITH_CRHGSMI
#define VBOXCRHGSMIPROFILE_TERM() do {} while (0)
#define VBOXCRHGSMIPROFILE_FUNC_PROLOGUE() \
#define VBOXCRHGSMIPROFILE_FUNC_EPILOGUE() \
#define VBOXCRHGSMIPROFILE_INIT() do {} while (0)
#define VBOXCRHGSMIPROFILE_TERM() do {} while (0)
#define VBOXCRHGSMIPROFILE_FUNC_PROLOGUE() do {} while (0)
#define VBOXCRHGSMIPROFILE_FUNC_EPILOGUE() do {} while (0)
int initialized;
int num_conns;
#ifdef CHROMIUM_THREADSAFE
#ifdef RT_OS_WINDOWS
int iGuestDrv;
bool bHgsmiOn;
typedef struct CRVBOXHGCMBUFFER {
#ifndef RT_OS_WINDOWS
#define TRUE true
#define FALSE false
int rc;
return VINF_SUCCESS;
return rc;
if (ppHgsmi)
return VINF_SUCCESS;
#ifdef VBOX_CRHGSMI_WITH_D3DDEV
if (pClient)
return NULL;
#ifdef VBOX_CRHGSMI_WITH_D3DDEV
return pClient;
if (pHgsmi)
return NULL;
int rc;
if (!buf)
cbSize);
return buf;
int rc;
return NULL;
return pBuf;
int rc;
return pHdr;
return NULL;
int rc;
return pHdr;
int rc;
return rc;
return rc;
return NULL;
int rc;
return NULL;
DECLINLINE(void) _crVBoxHGSMIFillCmd(VBOXUHGSMI_BUFFER_SUBMIT *pSubm, PCRVBOXHGSMI_CLIENT pClient, uint32_t cbData)
#ifndef IN_GUEST
return FALSE;
return TRUE;
crDebug("Host buffer too small %d out of requested %d bytes, reallocating", conn->cbHostBufferAllocated, len);
return FALSE;
return TRUE;
#ifdef IN_GUEST
# if defined(VBOX_WITH_CRHGSMI)
if (pClient)
# ifdef RT_OS_WINDOWS
NULL))
return VINF_SUCCESS;
/*On windows if we exceed max buffer len, we only get ERROR_GEN_FAILURE, and parms.hdr.result isn't changed.
return VERR_OUT_OF_RANGE;
return VERR_NOT_SUPPORTED;
int rc;
# ifdef RT_OS_LINUX
if (rc == 0)
if (rc >= 0)
return VINF_SUCCESS;
# ifdef RT_OS_LINUX
if (rc==0)
return VINF_SUCCESS;
return -rc;
return VERR_NOT_SUPPORTED;
return VERR_NOT_SUPPORTED;
#ifdef CHROMIUM_THREADSAFE
if (!buf)
if (!buf)
#ifdef CHROMIUM_THREADSAFE
void *pvBuff;
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
return pvBuff;
int rc;
#ifdef IN_GUEST
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
int rc;
crVBoxHGCMWriteReadExact(CRConnection *conn, const void *buf, unsigned int len, CRVBOXHGCMBUFFERKIND bufferKind)
int rc;
crDebug("SHCRGL_GUEST_FN_WRITE_BUFFER, offset=%u, size=%u", wbParms.ui32Offset.u.value32, wbParms.pBuffer.u.Pointer.size);
crError("SHCRGL_GUEST_FN_WRITE_BUFFER (%i) failed with %x %x\n", wbParms.pBuffer.u.Pointer.size, rc, wbParms.hdr.result);
crDebug("Reallocating host buffer from %d to %d bytes", conn->cbHostBufferAllocated, parms.cbWriteback.u.value32);
#ifdef CHROMIUM_THREADSAFE
#ifndef IN_GUEST
#ifdef CHROMIUM_THREADSAFE
#ifdef IN_GUEST
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
int rc;
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
case CR_VBOXHGCM_MEMORY:
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
case CR_VBOXHGCM_MEMORY_BIG:
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
#ifndef IN_GUEST
#ifndef IN_GUEST
/* CR_MESSAGE_OPCODES is freed in crserverlib/server_stream.c with crNetFree.
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
#ifdef IN_GUEST
int rc;
crWarning("Host doesn't accept our version %d.%d. Make sure you have appropriate additions installed!",
return FALSE;
return TRUE;
int rc;
return FALSE;
return TRUE;
#ifdef IN_GUEST
#ifdef RT_OS_WINDOWS
NULL,
NULL);
return FALSE;
return FALSE;
#ifdef RT_OS_WINDOWS
NULL))
int rc;
if (!rc)
return rc;
#ifdef RT_OS_WINDOWS
return rc;
return FALSE;
#ifdef RT_OS_WINDOWS
return FALSE;
return TRUE;
return FALSE;
#ifdef IN_GUEST
# ifdef RT_OS_WINDOWS
bool fHasActiveCons = false;
#ifdef CHROMIUM_THREADSAFE
#ifndef IN_GUEST
# ifdef RT_OS_WINDOWS
NULL) )
if (!fHasActiveCons)
# ifdef RT_OS_WINDOWS
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
bool _crVBoxHGSMIInit()
#ifndef VBOX_CRHGSMI_WITH_D3DDEV
if (bHasHGSMI < 0)
int rc;
#ifndef VBOX_CRHGSMI_WITH_D3DDEV
bHasHGSMI = 0;
return bHasHGSMI;
void _crVBoxHGSMITearDown()
int rc;
if (buf)
crWarning("_crVBoxHGSMIBufAlloc failed to allocate buffer of size (%d)", CRVBOXHGSMI_BUF_SIZE(cbSize));
void *pvBuf;
#ifdef CHROMIUM_THREADSAFE
if (pClient)
#ifdef CHROMIUM_THREADSAFE
return pvBuf;
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
int rc;
if (!pRecvBuffer)
if (!parms)
cbBuffer = 0;
if (cbBuffer)
if (pvData)
_crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void *buf, uint32_t offBuffer, unsigned int len, bool bIsBuffer)
CRVBOXHGSMIWRITEREAD *parms = (CRVBOXHGSMIWRITEREAD*)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
int rc;
if (!bIsBuffer)
void *pvBuf;
if (!pBuf)
offBuffer = 0;
if (!pRecvBuffer)
if (parms)
#ifdef DEBUG
if (cbWriteback)
if (pvData)
rc = pClient->pHgsmi->pfnBufferCreate(pClient->pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(cbWriteback), Flags, &pNewBuf);
crWarning("_crVBoxHGSMIWriteReadExact: pfnBufferCreate(%d) failed!", CRVBOXHGSMI_PAGE_ALIGN(cbWriteback));
if (!bIsBuffer)
static void _crVBoxHGSMIWriteExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, PVBOXUHGSMI_BUFFER pBuf, uint32_t offStart, unsigned int len)
int rc;
#ifdef IN_GUEST
CRVBOXHGSMIINJECT *parms = (CRVBOXHGSMIINJECT *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
if (!parms)
CRVBOXHGSMIWRITE * parms = (CRVBOXHGSMIWRITE *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));;
#ifdef CHROMIUM_THREADSAFE
if (pClient)
#ifndef IN_GUEST
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
if (!pBuf)
#ifdef CHROMIUM_THREADSAFE
#ifdef IN_GUEST
_crVBoxHGSMIWriteExact(conn, pClient, pBuf, CRVBOXHGSMI_BUF_OFFSET(start, *bufp) + CRVBOXHGSMI_BUF_HDR_SIZE(), len);
_crVBoxHGSMIWriteReadExact(conn, pClient, pBuf, CRVBOXHGSMI_BUF_OFFSET(start, *bufp) + CRVBOXHGSMI_BUF_HDR_SIZE(), len, true);
#ifdef CHROMIUM_THREADSAFE
CRASSERT(0);
CRASSERT(0);
#ifdef CHROMIUM_THREADSAFE
CRASSERT(0);
#ifdef CHROMIUM_THREADSAFE
CRASSERT(0);
#ifdef IN_GUEST
#ifdef CHROMIUM_THREADSAFE
if (pClient)
#ifdef CHROMIUM_THREADSAFE
bool fHasActiveCons = false;
#ifdef CHROMIUM_THREADSAFE
#ifndef VBOX_CRHGSMI_WITH_D3DDEV
#ifdef CHROMIUM_THREADSAFE
#ifdef CHROMIUM_THREADSAFE
CRASSERT(0);
#ifdef CHROMIUM_THREADSAFE
CRASSERT(0);
(void) mtu;
#ifdef RT_OS_WINDOWS
#ifdef CHROMIUM_THREADSAFE
case CR_VBOXHGCM_MEMORY:
case CR_VBOXHGCM_MEMORY_BIG:
void crVBoxHGCMTearDown(void)
#ifdef CHROMIUM_THREADSAFE
/* Connection count would be changed in calls to crNetDisconnect, so we have to store original value.
* Walking array backwards is not a good idea as it could cause some issues if we'd disconnect clients not in the
for (i=0; i<cCons; i++)
/* Note that [0] is intended, as the connections array would be shifted in each call to crNetDisconnect */
#ifdef CHROMIUM_THREADSAFE
#ifdef RT_OS_WINDOWS
int i, found = 0;
int n_bytes;
#if !defined(IN_GUEST)
#ifdef CHROMIUM_THREADSAFE
if (found == 0) {
#ifdef CHROMIUM_THREADSAFE
#if defined(IN_GUEST)
int crVBoxHGCMRecv(
int32_t i;
#ifdef CHROMIUM_THREADSAFE
#ifdef IN_GUEST
if ( !conn )
if ( !conn )
#ifdef CHROMIUM_THREADSAFE