Esempio n. 1
0
bool VBoxLikesVideoMode(uint32_t display, uint32_t width, uint32_t height, uint32_t bpp)
{
    bool bRC = FALSE;

    VMMDevVideoModeSupportedRequest2 *req2 = NULL;

    int rc = VbglGRAlloc((VMMDevRequestHeader**)&req2, sizeof(VMMDevVideoModeSupportedRequest2), VMMDevReq_VideoModeSupported2);
    if (RT_FAILURE(rc))
    {
        LOG(("ERROR allocating request, rc = %#xrc", rc));
        /* Most likely the VBoxGuest driver is not loaded.
         * To get at least the video working, report the mode as supported.
         */
        bRC = TRUE;
    }
    else
    {
        req2->display = display;
        req2->width  = width;
        req2->height = height;
        req2->bpp    = bpp;
        rc = VbglGRPerform(&req2->header);
        if (RT_SUCCESS(rc))
        {
            bRC = req2->fSupported;
        }
        else
        {
            /* Retry using old interface. */
            AssertCompile(sizeof(VMMDevVideoModeSupportedRequest2) >= sizeof(VMMDevVideoModeSupportedRequest));
            VMMDevVideoModeSupportedRequest *req = (VMMDevVideoModeSupportedRequest *)req2;
            req->header.size        = sizeof(VMMDevVideoModeSupportedRequest);
            req->header.version     = VMMDEV_REQUEST_HEADER_VERSION;
            req->header.requestType = VMMDevReq_VideoModeSupported;
            req->header.rc          = VERR_GENERAL_FAILURE;
            req->header.reserved1   = 0;
            req->header.reserved2   = 0;
            req->width  = width;
            req->height = height;
            req->bpp    = bpp;

            rc = VbglGRPerform(&req->header);
            if (RT_SUCCESS(rc))
            {
                bRC = req->fSupported;
            }
            else
            {
                WARN(("ERROR querying video mode supported status from VMMDev. rc = %#xrc", rc));
            }
        }
        VbglGRFree(&req2->header);
    }

    LOG(("width: %d, height: %d, bpp: %d -> %s", width, height, bpp, (bRC == 1) ? "OK" : "FALSE"));

    return bRC;
}
Esempio n. 2
0
void VbgdNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
{
#ifdef VBOXGUEST_WITH_INPUT_DRIVER
    int rc;
#endif
    NOREF(pDevExt);

    /*
     * Wake up everyone that's in a poll() and post anyone that has
     * subscribed to async notifications.
     */
    Log3(("VbgdNativeISRMousePollEvent: wake_up_all\n"));
    wake_up_all(&g_PollEventQueue);
    Log3(("VbgdNativeISRMousePollEvent: kill_fasync\n"));
    kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN);
#ifdef VBOXGUEST_WITH_INPUT_DRIVER
    /* Report events to the kernel input device */
    g_pMouseStatusReq->mouseFeatures = 0;
    g_pMouseStatusReq->pointerXPos = 0;
    g_pMouseStatusReq->pointerYPos = 0;
    rc = VbglGRPerform(&g_pMouseStatusReq->header);
    if (RT_SUCCESS(rc))
    {
        input_report_abs(g_pInputDevice, ABS_X,
                         g_pMouseStatusReq->pointerXPos);
        input_report_abs(g_pInputDevice, ABS_Y,
                         g_pMouseStatusReq->pointerYPos);
# ifdef EV_SYN
        input_sync(g_pInputDevice);
# endif
    }
#endif
    Log3(("VbgdNativeISRMousePollEvent: done\n"));
}
Esempio n. 3
0
uint32_t VBoxGetHeightReduction()
{
    uint32_t retHeight = 0;
    int rc;

    LOGF_ENTER();

    VMMDevGetHeightReductionRequest *req = NULL;

    rc = VbglGRAlloc((VMMDevRequestHeader**)&req, sizeof(VMMDevGetHeightReductionRequest), VMMDevReq_GetHeightReduction);
    if (RT_FAILURE(rc))
    {
        WARN(("ERROR allocating request, rc = %#xrc", rc));
    }
    else
    {
        rc = VbglGRPerform(&req->header);
        if (RT_SUCCESS(rc))
        {
            retHeight = req->heightReduction;
        }
        else
        {
            WARN(("ERROR querying height reduction value from VMMDev. rc = %#xrc", rc));
        }
        VbglGRFree(&req->header);
    }

    LOGF_LEAVE();
    return retHeight;
}
Esempio n. 4
0
static bool VBoxQueryPointerPosInternal(uint16_t *pPosX, uint16_t *pPosY)
{
    bool bRC = FALSE;

    VMMDevReqMouseStatus *req = NULL;

    int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);

    if (RT_FAILURE(rc))
    {
        LOG(("ERROR allocating request, rc = %#xrc", rc));
    }
    else
    {
        rc = VbglGRPerform(&req->header);

        if (RT_SUCCESS(rc))
        {
            if (req->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
            {
                if (pPosX)
                {
                    *pPosX = req->pointerXPos;
                }

                if (pPosY)
                {
                    *pPosY = req->pointerYPos;
                }

                bRC = TRUE;
            }
        }
        else
        {
            LOG(("ERROR querying mouse capabilities from VMMDev. rc = %#xrc", rc));
        }

        VbglGRFree(&req->header);
    }

    return bRC;
}
Esempio n. 5
0
bool VBoxQueryDisplayRequest(uint32_t *xres, uint32_t *yres, uint32_t *bpp, uint32_t *pDisplayId)
{
    bool bRC = FALSE;
    VMMDevDisplayChangeRequest2 *req = NULL;

    LOGF_ENTER();

    int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevDisplayChangeRequest2), VMMDevReq_GetDisplayChangeRequest2);

    if (RT_FAILURE(rc))
    {
        LOG(("ERROR allocating request, rc = %#xrc", rc));
    }
    else
    {
        req->eventAck = 0;

        rc = VbglGRPerform (&req->header);

        if (RT_SUCCESS(rc))
        {
            if (xres)
                *xres = req->xres;
            if (yres)
                *yres = req->yres;
            if (bpp)
                *bpp  = req->bpp;
            if (pDisplayId)
                *pDisplayId  = req->display;
            LOG(("returning %d x %d @ %d for %d", req->xres, req->yres, req->bpp, req->display));
            bRC = TRUE;
        }
        else
        {
            WARN(("ERROR querying display request from VMMDev. rc = %#xrc", rc));
        }

        VbglGRFree (&req->header);
    }

    LOGF_LEAVE();
    return bRC;
}
VOID VBoxDrvNotifyServiceCB(PVBOXMOUSE_DEVEXT pDevExt, PMOUSE_INPUT_DATA InputDataStart, PMOUSE_INPUT_DATA InputDataEnd, PULONG  InputDataConsumed)
{
    KIRQL Irql;
    /* we need to avoid concurrency between the poller thread and our ServiceCB.
     * this is perhaps not the best way of doing things, but the most easiest to avoid concurrency
     * and to ensure the pfnServiceCB is invoked at DISPATCH_LEVEL */
    KeAcquireSpinLock(&g_ctx.SyncLock, &Irql);
    if (pDevExt->pSCReq)
    {
        int rc = VbglGRPerform(&pDevExt->pSCReq->header);

        if (RT_SUCCESS(rc))
        {
            if (pDevExt->pSCReq->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
            {
                PMOUSE_INPUT_DATA pData = InputDataStart;
                while (pData<InputDataEnd)
                {
                    pData->LastX = pDevExt->pSCReq->pointerXPos;
                    pData->LastY = pDevExt->pSCReq->pointerYPos;
                    pData->Flags = MOUSE_MOVE_ABSOLUTE;
                    if (vboxNewProtIsEnabled())
                        pData->Flags |= MOUSE_VIRTUAL_DESKTOP;
                    pData++;
                }

                /* get the last data & cache it */
                --pData;
                g_ctx.LastReportedData.UnitId = pData->UnitId;
            }
        }
        else
        {
            WARN(("VbglGRPerform failed with rc=%#x", rc));
        }
    }

    /* Call original callback */
    pDevExt->OriginalConnectData.pfnServiceCB(pDevExt->OriginalConnectData.pDO,
                                              InputDataStart, InputDataEnd, InputDataConsumed);
    KeReleaseSpinLock(&g_ctx.SyncLock, Irql);
}
Esempio n. 7
0
/**
 * Used by vbglQueryDriverInfo and VbglInit to try get the host feature mask and
 * version information (g_vbgldata::hostVersion).
 *
 * This was first implemented by the host in 3.1 and we quietly ignore failures
 * for that reason.
 */
static void vbglR0QueryHostVersion (void)
{
    VMMDevReqHostVersion *pReq;

    int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);

    if (RT_SUCCESS (rc))
    {
        rc = VbglGRPerform (&pReq->header);

        if (RT_SUCCESS (rc))
        {
            g_vbgldata.hostVersion = *pReq;
            Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
                  pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
        }

        VbglGRFree (&pReq->header);
    }
}
/**
 * IRP_MJ_SHUTDOWN handler.
 *
 * @returns NT status code
 * @param pDevObj    Device object.
 * @param pIrp       IRP.
 */
NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;

    Log(("VBoxGuest::vboxguestwinGuestShutdown\n"));

    VMMDevPowerStateRequest *pReq = pDevExt->win.s.pPowerStateRequest;
    if (pReq)
    {
        pReq->header.requestType = VMMDevReq_SetPowerStatus;
        pReq->powerState = VMMDevPowerState_PowerOff;

        int rc = VbglGRPerform(&pReq->header);
        if (RT_FAILURE(rc))
        {
            Log(("VBoxGuest::vboxguestwinGuestShutdown: Error performing request to VMMDev! "
                     "rc = %Rrc\n", rc));
        }
    }
    return STATUS_SUCCESS;
}
Esempio n. 9
0
static DECLCALLBACK(void) VBoxVbvaFlush(void *pvFlush)
{
    LOGF_ENTER();

    PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT)pvFlush;
    PVBOXMP_DEVEXT pPrimary = pExt? pExt->pPrimary: NULL;

    if (pPrimary)
    {
        VMMDevVideoAccelFlush *req = (VMMDevVideoAccelFlush *)pPrimary->u.primary.pvReqFlush;

        if (req)
        {
            int rc = VbglGRPerform (&req->header);

            if (RT_FAILURE(rc))
            {
                WARN(("rc = %#xrc!", rc));
            }
        }
    }
    LOGF_LEAVE();
}
Esempio n. 10
0
/* Called for IOCTL_VIDEO_VBOX_SETVISIBLEREGION.
 * Sends visible regions information to the host.
 */
BOOLEAN VBoxMPSetVisibleRegion(uint32_t cRects, RTRECT *pRects, PSTATUS_BLOCK pStatus)
{
    int rc;
    BOOLEAN bRC = FALSE;
    LOGF_ENTER();

    VMMDevVideoSetVisibleRegion *req = NULL;
    rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevVideoSetVisibleRegion) + (cRects-1)*sizeof(RTRECT),
                      VMMDevReq_VideoSetVisibleRegion);

    if (RT_SUCCESS(rc))
    {
        req->cRect = cRects;
        memcpy(&req->Rect, pRects, cRects*sizeof(RTRECT));
        rc = VbglGRPerform(&req->header);

        if (RT_SUCCESS(rc))
        {
            bRC=TRUE;
        }

        VbglGRFree(&req->header);
    }
    else
    {
        WARN(("VbglGRAlloc rc = %#xrc", rc));
    }

    if (!bRC)
    {
        pStatus->Status = ERROR_INVALID_FUNCTION;
    }

    LOGF_LEAVE();
    return bRC;
}
Esempio n. 11
0
int VBoxVbvaEnable(PVBOXMP_DEVEXT pExt, BOOLEAN bEnable, VBVAENABLERESULT *pResult)
{
    int rc = VINF_SUCCESS;
    LOGF_ENTER();

    VMMDevMemory *pVMMDevMemory = NULL;

    rc = VbglQueryVMMDevMemory (&pVMMDevMemory);
    if (RT_FAILURE(rc))
    {
        WARN(("VbglQueryVMMDevMemory rc = %#xrc", rc));
        LOGF_LEAVE();
        return rc;
    }

    if (pExt->iDevice>0)
    {
        PVBOXMP_DEVEXT pPrimary = pExt->pPrimary;
        LOGF(("skipping non-primary display %d", pExt->iDevice));

        if (bEnable && pPrimary->u.primary.ulVbvaEnabled && pVMMDevMemory)
        {
            pResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
            pResult->pfnFlush    = VBoxVbvaFlush;
            pResult->pvFlush     = pExt;
        }
        else
        {
            VideoPortZeroMemory(&pResult, sizeof(VBVAENABLERESULT));
        }

        LOGF_LEAVE();
        return rc;
    }

    /* Allocate the memory block for VMMDevReq_VideoAccelFlush request. */
    if (pExt->u.primary.pvReqFlush == NULL)
    {
        VMMDevVideoAccelFlush *req = NULL;

        rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevVideoAccelFlush), VMMDevReq_VideoAccelFlush);

        if (RT_SUCCESS(rc))
        {
            pExt->u.primary.pvReqFlush = req;
        }
        else
        {
            WARN(("VbglGRAlloc(VMMDevVideoAccelFlush) rc = %#xrc", rc));
            LOGF_LEAVE();
            return rc;
        }
    }

    ULONG ulEnabled = 0;

    VMMDevVideoAccelEnable *req = NULL;
    rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevVideoAccelEnable), VMMDevReq_VideoAccelEnable);

    if (RT_SUCCESS(rc))
    {
        req->u32Enable    = bEnable;
        req->cbRingBuffer = VBVA_RING_BUFFER_SIZE;
        req->fu32Status   = 0;

        rc = VbglGRPerform(&req->header);
        if (RT_SUCCESS(rc))
        {
            if (req->fu32Status & VBVA_F_STATUS_ACCEPTED)
            {
                LOG(("accepted"));

                /* Initialize the result information and VBVA memory. */
                if (req->fu32Status & VBVA_F_STATUS_ENABLED)
                {
                    pResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
                    pResult->pfnFlush    = VBoxVbvaFlush;
                    pResult->pvFlush     = pExt;
                    ulEnabled = 1;
                }
                else
                {
                    VideoPortZeroMemory(&pResult, sizeof(VBVAENABLERESULT));
                }
            }
            else
            {
                LOG(("rejected"));

                /* Disable VBVA for old hosts. */
                req->u32Enable = 0;
                req->cbRingBuffer = VBVA_RING_BUFFER_SIZE;
                req->fu32Status = 0;

                VbglGRPerform(&req->header);

                rc = VERR_NOT_SUPPORTED;
            }
        }
        else
        {
            WARN(("rc = %#xrc", rc));
        }

        VbglGRFree(&req->header);
    }
    else
    {
        WARN(("VbglGRAlloc(VMMDevVideoAccelEnable) rc = %#xrc", rc));
    }

    pExt->u.primary.ulVbvaEnabled = ulEnabled;

    LOGF_LEAVE();
    return rc;
}
/**
 * Handle the Power requests.
 *
 * @returns   NT status code
 * @param     pDevObj   device object
 * @param     pIrp      IRP
 */
NTSTATUS vbgdNtPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    PIO_STACK_LOCATION  pStack   = IoGetCurrentIrpStackLocation(pIrp);
    PVBOXGUESTDEVEXTWIN pDevExt  = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
    POWER_STATE_TYPE    enmPowerType   = pStack->Parameters.Power.Type;
    POWER_STATE         PowerState     = pStack->Parameters.Power.State;
    POWER_ACTION        enmPowerAction = pStack->Parameters.Power.ShutdownType;

    Log(("VBoxGuest::vbgdNtGuestPower\n"));

    switch (pStack->MinorFunction)
    {
        case IRP_MN_SET_POWER:
        {
            Log(("VBoxGuest::vbgdNtGuestPower: IRP_MN_SET_POWER, type= %d\n", enmPowerType));
            switch (enmPowerType)
            {
                case SystemPowerState:
                {
                    Log(("VBoxGuest::vbgdNtGuestPower: SystemPowerState, action = %d, state = %d/%d\n",
                         enmPowerAction, PowerState.SystemState, PowerState.DeviceState));

                    switch (enmPowerAction)
                    {
                        case PowerActionSleep:

                            /* System now is in a working state. */
                            if (PowerState.SystemState == PowerSystemWorking)
                            {
                                if (   pDevExt
                                    && pDevExt->LastSystemPowerAction == PowerActionHibernate)
                                {
                                    Log(("VBoxGuest::vbgdNtGuestPower: Returning from hibernation!\n"));
                                    int rc = VbgdCommonReinitDevExtAfterHibernation(&pDevExt->Core,
                                                                                   vbgdNtVersionToOSType(g_enmVbgdNtVer));
                                    if (RT_FAILURE(rc))
                                        Log(("VBoxGuest::vbgdNtGuestPower: Cannot re-init VMMDev chain, rc = %d!\n", rc));
                                }
                            }
                            break;

                        case PowerActionShutdownReset:
                        {
                            Log(("VBoxGuest::vbgdNtGuestPower: Power action reset!\n"));

                            /* Tell the VMM that we no longer support mouse pointer integration. */
                            VMMDevReqMouseStatus *pReq = NULL;
                            int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus),
                                                  VMMDevReq_SetMouseStatus);
                            if (RT_SUCCESS(vrc))
                            {
                                pReq->mouseFeatures = 0;
                                pReq->pointerXPos = 0;
                                pReq->pointerYPos = 0;

                                vrc = VbglGRPerform(&pReq->header);
                                if (RT_FAILURE(vrc))
                                {
                                    Log(("VBoxGuest::PowerStateRequest: error communicating new power status to VMMDev. vrc = %Rrc\n", vrc));
                                }

                                VbglGRFree(&pReq->header);
                            }

                            /* Don't do any cleanup here; there might be still coming in some IOCtls after we got this
                             * power action and would assert/crash when we already cleaned up all the stuff! */
                            break;
                        }

                        case PowerActionShutdown:
                        case PowerActionShutdownOff:
                        {
                            Log(("VBoxGuest::vbgdNtGuestPower: Power action shutdown!\n"));
                            if (PowerState.SystemState >= PowerSystemShutdown)
                            {
                                Log(("VBoxGuest::vbgdNtGuestPower: Telling the VMMDev to close the VM ...\n"));

                                VMMDevPowerStateRequest *pReq = pDevExt->pPowerStateRequest;
                                int vrc = VERR_NOT_IMPLEMENTED;
                                if (pReq)
                                {
                                    pReq->header.requestType = VMMDevReq_SetPowerStatus;
                                    pReq->powerState = VMMDevPowerState_PowerOff;

                                    vrc = VbglGRPerform(&pReq->header);
                                }
                                if (RT_FAILURE(vrc))
                                    Log(("VBoxGuest::PowerStateRequest: Error communicating new power status to VMMDev. vrc = %Rrc\n", vrc));

                                /* No need to do cleanup here; at this point we should've been
                                 * turned off by VMMDev already! */
                            }
                            break;
                        }

                        case PowerActionHibernate:

                            Log(("VBoxGuest::vbgdNtGuestPower: Power action hibernate!\n"));
                            break;
                    }

                    /*
                     * Save the current system power action for later use.
                     * This becomes handy when we return from hibernation for example.
                     */
                    if (pDevExt)
                        pDevExt->LastSystemPowerAction = enmPowerAction;

                    break;
                }
                default:
                    break;
            }
            break;
        }
        default:
            break;
    }

    /*
     * Whether we are completing or relaying this power IRP,
     * we must call PoStartNextPowerIrp.
     */
    PoStartNextPowerIrp(pIrp);

    /*
     * Send the IRP down the driver stack, using PoCallDriver
     * (not IoCallDriver, as for non-power irps).
     */
    IoCopyCurrentIrpStackLocationToNext(pIrp);
    IoSetCompletionRoutine(pIrp,
                           vbgdNtPowerComplete,
                           (PVOID)pDevExt,
                           TRUE,
                           TRUE,
                           TRUE);
    return PoCallDriver(pDevExt->pNextLowerDriver, pIrp);
}
VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt)
{
    LOGF_ENTER();

    /* Save the allocated request pointer and clear the devExt. */
    VMMDevReqMouseStatus *pSCReq = (VMMDevReqMouseStatus *) InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, NULL);

    if (pDevExt->bHostMouse && vboxIsHostInformed())
    {
        // tell the VMM that from now on we can't handle absolute coordinates anymore
        VMMDevReqMouseStatus *req = NULL;

        int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);

        if (RT_SUCCESS(rc))
        {
            req->mouseFeatures = 0;
            req->pointerXPos = 0;
            req->pointerYPos = 0;

            rc = VbglGRPerform(&req->header);

            if (RT_FAILURE(rc))
            {
                WARN(("VbglGRPerform failed with rc=%#x", rc));
            }

            VbglGRFree(&req->header);
        }
        else
        {
            WARN(("VbglGRAlloc failed with rc=%#x", rc));
        }

        InterlockedExchange(&g_ctx.fHostInformed, FALSE);
    }

    if (pSCReq)
    {
        VbglGRFree(&pSCReq->header);
    }

    LONG callCnt = InterlockedDecrement(&g_ctx.cDevicesStarted);

    vboxNewProtDeviceRemoved(pDevExt);

    if (callCnt == 0)
    {
        if (vboxIsVBGLInited())
        {
            /* Set the flag to prevent reinitializing of the VBGL. */
            InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE);

            VbglTerminate();

            /* The VBGL is now in the not initialized state. */
            InterlockedExchange(&g_ctx.fVBGLInited, FALSE);
            InterlockedExchange(&g_ctx.fVBGLInitFailed, FALSE);
        }
    }

    LOGF_LEAVE();
}
VOID VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt)
{
    LOGF_ENTER();

    if (!vboxIsVBGLInited())
    {
        WARN(("!vboxIsVBGLInited"));
        return;
    }

    /* Inform host we support absolute coordinates */
    if (pDevExt->bHostMouse && !vboxIsHostInformed())
    {
        VMMDevReqMouseStatus *req = NULL;
        int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);

        if (RT_SUCCESS(rc))
        {
            req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
            if (vboxNewProtIsEnabled())
                req->mouseFeatures |= VMMDEV_MOUSE_NEW_PROTOCOL;

            req->pointerXPos = 0;
            req->pointerYPos = 0;

            rc = VbglGRPerform(&req->header);

            if (RT_SUCCESS(rc))
            {
                InterlockedExchange(&g_ctx.fHostInformed, TRUE);
            }
            else
            {
                WARN(("VbglGRPerform failed with rc=%#x", rc));
            }

            VbglGRFree(&req->header);
        }
        else
        {
            WARN(("VbglGRAlloc failed with rc=%#x", rc));
        }
    }

    /* Preallocate request to be used in VBoxServiceCB*/
    if (pDevExt->bHostMouse && !pDevExt->pSCReq)
    {
        VMMDevReqMouseStatus *req = NULL;

        int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);

        if (RT_SUCCESS(rc))
        {
            InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, req);
        }
        else
        {
            WARN(("VbglGRAlloc for service callback failed with rc=%#x", rc));
        }
    }

    LOGF_LEAVE();
}