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; }
/* * Display driver callbacks. */ BOOL APIENTRY VBoxDispDrvSetPalette(DHPDEV dhpdev, PALOBJ *ppalo, FLONG fl, ULONG iStart, ULONG cColors) { BYTE aClut[MAX_CLUT_SIZE]; PVIDEO_CLUT pClut = (PVIDEO_CLUT) aClut; PVIDEO_CLUTDATA pData = &pClut->LookupTable[0].RgbArray; PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev; NOREF(fl); int rc; LOGF_ENTER(); pClut->NumEntries = (USHORT) cColors; pClut->FirstEntry = (USHORT) iStart; /* Copy PALOBJ colors to PVIDEO_CLUT */ if (cColors != PALOBJ_cGetColors(ppalo, iStart, cColors, (ULONG*) pData)) { WARN(("PALOBJ_cGetColors failed")); return FALSE; } /* Set reserved bytes to 0 and perform shifting if needed */ for (ULONG idx=0; idx<cColors; ++idx) { pData[idx].Unused = 0; if (pDev->mode.ulPaletteShift) { pData[idx].Red >>= pDev->mode.ulPaletteShift; pData[idx].Green >>= pDev->mode.ulPaletteShift; pData[idx].Blue >>= pDev->mode.ulPaletteShift; } }
VOID APIENTRY VBoxDispDrvDisableSurface(DHPDEV dhpdev) { PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev; LOGF_ENTER(); if (pDev->surface.hSurface) { EngDeleteSurface(pDev->surface.hSurface); pDev->surface.hSurface = NULL; } if (pDev->surface.psoBitmap) { Assert(pDev->surface.hBitmap); EngUnlockSurface(pDev->surface.psoBitmap); pDev->surface.psoBitmap = NULL; } if (pDev->surface.hBitmap) { EngDeleteSurface((HSURF) pDev->surface.hBitmap); pDev->surface.hBitmap = NULL; } int rc; rc = VBoxDispMPUnmapMemory(pDev); VBOX_WARNRC(rc); LOGF_LEAVE(); }
BOOL APIENTRY VBoxDispDrvRealizeBrush(BRUSHOBJ *pbo, SURFOBJ *psoTarget, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch) { BOOL bRc = FALSE; LOGF_ENTER(); if (VBoxDispIsScreenSurface(psoTarget)) { PVBOXDISPDEV pDev = (PVBOXDISPDEV)psoTarget->dhpdev; if (pDev->vbvaCtx.pVBVA && (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED)) { if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET) { vrdpReset(pDev); pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &= ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; } if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_VRDP) { bRc = vrdpDrvRealizeBrush(pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch); } } } LOGF_LEAVE(); return bRc; }
/* Called to reset adapter to a given character mode. */ static BOOLEAN VBoxDrvResetHW(PVOID HwDeviceExtension, ULONG Columns, ULONG Rows) { RT_NOREF(Columns, Rows); PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; LOGF_ENTER(); if (pExt->iDevice==0) /* Primary device */ { VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED); #if 0 /* ResetHW is not the place to do such cleanup. See MSDN. */ if (pExt->u.primary.pvReqFlush != NULL) { VbglR0GRFree((VMMDevRequestHeader *)pExt->u.primary.pvReqFlush); pExt->u.primary.pvReqFlush = NULL; } VbglR0TerminateClient(); VBoxFreeDisplaysHGSMI(VBoxCommonFromDeviceExt(pExt)); #endif } else { LOG(("ignoring non primary device %d", pExt->iDevice)); } LOGF_LEAVE(); /* Tell the system to use VGA BIOS to set the text video mode. */ return FALSE; }
/* Called to enumerate child devices of our adapter, attached monitor(s) in our case */ static VP_STATUS VBoxDrvGetVideoChildDescriptor(PVOID HwDeviceExtension, PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, PVIDEO_CHILD_TYPE VideoChildType, PUCHAR pChildDescriptor, PULONG pUId, PULONG pUnused) { RT_NOREF(pChildDescriptor, pUnused); PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; PAGED_CODE(); LOGF_ENTER(); if (ChildEnumInfo->ChildIndex>0) { if ((int)ChildEnumInfo->ChildIndex <= VBoxCommonFromDeviceExt(pExt)->cDisplays) { *VideoChildType = Monitor; *pUId = ChildEnumInfo->ChildIndex; LOGF_LEAVE(); return VIDEO_ENUM_MORE_DEVICES; } } LOGF_LEAVE(); return ERROR_NO_MORE_DEVICES; }
VOID APIENTRY VBoxDispDrvDisableDirectDraw(DHPDEV dhpdev) { RT_NOREF(dhpdev); LOGF_ENTER(); LOGF_LEAVE(); return; }
/* Initial device configuration. */ static BOOLEAN VBoxDrvInitialize(PVOID HwDeviceExtension) { PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; USHORT DispiId; PAGED_CODE(); LOGF_ENTER(); /* Initialize the request pointer. */ pExt->u.primary.pvReqFlush = NULL; /* Check if the chip restricts horizontal resolution or not. */ VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX); DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); if (DispiId == VBE_DISPI_ID_ANYX) pExt->fAnyX = TRUE; else pExt->fAnyX = FALSE; VBoxMPCmnInitCustomVideoModes(pExt); LOGF_LEAVE(); return TRUE; }
/* Driver entry point */ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NOREF(RegistryPath); PAGED_CODE(); int irc = RTR0Init(0); if (RT_FAILURE(irc)) { LOGREL(("failed to init IPRT (rc=%#x)", irc)); return STATUS_INTERNAL_ERROR; } LOGF_ENTER(); DriverObject->DriverUnload = VBoxDrvUnload; DriverObject->DriverExtension->AddDevice = VBoxDrvAddDevice; for (int i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = VBoxIrpPassthrough; } DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxIrpInternalIOCTL; DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP; DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxIrpPower; NTSTATUS tmpStatus = VBoxNewProtInit(); if (!NT_SUCCESS(tmpStatus)) { WARN(("VBoxNewProtInit failed Status (0x%x)", tmpStatus)); } LOGF_LEAVE(); return STATUS_SUCCESS; }
/* Called for IOCTL_VIDEO_QUERY_HGSMI_INFO. * Returns hgsmi info for this adapter. */ BOOLEAN VBoxMPQueryHgsmiInfo(PVBOXMP_DEVEXT pExt, QUERYHGSMIRESULT *pResult, PSTATUS_BLOCK pStatus) { BOOLEAN bRC = TRUE; LOGF_ENTER(); if (VBoxCommonFromDeviceExt(pExt)->bHGSMI) { pResult->iDevice = pExt->iDevice; pResult->ulFlags = 0; pResult->areaDisplay = pExt->areaDisplay; pResult->u32DisplayInfoSize = VBVA_DISPLAY_INFORMATION_SIZE; pResult->u32MinVBVABufferSize = VBVA_MIN_BUFFER_SIZE; pResult->IOPortGuestCommand = VBoxCommonFromDeviceExt(pExt)->guestCtx.port; pStatus->Information = sizeof(QUERYHGSMIRESULT); } else { pStatus->Status = ERROR_INVALID_FUNCTION; bRC=FALSE; } LOGF_LEAVE(); return bRC; }
BOOLEAN VBoxMPQueryRegistryFlags(PVBOXMP_DEVEXT pExt, ULONG *pulFlags, PSTATUS_BLOCK pStatus) { BOOLEAN bRC = TRUE; LOGF_ENTER(); VBOXMPCMNREGISTRY Registry; int rc = VBoxMPCmnRegInit(pExt, &Registry); VBOXMP_WARN_VPS_NOBP(rc); if (rc == NO_ERROR) { uint32_t u32Flags = 0; rc = VBoxMPCmnRegQueryDword(Registry, L"VBoxVideoFlags", &u32Flags); VBOXMP_WARN_VPS_NOBP(rc); if (rc != NO_ERROR) { u32Flags = 0; } LOG(("Registry flags 0x%08X", u32Flags)); *pulFlags = u32Flags; pStatus->Information = sizeof(ULONG); } rc = VBoxMPCmnRegFini(Registry); VBOXMP_WARN_VPS_NOBP(rc); LOGF_LEAVE(); return bRC; }
/* Called to provide us GDI handle for our device, which we should use later for GDI calls */ VOID APIENTRY VBoxDispDrvCompletePDEV(DHPDEV dhpdev, HDEV hdev) { LOGF_ENTER(); ((PVBOXDISPDEV)dhpdev)->hDevGDI = hdev; LOGF_LEAVE(); }
/* Free all resources allocated in DrvEnableDriver */ VOID APIENTRY VBoxDispDrvDisableDriver() { LOGF_ENTER(); /* Intentionally left blank */ LOGF_LEAVE(); return; }
DWORD APIENTRY VBoxDispDDAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface) { LOGF_ENTER(); lpAddAttachedSurface->ddRVal = DD_OK; LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
/* Called for IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY. * Unmaps framebuffer previously mapped with IOCTL_VIDEO_SHARE_VIDEO_MEMORY. */ BOOLEAN VBoxMPUnshareVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_SHARE_MEMORY pMem, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); pStatus->Status = VideoPortUnmapMemory(pExt, pMem->RequestedVirtualAddress, pMem->ProcessHandle); LOGF_LEAVE(); return TRUE; }
/* Called for IOCTL_VIDEO_UNMAP_VIDEO_MEMORY. * Unmaps previously mapped FrameBuffer and video RAM from caller's virtual adress space. */ BOOLEAN VBoxMPUnmapVideoMemory(PVBOXMP_DEVEXT pExt, PVIDEO_MEMORY VideoMemory, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); HGSMIAreaClear(&pExt->areaDisplay); pStatus->Status = VideoPortUnmapMemory(pExt, VideoMemory->RequestedVirtualAddress, NULL); LOGF_LEAVE(); return TRUE; }
/* Called to free resources allocated for device in VBoxDispDrvEnablePDEV */ VOID APIENTRY VBoxDispDrvDisablePDEV(DHPDEV dhpdev) { LOGF_ENTER(); VBoxDispDestroyPalette((PVBOXDISPDEV) dhpdev); EngFreeMem(dhpdev); LOGF_LEAVE(); }
DWORD APIENTRY VBoxDispDDSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpSetOverlayPosition->lpDD->dhpdev; DD_SURFACE_LOCAL *pSrcSurf = lpSetOverlayPosition->lpDDSrcSurface; DD_SURFACE_LOCAL *pDstSurf = lpSetOverlayPosition->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; LOGF_ENTER(); if (pSrcDesc && pDstDesc) { if (!pSrcDesc->bVisible) { WARN(("!pSrcDesc->bVisible")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); if (pCmd) { VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; pBody->u.in.hDstSurf = pDstDesc->hHostHandle; pBody->u.in.xPos = lpSetOverlayPosition->lXPos; pBody->u.in.yPos = lpSetOverlayPosition->lYPos; VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); lpSetOverlayPosition->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pSrcDesc && pDstDesc)")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
/* Called to check if our hardware supports given power state. */ static VP_STATUS VBoxDrvGetPowerState(PVOID HwDeviceExtension, ULONG HwId, PVIDEO_POWER_MANAGEMENT VideoPowerControl) { PAGED_CODE(); LOGF_ENTER(); /*Not implemented*/ LOGF_LEAVE(); return NO_ERROR; }
NTSTATUS VBoxIrpPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PVBOXMOUSE_DEVEXT pDevExt; PAGED_CODE(); LOGF_ENTER(); pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension; PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); LOGF_LEAVE(); return PoCallDriver(pDevExt->pdoParent, Irp); }
/* Called for IOCTL_VIDEO_QUERY_CURRENT_MODE. * Returns information about current video mode. */ BOOLEAN VBoxMPQueryCurrentMode(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pModeInfo, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); pStatus->Information = sizeof(VIDEO_MODE_INFORMATION); VideoPortMoveMemory(pModeInfo, VBoxMPXpdmCurrentVideoMode(pExt), sizeof(VIDEO_MODE_INFORMATION)); LOGF_LEAVE(); return TRUE; }
/* Called for IOCTL_VIDEO_QUERY_AVAIL_MODES. * Returns information about supported video modes. */ BOOLEAN VBoxMPQueryAvailModes(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pModes, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); ULONG ulSize = VBoxMPXpdmGetVideoModesCount()*sizeof(VIDEO_MODE_INFORMATION); pStatus->Information = ulSize; VideoPortMoveMemory(pModes, VBoxMPCmnGetVideoModeInfo(0), ulSize); LOGF_LEAVE(); return TRUE; }
int VBoxDispMPSetColorRegisters(HANDLE hDriver, PVIDEO_CLUT pClut, DWORD cbClut) { DWORD dwrc; ULONG cbReturned; LOGF_ENTER(); dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SET_COLOR_REGISTERS, pClut, cbClut, NULL, 0, &cbReturned); VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); LOGF_LEAVE(); return VINF_SUCCESS; }
int VBoxDispMPResetDevice(HANDLE hDriver) { DWORD dwrc; ULONG cbReturned; LOGF_ENTER(); dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &cbReturned); VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); LOGF_LEAVE(); return VINF_SUCCESS; }
int VBoxDispMPDisablePointer(HANDLE hDriver) { DWORD dwrc; ULONG cbReturned; LOGF_ENTER(); dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &cbReturned); VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); LOGF_LEAVE(); return VINF_SUCCESS; }
BOOL APIENTRY VBoxDispDrvPaint(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, MIX mix) { BOOL bRc; LOGF_ENTER(); STATDRVENTRY(Paint, pso); bRc = EngPaint (getSurfObj(pso), pco, pbo, pptlBrushOrg, mix); VBVA_OPERATION(pso, Paint, (pso, pco, pbo, pptlBrushOrg, mix)); LOGF_LEAVE(); return bRc; }
NTSTATUS VBoxIrpPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PVBOXMOUSE_DEVEXT pDevExt; LOGF_ENTER(); pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension; IoSkipCurrentIrpStackLocation(Irp); LOGF_LEAVE(); return IoCallDriver(pDevExt->pdoParent, Irp); }
int VBoxDispMPSetVisibleRegion(HANDLE hDriver, PRTRECT pRects, DWORD cRects) { DWORD dwrc; ULONG cbReturned; LOGF_ENTER(); dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_VBOX_SETVISIBLEREGION, pRects, cRects*sizeof(RTRECT), NULL, 0, &cbReturned); VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); LOGF_LEAVE(); return VINF_SUCCESS; }
ULONG APIENTRY VBoxDispDrvDitherColor(DHPDEV dhpdev, ULONG iMode, ULONG rgb, ULONG *pul) { ULONG rc; LOGF_ENTER(); /* There is no EngDitherColor on NT4, so take the easy path and tell the graphics * engine to create a halftone approximation. */ rc = DCR_HALFTONE; LOGF_LEAVE(); return rc; }
int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem) { DWORD dwrc; ULONG cbReturned; LOGF_ENTER(); dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY), NULL, 0, &cbReturned); VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); LOGF_LEAVE(); return VINF_SUCCESS; }