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; }
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; }
/** * Creates the kernel input device. */ static int __init vboxguestLinuxCreateInputDevice(void) { int rc; rc = VbglGRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReq, sizeof(*g_pMouseStatusReq), VMMDevReq_GetMouseStatus); if (RT_FAILURE(rc)) return -ENOMEM; g_pInputDevice = input_allocate_device(); if (!g_pInputDevice) { VbglGRFree(&g_pMouseStatusReq->header); return -ENOMEM; } g_pInputDevice->id.bustype = BUS_PCI; g_pInputDevice->id.vendor = VMMDEV_VENDORID; g_pInputDevice->id.product = VMMDEV_DEVICEID; g_pInputDevice->id.version = VBOX_SHORT_VERSION; g_pInputDevice->open = vboxguestOpenInputDevice; g_pInputDevice->close = vboxguestCloseInputDevice; # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) g_pInputDevice->cdev.dev = &g_pPciDev->dev; # else g_pInputDevice->dev.parent = &g_pPciDev->dev; # endif { int rc = input_register_device(g_pInputDevice); if (rc) { VbglGRFree(&g_pMouseStatusReq->header); input_free_device(g_pInputDevice); return rc; } } /* Do what one of our competitors apparently does as that works. */ ASMBitSet(g_pInputDevice->evbit, EV_ABS); ASMBitSet(g_pInputDevice->evbit, EV_KEY); # ifdef EV_SYN ASMBitSet(g_pInputDevice->evbit, EV_SYN); # endif input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); ASMBitSet(g_pInputDevice->keybit, BTN_MOUSE); /** @todo this string should be in a header file somewhere. */ g_pInputDevice->name = "VirtualBox mouse integration"; return 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; }
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; }
/** * 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); } }
/* 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; }
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); }
NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath) #endif { PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension; #ifndef TARGET_NT4 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); #endif Log(("VBoxGuest::vboxguestwinInit\n")); int rc = STATUS_SUCCESS; #ifdef TARGET_NT4 /* * Let's have a look at what our PCI adapter offers. */ Log(("VBoxGuest::vboxguestwinInit: Starting to scan PCI resources of VBoxGuest ...\n")); /* Assign the PCI resources. */ PCM_RESOURCE_LIST pResourceList = NULL; UNICODE_STRING classNameString; RtlInitUnicodeString(&classNameString, L"VBoxGuestAdapter"); rc = HalAssignSlotResources(pRegPath, &classNameString, pDrvObj, pDevObj, PCIBus, pDevExt->win.s.busNumber, pDevExt->win.s.slotNumber, &pResourceList); if (pResourceList && pResourceList->Count > 0) vboxguestwinShowDeviceResources(&pResourceList->List[0].PartialResourceList); if (NT_SUCCESS(rc)) rc = vboxguestwinScanPCIResourceList(pResourceList, pDevExt); #else if (pStack->Parameters.StartDevice.AllocatedResources->Count > 0) vboxguestwinShowDeviceResources(&pStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList); if (NT_SUCCESS(rc)) rc = vboxguestwinScanPCIResourceList(pStack->Parameters.StartDevice.AllocatedResourcesTranslated, pDevExt); #endif if (NT_SUCCESS(rc)) { /* * Map physical address of VMMDev memory into MMIO region * and init the common device extension bits. */ void *pvMMIOBase = NULL; uint32_t cbMMIO = 0; rc = vboxguestwinMapVMMDevMemory(pDevExt, pDevExt->win.s.vmmDevPhysMemoryAddress, pDevExt->win.s.vmmDevPhysMemoryLength, &pvMMIOBase, &cbMMIO); if (NT_SUCCESS(rc)) { pDevExt->pVMMDevMemory = (VMMDevMemory *)pvMMIOBase; Log(("VBoxGuest::vboxguestwinInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->pVMMDevMemory = 0x%p\n", pvMMIOBase, pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL)); int vrc = VBoxGuestInitDevExt(pDevExt, pDevExt->IOPortBase, pvMMIOBase, cbMMIO, vboxguestwinVersionToOSType(g_winVersion), VMMDEV_EVENT_MOUSE_POSITION_CHANGED); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Could not init device extension, rc = %Rrc!\n", vrc)); rc = STATUS_DEVICE_CONFIGURATION_ERROR; } } else Log(("VBoxGuest::vboxguestwinInit: Could not map physical address of VMMDev, rc = 0x%x!\n", rc)); } if (NT_SUCCESS(rc)) { int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->win.s.pPowerStateRequest, sizeof (VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Alloc for pPowerStateRequest failed, rc = %Rrc\n", vrc)); rc = STATUS_UNSUCCESSFUL; } } if (NT_SUCCESS(rc)) { /* * Register DPC and ISR. */ Log(("VBoxGuest::vboxguestwinInit: Initializing DPC/ISR ...\n")); IoInitializeDpcRequest(pDevExt->win.s.pDeviceObject, vboxguestwinDpcHandler); #ifdef TARGET_NT4 ULONG uInterruptVector; KIRQL irqLevel; /* Get an interrupt vector. */ /* Only proceed if the device provides an interrupt. */ if ( pDevExt->win.s.interruptLevel || pDevExt->win.s.interruptVector) { Log(("VBoxGuest::vboxguestwinInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n", pDevExt->win.s.busNumber, pDevExt->win.s.interruptLevel, pDevExt->win.s.interruptVector)); uInterruptVector = HalGetInterruptVector(PCIBus, pDevExt->win.s.busNumber, pDevExt->win.s.interruptLevel, pDevExt->win.s.interruptVector, &irqLevel, &pDevExt->win.s.interruptAffinity); Log(("VBoxGuest::vboxguestwinInit: HalGetInterruptVector returns vector %u\n", uInterruptVector)); if (uInterruptVector == 0) Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n")); } else Log(("VBoxGuest::vboxguestwinInit: Device does not provide an interrupt!\n")); #endif if (pDevExt->win.s.interruptVector) { Log(("VBoxGuest::vboxguestwinInit: Connecting interrupt ...\n")); rc = IoConnectInterrupt(&pDevExt->win.s.pInterruptObject, /* Out: interrupt object. */ (PKSERVICE_ROUTINE)vboxguestwinIsrHandler, /* Our ISR handler. */ pDevExt, /* Device context. */ NULL, /* Optional spinlock. */ #ifdef TARGET_NT4 uInterruptVector, /* Interrupt vector. */ irqLevel, /* Interrupt level. */ irqLevel, /* Interrupt level. */ #else pDevExt->win.s.interruptVector, /* Interrupt vector. */ (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */ (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */ #endif pDevExt->win.s.interruptMode, /* LevelSensitive or Latched. */ TRUE, /* Shareable interrupt. */ pDevExt->win.s.interruptAffinity, /* CPU affinity. */ FALSE); /* Don't save FPU stack. */ if (NT_ERROR(rc)) Log(("VBoxGuest::vboxguestwinInit: Could not connect interrupt, rc = 0x%x\n", rc)); } else Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n")); } #ifdef VBOX_WITH_HGCM Log(("VBoxGuest::vboxguestwinInit: Allocating kernel session data ...\n")); int vrc = VBoxGuestCreateKernelSession(pDevExt, &pDevExt->win.s.pKernelSession); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Failed to allocated kernel session data! rc = %Rrc\n", rc)); rc = STATUS_UNSUCCESSFUL; } #endif if (RT_SUCCESS(rc)) { ULONG ulValue = 0; NTSTATUS s = vboxguestwinRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &ulValue); if (NT_SUCCESS(s)) { pDevExt->fLoggingEnabled = ulValue >= 0xFF; if (pDevExt->fLoggingEnabled) Log(("Logging to release log enabled (0x%x)", ulValue)); } /* Ready to rumble! */ Log(("VBoxGuest::vboxguestwinInit: Device is ready!\n")); VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING); } else { pDevExt->win.s.pInterruptObject = NULL; } Log(("VBoxGuest::vboxguestwinInit: Returned with rc = 0x%x\n", rc)); return rc; }
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(); }