/* 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; }
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; }
/* 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; }
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(); }
VOID APIENTRY VBoxDispDrvDisableDirectDraw(DHPDEV dhpdev) { RT_NOREF(dhpdev); LOGF_ENTER(); LOGF_LEAVE(); return; }
/* 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; }
/* 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; }
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; }
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(); }
/* 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; }
/* 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_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(); }
/* Returns video modes supported by our device/driver * Note: If we fail here we'd be asked to enter 800x600@4bpp mode later in VBoxDispDrvEnablePDEV. */ ULONG APIENTRY VBoxDispDrvGetModes(HANDLE hDriver, ULONG cjSize, DEVMODEW *pdm) { int rc; VIDEO_MODE_INFORMATION *pModesTable; ULONG cModes; LOGF_ENTER(); rc = VBoxDispMPGetVideoModes(hDriver, &pModesTable, &cModes); VBOX_WARNRC_RETV(rc, 0); if (!pdm) /* return size of buffer required to store all supported modes */ { EngFreeMem(pModesTable); LOGF_LEAVE(); return cModes * sizeof(DEVMODEW); } ULONG mode, cMaxNodes=cjSize/sizeof(DEVMODEW); for (mode=0; mode<cModes && mode<cMaxNodes; ++mode, ++pdm) { memset(pdm, 0, sizeof(DEVMODEW)); memcpy(pdm->dmDeviceName, VBOXDISP_DEVICE_NAME, sizeof(VBOXDISP_DEVICE_NAME)); pdm->dmSpecVersion = DM_SPECVERSION; pdm->dmDriverVersion = DM_SPECVERSION; pdm->dmSize = sizeof(DEVMODEW); pdm->dmDriverExtra = 0; pdm->dmBitsPerPel = pModesTable[mode].NumberOfPlanes*pModesTable[mode].BitsPerPlane; pdm->dmPelsWidth = pModesTable[mode].VisScreenWidth; pdm->dmPelsHeight = pModesTable[mode].VisScreenHeight; pdm->dmDisplayFrequency = pModesTable[mode].Frequency; pdm->dmDisplayFlags = 0; pdm->dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY|DM_DISPLAYFLAGS; } EngFreeMem(pModesTable); LOG(("%d mode(s) reported", mode)); LOGF_LEAVE(); return mode * sizeof(DEVMODEW); }
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; }
/* 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; }
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); }
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; }
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; }
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); }
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; }
DECLCALLBACK(int) VBoxMPHGSMIHostCmdRequestCB(HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, uint32_t iDisplay, struct VBVAHOSTCMD **ppCmd) { LOGF_ENTER(); if (!ppCmd) { LOGF_LEAVE(); return VERR_INVALID_PARAMETER; } PHGSMIHOSTCOMMANDCONTEXT pCtx = &((PVBOXMP_COMMON)hHGSMI)->hostCtx; /* pick up the host commands */ VBoxHGSMIProcessHostQueue(pCtx); HGSMICHANNEL *pChannel = HGSMIChannelFindById(&pCtx->channels, u8Channel); if(pChannel) { VBVA_CHANNELCONTEXTS * pContexts = (VBVA_CHANNELCONTEXTS *)pChannel->handler.pvHandler; VBVADISP_CHANNELCONTEXT *pDispContext = VBoxVbvaFindHandlerInfo(pContexts, iDisplay); if(pDispContext) { VBVAHOSTCMD *pCmd; do { pCmd = ASMAtomicReadPtrT(&pDispContext->pCmd, VBVAHOSTCMD *); } while (!ASMAtomicCmpXchgPtr(&pDispContext->pCmd, NULL, pCmd)); *ppCmd = VBoxVbvaReverseList(pCmd); LOGF_LEAVE(); return VINF_SUCCESS; } else { WARN(("!pDispContext for display %d", iDisplay)); } }
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; }