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