/* 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; }
/* Called for IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES. * Returns count of supported video modes and structure size in bytes, * used by the following IOCTL_VIDEO_QUERY_AVAIL_MODES. */ BOOLEAN VBoxMPQueryNumAvailModes(PVBOXMP_DEVEXT pExt, PVIDEO_NUM_MODES pNumModes, PSTATUS_BLOCK pStatus) { LOGF_ENTER(); VBoxMPXpdmBuildVideoModesTable(pExt); pNumModes->NumModes = VBoxMPXpdmGetVideoModesCount(); pNumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION); pStatus->Information = sizeof(VIDEO_NUM_MODES); LOGF_LEAVE(); return TRUE; }
/* Process Video Request Packet. */ static BOOLEAN VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket) { PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; PSTATUS_BLOCK pStatus = RequestPacket->StatusBlock; BOOLEAN bResult = FALSE; PAGED_CODE(); LOGF(("IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF)); pStatus->Status = NO_ERROR; switch (RequestPacket->IoControlCode) { /* ==================== System VRPs ==================== */ /*Maps FrameBuffer and video RAM to a caller's virtual adress space.*/ case IOCTL_VIDEO_MAP_VIDEO_MEMORY: { STARTIO_IN(VIDEO_MEMORY, pMemory); STARTIO_OUT(VIDEO_MEMORY_INFORMATION, pMemInfo); bResult = VBoxMPMapVideoMemory(pExt, pMemory, pMemInfo, pStatus); break; } /*Unmaps previously mapped FrameBuffer and video RAM from caller's virtual adress space.*/ case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: { STARTIO_IN(VIDEO_MEMORY, pMemory); bResult = VBoxMPUnmapVideoMemory(pExt, pMemory, pStatus); break; } /*Maps FrameBuffer as a linear frame buffer to a caller's virtual adress space. (obsolete)*/ case IOCTL_VIDEO_SHARE_VIDEO_MEMORY: { STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory); STARTIO_OUT(VIDEO_SHARE_MEMORY_INFORMATION, pShareMemInfo); bResult = VBoxMPShareVideoMemory(pExt, pShareMemory, pShareMemInfo, pStatus); break; } /*Unmaps framebuffer previously mapped with IOCTL_VIDEO_SHARE_VIDEO_MEMORY*/ case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: { STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory); bResult = VBoxMPUnshareVideoMemory(pExt, pShareMemory, pStatus); break; } /*Reset device to a state it comes at system boot time.*/ case IOCTL_VIDEO_RESET_DEVICE: { bResult = VBoxMPResetDevice(pExt, pStatus); break; } /*Set adapter video mode.*/ case IOCTL_VIDEO_SET_CURRENT_MODE: { STARTIO_IN(VIDEO_MODE, pMode); bResult = VBoxMPSetCurrentMode(pExt, pMode, pStatus); break; } /*Returns information about current video mode.*/ case IOCTL_VIDEO_QUERY_CURRENT_MODE: { STARTIO_OUT(VIDEO_MODE_INFORMATION, pModeInfo); bResult = VBoxMPQueryCurrentMode(pExt, pModeInfo, pStatus); break; } /* Returns count of supported video modes and structure size in bytes, * used to allocate buffer for the following IOCTL_VIDEO_QUERY_AVAIL_MODES call. */ case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: { STARTIO_OUT(VIDEO_NUM_MODES, pNumModes); bResult = VBoxMPQueryNumAvailModes(pExt, pNumModes, pStatus); break; } /* Returns information about supported video modes. */ case IOCTL_VIDEO_QUERY_AVAIL_MODES: { PVIDEO_MODE_INFORMATION pModes = (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer; if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION)) { pStatus->Status = ERROR_INSUFFICIENT_BUFFER; break; } bResult = VBoxMPQueryAvailModes(pExt, pModes, pStatus); break; } /* Sets adapter's color registers, have to be implemented if we support palette based modes. */ case IOCTL_VIDEO_SET_COLOR_REGISTERS: { STARTIO_IN(VIDEO_CLUT, pClut); if (RequestPacket->InputBufferLength < (sizeof(VIDEO_CLUT) + pClut->NumEntries * sizeof(ULONG))) { pStatus->Status = ERROR_INSUFFICIENT_BUFFER; break; } bResult = VBoxMPSetColorRegisters(pExt, pClut, pStatus); break; } /* Sets pointer attributes. */ case IOCTL_VIDEO_SET_POINTER_ATTR: { STARTIO_IN(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs); bResult = VBoxMPSetPointerAttr(pExt, pPointerAttrs, RequestPacket->InputBufferLength, pStatus); break; } /* Makes pointer visible. */ case IOCTL_VIDEO_ENABLE_POINTER: { bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus); break; } /* Hides pointer. */ case IOCTL_VIDEO_DISABLE_POINTER: { bResult = VBoxMPEnablePointer(pExt, FALSE, pStatus); break; } /* Sets pointer position, is called after IOCTL_VIDEO_ENABLE_POINTER. */ case IOCTL_VIDEO_SET_POINTER_POSITION: { STARTIO_IN(VIDEO_POINTER_POSITION, pPos); NOREF(pPos); /** @todo set pointer position*/ bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus); break; } /* Query pointer position. */ case IOCTL_VIDEO_QUERY_POINTER_POSITION: { STARTIO_OUT(VIDEO_POINTER_POSITION, pPos); bResult = VBoxMPQueryPointerPosition(pExt, pPos, pStatus); break; } /* Query supported hardware pointer feaures. */ case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES: { STARTIO_OUT(VIDEO_POINTER_CAPABILITIES, pCaps); bResult = VBoxMPQueryPointerCapabilities(pExt, pCaps, pStatus); break; } /* Query pointer attributes. (optional) */ case IOCTL_VIDEO_QUERY_POINTER_ATTR: { STARTIO_OUT(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs); NOREF(pPointerAttrs); /* Not Implemented */ pStatus->Status = ERROR_INVALID_FUNCTION; bResult = FALSE; break; } /* Called when a secondary adapter is about to be enabled/disabled. */ case IOCTL_VIDEO_SWITCH_DUALVIEW: { STARTIO_IN(ULONG, pAttach); LOGF(("IOCTL_VIDEO_SWITCH_DUALVIEW: [%d] attach = %d", pExt->iDevice, *pAttach)); if (pExt->iDevice>0) { pExt->u.secondary.bEnabled = (BOOLEAN)(*pAttach); /* Inform the host. * Currently only about secondary devices, because the driver does not support * disconnecting the primary display (it does not allow to change the primary display). */ if (!pExt->u.secondary.bEnabled) { PVBOXMP_COMMON pCommon = VBoxCommonFromDeviceExt(pExt); if (pCommon->bHGSMI) { VBoxHGSMIProcessDisplayInfo(&pCommon->guestCtx, pExt->iDevice, /* cOriginX = */ 0, /* cOriginY = */ 0, /* offStart = */ 0, /* cbPitch = */ 0, /* cWidth = */ 0, /* cHeight = */ 0, /* cBPP = */ 0, VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED); } } } bResult = TRUE; break; } /* Called to get child device status */ case IOCTL_VIDEO_GET_CHILD_STATE: { STARTIO_IN(ULONG, pChildIndex); STARTIO_OUT(ULONG, pChildState); LOGF(("IOCTL_VIDEO_GET_CHILD_STATE: [%d] idx = %d", pExt->iDevice, *pChildIndex)); if (*pChildIndex>0 && *pChildIndex<=(ULONG)VBoxCommonFromDeviceExt(pExt)->cDisplays) { *pChildState = VIDEO_CHILD_ACTIVE; pStatus->Information = sizeof(ULONG); bResult = TRUE; } else { pStatus->Status = ERROR_INVALID_PARAMETER; bResult = FALSE; } break; } /* ==================== VirtualBox specific VRPs ==================== */ /* Called by the display driver when it is ready to switch to VBVA operation mode. */ case IOCTL_VIDEO_VBVA_ENABLE: { STARTIO_IN(ULONG, pEnable); STARTIO_OUT(VBVAENABLERESULT, pResult); bResult = VBoxMPVBVAEnable(pExt, (BOOLEAN)*pEnable, pResult, pStatus); break; } /* Called by the display driver when it recieves visible regions information. */ case IOCTL_VIDEO_VBOX_SETVISIBLEREGION: { STARTIO_IN(RTRECT, pRects); uint32_t cRects = RequestPacket->InputBufferLength/sizeof(RTRECT); /*Sanity check*/ if ( cRects > _1M || RequestPacket->InputBufferLength != cRects * sizeof(RTRECT)) { pStatus->Status = ERROR_INSUFFICIENT_BUFFER; break; } bResult = VBoxMPSetVisibleRegion(cRects, pRects, pStatus); break; } /* Returns video port api function pointers. */ case IOCTL_VIDEO_HGSMI_QUERY_PORTPROCS: { STARTIO_OUT(HGSMIQUERYCPORTPROCS, pProcs); bResult = VBoxMPHGSMIQueryPortProcs(pExt, pProcs, pStatus); break; } /* Returns HGSMI related callbacks. */ case IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS: { STARTIO_OUT(HGSMIQUERYCALLBACKS, pCallbacks); bResult = VBoxMPHGSMIQueryCallbacks(pExt, pCallbacks, pStatus); break; } /* Returns hgsmi info for this adapter. */ case IOCTL_VIDEO_QUERY_HGSMI_INFO: { STARTIO_OUT(QUERYHGSMIRESULT, pResult); bResult = VBoxMPQueryHgsmiInfo(pExt, pResult, pStatus); break; } /* Enables HGSMI miniport channel. */ case IOCTL_VIDEO_HGSMI_HANDLER_ENABLE: { STARTIO_IN(HGSMIHANDLERENABLE, pChannel); bResult = VBoxMPHgsmiHandlerEnable(pExt, pChannel, pStatus); break; } case IOCTL_VIDEO_HGSMI_HANDLER_DISABLE: { /** @todo not implemented */ break; } #ifdef VBOX_WITH_VIDEOHWACCEL /* Returns framebuffer offset. */ case IOCTL_VIDEO_VHWA_QUERY_INFO: { STARTIO_OUT(VHWAQUERYINFO, pInfo); bResult = VBoxMPVhwaQueryInfo(pExt, pInfo, pStatus); break; } #endif case IOCTL_VIDEO_VBOX_ISANYX: { STARTIO_OUT(uint32_t, pu32AnyX); *pu32AnyX = VBoxCommonFromDeviceExt(pExt)->fAnyX; pStatus->Information = sizeof (uint32_t); bResult = TRUE; break; } case IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO: { STARTIO_IN(ULONG, pulInfoLevel); if (*pulInfoLevel == VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS) { STARTIO_OUT(ULONG, pulFlags); bResult = VBoxMPQueryRegistryFlags(pExt, pulFlags, pStatus); } else { pStatus->Status = ERROR_INVALID_PARAMETER; bResult = FALSE; } break; } default: { WARN(("unsupported IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF)); RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION; } } if (!bResult) { pStatus->Information = NULL; } VBOXMP_WARN_VPS(pStatus->Status); LOGF_LEAVE(); return TRUE; }