HGCMInternal.cpp revision 0c88062033e31a82f230397ded75f2627b1132eb
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync/* $Revision$ */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * VBoxGuestLib - Host-Guest Communication Manager internal functions, implemented by VBoxGuest
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * Copyright (C) 2006-2007 Oracle Corporation
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * available from http://www.virtualbox.org. This file is free software;
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * General Public License (GPL) as published by the Free Software
9496b6f77d66eb89f088668752b8838d578d6e10vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * The contents of this file may alternatively be used under the terms
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * of the Common Development and Distribution License Version 1.0
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * CDDL are applicable instead of those of the GPL.
4b9d6701570cb98fd36e209314239d104ec584d3vboxsync * You may elect to license modified versions of this file under the
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * terms and conditions of either the GPL or the CDDL or both.
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync/* Entire file is ifdef'ed with VBGL_VBOXGUEST */
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync/*******************************************************************************
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync* Header Files *
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync*******************************************************************************/
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync/*******************************************************************************
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync* Defined Constants And Macros *
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync*******************************************************************************/
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync/** The max parameter buffer size for a user request. */
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync/** The max parameter buffer size for a kernel request. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync/** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted
95714accc37694e6f4ae3c646dd01f3827c3d260vboxsync * side effects. */
b0a3d0ec5780199a2f379da63c59ccf48f1a73b9vboxsync/*******************************************************************************
b0a3d0ec5780199a2f379da63c59ccf48f1a73b9vboxsync* Structures and Typedefs *
b0a3d0ec5780199a2f379da63c59ccf48f1a73b9vboxsync*******************************************************************************/
b0a3d0ec5780199a2f379da63c59ccf48f1a73b9vboxsync * Lock info structure used by VbglR0HGCMInternalCall and its helpers.
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync/* These functions can be only used by VBoxGuest. */
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsyncDECLVBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync /* Allocate request */
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync /* Initialize request memory */
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
0c8b774aca1168c2007424a49f6fa159fc23e42bvboxsync /* Issue request */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /* Check if host decides to process the request asynchronously. */
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync /* Wait for request completion interrupt notification from host */
41e3b5da61b49017cb647f2f32a231c524fc370avboxsync pfnAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync pConnectInfo->result = pHGCMConnect->header.result;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsyncDECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync /* Allocate request */
907ba2c9b3d1821f95be17115ecad9fe8a2cae02vboxsync rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync /* Initialize request memory */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
f6cc81e94c29cc9b39b896cf32ecfe0501b4a1e5vboxsync /* Issue request */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync rc = VbglGRPerform (&pHGCMDisconnect->header.header);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync /* Check if host decides to process the request asynchronously. */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync /* Wait for request completion interrupt notification from host */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pfnAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pDisconnectInfo->result = pHGCMDisconnect->header.result;
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync * Preprocesses the HGCM call, validating and locking/buffering parameters.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * @returns VBox status code.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * @param pCallInfo The call info.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * @param cbCallInfo The size of the call info structure.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * @param fIsUser Is it a user request or kernel request.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * @param pcbExtra Where to return the extra request space needed for
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * physical page lists.
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsyncstatic int vbglR0HGCMInternalPreprocessCall(VBoxGuestHGCMCallInfo const *pCallInfo, uint32_t cbCallInfo,
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync bool fIsUser, struct VbglR0ParmInfo *pParmInfo, size_t *pcbExtra)
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync HGCMFunctionParameter const *pSrcParm = VBOXGUEST_HGCM_CALL_PARMS(pCallInfo);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync * Lock down the any linear buffers so we can get their addresses
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync * and figure out how much extra storage we need for page lists.
9c59bcefe2993070fafaf0d6cee9673f48479128vboxsync * Note! With kernel mode users we can be assertive. For user mode users
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync * we should just (debug) log it and fail without any fanfare.
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync for (iParm = 0; iParm < cParms; iParm++, pSrcParm++)
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync Log4(("GstHGCMCall: parm=%u type=32bit: %#010x\n", iParm, pSrcParm->u.value32));
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync Log4(("GstHGCMCall: parm=%u type=64bit: %#018x\n", iParm, pSrcParm->u.value64));
62e5c2cfabb91397405d7bfe7908ec2b3a483831vboxsync AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync AssertMsgReturn( off >= pCallInfo->cParms * sizeof(HGCMFunctionParameter)
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync ("offset=%#x cParms=%#x cbCallInfo=%#x\n", off, pCallInfo->cParms, cbCallInfo),
2c18e977ea3600677b8c58c9de0caa61792ba428vboxsync pPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + off);
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync u32 = RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]) + off;
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync ("u32=%#x (cPages=%#x offset=%#x) cbCallInfo=%#x\n", u32, cPages, off, cbCallInfo),
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync AssertMsgReturn(pPgLst->offFirstPage < PAGE_SIZE, ("#x\n", pPgLst->offFirstPage), VERR_INVALID_PARAMETER);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync u32 = RT_ALIGN_32(pPgLst->offFirstPage + cb, PAGE_SIZE) >> PAGE_SHIFT;
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync AssertMsgReturn(cPages == u32, ("cPages=%#x u32=%#x\n", cPages, u32), VERR_INVALID_PARAMETER);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync AssertMsgReturn(VBOX_HGCM_F_PARM_ARE_VALID(pPgLst->flags), ("%#x\n", pPgLst->flags), VERR_INVALID_PARAMETER);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync Log4(("GstHGCMCall: parm=%u type=pglst: cb=%#010x cPgs=%u offPg0=%#x flags=%#x\n",
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync iParm, cb, cPages, pPgLst->offFirstPage, pPgLst->flags));
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync while (u32-- > 0)
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync Log4(("GstHGCMCall: pg#%u=%RHp\n", u32, pPgLst->aPages[u32]));
01f38d7bedc71f105edc6e67f8cbb9a0bf325442vboxsync AssertMsgReturn(!(pPgLst->aPages[u32] & (PAGE_OFFSET_MASK | UINT64_C(0xfff0000000000000))),
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync *pcbExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[pPgLst->cPages]);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync Log4(("GstHGCMCall: parm=%u type=pglst: cb=0\n", iParm));
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync Log4(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p\n",
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr));
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync /* fall thru */
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync uint32_t fAccess = pSrcParm->type == VMMDevHGCMParmType_LinAddr_In
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync || pSrcParm->type == VMMDevHGCMParmType_LinAddr_Locked_In
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync AssertReturn(iLockBuf < RT_ELEMENTS(pParmInfo->aLockBufs), VERR_INVALID_PARAMETER);
693d9f3305eb4a4684a6613b8a41a6fa150cc101vboxsync AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
933606e7609b250f207a2f97112f8388f88998c1vboxsync rc = RTR0MemObjLockKernel(&hObj, (void *)pSrcParm->u.Pointer.u.linearAddr, cb, fAccess);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockKernel(,%p,%#x) -> %Rrc\n",
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked kernel -> %p\n",
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync Log(("GstHGCMCall: id=%#x fn=%u parm=%u pv=%p cb=%#x > %#x -> out of range\n",
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr,
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync rc = RTR0MemObjLockUser(&hObj, (RTR3PTR)pSrcParm->u.Pointer.u.linearAddr, cb, fAccess, NIL_RTR0PROCESS);
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockUser(,%p,%#x,nil) -> %Rrc\n",
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked user -> %p\n",
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
5f9ec43969b9ba00f6c2d03bafc9ac36a41c95e1vboxsync#else /* USE_BOUNCE_BUFFERS */
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync * This is a bit massive, but we don't want to waste a
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync * whole page for a 3 byte string buffer (guest props).
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync * The threshold is ASSUMING sizeof(RTMEMHDR) == 16 and
9ced981a0263f6280ccbf5dc64c0e81fbe4a2fdavboxsync * the system is using some power of two allocator.
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync /** @todo A more efficient strategy would be to combine buffers. However it
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync * is probably going to be more massive than the current code, so
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync * it can wait till later. */
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync bool fCopyIn = pSrcParm->type != VMMDevHGCMParmType_LinAddr_Out
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync && pSrcParm->type != VMMDevHGCMParmType_LinAddr_Locked_Out;
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync pvSmallBuf = fCopyIn ? RTMemTmpAlloc(cb) : RTMemTmpAllocZ(cb);
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync rc = RTR0MemUserCopyFrom(pvSmallBuf, pSrcParm->u.Pointer.u.linearAddr, cb);
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync pCallInfo->u32ClientID, pCallInfo->u32Function, iParm,
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync rc = RTR0MemObjLockKernel(&hObj, pvSmallBuf, cb, fAccess);
1826861f34e9be70b29cd5e1a6038caf9fbf37bevboxsync Log(("GstHGCMCall: RTR0MemObjLockKernel failed for small buffer: rc=%Rrc pvSmallBuf=%p cb=%#x\n",
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p small buffer %p -> %p\n",
674c51d0cb8c72a2852b315b70f76d11d82b20f5vboxsync iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, pvSmallBuf, hObj));
e12a6ea07ddb7a02b3575e78b24960e13f42bf4cvboxsync rc = RTR0MemObjAllocPage(&hObj, cb, false /*fExecutable*/);
53e1c27c7564c45ad0b92676ddea561591a3e869vboxsync rc = RTR0MemUserCopyFrom(RTR0MemObjAddress(hObj), pSrcParm->u.Pointer.u.linearAddr, cb);
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
77c85c820fe4467a0856134e0c9e5c5790cd847evboxsync pCallInfo->u32ClientID, pCallInfo->u32Function, iParm,
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p big buffer -> %p\n",
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync#endif /* USE_BOUNCE_BUFFERS */
9b5e4e8f5c00e8cd2289a73d173c96e551c79397vboxsync pParmInfo->aLockBufs[iLockBuf].pvSmallBuf = pvSmallBuf;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync size_t const cPages = RTR0MemObjSize(hObj) >> PAGE_SHIFT;
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync *pcbExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]);
f2ba84c335a6e7ac91f69863ff51b10c65c9d40fvboxsync Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * Translates locked linear address to the normal type.
static HGCMFunctionParameterType vbglR0HGCMInternalConvertLinAddrType(HGCMFunctionParameterType enmType)
switch (enmType)
return VMMDevHGCMParmType_LinAddr_In;
return VMMDevHGCMParmType_LinAddr_Out;
return VMMDevHGCMParmType_LinAddr;
return enmType;
switch (enmType)
default: AssertFailed();
return VBOX_HGCM_F_PARM_DIRECTION_BOTH;
static void vbglR0HGCMInternalInitCall(VMMDevHGCMCall *pHGCMCall, VBoxGuestHGCMCallInfo const *pCallInfo,
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
HGCMPageListInfo const *pSrcPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + pSrcParm->u.PageList.offset);
if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
#ifdef USE_BOUNCE_BUFFERS
#ifdef USE_BOUNCE_BUFFERS
if (fIsUser)
#ifdef USE_BOUNCE_BUFFERS
if (fIsUser)
iLockBuf++;
AssertFailed();
static int vbglR0HGCMInternalDoCall(VMMDevHGCMCall *pHGCMCall, PFNVBGLHGCMCALLBACK pfnAsyncCallback,
int rc;
*pfLeakIt = false;
int rc2 = VbglGRAlloc((VMMDevRequestHeader **)&pCancelReq, sizeof(*pCancelReq), VMMDevReq_HGCMCancel2);
if (RT_SUCCESS(rc)) rc = VERR_INTERRUPTED; /** @todo weed this out from the WINNT VBoxGuest code. */
static unsigned s_cErrors = 0;
LogRel(("vbglR0HGCMInternalDoCall: Leaking %u bytes. Pending call to %u with %u parms. (rc2=%Rrc)\n",
*pfLeakIt = true;
Log(("vbglR0HGCMInternalDoCall: Cancel race ended with rc=%Rrc (rc2=%Rrc) after %llu ms\n", rc, rc2, cElapsed));
return rc;
static int vbglR0HGCMInternalCopyBackResult(VBoxGuestHGCMCallInfo *pCallInfo, VMMDevHGCMCall const *pHGCMCall,
#ifdef USE_BOUNCE_BUFFERS
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
#ifdef USE_BOUNCE_BUFFERS
if ( fIsUser
iLockBuf++;
if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
#ifdef USE_BOUNCE_BUFFERS
if (fIsUser)
if (cbOut)
int rc2;
cbOut);
return rc2;
iLockBuf++;
iLockBuf++;
AssertFailed();
#ifdef USE_BOUNCE_BUFFERS
return rc;
DECLR0VBGL(int) VbglR0HGCMInternalCall(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
int rc;
|| !pfnAsyncCallback
pCallInfo->u32ClientID, pCallInfo->u32ClientID, pCallInfo->u32Function, pCallInfo->cParms, cbCallInfo, fFlags));
bool fLeakIt;
static unsigned s_cErrors = 0;
if (!fLeakIt)
#ifdef USE_BOUNCE_BUFFERS
return rc;
DECLR0VBGL(int) VbglR0HGCMInternalCall32(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
|| !pfnAsyncCallback
Log(("VbglR0HGCMInternalCall32: cParms=%d, u32Function=%d, fFlags=%#x\n", cParms, pCallInfo->u32Function, fFlags));
pCallInfo64 = (VBoxGuestHGCMCallInfo *)RTMemTmpAllocZ(sizeof(*pCallInfo64) + cParms * sizeof(HGCMFunctionParameter));
if (!pCallInfo64)
return VERR_NO_TMP_MEMORY;
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
rc = VbglR0HGCMInternalCall(pCallInfo64, sizeof(*pCallInfo64) + cParms * sizeof(HGCMFunctionParameter), fFlags,
case VMMDevHGCMParmType_32bit:
case VMMDevHGCMParmType_64bit:
static unsigned s_cErrors = 0;
static unsigned s_cErrors = 0;
return rc;