[36867] | 1 | /* $Id: VBoxMPDriver.cpp 99828 2023-05-17 13:48:57Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * VBox XPDM Miniport driver interface functions
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2011-2023 Oracle and/or its affiliates.
|
---|
[36867] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
[36867] | 26 | */
|
---|
| 27 |
|
---|
[63549] | 28 |
|
---|
[63039] | 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
[36867] | 32 | #include "VBoxMPInternal.h"
|
---|
[65381] | 33 | #include <VBoxVideoVBE.h>
|
---|
[36867] | 34 | #include <VBox/VBoxGuestLib.h>
|
---|
[65381] | 35 | #include <VBoxVideo.h>
|
---|
[36867] | 36 | #include "common/VBoxMPHGSMI.h"
|
---|
| 37 | #include "common/VBoxMPCommon.h"
|
---|
| 38 | #include "VBoxDisplay.h"
|
---|
| 39 | #include <iprt/initterm.h>
|
---|
[55210] | 40 | #include <VBox/version.h>
|
---|
[36867] | 41 |
|
---|
[63039] | 42 |
|
---|
| 43 | /*********************************************************************************************************************************
|
---|
| 44 | * Global Variables *
|
---|
| 45 | *********************************************************************************************************************************/
|
---|
[93299] | 46 | /** Legacy VGA resource list. */
|
---|
[63039] | 47 | static VIDEO_ACCESS_RANGE g_aVBoxLegacyVGAResources[] =
|
---|
[36867] | 48 | {
|
---|
[93299] | 49 | /* RangeStart Length I V S P
|
---|
| 50 | n i h a
|
---|
| 51 | I s a s
|
---|
| 52 | o i r s
|
---|
| 53 | S b a i
|
---|
| 54 | p l b v
|
---|
| 55 | a e l e
|
---|
| 56 | c e
|
---|
| 57 | e */
|
---|
| 58 | { {0x000003B0, 0x00000000}, 0x0000000C, 1, 1, 1, 0 }, /* VGA regs (0x3B0-0x3BB) */
|
---|
| 59 | { {0x000003C0, 0x00000000}, 0x00000020, 1, 1, 1, 0 }, /* VGA regs (0x3C0-0x3DF) */
|
---|
| 60 | { {0x000A0000, 0x00000000}, 0x00020000, 0, 0, 1, 0 }, /* Frame buffer (0xA0000-0xBFFFF) */
|
---|
[36867] | 61 | };
|
---|
| 62 |
|
---|
| 63 | /* Card info for property dialog */
|
---|
[63039] | 64 | static WCHAR g_wszVBoxChipType[] = L"VBOX";
|
---|
| 65 | static WCHAR g_wszVBoxDACType[] = L"Integrated RAMDAC";
|
---|
| 66 | static WCHAR g_wszVBoxAdapterString[] = L"VirtualBox Video Adapter";
|
---|
| 67 | static WCHAR g_wszVBoxBiosString[] = L"Version 0xB0C2 or later";
|
---|
[36867] | 68 |
|
---|
[63039] | 69 |
|
---|
[36867] | 70 | /* Checks if we have a device supported by our driver and initialize
|
---|
| 71 | * our driver/card specific information.
|
---|
| 72 | * In particular we obtain VM monitors configuration and configure related structures.
|
---|
| 73 | */
|
---|
| 74 | static VP_STATUS
|
---|
| 75 | VBoxDrvFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PWSTR ArgumentString,
|
---|
| 76 | IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo, OUT PUCHAR Again)
|
---|
| 77 | {
|
---|
[63039] | 78 | RT_NOREF(HwContext, ArgumentString, Again);
|
---|
[36867] | 79 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 80 | VP_STATUS rc;
|
---|
| 81 | USHORT DispiId;
|
---|
[40566] | 82 | ULONG cbVRAM = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES;
|
---|
| 83 | PHYSICAL_ADDRESS phVRAM = {0};
|
---|
| 84 | ULONG ulApertureSize = 0;
|
---|
[36867] | 85 |
|
---|
| 86 | PAGED_CODE();
|
---|
| 87 | LOGF_ENTER();
|
---|
| 88 |
|
---|
| 89 | /* Init video port api */
|
---|
| 90 | VBoxSetupVideoPortAPI(pExt, ConfigInfo);
|
---|
| 91 |
|
---|
| 92 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
|
---|
| 93 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID2);
|
---|
| 94 | DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA);
|
---|
| 95 |
|
---|
| 96 | if (DispiId != VBE_DISPI_ID2)
|
---|
| 97 | {
|
---|
| 98 | WARN(("VBE card not found, returning ERROR_DEV_NOT_EXIST"));
|
---|
| 99 | return ERROR_DEV_NOT_EXIST;
|
---|
| 100 | }
|
---|
| 101 | LOG(("found the VBE card"));
|
---|
| 102 |
|
---|
| 103 | /*
|
---|
| 104 | * Query the adapter's memory size. It's a bit of a hack, we just read
|
---|
| 105 | * an ULONG from the data port without setting an index before.
|
---|
| 106 | */
|
---|
[40566] | 107 | cbVRAM = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA);
|
---|
[36867] | 108 |
|
---|
| 109 | /* Write hw information to registry, so that it's visible in windows property dialog */
|
---|
[99828] | 110 | rc = VideoPortSetRegistryParameters(pExt, (PWSTR)L"HardwareInformation.ChipType",
|
---|
[63039] | 111 | g_wszVBoxChipType, sizeof(g_wszVBoxChipType));
|
---|
[36867] | 112 | VBOXMP_WARN_VPS(rc);
|
---|
[99828] | 113 | rc = VideoPortSetRegistryParameters(pExt, (PWSTR)L"HardwareInformation.DacType",
|
---|
[63039] | 114 | g_wszVBoxDACType, sizeof(g_wszVBoxDACType));
|
---|
[36867] | 115 | VBOXMP_WARN_VPS(rc);
|
---|
[99828] | 116 | rc = VideoPortSetRegistryParameters(pExt, (PWSTR)L"HardwareInformation.MemorySize",
|
---|
[40566] | 117 | &cbVRAM, sizeof(ULONG));
|
---|
[36867] | 118 | VBOXMP_WARN_VPS(rc);
|
---|
[99828] | 119 | rc = VideoPortSetRegistryParameters(pExt, (PWSTR)L"HardwareInformation.AdapterString",
|
---|
[63039] | 120 | g_wszVBoxAdapterString, sizeof(g_wszVBoxAdapterString));
|
---|
[36867] | 121 | VBOXMP_WARN_VPS(rc);
|
---|
[99828] | 122 | rc = VideoPortSetRegistryParameters(pExt, (PWSTR)L"HardwareInformation.BiosString",
|
---|
[63039] | 123 | g_wszVBoxBiosString, sizeof(g_wszVBoxBiosString));
|
---|
[36867] | 124 | VBOXMP_WARN_VPS(rc);
|
---|
| 125 |
|
---|
[40489] | 126 | /* Call VideoPortGetAccessRanges to ensure interrupt info in ConfigInfo gets set up
|
---|
| 127 | * and to get LFB aperture data.
|
---|
| 128 | */
|
---|
[36867] | 129 | {
|
---|
| 130 | VIDEO_ACCESS_RANGE tmpRanges[4];
|
---|
| 131 | ULONG slot = 0;
|
---|
| 132 |
|
---|
| 133 | VideoPortZeroMemory(tmpRanges, sizeof(tmpRanges));
|
---|
| 134 |
|
---|
[75403] | 135 | if (VBoxQueryWinVersion(NULL) == WINVERSION_NT4)
|
---|
[36867] | 136 | {
|
---|
| 137 | /* NT crashes if either of 'vendorId, 'deviceId' or 'slot' parameters is NULL,
|
---|
| 138 | * and needs PCI ids for a successful VideoPortGetAccessRanges call.
|
---|
| 139 | */
|
---|
| 140 | ULONG vendorId = 0x80EE;
|
---|
| 141 | ULONG deviceId = 0xBEEF;
|
---|
[37384] | 142 | rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges,
|
---|
[36867] | 143 | &vendorId, &deviceId, &slot);
|
---|
| 144 | }
|
---|
| 145 | else
|
---|
| 146 | {
|
---|
| 147 | rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges, NULL, NULL, &slot);
|
---|
| 148 | }
|
---|
| 149 | VBOXMP_WARN_VPS(rc);
|
---|
[40489] | 150 | if (rc != NO_ERROR) {
|
---|
| 151 | return rc;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
[75468] | 154 | /* The first non-IO range is the framebuffer. We require that information. */
|
---|
| 155 | for (int iRange = 0; iRange < RT_ELEMENTS(tmpRanges); ++iRange)
|
---|
| 156 | {
|
---|
| 157 | if (!tmpRanges[iRange].RangeInIoSpace)
|
---|
| 158 | {
|
---|
| 159 | phVRAM = tmpRanges[iRange].RangeStart;
|
---|
| 160 | ulApertureSize = tmpRanges[iRange].RangeLength;
|
---|
| 161 | break;
|
---|
| 162 | }
|
---|
| 163 | }
|
---|
[36867] | 164 | }
|
---|
| 165 |
|
---|
| 166 | /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */
|
---|
[68550] | 167 | rc = VbglR0InitClient();
|
---|
[36867] | 168 | VBOXMP_WARN_VPS(rc);
|
---|
| 169 |
|
---|
| 170 | /* Preinitialize the primary extension. */
|
---|
| 171 | pExt->pNext = NULL;
|
---|
| 172 | pExt->pPrimary = pExt;
|
---|
| 173 | pExt->iDevice = 0;
|
---|
| 174 | pExt->ulFrameBufferOffset = 0;
|
---|
| 175 | pExt->ulFrameBufferSize = 0;
|
---|
| 176 | pExt->u.primary.ulVbvaEnabled = 0;
|
---|
| 177 | VideoPortZeroMemory(&pExt->areaDisplay, sizeof(HGSMIAREA));
|
---|
| 178 |
|
---|
| 179 | /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old
|
---|
| 180 | * code will be ifdef'ed and later removed.
|
---|
| 181 | * The host will however support both old and new interface to keep compatibility
|
---|
| 182 | * with old guest additions.
|
---|
| 183 | */
|
---|
[40566] | 184 | VBoxSetupDisplaysHGSMI(&pExt->u.primary.commonInfo, phVRAM, ulApertureSize, cbVRAM, 0);
|
---|
[36867] | 185 |
|
---|
[45037] | 186 | /* Check if the chip restricts horizontal resolution or not.
|
---|
| 187 | * Must be done after VBoxSetupDisplaysHGSMI, because it initializes the common structure.
|
---|
| 188 | */
|
---|
| 189 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
|
---|
| 190 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
|
---|
| 191 | DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA);
|
---|
| 192 |
|
---|
| 193 | if (DispiId == VBE_DISPI_ID_ANYX)
|
---|
| 194 | VBoxCommonFromDeviceExt(pExt)->fAnyX = TRUE;
|
---|
| 195 | else
|
---|
| 196 | VBoxCommonFromDeviceExt(pExt)->fAnyX = FALSE;
|
---|
| 197 |
|
---|
[36867] | 198 | if (pExt->u.primary.commonInfo.bHGSMI)
|
---|
| 199 | {
|
---|
| 200 | LOGREL(("using HGSMI"));
|
---|
| 201 | VBoxCreateDisplays(pExt, ConfigInfo);
|
---|
| 202 | }
|
---|
| 203 |
|
---|
[37384] | 204 | /** @todo pretend success to make the driver work. */
|
---|
[36867] | 205 | rc = NO_ERROR;
|
---|
| 206 |
|
---|
| 207 | LOGF_LEAVE();
|
---|
| 208 | VBOXMP_WARN_VPS(rc);
|
---|
| 209 | return rc;
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | /* Initial device configuration. */
|
---|
| 213 | static BOOLEAN
|
---|
| 214 | VBoxDrvInitialize(PVOID HwDeviceExtension)
|
---|
| 215 | {
|
---|
| 216 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 217 |
|
---|
| 218 | PAGED_CODE();
|
---|
| 219 | LOGF_ENTER();
|
---|
| 220 |
|
---|
| 221 | /* Initialize the request pointer. */
|
---|
| 222 | pExt->u.primary.pvReqFlush = NULL;
|
---|
| 223 |
|
---|
| 224 | VBoxMPCmnInitCustomVideoModes(pExt);
|
---|
| 225 |
|
---|
| 226 | LOGF_LEAVE();
|
---|
| 227 | return TRUE;
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | /* VBoxDrvStartIO parameter check helper macros */
|
---|
| 231 | #define STARTIO_IN(_type, _name) \
|
---|
| 232 | _type *_name = (_type*) RequestPacket->InputBuffer; \
|
---|
| 233 | if (RequestPacket->InputBufferLength < sizeof(_type)) \
|
---|
| 234 | { \
|
---|
| 235 | WARN(("Input buffer too small %d/%d bytes", \
|
---|
| 236 | RequestPacket->InputBufferLength, sizeof(_type))); \
|
---|
| 237 | pStatus->Status = ERROR_INSUFFICIENT_BUFFER; \
|
---|
| 238 | break; \
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | #define STARTIO_OUT(_type, _name) \
|
---|
| 242 | _type *_name = (_type*) RequestPacket->OutputBuffer; \
|
---|
| 243 | if (RequestPacket->OutputBufferLength < sizeof(_type)) \
|
---|
| 244 | { \
|
---|
| 245 | WARN(("Output buffer too small %d/%d bytes", \
|
---|
| 246 | RequestPacket->OutputBufferLength, sizeof(_type))); \
|
---|
| 247 | pStatus->Status = ERROR_INSUFFICIENT_BUFFER; \
|
---|
| 248 | break; \
|
---|
| 249 | }
|
---|
| 250 |
|
---|
| 251 | /* Process Video Request Packet. */
|
---|
| 252 | static BOOLEAN
|
---|
| 253 | VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
|
---|
| 254 | {
|
---|
| 255 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 256 | PSTATUS_BLOCK pStatus = RequestPacket->StatusBlock;
|
---|
| 257 | BOOLEAN bResult = FALSE;
|
---|
| 258 |
|
---|
| 259 | PAGED_CODE();
|
---|
| 260 |
|
---|
[66826] | 261 | LOGF(("IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF));
|
---|
[36867] | 262 |
|
---|
| 263 | pStatus->Status = NO_ERROR;
|
---|
| 264 |
|
---|
| 265 | switch (RequestPacket->IoControlCode)
|
---|
| 266 | {
|
---|
| 267 | /* ==================== System VRPs ==================== */
|
---|
| 268 |
|
---|
| 269 | /*Maps FrameBuffer and video RAM to a caller's virtual adress space.*/
|
---|
| 270 | case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
|
---|
| 271 | {
|
---|
| 272 | STARTIO_IN(VIDEO_MEMORY, pMemory);
|
---|
| 273 | STARTIO_OUT(VIDEO_MEMORY_INFORMATION, pMemInfo);
|
---|
| 274 |
|
---|
| 275 | bResult = VBoxMPMapVideoMemory(pExt, pMemory, pMemInfo, pStatus);
|
---|
| 276 | break;
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | /*Unmaps previously mapped FrameBuffer and video RAM from caller's virtual adress space.*/
|
---|
| 280 | case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
|
---|
| 281 | {
|
---|
| 282 | STARTIO_IN(VIDEO_MEMORY, pMemory);
|
---|
| 283 |
|
---|
| 284 | bResult = VBoxMPUnmapVideoMemory(pExt, pMemory, pStatus);
|
---|
| 285 | break;
|
---|
| 286 | }
|
---|
| 287 |
|
---|
| 288 | /*Maps FrameBuffer as a linear frame buffer to a caller's virtual adress space. (obsolete)*/
|
---|
| 289 | case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
|
---|
| 290 | {
|
---|
| 291 | STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory);
|
---|
| 292 | STARTIO_OUT(VIDEO_SHARE_MEMORY_INFORMATION, pShareMemInfo);
|
---|
| 293 |
|
---|
| 294 | bResult = VBoxMPShareVideoMemory(pExt, pShareMemory, pShareMemInfo, pStatus);
|
---|
| 295 | break;
|
---|
| 296 | }
|
---|
| 297 |
|
---|
| 298 | /*Unmaps framebuffer previously mapped with IOCTL_VIDEO_SHARE_VIDEO_MEMORY*/
|
---|
| 299 | case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
|
---|
| 300 | {
|
---|
| 301 | STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory);
|
---|
| 302 |
|
---|
| 303 | bResult = VBoxMPUnshareVideoMemory(pExt, pShareMemory, pStatus);
|
---|
| 304 | break;
|
---|
| 305 | }
|
---|
| 306 |
|
---|
| 307 | /*Reset device to a state it comes at system boot time.*/
|
---|
| 308 | case IOCTL_VIDEO_RESET_DEVICE:
|
---|
| 309 | {
|
---|
| 310 | bResult = VBoxMPResetDevice(pExt, pStatus);
|
---|
| 311 | break;
|
---|
| 312 | }
|
---|
| 313 |
|
---|
| 314 | /*Set adapter video mode.*/
|
---|
| 315 | case IOCTL_VIDEO_SET_CURRENT_MODE:
|
---|
| 316 | {
|
---|
| 317 | STARTIO_IN(VIDEO_MODE, pMode);
|
---|
| 318 |
|
---|
| 319 | bResult = VBoxMPSetCurrentMode(pExt, pMode, pStatus);
|
---|
| 320 | break;
|
---|
| 321 | }
|
---|
| 322 |
|
---|
| 323 | /*Returns information about current video mode.*/
|
---|
| 324 | case IOCTL_VIDEO_QUERY_CURRENT_MODE:
|
---|
| 325 | {
|
---|
| 326 | STARTIO_OUT(VIDEO_MODE_INFORMATION, pModeInfo);
|
---|
| 327 |
|
---|
| 328 | bResult = VBoxMPQueryCurrentMode(pExt, pModeInfo, pStatus);
|
---|
| 329 | break;
|
---|
| 330 | }
|
---|
| 331 |
|
---|
[37384] | 332 | /* Returns count of supported video modes and structure size in bytes,
|
---|
[36867] | 333 | * used to allocate buffer for the following IOCTL_VIDEO_QUERY_AVAIL_MODES call.
|
---|
| 334 | */
|
---|
| 335 | case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
|
---|
| 336 | {
|
---|
| 337 | STARTIO_OUT(VIDEO_NUM_MODES, pNumModes);
|
---|
| 338 |
|
---|
| 339 | bResult = VBoxMPQueryNumAvailModes(pExt, pNumModes, pStatus);
|
---|
| 340 | break;
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | /* Returns information about supported video modes. */
|
---|
| 344 | case IOCTL_VIDEO_QUERY_AVAIL_MODES:
|
---|
| 345 | {
|
---|
| 346 | PVIDEO_MODE_INFORMATION pModes = (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer;
|
---|
| 347 |
|
---|
[49450] | 348 | if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION))
|
---|
[36867] | 349 | {
|
---|
| 350 | pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
|
---|
| 351 | break;
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 | bResult = VBoxMPQueryAvailModes(pExt, pModes, pStatus);
|
---|
| 355 | break;
|
---|
| 356 | }
|
---|
| 357 |
|
---|
| 358 | /* Sets adapter's color registers, have to be implemented if we support palette based modes. */
|
---|
| 359 | case IOCTL_VIDEO_SET_COLOR_REGISTERS:
|
---|
| 360 | {
|
---|
| 361 | STARTIO_IN(VIDEO_CLUT, pClut);
|
---|
| 362 |
|
---|
| 363 | if (RequestPacket->InputBufferLength < (sizeof(VIDEO_CLUT) + pClut->NumEntries * sizeof(ULONG)))
|
---|
| 364 | {
|
---|
| 365 | pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
|
---|
| 366 | break;
|
---|
| 367 | }
|
---|
| 368 |
|
---|
| 369 | bResult = VBoxMPSetColorRegisters(pExt, pClut, pStatus);
|
---|
| 370 | break;
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | /* Sets pointer attributes. */
|
---|
| 374 | case IOCTL_VIDEO_SET_POINTER_ATTR:
|
---|
| 375 | {
|
---|
| 376 | STARTIO_IN(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs);
|
---|
| 377 |
|
---|
| 378 | bResult = VBoxMPSetPointerAttr(pExt, pPointerAttrs, RequestPacket->InputBufferLength, pStatus);
|
---|
| 379 | break;
|
---|
| 380 | }
|
---|
| 381 |
|
---|
| 382 | /* Makes pointer visible. */
|
---|
| 383 | case IOCTL_VIDEO_ENABLE_POINTER:
|
---|
| 384 | {
|
---|
| 385 | bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus);
|
---|
| 386 | break;
|
---|
| 387 | }
|
---|
| 388 |
|
---|
| 389 | /* Hides pointer. */
|
---|
| 390 | case IOCTL_VIDEO_DISABLE_POINTER:
|
---|
| 391 | {
|
---|
| 392 | bResult = VBoxMPEnablePointer(pExt, FALSE, pStatus);
|
---|
| 393 | break;
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | /* Sets pointer position, is called after IOCTL_VIDEO_ENABLE_POINTER. */
|
---|
| 397 | case IOCTL_VIDEO_SET_POINTER_POSITION:
|
---|
| 398 | {
|
---|
| 399 | STARTIO_IN(VIDEO_POINTER_POSITION, pPos);
|
---|
| 400 |
|
---|
[63039] | 401 | NOREF(pPos); /** @todo set pointer position*/
|
---|
[36867] | 402 | bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus);
|
---|
| 403 | break;
|
---|
| 404 | }
|
---|
| 405 |
|
---|
| 406 | /* Query pointer position. */
|
---|
| 407 | case IOCTL_VIDEO_QUERY_POINTER_POSITION:
|
---|
| 408 | {
|
---|
| 409 | STARTIO_OUT(VIDEO_POINTER_POSITION, pPos);
|
---|
| 410 |
|
---|
| 411 | bResult = VBoxMPQueryPointerPosition(pExt, pPos, pStatus);
|
---|
| 412 | break;
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | /* Query supported hardware pointer feaures. */
|
---|
| 416 | case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
|
---|
| 417 | {
|
---|
| 418 | STARTIO_OUT(VIDEO_POINTER_CAPABILITIES, pCaps);
|
---|
| 419 |
|
---|
| 420 | bResult = VBoxMPQueryPointerCapabilities(pExt, pCaps, pStatus);
|
---|
| 421 | break;
|
---|
| 422 | }
|
---|
| 423 |
|
---|
| 424 | /* Query pointer attributes. (optional) */
|
---|
| 425 | case IOCTL_VIDEO_QUERY_POINTER_ATTR:
|
---|
| 426 | {
|
---|
| 427 | STARTIO_OUT(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs);
|
---|
| 428 |
|
---|
[63039] | 429 | NOREF(pPointerAttrs); /* Not Implemented */
|
---|
[36867] | 430 | pStatus->Status = ERROR_INVALID_FUNCTION;
|
---|
| 431 |
|
---|
| 432 | bResult = FALSE;
|
---|
| 433 | break;
|
---|
| 434 | }
|
---|
| 435 |
|
---|
| 436 | /* Called when a secondary adapter is about to be enabled/disabled. */
|
---|
| 437 | case IOCTL_VIDEO_SWITCH_DUALVIEW:
|
---|
| 438 | {
|
---|
| 439 | STARTIO_IN(ULONG, pAttach);
|
---|
| 440 |
|
---|
[41044] | 441 | LOGF(("IOCTL_VIDEO_SWITCH_DUALVIEW: [%d] attach = %d", pExt->iDevice, *pAttach));
|
---|
| 442 |
|
---|
[36867] | 443 | if (pExt->iDevice>0)
|
---|
| 444 | {
|
---|
| 445 | pExt->u.secondary.bEnabled = (BOOLEAN)(*pAttach);
|
---|
[41044] | 446 |
|
---|
| 447 | /* Inform the host.
|
---|
| 448 | * Currently only about secondary devices, because the driver does not support
|
---|
| 449 | * disconnecting the primary display (it does not allow to change the primary display).
|
---|
| 450 | */
|
---|
| 451 | if (!pExt->u.secondary.bEnabled)
|
---|
| 452 | {
|
---|
| 453 | PVBOXMP_COMMON pCommon = VBoxCommonFromDeviceExt(pExt);
|
---|
| 454 | if (pCommon->bHGSMI)
|
---|
| 455 | {
|
---|
| 456 | VBoxHGSMIProcessDisplayInfo(&pCommon->guestCtx, pExt->iDevice,
|
---|
| 457 | /* cOriginX = */ 0, /* cOriginY = */ 0,
|
---|
| 458 | /* offStart = */ 0, /* cbPitch = */ 0,
|
---|
| 459 | /* cWidth = */ 0, /* cHeight = */ 0, /* cBPP = */ 0,
|
---|
| 460 | VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED);
|
---|
| 461 | }
|
---|
| 462 | }
|
---|
[36867] | 463 | }
|
---|
| 464 |
|
---|
| 465 | bResult = TRUE;
|
---|
| 466 | break;
|
---|
| 467 | }
|
---|
| 468 |
|
---|
| 469 | /* Called to get child device status */
|
---|
| 470 | case IOCTL_VIDEO_GET_CHILD_STATE:
|
---|
| 471 | {
|
---|
| 472 | STARTIO_IN(ULONG, pChildIndex);
|
---|
| 473 | STARTIO_OUT(ULONG, pChildState);
|
---|
| 474 |
|
---|
[41044] | 475 | LOGF(("IOCTL_VIDEO_GET_CHILD_STATE: [%d] idx = %d", pExt->iDevice, *pChildIndex));
|
---|
| 476 |
|
---|
[36867] | 477 | if (*pChildIndex>0 && *pChildIndex<=(ULONG)VBoxCommonFromDeviceExt(pExt)->cDisplays)
|
---|
| 478 | {
|
---|
| 479 | *pChildState = VIDEO_CHILD_ACTIVE;
|
---|
| 480 | pStatus->Information = sizeof(ULONG);
|
---|
| 481 | bResult = TRUE;
|
---|
| 482 | }
|
---|
| 483 | else
|
---|
| 484 | {
|
---|
| 485 | pStatus->Status = ERROR_INVALID_PARAMETER;
|
---|
| 486 | bResult = FALSE;
|
---|
| 487 | }
|
---|
| 488 |
|
---|
| 489 | break;
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | /* ==================== VirtualBox specific VRPs ==================== */
|
---|
| 493 |
|
---|
| 494 | /* Called by the display driver when it is ready to switch to VBVA operation mode. */
|
---|
| 495 | case IOCTL_VIDEO_VBVA_ENABLE:
|
---|
| 496 | {
|
---|
| 497 | STARTIO_IN(ULONG, pEnable);
|
---|
| 498 | STARTIO_OUT(VBVAENABLERESULT, pResult);
|
---|
| 499 |
|
---|
| 500 | bResult = VBoxMPVBVAEnable(pExt, (BOOLEAN)*pEnable, pResult, pStatus);
|
---|
| 501 | break;
|
---|
| 502 | }
|
---|
| 503 |
|
---|
| 504 | /* Called by the display driver when it recieves visible regions information. */
|
---|
| 505 | case IOCTL_VIDEO_VBOX_SETVISIBLEREGION:
|
---|
| 506 | {
|
---|
| 507 | STARTIO_IN(RTRECT, pRects);
|
---|
| 508 |
|
---|
| 509 | uint32_t cRects = RequestPacket->InputBufferLength/sizeof(RTRECT);
|
---|
| 510 | /*Sanity check*/
|
---|
[37384] | 511 | if ( cRects > _1M
|
---|
| 512 | || RequestPacket->InputBufferLength != cRects * sizeof(RTRECT))
|
---|
[36867] | 513 | {
|
---|
| 514 | pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
|
---|
| 515 | break;
|
---|
| 516 | }
|
---|
| 517 |
|
---|
| 518 | bResult = VBoxMPSetVisibleRegion(cRects, pRects, pStatus);
|
---|
| 519 | break;
|
---|
| 520 | }
|
---|
| 521 |
|
---|
| 522 | /* Returns video port api function pointers. */
|
---|
| 523 | case IOCTL_VIDEO_HGSMI_QUERY_PORTPROCS:
|
---|
| 524 | {
|
---|
| 525 | STARTIO_OUT(HGSMIQUERYCPORTPROCS, pProcs);
|
---|
| 526 |
|
---|
| 527 | bResult = VBoxMPHGSMIQueryPortProcs(pExt, pProcs, pStatus);
|
---|
| 528 | break;
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 | /* Returns HGSMI related callbacks. */
|
---|
| 532 | case IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS:
|
---|
| 533 | {
|
---|
| 534 | STARTIO_OUT(HGSMIQUERYCALLBACKS, pCallbacks);
|
---|
| 535 |
|
---|
| 536 | bResult = VBoxMPHGSMIQueryCallbacks(pExt, pCallbacks, pStatus);
|
---|
| 537 | break;
|
---|
| 538 | }
|
---|
| 539 |
|
---|
| 540 | /* Returns hgsmi info for this adapter. */
|
---|
| 541 | case IOCTL_VIDEO_QUERY_HGSMI_INFO:
|
---|
| 542 | {
|
---|
| 543 | STARTIO_OUT(QUERYHGSMIRESULT, pResult);
|
---|
| 544 |
|
---|
| 545 | bResult = VBoxMPQueryHgsmiInfo(pExt, pResult, pStatus);
|
---|
| 546 | break;
|
---|
| 547 | }
|
---|
| 548 |
|
---|
| 549 | /* Enables HGSMI miniport channel. */
|
---|
| 550 | case IOCTL_VIDEO_HGSMI_HANDLER_ENABLE:
|
---|
| 551 | {
|
---|
| 552 | STARTIO_IN(HGSMIHANDLERENABLE, pChannel);
|
---|
| 553 |
|
---|
| 554 | bResult = VBoxMPHgsmiHandlerEnable(pExt, pChannel, pStatus);
|
---|
| 555 | break;
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | case IOCTL_VIDEO_HGSMI_HANDLER_DISABLE:
|
---|
| 559 | {
|
---|
[37384] | 560 | /** @todo not implemented */
|
---|
[36867] | 561 | break;
|
---|
| 562 | }
|
---|
| 563 |
|
---|
| 564 | #ifdef VBOX_WITH_VIDEOHWACCEL
|
---|
| 565 | /* Returns framebuffer offset. */
|
---|
| 566 | case IOCTL_VIDEO_VHWA_QUERY_INFO:
|
---|
| 567 | {
|
---|
| 568 | STARTIO_OUT(VHWAQUERYINFO, pInfo);
|
---|
| 569 |
|
---|
| 570 | bResult = VBoxMPVhwaQueryInfo(pExt, pInfo, pStatus);
|
---|
| 571 | break;
|
---|
| 572 | }
|
---|
| 573 | #endif
|
---|
[42233] | 574 |
|
---|
| 575 | case IOCTL_VIDEO_VBOX_ISANYX:
|
---|
| 576 | {
|
---|
| 577 | STARTIO_OUT(uint32_t, pu32AnyX);
|
---|
[45037] | 578 | *pu32AnyX = VBoxCommonFromDeviceExt(pExt)->fAnyX;
|
---|
[42233] | 579 | pStatus->Information = sizeof (uint32_t);
|
---|
| 580 | bResult = TRUE;
|
---|
| 581 | break;
|
---|
| 582 | }
|
---|
| 583 |
|
---|
[46896] | 584 | case IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO:
|
---|
| 585 | {
|
---|
| 586 | STARTIO_IN(ULONG, pulInfoLevel);
|
---|
| 587 | if (*pulInfoLevel == VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS)
|
---|
| 588 | {
|
---|
| 589 | STARTIO_OUT(ULONG, pulFlags);
|
---|
| 590 | bResult = VBoxMPQueryRegistryFlags(pExt, pulFlags, pStatus);
|
---|
| 591 | }
|
---|
| 592 | else
|
---|
| 593 | {
|
---|
| 594 | pStatus->Status = ERROR_INVALID_PARAMETER;
|
---|
| 595 | bResult = FALSE;
|
---|
| 596 | }
|
---|
[48944] | 597 |
|
---|
[46896] | 598 | break;
|
---|
| 599 | }
|
---|
| 600 |
|
---|
[36867] | 601 | default:
|
---|
| 602 | {
|
---|
[66826] | 603 | WARN(("unsupported IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF));
|
---|
[36867] | 604 | RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
|
---|
| 605 | }
|
---|
| 606 | }
|
---|
| 607 |
|
---|
| 608 | if (!bResult)
|
---|
| 609 | {
|
---|
| 610 | pStatus->Information = NULL;
|
---|
| 611 | }
|
---|
| 612 |
|
---|
| 613 | VBOXMP_WARN_VPS(pStatus->Status);
|
---|
| 614 | LOGF_LEAVE();
|
---|
| 615 | return TRUE;
|
---|
| 616 | }
|
---|
| 617 |
|
---|
[37384] | 618 | /* Called to set out hardware into desired power state, not supported at the moment.
|
---|
[36867] | 619 | * Required to return NO_ERROR always.
|
---|
| 620 | */
|
---|
| 621 | static VP_STATUS
|
---|
| 622 | VBoxDrvSetPowerState(PVOID HwDeviceExtension, ULONG HwId, PVIDEO_POWER_MANAGEMENT VideoPowerControl)
|
---|
| 623 | {
|
---|
| 624 | PAGED_CODE();
|
---|
| 625 | LOGF_ENTER();
|
---|
| 626 |
|
---|
| 627 | /*Not implemented*/
|
---|
[63039] | 628 | RT_NOREF(HwDeviceExtension, HwId, VideoPowerControl);
|
---|
[36867] | 629 |
|
---|
| 630 | LOGF_LEAVE();
|
---|
| 631 | return NO_ERROR;
|
---|
| 632 | }
|
---|
| 633 |
|
---|
| 634 | /* Called to check if our hardware supports given power state. */
|
---|
| 635 | static VP_STATUS
|
---|
| 636 | VBoxDrvGetPowerState(PVOID HwDeviceExtension, ULONG HwId, PVIDEO_POWER_MANAGEMENT VideoPowerControl)
|
---|
| 637 | {
|
---|
| 638 | PAGED_CODE();
|
---|
| 639 | LOGF_ENTER();
|
---|
| 640 |
|
---|
| 641 | /*Not implemented*/
|
---|
[63039] | 642 | RT_NOREF(HwDeviceExtension, HwId, VideoPowerControl);
|
---|
[36867] | 643 |
|
---|
| 644 | LOGF_LEAVE();
|
---|
| 645 | return NO_ERROR;
|
---|
| 646 | }
|
---|
| 647 |
|
---|
| 648 | /* Called to enumerate child devices of our adapter, attached monitor(s) in our case */
|
---|
| 649 | static VP_STATUS
|
---|
| 650 | VBoxDrvGetVideoChildDescriptor(PVOID HwDeviceExtension, PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
|
---|
| 651 | PVIDEO_CHILD_TYPE VideoChildType, PUCHAR pChildDescriptor, PULONG pUId,
|
---|
| 652 | PULONG pUnused)
|
---|
| 653 | {
|
---|
[63039] | 654 | RT_NOREF(pChildDescriptor, pUnused);
|
---|
[36867] | 655 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 656 |
|
---|
| 657 | PAGED_CODE();
|
---|
| 658 | LOGF_ENTER();
|
---|
| 659 |
|
---|
| 660 | if (ChildEnumInfo->ChildIndex>0)
|
---|
| 661 | {
|
---|
| 662 | if ((int)ChildEnumInfo->ChildIndex <= VBoxCommonFromDeviceExt(pExt)->cDisplays)
|
---|
| 663 | {
|
---|
| 664 | *VideoChildType = Monitor;
|
---|
| 665 | *pUId = ChildEnumInfo->ChildIndex;
|
---|
| 666 |
|
---|
| 667 | LOGF_LEAVE();
|
---|
| 668 | return VIDEO_ENUM_MORE_DEVICES;
|
---|
| 669 | }
|
---|
| 670 | }
|
---|
| 671 | LOGF_LEAVE();
|
---|
| 672 | return ERROR_NO_MORE_DEVICES;
|
---|
| 673 | }
|
---|
| 674 |
|
---|
| 675 | /* Called to reset adapter to a given character mode. */
|
---|
| 676 | static BOOLEAN
|
---|
| 677 | VBoxDrvResetHW(PVOID HwDeviceExtension, ULONG Columns, ULONG Rows)
|
---|
| 678 | {
|
---|
[63039] | 679 | RT_NOREF(Columns, Rows);
|
---|
[36867] | 680 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 681 |
|
---|
| 682 | LOGF_ENTER();
|
---|
| 683 |
|
---|
| 684 | if (pExt->iDevice==0) /* Primary device */
|
---|
| 685 | {
|
---|
| 686 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
|
---|
| 687 | VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
|
---|
| 688 |
|
---|
[38635] | 689 | #if 0
|
---|
| 690 | /* ResetHW is not the place to do such cleanup. See MSDN. */
|
---|
[36867] | 691 | if (pExt->u.primary.pvReqFlush != NULL)
|
---|
| 692 | {
|
---|
[68654] | 693 | VbglR0GRFree((VMMDevRequestHeader *)pExt->u.primary.pvReqFlush);
|
---|
[36867] | 694 | pExt->u.primary.pvReqFlush = NULL;
|
---|
| 695 | }
|
---|
| 696 |
|
---|
[68550] | 697 | VbglR0TerminateClient();
|
---|
[36867] | 698 |
|
---|
| 699 | VBoxFreeDisplaysHGSMI(VBoxCommonFromDeviceExt(pExt));
|
---|
[38635] | 700 | #endif
|
---|
[36867] | 701 | }
|
---|
| 702 | else
|
---|
| 703 | {
|
---|
| 704 | LOG(("ignoring non primary device %d", pExt->iDevice));
|
---|
| 705 | }
|
---|
| 706 |
|
---|
| 707 | LOGF_LEAVE();
|
---|
[38635] | 708 | /* Tell the system to use VGA BIOS to set the text video mode. */
|
---|
| 709 | return FALSE;
|
---|
[36867] | 710 | }
|
---|
| 711 |
|
---|
| 712 | #ifdef VBOX_WITH_VIDEOHWACCEL
|
---|
| 713 | static VOID VBoxMPHGSMIDpc(IN PVOID HwDeviceExtension, IN PVOID Context)
|
---|
| 714 | {
|
---|
[63039] | 715 | NOREF(Context);
|
---|
[36867] | 716 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 717 |
|
---|
| 718 | VBoxHGSMIProcessHostQueue(&VBoxCommonFromDeviceExt(pExt)->hostCtx);
|
---|
| 719 | }
|
---|
| 720 |
|
---|
| 721 | static BOOLEAN
|
---|
| 722 | VBoxDrvInterrupt(PVOID HwDeviceExtension)
|
---|
| 723 | {
|
---|
| 724 | PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
|
---|
| 725 |
|
---|
| 726 | //LOGF_ENTER();
|
---|
| 727 |
|
---|
| 728 | /* Check if it could be our IRQ*/
|
---|
| 729 | if (VBoxCommonFromDeviceExt(pExt)->hostCtx.pfHostFlags)
|
---|
| 730 | {
|
---|
| 731 | uint32_t flags = VBoxCommonFromDeviceExt(pExt)->hostCtx.pfHostFlags->u32HostFlags;
|
---|
[36896] | 732 | if ((flags & HGSMIHOSTFLAGS_IRQ) != 0)
|
---|
[36867] | 733 | {
|
---|
| 734 | /* queue a DPC*/
|
---|
| 735 | BOOLEAN bResult = pExt->pPrimary->u.primary.VideoPortProcs.pfnQueueDpc(pExt->pPrimary, VBoxMPHGSMIDpc, NULL);
|
---|
| 736 |
|
---|
| 737 | if (!bResult)
|
---|
| 738 | {
|
---|
| 739 | LOG(("VideoPortQueueDpc failed!"));
|
---|
| 740 | }
|
---|
[36896] | 741 |
|
---|
| 742 | /* clear the IRQ */
|
---|
| 743 | VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pExt)->hostCtx);
|
---|
| 744 | //LOGF_LEAVE();
|
---|
| 745 | return TRUE;
|
---|
[36867] | 746 | }
|
---|
| 747 | }
|
---|
| 748 |
|
---|
| 749 | //LOGF_LEAVE();
|
---|
| 750 | return FALSE;
|
---|
| 751 | }
|
---|
| 752 | #endif
|
---|
| 753 |
|
---|
| 754 | /* Video Miniport Driver entry point */
|
---|
| 755 | ULONG DriverEntry(IN PVOID Context1, IN PVOID Context2)
|
---|
| 756 | {
|
---|
| 757 | PAGED_CODE();
|
---|
| 758 |
|
---|
| 759 | int irc = RTR0Init(0);
|
---|
| 760 | if (RT_FAILURE(irc))
|
---|
| 761 | {
|
---|
| 762 | LogRel(("VBoxMP::failed to init IPRT (rc=%#x)", irc));
|
---|
| 763 | return ERROR_INVALID_FUNCTION;
|
---|
| 764 | }
|
---|
| 765 |
|
---|
| 766 | LOGF_ENTER();
|
---|
| 767 |
|
---|
[55210] | 768 | LOGREL(("VBox XPDM Driver for Windows version %d.%d.%dr%d, %d bit; Built %s %s",
|
---|
| 769 | VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV,
|
---|
| 770 | (sizeof (void*) << 3), __DATE__, __TIME__));
|
---|
| 771 |
|
---|
[36867] | 772 | VIDEO_HW_INITIALIZATION_DATA vhwData;
|
---|
| 773 |
|
---|
| 774 | /*Zero the structure*/
|
---|
| 775 | VideoPortZeroMemory(&vhwData, sizeof(vhwData));
|
---|
| 776 |
|
---|
| 777 | /*Required driver callbacks*/
|
---|
| 778 | vhwData.HwFindAdapter = VBoxDrvFindAdapter;
|
---|
| 779 | vhwData.HwInitialize = VBoxDrvInitialize;
|
---|
| 780 | vhwData.HwStartIO = VBoxDrvStartIO;
|
---|
| 781 | vhwData.HwSetPowerState = VBoxDrvSetPowerState;
|
---|
| 782 | vhwData.HwGetPowerState = VBoxDrvGetPowerState;
|
---|
| 783 | vhwData.HwGetVideoChildDescriptor = VBoxDrvGetVideoChildDescriptor;
|
---|
| 784 |
|
---|
| 785 | /*Optional callbacks*/
|
---|
| 786 | vhwData.HwResetHw = VBoxDrvResetHW;
|
---|
| 787 | #ifdef VBOX_WITH_VIDEOHWACCEL
|
---|
| 788 | vhwData.HwInterrupt = VBoxDrvInterrupt;
|
---|
| 789 | #endif
|
---|
| 790 |
|
---|
| 791 | /*Our private storage space*/
|
---|
| 792 | vhwData.HwDeviceExtensionSize = sizeof(VBOXMP_DEVEXT);
|
---|
| 793 |
|
---|
| 794 | /*Claim legacy VGA resource ranges*/
|
---|
[63039] | 795 | vhwData.HwLegacyResourceList = g_aVBoxLegacyVGAResources;
|
---|
| 796 | vhwData.HwLegacyResourceCount = RT_ELEMENTS(g_aVBoxLegacyVGAResources);
|
---|
[36867] | 797 |
|
---|
| 798 | /*Size of this structure changes between windows/ddk versions,
|
---|
| 799 | *so we query current version and report the expected size
|
---|
| 800 | *to allow our driver to be loaded.
|
---|
| 801 | */
|
---|
[75403] | 802 | switch (VBoxQueryWinVersion(NULL))
|
---|
[36867] | 803 | {
|
---|
[53008] | 804 | case WINVERSION_NT4:
|
---|
| 805 | LOG(("WINVERSION_NT4"));
|
---|
[36867] | 806 | vhwData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
|
---|
| 807 | break;
|
---|
[53008] | 808 | case WINVERSION_2K:
|
---|
| 809 | LOG(("WINVERSION_2K"));
|
---|
[36867] | 810 | vhwData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
|
---|
| 811 | break;
|
---|
| 812 | default:
|
---|
| 813 | vhwData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
|
---|
| 814 | break;
|
---|
| 815 | }
|
---|
| 816 |
|
---|
| 817 | /*Even though msdn claims that this field is ignored and should remain zero-initialized,
|
---|
| 818 | windows NT4 SP0 dies without the following line.
|
---|
| 819 | */
|
---|
| 820 | vhwData.AdapterInterfaceType = PCIBus;
|
---|
| 821 |
|
---|
| 822 | /*Allocate system resources*/
|
---|
| 823 | ULONG rc = VideoPortInitialize(Context1, Context2, &vhwData, NULL);
|
---|
| 824 | if (rc != NO_ERROR)
|
---|
[38906] | 825 | LOG(("VideoPortInitialize failed with %#x", rc));
|
---|
[36867] | 826 |
|
---|
| 827 | LOGF_LEAVE();
|
---|
| 828 | return rc;
|
---|
| 829 | }
|
---|