VBoxGuest.cpp revision f5fc6d91e150cd61b1758c89b31d915270134385
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VBoxGuest - Guest Additions Driver, Common Code.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Copyright (C) 2007-2015 Oracle Corporation
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * available from http://www.virtualbox.org. This file is free software;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * General Public License (GPL) as published by the Free Software
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * The contents of this file may alternatively be used under the terms
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * of the Common Development and Distribution License Version 1.0
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * VirtualBox OSE distribution, in which case the provisions of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * CDDL are applicable instead of those of the GPL.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * You may elect to license modified versions of this file under the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * terms and conditions of either the GPL or the CDDL or both.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Header Files *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Defined Constants And Macros *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#define VBOXGUEST_ACQUIRE_STYLE_EVENTS (VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Structures and Typedefs *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/** Host flags to be updated by a given invocation of the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * vboxGuestUpdateHostFlags() method. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/** @todo r=bird: Use RT_BIT_32 for the bits, preferably replace enum with
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * \#define. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Internal Functions *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic DECLCALLBACK(int) vbgdHgcmAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdIoCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic void vbgdBitUsageTrackerClear(PVBOXGUESTBITUSAGETRACER pTracker);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic uint32_t vbgdGetAllowedEventMaskForSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdResetEventFilterOnHost(PVBOXGUESTDEVEXT pDevExt, uint32_t fFixedEvents);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdResetMouseStatusOnHost(PVBOXGUESTDEVEXT pDevExt);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdResetCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdSetSessionEventFilter(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdSetSessionMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint32_t fOrMask, uint32_t fNoMask, bool fSessionTermination);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdAcquireSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags, bool fSessionTermination);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int vbgdDispatchEventsLocked(PVBOXGUESTDEVEXT pDevExt, uint32_t fEvents);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync* Global Variables *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync*******************************************************************************/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic const uint32_t g_cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Drag in the rest of IRPT since we share it with the
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * rest of the kernel modules on Solaris.
2b3dc93fedb4e72ac5b3cbaa89a9fc2f559be550vboxsync /* VirtioNet */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* RTSemMutex* */
int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevReqHypervisorInfo), VMMDevReq_GetHypervisorInfo);
return rc;
return rc;
bool fBitched = false;
rc = RTR0MemObjEnterPhys(&hObj, VBOXGUEST_HYPERVISOR_PHYSICAL_START, cbHypervisor + _4M, RTMEM_CACHE_POLICY_DONT_CARE);
rc = RTR0MemObjMapKernel(&hObj, hFictive, (void *)-1, uAlignment, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
rc = RTR0MemObjMapKernel(&hObj, hFictive, (void *)-1, uAlignment, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
LogRel(("VBoxGuest: Failed to reserve memory for the hypervisor: rc=%Rrc (cbHypervisor=%#x uAlignment=%#x iTry=%u)\n",
fBitched = true;
AssertMsg(RT_ALIGN_32(pReq->hypervisorStart, _4M) == pReq->hypervisorStart, ("%#x\n", pReq->hypervisorStart));
while (iTry-- > 0)
LogRel(("VBoxGuest: Warning: failed to reserve %#d of memory for guest mappings.\n", cbHypervisor));
return VINF_SUCCESS;
int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevReqHypervisorInfo), VMMDevReq_SetHypervisorInfo);
int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReqInfo2, sizeof (VMMDevReportGuestInfo2), VMMDevReq_ReportGuestInfo2);
rc = VbglGRAlloc((VMMDevRequestHeader **)&pReqInfo1, sizeof (VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo);
return rc;
Log(("vbgdReportDriverStatus: VbglGRPerform VMMDevReportGuestStatus completed with fActive=%d, rc=%Rrc\n",
return rc;
int rc;
return rc;
int rc;
return rc;
return rc;
return VINF_SUCCESS;
static int vbgdSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks, uint32_t *pfHandleInR3)
uint32_t i;
return VERR_INVALID_PARAMETER;
pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
return VERR_NO_MEMORY;
rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
return rc;
return rc;
static int vbgdSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint64_t u64ChunkAddr, bool fInflate)
uint32_t i;
if (fInflate)
return VERR_INVALID_PARAMETER;
pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
return VERR_NO_MEMORY;
return VERR_INVALID_PARAMETER;
if ( fInflate
&& !pMemObj
if (fInflate)
if (!pMemObj)
if (fInflate)
return VERR_NO_MEMORY;
return VERR_NOT_FOUND;
rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
return rc;
if (fInflate)
return rc;
int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, g_cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
uint32_t i;
LogRel(("vbgdCloseMemBalloon: Failed to allocate VMMDev request buffer (rc=%Rrc). Will leak %u chunks.\n",
int rc;
return rc;
int rc;
Log(("vbgdHeartbeatHostConfigure: VbglGRAlloc vbgdHeartbeatHostConfigure completed with rc=%Rrc\n", rc));
Log(("vbgdHeartbeatHostConfigure: VbglGRPerform vbgdHeartbeatHostConfigure completed with rc=%Rrc\n", rc));
return rc;
rc = VbglGRAlloc(&pDevExt->pReqGuestHeartbeat, sizeof(*pDevExt->pReqGuestHeartbeat), VMMDevReq_GuestHeartbeat);
return VINF_SUCCESS;
return rc;
Log(("VbgdCommonReinitDevExtAfterHibernation: could not report guest driver status, rc=%Rrc\n", rc));
Log(("VbgdCommonReinitDevExtAfterHibernation: could not report guest information to host, rc=%Rrc\n", rc));
return rc;
rc = RTLogCreate(&pRelLogger, 0 /*fFlags*/, "all", "VBOXGUEST_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
#ifdef VBOX_WITH_HGCM
#ifdef VBOX_WITH_HGCM
if (pvMMIOBase)
LogRel(("VbgdCommonInitDevExt: Bogus VMMDev memory; u32Version=%RX32 (expected %RX32) u32Size=%RX32 (expected <= %RX32)\n",
rc = RTSpinlockCreate(&pDevExt->SessionSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestSession");
return rc;
return rc;
rc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->pIrqAckEvents, sizeof(VMMDevEvents), VMMDevReq_AcknowledgeEvents);
return VINF_SUCCESS;
int rc2;
int rc2;
#ifdef VBOX_WITH_HGCM
return VERR_NO_MEMORY;
pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
return VINF_SUCCESS;
return VERR_NO_MEMORY;
pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
return VINF_SUCCESS;
#ifdef VBOX_WITH_HGCM
pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
vbgdSetSessionCapabilities(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
vbgdSetSessionEventFilter(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
vbgdSetSessionMouseStatus(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/);
#ifdef VBOX_WITH_HGCM
if (pWait)
if (pWait)
if (!pWait)
int rc;
if (!pWait)
return NULL;
return NULL;
#ifdef VBOX_WITH_HGCM
return pWait;
#ifdef VBOX_WITH_HGCM
int rc;
if (!pWait)
LogFlow(("VbgdCommonIoCtlFast: iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession));
return VERR_NOT_SUPPORTED;
static int vbgdIoCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGuestPortInfo *pInfo, size_t *pcbDataReturned)
if (pcbDataReturned)
return VINF_SUCCESS;
#ifndef RT_OS_WINDOWS
int vbgdIoCtl_SetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGuestMouseSetNotifyCallback *pNotify)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_TIMEOUT;
int iEvent;
int rc;
if (pcbDataReturned)
return VERR_INVALID_PARAMETER;
return rc;
return VERR_TIMEOUT;
if (!pWait)
return VERR_NO_MEMORY;
return rc;
if (fInterruptible)
return rc;
if ( fResEvents
return rc;
int rc = 0;
bool fCancelledOne = false;
fCancelledOne = true;
if (!fCancelledOne)
return VINF_SUCCESS;
static int vbgdCheckIfVmmReqIsAllowed(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
kLevel_Invalid, kLevel_NoOne, kLevel_OnlyVBoxGuest, kLevel_OnlyKernel, kLevel_TrustedUsers, kLevel_AllUsers
} enmRequired;
switch (enmType)
#ifdef VBOX_WITH_HGCM
case VMMDevReq_HGCMConnect:
case VMMDevReq_HGCMDisconnect:
# ifdef VBOX_WITH_64_BITS_GUESTS
case VMMDevReq_HGCMCall32:
case VMMDevReq_HGCMCall64:
case VMMDevReq_HGCMCall:
case VMMDevReq_HGCMCancel:
case VMMDevReq_HGCMCancel2:
case VMMDevReq_WriteCoreDump:
case VMMDevReq_GetMouseStatus:
case VMMDevReq_SetMouseStatus:
case VMMDevReq_GetHostVersion:
case VMMDevReq_Idle:
case VMMDevReq_GetHostTime:
case VMMDevReq_SetPowerStatus:
case VMMDevReq_LogString:
case VMMDevReq_GetSessionId:
switch (enmRequired)
case kLevel_NoOne:
case kLevel_OnlyVBoxGuest:
case kLevel_OnlyKernel:
return VINF_SUCCESS;
case kLevel_TrustedUsers:
case kLevel_AllUsers:
return VINF_SUCCESS;
return VERR_PERMISSION_DENIED;
int rc;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
Log(("VbgdCommonIoCtl: VMMREQUEST: invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc=%Rrc!!\n",
return rc;
return rc;
Log(("VbgdCommonIoCtl: VMMREQUEST: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
return rc;
if (pcbDataReturned)
return rc;
#ifdef VBOX_WITH_HGCM
static int vbgdHgcmAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile *pHdr, PVBOXGUESTDEVEXT pDevExt,
int rc;
return VINF_SUCCESS;
if (pWait)
if (fInterruptible)
return VERR_INTERRUPTED;
return VINF_SUCCESS;
if (fInterruptible)
return rc;
&& ( !fInterruptible
return rc;
static DECLCALLBACK(int) vbgdHgcmAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
static DECLCALLBACK(int) vbgdHgcmAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
int rc;
return VERR_TOO_MANY_OPEN_FILES;
if (pcbDataReturned)
return rc;
int rc;
return VERR_INVALID_HANDLE;
if (pcbDataReturned)
return rc;
static int vbgdIoCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestHGCMCallInfo *pInfo,
int rc;
return VERR_INVALID_PARAMETER;
#ifdef RT_ARCH_AMD64
if (f32bit)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_HANDLE;
fFlags = !fUserData && pSession->R0Process == NIL_RTR0PROCESS ? VBGLR0_HGCMCALL_F_KERNEL : VBGLR0_HGCMCALL_F_USER;
#ifdef RT_ARCH_AMD64
if (f32bit)
if (fInterruptible)
rc = VbglR0HGCMInternalCall32(pInfo, cbInfo, fFlags, vbgdHgcmAsyncWaitCallbackInterruptible, pDevExt, cMillies);
if (fInterruptible)
rc = VbglR0HGCMInternalCall(pInfo, cbInfo, fFlags, vbgdHgcmAsyncWaitCallbackInterruptible, pDevExt, cMillies);
if (pcbDataReturned)
return rc;
int rc;
rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest);
Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0);
if (pcbDataReturned)
return rc;
int rc;
if (pcbDataReturned)
*pcbDataReturned = 0;
return rc;
int rc;
Log(("VbgdCommonIoCtl: WRITE_CORE_DUMP: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
return rc;
return rc;
static int vbgdIoCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, size_t cbData, size_t *pcbDataReturned, bool fUserSession)
else if (!fUserSession)
if (pcbDataReturned)
*pcbDataReturned = 0;
return VINF_SUCCESS;
#ifdef VBOX_STRICT
static void vbgdBitUsageTrackerCheckMask(PCVBOXGUESTBITUSAGETRACER pTracker, uint32_t cMax, const char *pszWhat)
static bool vbgdBitUsageTrackerChange(PVBOXGUESTBITUSAGETRACER pTracker, uint32_t fChanged, uint32_t fPrevious,
bool fGlobalChange = false;
fGlobalChange = true;
("pTracker->acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax));
fGlobalChange = true;
if (!fChanged)
#ifdef VBOX_STRICT
return fGlobalChange;
return rc;
int rc;
else if (!fSessionTermination)
return rc;
if (fChanged)
if (pReq)
if (!fSessionTermination)
if (pReq)
return rc;
static int vbgdIoCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestFilterMaskInfo *pInfo)
LogFlow(("VbgdCommonIoCtl: CTL_FILTER_MASK or=%#x not=%#x\n", pInfo->u32OrMask, pInfo->u32NotMask));
Log(("VbgdCommonIoCtl: CTL_FILTER_MASK or=%#x not=%#x: Invalid masks!\n", pInfo->u32OrMask, pInfo->u32NotMask));
return VERR_INVALID_PARAMETER;
return vbgdSetSessionEventFilter(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/);
return rc;
int rc;
else if (!fSessionTermination)
return rc;
if (fChanged)
if (pReq)
if (!fSessionTermination)
if (pReq)
return rc;
static int vbgdIoCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)
int rc;
return VERR_INVALID_PARAMETER;
return vbgdSetSessionMouseStatus(pDevExt, pSession, fFeatures, ~fFeatures, false /*fSessionTermination*/);
static uint32_t vbgdGetAllowedEventMaskForSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
if (fAcquireModeGuestCaps == 0)
return VMMDEV_EVENT_VALID_EVENT_MASK;
return fAllowedEvents;
return rc;
static int vbgdUpdateCapabilitiesOnHostWithReqAndLock(PVBOXGUESTDEVEXT pDevExt, VMMDevReqGuestCapabilities2 *pReq)
int rc;
return rc;
bool fSessionTermination)
int rc;
LogRel(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x -- invalid fOrMask\n",
return VERR_INVALID_PARAMETER;
LogRel(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: invalid enmFlags %d\n",
return VERR_INVALID_PARAMETER;
else if (!fSessionTermination)
LogRel(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: VbglGRAlloc failure: %Rrc\n",
return rc;
if (pReq)
LogRel(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: calling caps acquire for set caps\n",
return VERR_INVALID_STATE;
Log(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: configured acquire caps: 0x%x\n",
return VINF_SUCCESS;
if (!fOtherConflictingCaps)
if (fSessionAddedCaps)
if (fSessionRemovedCaps)
if (pReq)
if (fSessionAddedCaps)
if (fSessionRemovedCaps)
LogRel(("vbgdAcquireSessionCapabilities: vbgdUpdateCapabilitiesOnHostWithReqAndLock failed: rc=%Rrc\n", rc));
return rc;
return VERR_RESOURCE_BUSY;
if (pReq)
if (fSessionAddedCaps)
return VINF_SUCCESS;
static int vbgdIoCtl_GuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestCapsAquire *pAcquire)
int rc;
rc = vbgdAcquireSessionCapabilities(pDevExt, pSession, pAcquire->u32OrMask, pAcquire->u32NotMask, pAcquire->enmFlags,
return VINF_SUCCESS;
else if (!fSessionTermination)
return rc;
if (fChanged)
if (pReq)
if (pReq)
return rc;
static int vbgdIoCtl_SetCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestSetCapabilitiesInfo *pInfo)
int rc;
LogFlow(("VbgdCommonIoCtl: SET_GUEST_CAPABILITIES or=%#x not=%#x\n", pInfo->u32OrMask, pInfo->u32NotMask));
rc = vbgdSetSessionCapabilities(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/);
return rc;
int rc;
if (pcbDataReturned)
*pcbDataReturned = 0;
return VERR_PERMISSION_DENIED; \
return VERR_BUFFER_OVERFLOW; \
return VERR_INVALID_POINTER; \
return VERR_BUFFER_OVERFLOW; \
return VERR_INVALID_POINTER; \
if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_VMMREQUEST(0)))
rc = vbgdIoCtl_VMMRequest(pDevExt, pSession, (VMMDevRequestHeader *)pvData, cbData, pcbDataReturned);
#ifdef VBOX_WITH_HGCM
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)))
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(0)))
bool fInterruptible = true;
# ifdef RT_ARCH_AMD64
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_32(0)))
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED_32(0)))
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)))
switch (iFunction)
if (cbData != 0)
#ifdef VBOX_WITH_HGCM
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
rc = vbgdIoCtl_HGCMDisconnect(pDevExt, pSession, (VBoxGuestHGCMDisconnectInfo *)pvData, pcbDataReturned);
rc = vbgdIoCtl_CheckMemoryBalloon(pDevExt, pSession, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);
rc = vbgdIoCtl_ChangeMemoryBalloon(pDevExt, pSession, (VBoxGuestChangeBalloonInfo *)pvData, pcbDataReturned);
LogFlow(("VbgdCommonIoCtl: returns %Rrc *pcbDataReturned=%zu\n", rc, pcbDataReturned ? *pcbDataReturned : 0));
return rc;
if ( fHandledEvents != 0
if (fHandledEvents)
if (!fEvents)
return rc;
bool fMousePositionChanged = false;
int rc = 0;
bool fOurIrq;
if (fOurIrq)
fMousePositionChanged = true;
#ifndef RT_OS_WINDOWS
#ifdef VBOX_WITH_HGCM
# ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
return fOurIrq;