1 /* 2 * VGA.C - a generic VGA miniport driver 3 * 4 */ 5 6 // ------------------------------------------------------- Includes 7 8 #include "vgamp.h" 9 10 #include <dderror.h> 11 #include <devioctl.h> 12 13 VIDEO_ACCESS_RANGE VGAAccessRange[] = 14 { 15 { {{0x3b0}}, 0x3bb - 0x3b0 + 1, 1, 0, 0 }, 16 { {{0x3c0}}, 0x3df - 0x3c0 + 1, 1, 0, 0 }, 17 { {{0xa0000}}, 0x20000, 0, 0, 0 }, 18 }; 19 20 // ------------------------------------------------------- Public Interface 21 22 // DriverEntry 23 // 24 // DESCRIPTION: 25 // This function initializes the driver. 26 // 27 // RUN LEVEL: 28 // PASSIVE_LEVEL 29 // 30 // ARGUMENTS: 31 // IN PVOID Context1 Context parameter to pass to VidPortInitialize 32 // IN PVOID Context2 Context parameter to pass to VidPortInitialize 33 // RETURNS: 34 // ULONG 35 36 ULONG NTAPI 37 DriverEntry(IN PVOID Context1, 38 IN PVOID Context2) 39 { 40 VIDEO_HW_INITIALIZATION_DATA InitData; 41 42 VideoPortZeroMemory(&InitData, sizeof InitData); 43 44 InitData.HwInitDataSize = sizeof(InitData); 45 /* FIXME: Fill in InitData members */ 46 InitData.StartingDeviceNumber = 0; 47 48 /* Export driver entry points... */ 49 InitData.HwFindAdapter = VGAFindAdapter; 50 InitData.HwInitialize = VGAInitialize; 51 InitData.HwStartIO = VGAStartIO; 52 /* InitData.HwInterrupt = VGAInterrupt; */ 53 InitData.HwResetHw = VGAResetHw; 54 /* InitData.HwTimer = VGATimer; */ 55 InitData.HwLegacyResourceList = VGAAccessRange; 56 InitData.HwLegacyResourceCount = ARRAYSIZE(VGAAccessRange); 57 58 return VideoPortInitialize(Context1, Context2, &InitData, NULL); 59 } 60 61 // VGAFindAdapter 62 // 63 // DESCRIPTION: 64 // This routine is called by the videoport driver to find and allocate 65 // the adapter for a given bus. The miniport driver needs to do the 66 // following in this routine: 67 // - Determine if the adapter is present 68 // - Claim any necessary memory/IO resources for the adapter 69 // - Map resources into system memory for the adapter 70 // - fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer 71 // - update registry settings for adapter specifics. 72 // - Set 'Again' based on whether the function should be called again 73 // another adapter on the same bus. 74 // 75 // RUN LEVEL: 76 // PASSIVE_LEVEL 77 // 78 // ARGUMENTS: 79 // PVOID DeviceExtension 80 // PVOID Context 81 // PWSTR ArgumentString 82 // PVIDEO_PORT_CONFIG_INFO ConfigInfo 83 // PUCHAR Again 84 // RETURNS: 85 // VP_STATUS 86 87 VP_STATUS NTAPI 88 VGAFindAdapter(PVOID DeviceExtension, 89 PVOID Context, 90 PWSTR ArgumentString, 91 PVIDEO_PORT_CONFIG_INFO ConfigInfo, 92 PUCHAR Again) 93 { 94 VP_STATUS Status; 95 96 /* FIXME: Determine if the adapter is present */ 97 *Again = FALSE; 98 99 if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) 100 return ERROR_INVALID_PARAMETER; 101 102 Status = VideoPortVerifyAccessRanges(DeviceExtension, ARRAYSIZE(VGAAccessRange), VGAAccessRange); 103 if (Status != NO_ERROR) 104 return Status; 105 106 ConfigInfo->VdmPhysicalVideoMemoryAddress = VGAAccessRange[2].RangeStart; 107 ConfigInfo->VdmPhysicalVideoMemoryLength = VGAAccessRange[2].RangeLength; 108 return NO_ERROR; 109 110 /* FIXME: Claim any necessary memory/IO resources for the adapter */ 111 /* FIXME: Map resources into system memory for the adapter */ 112 /* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer */ 113 /* FIXME: Update registry settings for adapter specifics. */ 114 // return NO_ERROR; 115 } 116 117 // VGAInitialize 118 // 119 // DESCRIPTION: 120 // Perform initialization tasks, but leave the adapter in the same 121 // user visible state 122 // 123 // RUN LEVEL: 124 // PASSIVE_LEVEL 125 // 126 // ARGUMENTS: 127 // PVOID DeviceExtension 128 // RETURNS: 129 // BOOLEAN Success or failure 130 BOOLEAN NTAPI 131 VGAInitialize(PVOID DeviceExtension) 132 { 133 return TRUE; 134 } 135 136 // VGAStartIO 137 // 138 // DESCRIPTION: 139 // This function gets called in responce to GDI EngDeviceIoControl 140 // calls. Device requests are passed in VRPs. 141 // Required VRPs: 142 // IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES 143 // IOCTL_VIDEO_QUERY_AVAIL_MODES 144 // IOCTL_VIDEO_QUERY_CURRENT_MODE 145 // IOCTL_VIDEO_SET_CURRENT_MODE 146 // IOCTL_VIDEO_RESET_DEVICE 147 // IOCTL_VIDEO_MAP_VIDEO_MEMORY 148 // IOCTL_VIDEO_UNMAP_VIDEO_MEMORY 149 // IOCTL_VIDEO_SHARE_VIDEO_MEMORY 150 // IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY 151 // Optional VRPs: 152 // IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES 153 // IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES 154 // IOCTL_VIDEO_GET_POWER_MANAGEMENT 155 // IOCTL_VIDEO_SET_POWER_MANAGEMENT 156 // IOCTL_QUERY_COLOR_CAPABILITIES 157 // IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette) 158 // IOCTL_VIDEO_DISABLE_POINTER 159 // IOCTL_VIDEO_ENABLE_POINTER 160 // IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES 161 // IOCTL_VIDEO_QUERY_POINTER_ATTR 162 // IOCTL_VIDEO_SET_POINTER_ATTR 163 // IOCTL_VIDEO_QUERY_POINTER_POSITION 164 // IOCTL_VIDEO_SET_POINTER_POSITION 165 // IOCTL_VIDEO_SAVE_HARDWARE_STATE 166 // IOCTL_VIDEO_RESTORE_HARDWARE_STATE 167 // IOCTL_VIDEO_DISABLE_CURSOR 168 // IOCTL_VIDEO_ENABLE_CURSOR 169 // IOCTL_VIDEO_QUERY_CURSOR_ATTR 170 // IOCTL_VIDEO_SET_CURSOR_ATTR 171 // IOCTL_VIDEO_QUERY_CURSOR_POSITION 172 // IOCTL_VIDEO_SET_CURSOR_POSITION 173 // IOCTL_VIDEO_GET_BANK_SELECT_CODE 174 // IOCTL_VIDEO_SET_PALETTE_REGISTERS 175 // IOCTL_VIDEO_LOAD_AND_SET_FONT 176 // 177 // RUN LEVEL: 178 // PASSIVE_LEVEL 179 // 180 // ARGUMENTS: 181 // PVOID DeviceExtension 182 // PVIDEO_REQUEST_PACKET RequestPacket 183 // RETURNS: 184 // BOOLEAN This function must return TRUE, and complete the work or 185 // set an error status in the VRP. 186 187 BOOLEAN NTAPI 188 VGAStartIO(PVOID DeviceExtension, 189 PVIDEO_REQUEST_PACKET RequestPacket) 190 { 191 BOOLEAN Result; 192 193 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION; 194 195 switch (RequestPacket->IoControlCode) 196 { 197 case IOCTL_VIDEO_MAP_VIDEO_MEMORY: 198 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) || 199 RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 200 { 201 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 202 return TRUE; 203 } 204 Result = VGAMapVideoMemory(DeviceExtension, 205 (PVIDEO_MEMORY) RequestPacket->InputBuffer, 206 (PVIDEO_MEMORY_INFORMATION) 207 RequestPacket->OutputBuffer, 208 RequestPacket->StatusBlock); 209 break; 210 211 case IOCTL_VIDEO_QUERY_AVAIL_MODES: 212 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) 213 { 214 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 215 return TRUE; 216 } 217 Result = VGAQueryAvailModes((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer, 218 RequestPacket->StatusBlock); 219 break; 220 221 case IOCTL_VIDEO_QUERY_CURRENT_MODE: 222 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) 223 { 224 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 225 return TRUE; 226 } 227 Result = VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer, 228 RequestPacket->StatusBlock); 229 break; 230 231 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: 232 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) 233 { 234 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 235 return TRUE; 236 } 237 Result = VGAQueryNumAvailModes((PVIDEO_NUM_MODES) RequestPacket->OutputBuffer, 238 RequestPacket->StatusBlock); 239 break; 240 241 case IOCTL_VIDEO_RESET_DEVICE: 242 VGAResetDevice(RequestPacket->StatusBlock); 243 Result = TRUE; 244 break; 245 246 case IOCTL_VIDEO_SET_COLOR_REGISTERS: 247 if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) || 248 RequestPacket->InputBufferLength < 249 (((PVIDEO_CLUT)RequestPacket->InputBuffer)->NumEntries * sizeof(ULONG)) + 250 FIELD_OFFSET(VIDEO_CLUT, LookupTable)) 251 { 252 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 253 return TRUE; 254 } 255 Result = VGASetColorRegisters((PVIDEO_CLUT) RequestPacket->InputBuffer, 256 RequestPacket->StatusBlock); 257 break; 258 259 case IOCTL_VIDEO_SET_CURRENT_MODE: 260 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) 261 { 262 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 263 return TRUE; 264 } 265 Result = VGASetCurrentMode((PVIDEO_MODE) RequestPacket->InputBuffer, 266 RequestPacket->StatusBlock); 267 break; 268 269 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY: 270 if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) || 271 RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY)) 272 { 273 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 274 return TRUE; 275 } 276 Result = VGAShareVideoMemory((PVIDEO_SHARE_MEMORY) RequestPacket->InputBuffer, 277 (PVIDEO_MEMORY_INFORMATION) RequestPacket->OutputBuffer, 278 RequestPacket->StatusBlock); 279 break; 280 281 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: 282 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 283 { 284 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 285 return TRUE; 286 } 287 Result = VGAUnmapVideoMemory(DeviceExtension, 288 (PVIDEO_MEMORY) RequestPacket->InputBuffer, 289 RequestPacket->StatusBlock); 290 break; 291 292 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY: 293 if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 294 { 295 RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER; 296 return TRUE; 297 } 298 Result = VGAUnshareVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer, 299 RequestPacket->StatusBlock); 300 break; 301 case IOCTL_VIDEO_SET_PALETTE_REGISTERS: 302 Result = VGASetPaletteRegisters((PUSHORT) RequestPacket->InputBuffer, 303 RequestPacket->StatusBlock); 304 break; 305 306 #if 0 307 case IOCTL_VIDEO_DISABLE_CURSOR: 308 case IOCTL_VIDEO_DISABLE_POINTER: 309 case IOCTL_VIDEO_ENABLE_CURSOR: 310 case IOCTL_VIDEO_ENABLE_POINTER: 311 312 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES: 313 VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES) 314 RequestPacket->InputBuffer, 315 RequestPacket->StatusBlock); 316 break; 317 318 case IOCTL_VIDEO_GET_BANK_SELECT_CODE: 319 case IOCTL_VIDEO_GET_POWER_MANAGEMENT: 320 case IOCTL_VIDEO_LOAD_AND_SET_FONT: 321 case IOCTL_VIDEO_QUERY_CURSOR_POSITION: 322 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES: 323 case IOCTL_VIDEO_QUERY_CURSOR_ATTR: 324 case IOCTL_VIDEO_QUERY_POINTER_ATTR: 325 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES: 326 case IOCTL_VIDEO_QUERY_POINTER_POSITION: 327 328 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES: 329 VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES) 330 RequestPacket->OutputBuffer, 331 RequestPacket->StatusBlock); 332 break; 333 334 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE: 335 case IOCTL_VIDEO_SAVE_HARDWARE_STATE: 336 case IOCTL_VIDEO_SET_CURSOR_ATTR: 337 case IOCTL_VIDEO_SET_CURSOR_POSITION: 338 case IOCTL_VIDEO_SET_POINTER_ATTR: 339 case IOCTL_VIDEO_SET_POINTER_POSITION: 340 case IOCTL_VIDEO_SET_POWER_MANAGEMENT: 341 342 #endif 343 344 default: 345 RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION; 346 return FALSE; 347 } 348 349 if (Result) 350 RequestPacket->StatusBlock->Status = NO_ERROR; 351 352 return TRUE; 353 } 354 355 #if 0 356 // VGAInterrupt 357 // 358 // DESCRIPTION: 359 // This function will be called upon receipt of a adapter generated 360 // interrupt when enabled. 361 // 362 // RUN LEVEL: 363 // IRQL 364 // 365 // ARGUMENTS: 366 // PVOID DeviceExtension 367 // RETURNS: 368 // BOOLEAN TRUE if the interrupt was handled by the routine 369 370 static BOOLEAN NTAPI 371 VGAInterrupt(PVOID DeviceExtension) 372 { 373 return(TRUE); 374 } 375 #endif 376 377 // VGAResetHw 378 // 379 // DESCRIPTION: 380 // This function is called to reset the hardware to a known state 381 // if calling a BIOS int 10 reset will not achieve this result. 382 // 383 // RUN LEVEL: 384 // PASSIVE_LEVEL 385 // 386 // ARGUMENTS: 387 // PVOID DeviceExtension 388 // ULONG Columns Columns and Rows specify the mode parameters 389 // ULONG Rows to reset to. 390 // RETURNS: 391 // BOOLEAN TRUE if no further action is necessary, FALSE if the system 392 // needs to still do a BIOS int 10 reset. 393 394 BOOLEAN NTAPI 395 VGAResetHw(PVOID DeviceExtension, 396 ULONG Columns, 397 ULONG Rows) 398 { 399 /* We don't anything to the vga that int10 can't cope with. */ 400 return(FALSE); 401 } 402 403 #if 0 404 // VGATimer 405 // 406 // DESCRIPTION: 407 // This function will be called once a second when enabled 408 // 409 // RUN LEVEL: 410 // PASSIVE_LEVEL 411 // 412 // ARGUMENTS: 413 // PVOID DeviceExtension 414 // RETURNS: 415 // VOID 416 417 static VOID NTAPI 418 VGATimer(PVOID DeviceExtension) 419 { 420 } 421 422 #endif 423 424 BOOLEAN VGAMapVideoMemory(IN PVOID DeviceExtension, 425 IN PVIDEO_MEMORY RequestedAddress, 426 OUT PVIDEO_MEMORY_INFORMATION MapInformation, 427 OUT PSTATUS_BLOCK StatusBlock) 428 { 429 ULONG ReturnedLength; 430 PVOID ReturnedAddress; 431 ULONG IoSpace; 432 PHYSICAL_ADDRESS FrameBufferBase; 433 ReturnedAddress = RequestedAddress->RequestedVirtualAddress; 434 ReturnedLength = 256 * 1024; 435 FrameBufferBase.QuadPart = 0xA0000; 436 IoSpace = VIDEO_MEMORY_SPACE_MEMORY; 437 StatusBlock->Status = VideoPortMapMemory(DeviceExtension, 438 FrameBufferBase, 439 &ReturnedLength, 440 &IoSpace, 441 &ReturnedAddress); 442 if (StatusBlock->Status != 0) 443 { 444 StatusBlock->Information = 0; 445 return TRUE; 446 } 447 MapInformation->VideoRamBase = MapInformation->FrameBufferBase = 448 ReturnedAddress; 449 MapInformation->VideoRamLength = MapInformation->FrameBufferLength = 450 ReturnedLength; 451 StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION); 452 return TRUE; 453 } 454 455 BOOLEAN VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes, 456 OUT PSTATUS_BLOCK StatusBlock) 457 { 458 /* Only one mode exists in VGA (640x480), so use VGAQueryCurrentMode */ 459 return VGAQueryCurrentMode(ReturnedModes, StatusBlock); 460 } 461 462 BOOLEAN VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode, 463 OUT PSTATUS_BLOCK StatusBlock) 464 { 465 CurrentMode->Length = sizeof(VIDEO_MODE_INFORMATION); 466 CurrentMode->ModeIndex = 2; 467 CurrentMode->VisScreenWidth = 640; 468 CurrentMode->VisScreenHeight = 480; 469 CurrentMode->ScreenStride = 80; 470 CurrentMode->NumberOfPlanes = 4; 471 CurrentMode->BitsPerPlane = 1; 472 CurrentMode->Frequency = 60; 473 CurrentMode->XMillimeter = 320; 474 CurrentMode->YMillimeter = 240; 475 CurrentMode->NumberRedBits = 476 CurrentMode->NumberGreenBits = 477 CurrentMode->NumberBlueBits = 6; 478 CurrentMode->RedMask = 479 CurrentMode->GreenMask = 480 CurrentMode->BlueMask = 0; 481 CurrentMode->VideoMemoryBitmapWidth = 640; 482 CurrentMode->VideoMemoryBitmapHeight = 480; 483 CurrentMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR | 484 VIDEO_MODE_NO_OFF_SCREEN; 485 CurrentMode->DriverSpecificAttributeFlags = 0; 486 487 StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION); 488 return TRUE; 489 } 490 491 BOOLEAN VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes, 492 OUT PSTATUS_BLOCK StatusBlock) 493 { 494 NumberOfModes->NumModes = 1; 495 NumberOfModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION); 496 StatusBlock->Information = sizeof(VIDEO_NUM_MODES); 497 return TRUE; 498 } 499 500 BOOLEAN VGASetPaletteRegisters(IN PUSHORT PaletteRegisters, 501 OUT PSTATUS_BLOCK StatusBlock) 502 { 503 ; 504 505 /* 506 We don't need the following code because the palette registers are set correctly on VGA initialization. 507 Still, we may include\test this is in the future. 508 509 int i, j = 2; 510 char tmp, v; 511 512 tmp = VideoPortReadPortUchar(0x03da); 513 v = VideoPortReadPortUchar(0x03c0); 514 515 // Set the first 16 palette registers to map to the first 16 palette colors 516 for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++) 517 { 518 tmp = VideoPortReadPortUchar(0x03da); 519 VideoPortWritePortUchar(0x03c0, i); 520 VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]); 521 } 522 523 tmp = VideoPortReadPortUchar(0x03da); 524 VideoPortWritePortUchar(0x03d0, v | 0x20); 525 */ 526 return TRUE; 527 } 528 529 BOOLEAN VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable, 530 OUT PSTATUS_BLOCK StatusBlock) 531 { 532 int i; 533 534 for (i=ColorLookUpTable->FirstEntry; i<ColorLookUpTable->NumEntries; i++) 535 { 536 VideoPortWritePortUchar((PUCHAR)0x03c8, i); 537 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Red); 538 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Green); 539 VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Blue); 540 } 541 542 return TRUE; 543 } 544 545 BOOLEAN VGASetCurrentMode(IN PVIDEO_MODE RequestedMode, 546 OUT PSTATUS_BLOCK StatusBlock) 547 { 548 if(RequestedMode->RequestedMode == 2) 549 { 550 InitVGAMode(); 551 return TRUE; 552 } else { 553 VideoPortDebugPrint(Warn, "Unrecognised mode for VGASetCurrentMode\n"); 554 return FALSE; 555 } 556 } 557 558 BOOLEAN VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory, 559 OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory, 560 OUT PSTATUS_BLOCK StatusBlock) 561 { 562 UNIMPLEMENTED; 563 564 StatusBlock->Status = ERROR_INVALID_FUNCTION; 565 return FALSE; 566 } 567 568 BOOLEAN VGAUnmapVideoMemory(IN PVOID DeviceExtension, 569 IN PVIDEO_MEMORY MemoryToUnmap, 570 OUT PSTATUS_BLOCK StatusBlock) 571 { 572 if (VideoPortUnmapMemory(DeviceExtension, 573 MemoryToUnmap->RequestedVirtualAddress, 574 0) == NO_ERROR) 575 return TRUE; 576 else 577 return FALSE; 578 } 579 580 BOOLEAN VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare, 581 OUT PSTATUS_BLOCK StatusBlock) 582 { 583 UNIMPLEMENTED; 584 585 StatusBlock->Status = ERROR_INVALID_FUNCTION; 586 return FALSE; 587 } 588