VBoxVideo.cpp revision bd88a03fe4f970611c171f081be318fcd74e85e8
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * VirtualBox Video miniport driver for NT/2k/XP
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Based on DDK sample code.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * available from http://www.virtualbox.org. This file is free software;
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * you can redistribute it and/or modify it under the terms of the GNU
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * General Public License (GPL) as published by the Free Software
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * additional information or have any questions.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync#if _MSC_VER >= 1400 /* bird: MS fixed swprintf to be standard-conforming... */
615105a2b89b7dd89a76504e6a9b8e099704c0d9vboxsyncextern "C" int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsyncstatic WCHAR VBoxAdapterString[] = L"VirtualBox Video Adapter";
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsyncstatic WCHAR VBoxBiosString[] = L"Version 0xB0C2 or later";
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Globals for the last custom resolution set. This is important
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync * for system startup so that we report the last currently set
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync * custom resolution and Windows can use it again.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync#endif /* !VBOX_WITH_MULTIMONITOR_FIX */
83c86878d483df62ca8db465c671995984838338vboxsyncint vboxVbvaEnable (PDEVICE_EXTENSION pDevExt, ULONG ulEnable, VBVAENABLERESULT *pVbvaResult);
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncULONG DriverEntry(IN PVOID Context1, IN PVOID Context2)
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync dprintf(("VBoxVideo::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync VideoPortZeroMemory(&InitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync#if defined(VBOX_WITH_HGSMI) && defined(VBOX_WITH_VIDEOHWACCEL)
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync // nowhere documented but without the following line, NT4 SP0 will choke
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync InitData.HwGetVideoChildDescriptor = VBoxVideoGetChildDescriptor;
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync InitData.HwDeviceExtensionSize = sizeof(DEVICE_EXTENSION);
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync // our DDK is at the Win2k3 level so we have to take special measures
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync // for backwards compatibility
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync InitData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
e120ca0501a41ca43369b7ba984f4db2f720bdc8vboxsync InitData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
e120ca0501a41ca43369b7ba984f4db2f720bdc8vboxsync rc = VideoPortInitialize(Context1, Context2, &InitData, NULL);
e120ca0501a41ca43369b7ba984f4db2f720bdc8vboxsync dprintf(("VBoxVideo::DriverEntry: returning with rc = 0x%x\n", rc));
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsyncRoutine Description:
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync This routine is used to read back various registry values.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync HwDeviceExtension
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync Supplies a pointer to the miniport's device extension.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync Context value passed to the get registry parameters routine.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync If this is not null assume it's a ULONG* and save the data value in it.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync Name of the value requested.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync Pointer to the requested data.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync ValueLength
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync Length of the requested data.
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsyncReturn Value:
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync If the variable doesn't exist return an error,
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync else if a context is supplied assume it's a PULONG and fill in the value
4dee4a4f4ff664b16f478e200e0d231407a2b097vboxsync and return no error, else if the value is non-zero return an error.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncVP_STATUS VBoxRegistryCallback(PVOID HwDeviceExtension, PVOID Context,
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync PWSTR ValueName, PVOID ValueData, ULONG ValueLength)
4ffdae046e05f397b6552d5489685f5802bbd249vboxsync //dprintf(("VBoxVideo::VBoxRegistryCallback: Context: %p, ValueName: %S, ValueData: %p, ValueLength: %d\n",
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync // Context, ValueName, ValueData, ValueLength));
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncVP_STATUS VBoxVideoCmnRegQueryDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t *pVal)
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync return VideoPortGetRegistryParameters(Reg, pName, FALSE, VBoxRegistryCallback, pVal);
e8a568d25b577fb2ce7213b11c63f71eca1f84c2vboxsyncVP_STATUS VBoxVideoCmnRegSetDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t Val)
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync return VideoPortSetRegistryParameters(Reg, pName, &Val, sizeof(Val));
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync#endif /* #ifndef VBOXWDDM */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Global list of supported standard video modes. It will be
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync * filled dynamically.
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsyncstatic VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 2] = { 0 };
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync * Additional space is reserved for custom video modes for 64 guest monitors.
f2fedb6cbb946e9dd6d418b1472373395e2ac34fvboxsync * The custom video mode index is alternating and 2 indexes are reserved for the last custom mode.
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsyncstatic VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 64 + 2] = { 0 };
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync/* On the driver startup this is initialized from registry (replaces gCustom*). */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncstatic VIDEO_MODE_INFORMATION CustomVideoModes[64] = { 0 };
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync#endif /* VBOX_WITH_MULTIMONITOR_FIX */
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync/* number of available video modes, set by VBoxBuildModesTable */
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsyncstatic void initVideoModeInformation(VIDEO_MODE_INFORMATION *pVideoMode, ULONG xres, ULONG yres, ULONG bpp, ULONG index, ULONG yoffset)
615105a2b89b7dd89a76504e6a9b8e099704c0d9vboxsync * Build mode entry.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync memset(pVideoMode, 0, sizeof(VIDEO_MODE_INFORMATION));
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync pVideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync pVideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync pVideoMode->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync pVideoMode->VideoMemoryBitmapHeight = yres - yoffset;
e8a568d25b577fb2ce7213b11c63f71eca1f84c2vboxsync#endif /* VBOX_WITH_MULTIMONITOR_FIX */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync/* preferred mode index */
615105a2b89b7dd89a76504e6a9b8e099704c0d9vboxsyncstatic D3DKMDT_2DREGION g_VBoxWddmVideoResolutions[RT_ELEMENTS(VideoModes)];
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncDECLINLINE(int) vboxWddmRectComparator(const D3DKMDT_2DREGION *pReg1, const D3DKMDT_2DREGION *pReg2)
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync/* builds a g_VBoxWddmVideoResolutions given VideoModes info */
615105a2b89b7dd89a76504e6a9b8e099704c0d9vboxsync /* we don't care about the efficiency at this time */
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync bool bFound = false;
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync for (uint32_t j = 0; j < g_VBoxWddmNumResolutions; ++j)
1f277e5b999f572b1ef1fe4ef593c603ea463be3vboxsync if (g_VBoxWddmVideoResolutions[j].cx == pMode->VisScreenWidth
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync && g_VBoxWddmVideoResolutions[j].cy == pMode->VisScreenHeight)
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync Assert(g_VBoxWddmNumResolutions < RT_ELEMENTS(g_VBoxWddmVideoResolutions));
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync g_VBoxWddmVideoResolutions[g_VBoxWddmNumResolutions].cx = pMode->VisScreenWidth;
f2fedb6cbb946e9dd6d418b1472373395e2ac34fvboxsync g_VBoxWddmVideoResolutions[g_VBoxWddmNumResolutions].cy = pMode->VisScreenHeight;
e8a568d25b577fb2ce7213b11c63f71eca1f84c2vboxsyncstatic uint32_t g_xresNoVRAM = 0, g_yresNoVRAM = 0, g_bppNoVRAM = 0;
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * Helper function to dynamically build our table of standard video
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * modes. We take the amount of VRAM and create modes with standard
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * geometries until we've either reached the maximum number of modes
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * or the available VRAM does not allow for additional modes.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsyncVOID VBoxBuildModesTable(PDEVICE_EXTENSION DeviceExtension)
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync /* we need this static counter to always have a new mode index for our */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* custom video mode, otherwise Windows thinks there is no mode switch */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync static int gInvocationCounter = 0;
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync /* the resolution matrix */
5413a6a2dab50ebebc702aa2ae7d8059dcd09c9cvboxsync /* standard modes */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* multi screen modes with 1280x1024 */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* multi screen modes with 1600x1200 */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync size_t matrixSize = sizeof(resolutionMatrix) / sizeof(resolutionMatrix[0]);
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* there are 4 color depths: 8, 16, 24 and 32bpp and we reserve 50% of the modes for other sources */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync size_t maxModesPerColorDepth = MAX_VIDEO_MODES / 2 / 4;
615105a2b89b7dd89a76504e6a9b8e099704c0d9vboxsync /* size of the VRAM in bytes */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize;
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync ULONG vramSize = vboxWddmVramCpuVisibleSegmentSize(DeviceExtension);
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* at least two surfaces will be needed: primary & shadow */
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync /* Always add 800x600 video modes. Windows XP+ needs at least 800x600 resolution
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * and fallbacks to 800x600x4bpp VGA mode if the driver did not report suitable modes.
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync * This resolution could be rejected by a low resolution host (netbooks, etc).
05c28d9d4557bed6e320dfee1acca69408bc3c15vboxsync for (cBytesPerPixel = 1; cBytesPerPixel <= 4; cBytesPerPixel++)
391cf11262671da62bcc02db361038e7ffbab8f7vboxsync int cBitsPerPixel = cBytesPerPixel * 8; /* 8, 16, 24, 32 */
e8e40640deaea2e9002e1bf9cf4944e2590c6e7avboxsync#endif /* !VBOX_WITH_8BPP_MODES */
f2fedb6cbb946e9dd6d418b1472373395e2ac34fvboxsync /* does the mode fit into the VRAM? */
6c5e2fff0e3fdfc7c3f3fb2e7b7ec8ebb2223cecvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
f2fedb6cbb946e9dd6d418b1472373395e2ac34fvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
switch (cBytesPerPixel)
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN |
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
#ifdef VBOXWDDM
#ifdef VBOX_WITH_8BPP_MODES
matrixIndex = 0;
++matrixIndex;
if (yOffset == 0 && resolutionMatrix[matrixIndex].xRes == 800 && resolutionMatrix[matrixIndex].yRes == 600)
++matrixIndex;
if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 8))
++matrixIndex;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN |
++matrixIndex;
matrixIndex = 0;
++matrixIndex;
if (yOffset == 0 && resolutionMatrix[matrixIndex].xRes == 800 && resolutionMatrix[matrixIndex].yRes == 600)
++matrixIndex;
if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 16))
++matrixIndex;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
++matrixIndex;
matrixIndex = 0;
++matrixIndex;
if (yOffset == 0 && resolutionMatrix[matrixIndex].xRes == 800 && resolutionMatrix[matrixIndex].yRes == 600)
++matrixIndex;
if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 24))
++matrixIndex;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
++matrixIndex;
matrixIndex = 0;
++matrixIndex;
if (yOffset == 0 && resolutionMatrix[matrixIndex].xRes == 800 && resolutionMatrix[matrixIndex].yRes == 600)
++matrixIndex;
if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 32))
++matrixIndex;
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
++matrixIndex;
int curKeyNo = 0;
#ifdef VBOXWDDM
int fPreferredSet = 0;
dprintf(("VBoxVideo: adding mode from registry: xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
#ifdef VBOXWDDM
if (!fPreferredSet)
switch (bpp)
#ifdef VBOXWDDM
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
curKeyNo++;
#ifdef VBOX_WITH_MULTIMONITOR_FIX
int iCustomMode;
#ifdef LOG_ENABLED
* because these 2 entries will be added by "if (fDisplayChangeRequest || DeviceExtension->CurrentMode == 0)"
#ifndef VBOX_WITH_MULTIMONITOR_FIX
#ifndef VBOXWDDM
dprintf(("VBoxVideo: adding custom video mode as #%d, current mode: %d \n", gNumVideoModes + 1, DeviceExtension->CurrentMode));
#ifndef VBOX_WITH_MULTIMONITOR_FIX
if (!xres)
if (!yres)
if (!bpp)
if (!xres)
if (!yres)
if (!bpp)
dprintf(("VBoxVideo: using stored custom resolution %dx%dx%d for %d\n", xres, yres, bpp, DeviceExtension->iDevice));
#ifndef VBOXWDDM
if (!xres)
if (!yres)
if (!bpp)
if (!xres)
if (!yres)
if (!bpp)
if (!bpp)
if ( ( xres
&& yres
#ifdef VBOX_WITH_8BPP_MODES
#ifdef VBOX_WITH_MULTIMONITOR_FIX
#ifndef VBOXWDDM
#ifndef VBOX_WITH_MULTIMONITOR_FIX
if (fNewInvocation)
dprintf(("VBoxVideo: setting special mode to xres = %d, yres = %d, bpp = %d, display = %d\n", xres, yres, bpp, display));
#ifdef VBOX_WITH_MULTIMONITOR_FIX
dprintf(("VBoxVideo: fNewInvocation = %d, fAlternatedIndex = %d\n", fNewInvocation, fAlternatedIndex));
#ifdef VBOXWDDM
switch (bpp)
#ifdef VBOX_WITH_8BPP_MODES
VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
#ifdef VBOX_WITH_8BPP_MODES
VideoModes[gNumVideoModes].AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
#ifdef VBOX_WITH_MULTIMONITOR_FIX
#ifndef VBOXWDDM
memcpy(&VideoModes[gNumVideoModes], &VideoModes[gNumVideoModes - 1], sizeof(VIDEO_MODE_INFORMATION));
#ifdef VBOX_WITH_MULTIMONITOR_FIX
else if (!fAlternatedIndex)
#ifndef VBOX_WITH_MULTIMONITOR_FIX
dprintf(("VBoxVideo: invalid parameters for special mode: (xres = %d, yres = %d, bpp = %d, vramSize = %d)\n",
LogRel(("VBoxVideo: not enough VRAM for video mode %dx%dx%dbpp. Available: %d bytes. Required: more than %d bytes.\n",
#if defined(LOG_ENABLED)
#ifndef VBOXWDDM
dprintf(("VBoxVideo: VideoModes (CurrentMode = %d, last #%d)\n", DeviceExtension->CurrentMode, gNumVideoModes));
#ifdef VBOXWDDM
#ifdef VBOXWDDM
static bool g_bModesTableInitialized = false;
g_bModesTableInitialized = true;
g_bModesTableInitialized = false;
++cFound;
if (piPreferrableMode)
return Status;
#ifndef VBOX_WITH_HGSMI
dprintf(("VBoxVideo::VBoxComputeFrameBufferSizes: cbVRAM = 0x%08X, cDisplays = %d, ulSize = 0x%08X, ulSize * cDisplays = 0x%08X, slack = 0x%08X\n",
#ifndef VBOX_WITH_HGSMI
ulSize = 0;
#ifndef VBOX_WITH_HGSMI
while (Extension)
#ifndef VBOX_WITH_HGSMI
int VBoxMapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension, void **ppv, ULONG ulOffset, ULONG ulSize)
if (!ulSize)
return ERROR_INVALID_PARAMETER;
#ifndef VBOXWDDM
&VideoRamBase);
NTSTATUS ntStatus = PrimaryExtension->u.primary.DxgkInterface.DxgkCbMapMemory(PrimaryExtension->u.primary.DxgkInterface.DeviceHandle,
Status = ntStatus == STATUS_SUCCESS ? NO_ERROR : ERROR_INVALID_PARAMETER; /*<- this is what VideoPortMapMemory returns according to the docs */
return Status;
if (*ppv)
#ifndef VBOXWDDM
NTSTATUS ntStatus = PrimaryExtension->u.primary.DxgkInterface.DxgkCbUnmapMemory(PrimaryExtension->u.primary.DxgkInterface.DeviceHandle,
*ppv);
#ifndef VBOX_WITH_HGSMI
# ifdef VBOXWDDM
typedef struct _VBOXVIDEOQCONF32
while (Extension)
VOID VBoxSetupDisplays(PDEVICE_EXTENSION PrimaryExtension, PVIDEO_PORT_CONFIG_INFO pConfigInfo, ULONG AdapterMemorySize)
dprintf(("VBoxVideo::VBoxSetupDisplays: VBoxMapAdapterMemory pvAdapterInfoirrmation failed rc = %d\n",
rc));
dprintf(("VBoxVideo::VBoxSetupDisplays: cbMiniportHeap = 0x%08X, PrimaryExtension->u.primary.cbMiniportHeap = 0x%08X, cbMiniportHeapMaxSize = 0x%08X\n",
cDisplays));
rc = pfnCreateSecondaryDisplay (PrimaryExtension, (PVOID*)&SecondaryExtension, VIDEO_DUALVIEW_REMOVABLE);
dprintf(("VBoxVideo::VBoxSetupDisplays: VideoPortCreateSecondaryDisplay returned %#x, SecondaryExtension = %p\n",
VBoxUnmapAdapterMemory (PrimaryExtension, &PrimaryExtension->u.primary.pvMiniportHeap, PrimaryExtension->u.primary.cbMiniportHeap);
VBoxUnmapAdapterMemory (PrimaryExtension, &PrimaryExtension->u.primary.pvAdapterInformation, VBOX_VIDEO_ADAPTER_INFORMATION_SIZE);
#ifndef VBOXWDDM
#ifdef VBOX_WITH_HGSMI
VBoxSetupVideoPortFunctions((PDEVICE_EXTENSION)HwDeviceExtension, &((PDEVICE_EXTENSION)HwDeviceExtension)->u.primary.VideoPortProcs, ConfigInfo);
sizeof(VBoxChipType));
sizeof(VBoxDACType));
sizeof(ULONG));
sizeof(VBoxAdapterString));
sizeof(VBoxBiosString));
#ifdef VBOX_WITH_HGSMI
NULL,
&vendorId,
&deviceId,
&slot);
NULL,
NULL,
NULL,
&slot);
#ifndef VBOX_WITH_HGSMI
return rc;
#ifndef VBOX_WITH_MULTIMONITOR_FIX
&gCustomXRes);
gCustomXRes = 0;
&gCustomYRes);
gCustomYRes = 0;
&gCustomBPP);
gCustomBPP = 0;
dprintf(("VBoxVideo: got stored custom resolution %dx%dx%d\n", gCustomXRes, gCustomYRes, gCustomBPP));
int iCustomMode;
if (iCustomMode == 0)
&CustomXRes);
CustomXRes = 0;
&CustomYRes);
CustomYRes = 0;
&CustomBPP);
CustomBPP = 0;
&CustomXRes);
CustomXRes = 0;
&CustomYRes);
CustomYRes = 0;
&CustomBPP);
CustomBPP = 0;
dprintf(("VBoxVideo: got stored custom resolution[%d] %dx%dx%d\n", iCustomMode, CustomXRes, CustomYRes, CustomBPP));
if (CustomXRes == 0)
if (CustomYRes == 0)
if (CustomBPP == 0)
return TRUE;
if (PrimaryExtension)
BOOLEAN bResult = PrimaryExtension->u.primary.VideoPortProcs.pfnQueueDpc(PrimaryExtension, VBoxVideoHGSMIDpc, (PVOID)1);
return TRUE;
return FALSE;
#ifndef VBOXWDDM
#ifndef VBOX_WITH_HGSMI
if (Result)
return Result;
#ifndef VBOXWDDM
return TRUE;
case IOCTL_VIDEO_RESET_DEVICE:
return TRUE;
return TRUE;
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SHARE_VIDEO_MEMORY: ERROR_INSUFFICIENT_BUFFER\n"));
|| ((pShareMemory->ViewOffset + pShareMemory->ViewSize) > pDevExt->pPrimary->u.primary.ulMaxFrameBufferSize) ) {
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SHARE_VIDEO_MEMORY - ERROR_INVALID_PARAMETER %x:%x size %x\n", pShareMemory->ViewOffset, pShareMemory->ViewSize, pDevExt->pPrimary->u.primary.ulMaxFrameBufferSize));
status = VideoPortMapMemory(HwDeviceExtension, shareAddress, &sharedViewSize, &inIoSpace, &virtualAddress);
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: ERROR_INSUFFICIENT_BUFFER\n"));
status = VideoPortUnmapMemory(HwDeviceExtension, pShareMemory->RequestedVirtualAddress, pShareMemory->ProcessHandle);
return TRUE;
return TRUE;
sizeof(VIDEO_CLUT))
return TRUE;
return TRUE;
if (vboxQueryHostWantsAbsolute())
if (vboxQueryHostWantsAbsolute())
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));
if (Result)
dprintf(("VBoxVideo::VBoxVideoStartIO: Input buffer too small (%d bytes)\n", RequestPacket->InputBufferLength));
return TRUE;
if (vboxQueryHostWantsAbsolute())
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES)RequestPacket->InputBuffer;
dprintf(("\tBytes attached: %d\n", RequestPacket->InputBufferLength - sizeof(VIDEO_POINTER_ATTRIBUTES)));
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, pPointerAttributes, RequestPacket->InputBufferLength);
if (!Result)
if (vboxQueryHostWantsAbsolute())
return TRUE;
if (!Result)
return TRUE;
dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_SWITCH_DUALVIEW[%d] (%ld)\n", pDevExt->iDevice, ulAttach));
VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
#ifndef VBOX_WITH_HGSMI
return FALSE;
case IOCTL_VIDEO_VBVA_ENABLE:
int rc;
return FALSE;
return FALSE;
return FALSE;
int rc;
dprintf(("VBoxVideo::IOCTL_VIDEO_VBOX_SETVISIBLEREGION: Output buffer too small: %d needed: %d!!!\n",
return FALSE;
return FALSE;
#ifdef VBOX_WITH_HGSMI
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
# ifdef VBOX_WITH_VIDEOHWACCEL
return FALSE;
return FALSE;
return FALSE;
if (Result)
return TRUE;
return TRUE;
VbglTerminate ();
VBoxUnmapAdapterMemory (pDevExt, &pDevExt->u.primary.pvMiniportHeap, pDevExt->u.primary.cbMiniportHeap);
VBoxUnmapAdapterMemory (pDevExt, &pDevExt->u.primary.pvAdapterInformation, VBVA_ADAPTER_INFORMATION_SIZE);
return TRUE;
return NO_ERROR;
return NO_ERROR;
int rc;
sizeof (VMMDevReqGuestCapabilities2),
VBoxVideoCmnPortWriteUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
return TRUE;
#ifndef VBOXWDDM
return TRUE;
return TRUE;
return TRUE;
dprintf(("VBoxVideo::VBoxVideoMapVideoMemory: fb offset 0x%x\n", DeviceExtension->ulFrameBufferOffset));
#ifndef VBOX_WITH_HGSMI
#ifdef VBOX_WITH_HGSMI
return TRUE;
return FALSE;
#ifdef VBOX_WITH_HGSMI
return TRUE;
return TRUE;
return TRUE;
return TRUE;
dprintf(("VBoxVideo::VBoxVideoSetColorRegisters first entry %d num entries %d\n", ColorLookUpTable->FirstEntry, ColorLookUpTable->NumEntries));
return FALSE;
Entry++)
return TRUE;
#ifndef VBOXWDDM
return VIDEO_ENUM_MORE_DEVICES;
return ERROR_NO_MORE_DEVICES;
if (pPrimaryDevExt)
if (req)
dprintf(("VBoxVideo::vboxVbvaEnable: VbglQueryVMMDevMemory rc = %d, pVMMDevMemory = %p\n", rc, pVMMDevMemory));
if ( ulEnable
return rc;
sizeof (VMMDevVideoAccelFlush),
sizeof (VMMDevVideoAccelEnable),
return rc;