VBoxVideo.cpp revision 3400a1195003605b6899c61cd77ea05053a0db48
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox Video miniport driver for NT/2k/XP
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Based on DDK sample code.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * additional information or have any questions.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#if _MSC_VER >= 1400 /* bird: MS fixed swprintf to be standard-conforming... */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern "C" int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic WCHAR VBoxAdapterString[] = L"VirtualBox Video Adapter";
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic WCHAR VBoxBiosString[] = L"Version 0xB0C2 or later";
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Globals for the last custom resolution set. This is important
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * for system startup so that we report the last currently set
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * custom resolution and Windows can use it again.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncint vboxVbvaEnable (PDEVICE_EXTENSION pDevExt, ULONG ulEnable, VBVAENABLERESULT *pVbvaResult);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncULONG DriverEntry(IN PVOID Context1, IN PVOID Context2)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoPortZeroMemory(&InitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync // nowhere documented but without the following line, NT4 SP0 will choke
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync InitData.HwGetVideoChildDescriptor = VBoxVideoGetChildDescriptor;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync InitData.HwDeviceExtensionSize = sizeof(DEVICE_EXTENSION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync // our DDK is at the Win2k3 level so we have to take special measures
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync // for backwards compatibility
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync InitData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync InitData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync rc = VideoPortInitialize(Context1, Context2, &InitData, NULL);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo::DriverEntry: returning with rc = 0x%x\n", rc));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRoutine Description:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync This routine is used to read back various registry values.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync HwDeviceExtension
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Supplies a pointer to the miniport's device extension.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Context value passed to the get registry parameters routine.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync If this is not null assume it's a ULONG* and save the data value in it.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Name of the value requested.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Pointer to the requested data.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ValueLength
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Length of the requested data.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncReturn Value:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync If the variable doesn't exist return an error,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync else if a context is supplied assume it's a PULONG and fill in the value
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and return no error, else if the value is non-zero return an error.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncVP_STATUS VBoxRegistryCallback(PVOID HwDeviceExtension, PVOID Context,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PWSTR ValueName, PVOID ValueData, ULONG ValueLength)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync //dprintf(("VBoxVideo::VBoxRegistryCallback: Context: %p, ValueName: %S, ValueData: %p, ValueLength: %d\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync // Context, ValueName, ValueData, ValueLength));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Global list of supported standard video modes. It will be
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * filled dynamically.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic VIDEO_MODE_INFORMATION VideoModes[MAX_VIDEO_MODES + 2] = { 0 };
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* number of available video modes, set by VBoxBuildModesTable */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic uint32_t g_xresNoVRAM = 0, g_yresNoVRAM = 0, g_bppNoVRAM = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Helper function to dynamically build our table of standard video
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * modes. We take the amount of VRAM and create modes with standard
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * geometries until we've either reached the maximum number of modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * or the available VRAM does not allow for additional modes.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncVOID VBoxBuildModesTable(PDEVICE_EXTENSION DeviceExtension)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* we need this static counter to always have a new mode index for our */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* custom video mode, otherwise Windows thinks there is no mode switch */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync static int gInvocationCounter = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* the resolution matrix */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* standard modes */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* multi screen modes with 1280x1024 */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* multi screen modes with 1600x1200 */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync size_t matrixSize = sizeof(resolutionMatrix) / sizeof(resolutionMatrix[0]);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* there are 4 color depths: 8, 16, 24 and 32bpp and we reserve 50% of the modes for other sources */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync size_t maxModesPerColorDepth = MAX_VIDEO_MODES / 2 / 4;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* size of the VRAM in bytes */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ULONG vramSize = DeviceExtension->pPrimary->u.primary.ulMaxFrameBufferSize;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Query the y-offset from the host
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * 8 bit video modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* are there any modes left in the matrix? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the mode fit into the VRAM? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 1 > (LONG)vramSize)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the host like that mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 8))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN |
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* a new mode has been filled in */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* advance to the next mode matrix entry */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif /* VBOX_WITH_8BPP_MODES */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * 16 bit video modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* are there any modes left in the matrix? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the mode fit into the VRAM? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 2 > (LONG)vramSize)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the host like that mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 16))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 2;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* a new mode has been filled in */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* advance to the next mode matrix entry */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * 24 bit video modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* are there any modes left in the matrix? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the mode fit into the VRAM? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 3 > (LONG)vramSize)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the host like that mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 24))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 3;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* a new mode has been filled in */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* advance to the next mode matrix entry */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * 32 bit video modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while (numModesCurrentColorDepth < maxModesPerColorDepth)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* are there any modes left in the matrix? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the mode fit into the VRAM? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (resolutionMatrix[matrixIndex].xRes * resolutionMatrix[matrixIndex].yRes * 4 > (LONG)vramSize)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the host like that mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!vboxLikesVideoMode(resolutionMatrix[matrixIndex].xRes, resolutionMatrix[matrixIndex].yRes - yOffset, 32))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = resolutionMatrix[matrixIndex].xRes * 4;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = resolutionMatrix[matrixIndex].xRes;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = resolutionMatrix[matrixIndex].yRes - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* a new mode has been filled in */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* advance to the next mode matrix entry */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Next, check the registry for additional modes
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* check if there is space in the mode list */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* upon the first error, we give up */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync swprintf(keyname, L"CustomMode%dHeight", curKeyNo);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* upon the first error, we give up */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortGetRegistryParameters(DeviceExtension->pPrimary,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* upon the first error, we give up */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: custom mode %u returned: xres = %u, yres = %u, bpp = %u\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* first test: do the values make sense? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* round down width to be a multiple of 8 */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* second test: does it fit within our VRAM? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* third test: does the host like the video mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: adding mode from registry: xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Build mode entry.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Note that we have to apply the y offset for the custom mode.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VisScreenHeight = yres - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = xres * (bpp / 8);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = xres;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = yres - yOffset;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* next run */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* only support 128 modes for now */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync } while(1);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Now we ask the host for a display change request. If there's one,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * this will be appended as a special mode so that it can be used by
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * the Additions service process. The mode table is guaranteed to have
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * two spare entries for this mode (alternating index thus 2).
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: adding custom video mode as #%d, current mode: %d \n", gNumVideoModes + 1, DeviceExtension->CurrentMode));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* handle the startup case */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: using stored custom resolution %dx%dx%d\n", xres, yres, bpp));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* round down to multiple of 8 */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: rounding down xres from %d to %d\n", xres, xres & 0xfff8));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* take the current values for the fields that are not set */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* does the host like that mode? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* we must have a valid video mode by now and it must fit within the VRAM */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* we need an alternating index */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: setting special mode to xres = %d, yres = %d, bpp = %d\n", xres, yres, bpp));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Build mode entry.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Note that we do not apply the y offset for the custom mode. It is
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * only used for the predefined modes that the user can configure in
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * the display properties dialog.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].Length = sizeof(VIDEO_MODE_INFORMATION);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ScreenStride = xres * (bpp / 8);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | VIDEO_MODE_NO_OFF_SCREEN;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapWidth = xres;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].VideoMemoryBitmapHeight = yres;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].DriverSpecificAttributeFlags = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* for the startup case, we need this mode twice due to the alternating mode number */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: making a copy of the custom mode as #%d\n", gNumVideoModes + 1));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync memcpy(&VideoModes[gNumVideoModes], &VideoModes[gNumVideoModes - 1], sizeof(VIDEO_MODE_INFORMATION));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[gNumVideoModes].ModeIndex = gNumVideoModes + 1;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* store this video mode as the last custom video mode */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomXRes",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: error %d writing CustomXRes\n", status));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomYRes",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: error %d writing CustomYRes\n", status));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync status = VideoPortSetRegistryParameters(DeviceExtension, L"CustomBPP",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: error %d writing CustomBPP\n", status));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: invalid parameters for special mode: (xres = %d, yres = %d, bpp = %d, vramSize = %d)\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync && (xres != g_xresNoVRAM || yres != g_yresNoVRAM || bpp != g_bppNoVRAM))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync LogRel(("VBoxVideo: not enough VRAM for video mode %dx%dx%dbpp. Available: %d bytes. Required: more than %d bytes.\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xres, yres, bpp, vramSize, xres * yres * (bpp / 8)));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: host does not like special mode: (xres = %d, yres = %d, bpp = %d)\n",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dprintf(("VBoxVideo: VideoModes (CurrentMode = %d)\n", DeviceExtension->CurrentMode));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync VideoModes[i].VisScreenHeight, VideoModes[i].BitsPerPlane));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* Computes the size of a framebuffer. DualView has a few framebuffers of the computed size. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncvoid VBoxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ULONG ulAvailable = PrimaryExtension->u.primary.cbVRAM
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;
&VideoRamBase);
return Status;
if (*ppv)
#ifndef VBOX_WITH_HGSMI
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",
sizeof(VBoxChipType));
sizeof(VBoxDACType));
sizeof(ULONG));
sizeof(VBoxAdapterString));
sizeof(VBoxBiosString));
#ifndef VBOX_WITH_HGSMI
if (VBoxHGSMIIsSupported ())
return rc;
&gCustomXRes);
gCustomXRes = 0;
&gCustomYRes);
gCustomYRes = 0;
&gCustomBPP);
gCustomBPP = 0;
dprintf(("VBoxVideo: got stored custom resolution %dx%dx%d\n", gCustomXRes, gCustomYRes, gCustomBPP));
return TRUE;
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())
#ifndef VBOX_WITH_HGSMI
Result = vboxUpdatePointerShape((PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));
if (!Result)
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;
dprintf(("VBoxVideo::VBoxVideoStartIO: Failed with rc=%x (hdr.rc=%x)\n", rc, (req) ? req->header.rc : -1));
return FALSE;
#ifdef VBOX_WITH_HGSMI
return FALSE;
return FALSE;
return FALSE;
if (Result)
return TRUE;
return TRUE;
VbglTerminate ();
return TRUE;
return NO_ERROR;
return NO_ERROR;
int rc;
sizeof (VMMDevReqGuestCapabilities2),
dprintf(("VBoxVideoSetGraphicsCap: request failed, rc = %Rrc, VMMDev rc = %Rrc\n", rc, req->header.rc));
return TRUE;
VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
return TRUE;
return TRUE;
return TRUE;
#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;
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;