update for HEAD-2003091401
[reactos.git] / drivers / dd / videoprt / videoprt.c
index a83e243..d1dbf1a 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <errors.h>
-#include <ddk/ntddk.h>
+#include <roskrnl.h>
 #include <ddk/ntddvid.h>
 
 #include "../../../ntoskrnl/include/internal/v86m.h"
@@ -38,6 +38,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
   KIRQL  IRQL;
   KAFFINITY  Affinity;
   PVIDEO_HW_INITIALIZE HwInitialize;
+  PVIDEO_HW_RESET_HW HwResetHw;
   LIST_ENTRY AddressMappingListHead;
   INTERFACE_TYPE AdapterInterfaceType;
   ULONG SystemIoBusNumber;
@@ -48,7 +49,8 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
 
 
 static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchOpen(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
 static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
 static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
                                        IN PHYSICAL_ADDRESS  IoAddress,
@@ -58,8 +60,8 @@ static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceEx
                                         IN PVOID MappedAddress);
 
 static BOOLEAN CsrssInitialized = FALSE;
-static HANDLE CsrssHandle = 0;
-static struct _EPROCESS* Csrss = NULL;
+static PEPROCESS Csrss = NULL;
+static PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
 
 PBYTE ReturnCsrssAddress(void)
 {
@@ -94,6 +96,9 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
   return(STATUS_SUCCESS);
 }
 
+/*
+ * @implemented
+ */
 VOID
 VideoPortDebugPrint(IN ULONG DebugPrintLevel,
                     IN PCHAR DebugMessage, ...)
@@ -112,6 +117,10 @@ VideoPortDebugPrint(IN ULONG DebugPrintLevel,
        DbgPrint (Buffer);
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortDisableInterrupt(IN PVOID  HwDeviceExtension)
@@ -120,6 +129,10 @@ VideoPortDisableInterrupt(IN PVOID  HwDeviceExtension)
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortEnableInterrupt(IN PVOID  HwDeviceExtension)
@@ -128,6 +141,10 @@ VideoPortEnableInterrupt(IN PVOID  HwDeviceExtension)
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortFreeDeviceBase(IN PVOID  HwDeviceExtension, 
@@ -144,6 +161,10 @@ VideoPortFreeDeviceBase(IN PVOID  HwDeviceExtension,
   InternalUnmapMemory(DeviceExtension, MappedAddress);
 }
 
+
+/*
+ * @implemented
+ */
 ULONG 
 STDCALL
 VideoPortGetBusData(IN PVOID  HwDeviceExtension,
@@ -169,6 +190,10 @@ VideoPortGetBusData(IN PVOID  HwDeviceExtension,
                                Length);
 }
 
+
+/*
+ * @implemented
+ */
 UCHAR 
 STDCALL
 VideoPortGetCurrentIrql(VOID)
@@ -177,6 +202,10 @@ VideoPortGetCurrentIrql(VOID)
   return KeGetCurrentIrql();
 }
 
+
+/*
+ * @implemented
+ */
 PVOID 
 STDCALL
 VideoPortGetDeviceBase(IN PVOID  HwDeviceExtension,
@@ -195,6 +224,10 @@ VideoPortGetDeviceBase(IN PVOID  HwDeviceExtension,
   return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace);
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortGetDeviceData(IN PVOID  HwDeviceExtension,
@@ -206,6 +239,10 @@ VideoPortGetDeviceData(IN PVOID  HwDeviceExtension,
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @implemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortGetAccessRanges(IN PVOID  HwDeviceExtension,
@@ -321,6 +358,10 @@ VideoPortGetAccessRanges(IN PVOID  HwDeviceExtension,
   return STATUS_SUCCESS;
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortGetRegistryParameters(IN PVOID  HwDeviceExtension,
@@ -337,6 +378,10 @@ VideoPortGetRegistryParameters(IN PVOID  HwDeviceExtension,
 */
 }
 
+
+/*
+ * @implemented
+ */
 ULONG STDCALL
 VideoPortInitialize(IN PVOID  Context1,
                     IN PVOID  Context2,
@@ -391,15 +436,16 @@ VideoPortInitialize(IN PVOID  Context1,
       MPDriverObject->DeviceObject = MPDeviceObject;
 
       /* Initialize the miniport drivers dispatch table */
-      MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
-      MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
-      MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
+      MPDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) VidDispatchOpen;
+      MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) VidDispatchClose;
+      MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) VidDispatchDeviceControl;
 
       /* Initialize our device extension */
       DeviceExtension = 
         (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
       DeviceExtension->DeviceObject = MPDeviceObject;
       DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
+      DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
       DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
       DeviceExtension->SystemIoBusNumber = 0;
       MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
@@ -539,15 +585,25 @@ VideoPortInitialize(IN PVOID  Context1,
   return  STATUS_SUCCESS;
 }
 
+
+/*
+ * @implemented
+ */
 VP_STATUS STDCALL
 VideoPortInt10(IN PVOID  HwDeviceExtension,
                IN PVIDEO_X86_BIOS_ARGUMENTS  BiosArguments)
 {
   KV86M_REGISTERS Regs;
   NTSTATUS Status;
+  PEPROCESS CallingProcess;
 
   DPRINT("VideoPortInt10\n");
-  KeAttachProcess(Csrss);
+
+  CallingProcess = PsGetCurrentProcess();
+  if (CallingProcess != Csrss)
+    {
+      KeAttachProcess(Csrss);
+    }
 
   memset(&Regs, 0, sizeof(Regs));
   Regs.Eax = BiosArguments->Eax;
@@ -559,11 +615,18 @@ VideoPortInt10(IN PVOID  HwDeviceExtension,
   Regs.Ebp = BiosArguments->Ebp;
   Status = Ke386CallBios(0x10, &Regs);
 
-  KeDetachProcess();
+  if (CallingProcess != Csrss)
+    {
+      KeDetachProcess();
+    }
 
   return(Status);
 }
 
+
+/*
+ * @unimplemented
+ */
 VOID 
 STDCALL
 VideoPortLogError(IN PVOID  HwDeviceExtension,
@@ -571,10 +634,18 @@ VideoPortLogError(IN PVOID  HwDeviceExtension,
                   IN VP_STATUS  ErrorCode,
                   IN ULONG  UniqueId)
 {
-  DPRINT("VideoPortLogError\n");
-  UNIMPLEMENTED;
+  DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
+          ErrorCode, ErrorCode, UniqueId, UniqueId);
+  if (NULL != Vrp)
+    {
+      DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode);
+    }
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortMapBankedMemory(IN PVOID  HwDeviceExtension,
@@ -591,6 +662,10 @@ VideoPortMapBankedMemory(IN PVOID  HwDeviceExtension,
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @implemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortMapMemory(IN PVOID  HwDeviceExtension,
@@ -614,6 +689,10 @@ VideoPortMapMemory(IN PVOID  HwDeviceExtension,
   return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS;
 }
 
+
+/*
+ * @implemented
+ */
 UCHAR 
 STDCALL
 VideoPortReadPortUchar(IN PUCHAR  Port)
@@ -622,6 +701,10 @@ VideoPortReadPortUchar(IN PUCHAR  Port)
   return  READ_PORT_UCHAR(Port);
 }
 
+
+/*
+ * @implemented
+ */
 USHORT 
 STDCALL
 VideoPortReadPortUshort(IN PUSHORT Port)
@@ -630,6 +713,10 @@ VideoPortReadPortUshort(IN PUSHORT Port)
   return  READ_PORT_USHORT(Port);
 }
 
+
+/*
+ * @implemented
+ */
 ULONG 
 STDCALL
 VideoPortReadPortUlong(IN PULONG Port)
@@ -638,6 +725,10 @@ VideoPortReadPortUlong(IN PULONG Port)
   return  READ_PORT_ULONG(Port);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadPortBufferUchar(IN PUCHAR  Port, 
@@ -648,6 +739,10 @@ VideoPortReadPortBufferUchar(IN PUCHAR  Port,
   READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadPortBufferUshort(IN PUSHORT Port, 
@@ -658,6 +753,10 @@ VideoPortReadPortBufferUshort(IN PUSHORT Port,
   READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadPortBufferUlong(IN PULONG Port, 
@@ -668,6 +767,10 @@ VideoPortReadPortBufferUlong(IN PULONG Port,
   READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 UCHAR 
 STDCALL
 VideoPortReadRegisterUchar(IN PUCHAR Register)
@@ -676,6 +779,10 @@ VideoPortReadRegisterUchar(IN PUCHAR Register)
   return  READ_REGISTER_UCHAR(Register);
 }
 
+
+/*
+ * @implemented
+ */
 USHORT 
 STDCALL
 VideoPortReadRegisterUshort(IN PUSHORT Register)
@@ -684,6 +791,10 @@ VideoPortReadRegisterUshort(IN PUSHORT Register)
   return  READ_REGISTER_USHORT(Register);
 }
 
+
+/*
+ * @implemented
+ */
 ULONG 
 STDCALL
 VideoPortReadRegisterUlong(IN PULONG Register)
@@ -692,6 +803,10 @@ VideoPortReadRegisterUlong(IN PULONG Register)
   return  READ_REGISTER_ULONG(Register);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadRegisterBufferUchar(IN PUCHAR  Register, 
@@ -702,6 +817,10 @@ VideoPortReadRegisterBufferUchar(IN PUCHAR  Register,
   READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadRegisterBufferUshort(IN PUSHORT  Register, 
@@ -712,6 +831,10 @@ VideoPortReadRegisterBufferUshort(IN PUSHORT  Register,
   READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortReadRegisterBufferUlong(IN PULONG  Register, 
@@ -722,6 +845,10 @@ VideoPortReadRegisterBufferUlong(IN PULONG  Register,
   READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 BOOLEAN 
 STDCALL
 VideoPortScanRom(IN PVOID  HwDeviceExtension, 
@@ -729,10 +856,33 @@ VideoPortScanRom(IN PVOID  HwDeviceExtension,
                  IN ULONG  RomLength,
                  IN PUCHAR  String)
 {
-  DPRINT("VideoPortScanRom\n");
-  UNIMPLEMENTED;
+  ULONG StringLength;
+  BOOLEAN Found;
+  PUCHAR SearchLocation;
+
+  DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
+
+  StringLength = strlen(String);
+  Found = FALSE;
+  SearchLocation = RomBase;
+  for (SearchLocation = RomBase;
+       ! Found && SearchLocation < RomBase + RomLength - StringLength;
+       SearchLocation++)
+    {
+      Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength);
+      if (Found)
+       {
+         DPRINT("Match found at %p\n", SearchLocation);
+       }
+    }
+
+  return Found;
 }
 
+
+/*
+ * @implemented
+ */
 ULONG 
 STDCALL
 VideoPortSetBusData(IN PVOID  HwDeviceExtension,
@@ -751,6 +901,10 @@ VideoPortSetBusData(IN PVOID  HwDeviceExtension,
                                 Length);
 }
 
+
+/*
+ * @implemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortSetRegistryParameters(IN PVOID  HwDeviceExtension,
@@ -775,6 +929,10 @@ VideoPortSetRegistryParameters(IN PVOID  HwDeviceExtension,
                                ValueLength);
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortSetTrappedEmulatorPorts(IN PVOID  HwDeviceExtension,
@@ -785,6 +943,10 @@ VideoPortSetTrappedEmulatorPorts(IN PVOID  HwDeviceExtension,
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortStartTimer(IN PVOID  HwDeviceExtension)
@@ -799,6 +961,10 @@ VideoPortStartTimer(IN PVOID  HwDeviceExtension)
   IoStartTimer(DeviceExtension->DeviceObject);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortStopTimer(IN PVOID  HwDeviceExtension)
@@ -813,6 +979,10 @@ VideoPortStopTimer(IN PVOID  HwDeviceExtension)
   IoStopTimer(DeviceExtension->DeviceObject);
 }
 
+
+/*
+ * @implemented
+ */
 BOOLEAN 
 STDCALL
 VideoPortSynchronizeExecution(IN PVOID  HwDeviceExtension,
@@ -820,10 +990,55 @@ VideoPortSynchronizeExecution(IN PVOID  HwDeviceExtension,
                               IN PMINIPORT_SYNCHRONIZE_ROUTINE  SynchronizeRoutine,
                               OUT PVOID  Context)
 {
+  BOOLEAN Ret;
+  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+  KIRQL OldIrql;
+
   DPRINT("VideoPortSynchronizeExecution\n");
-  UNIMPLEMENTED;
+
+  switch(Priority)
+    {
+    case VpLowPriority:
+      Ret = (*SynchronizeRoutine)(Context);
+      break;
+    case VpMediumPriority:
+      DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+                                          VIDEO_PORT_DEVICE_EXTENSION,
+                                          MiniPortDeviceExtension);
+      if (NULL == DeviceExtension->InterruptObject)
+       {
+         Ret = (*SynchronizeRoutine)(Context);
+       }
+      else
+       {
+         Ret = KeSynchronizeExecution(DeviceExtension->InterruptObject,
+                                      SynchronizeRoutine,
+                                      Context);
+       }
+      break;
+    case VpHighPriority:
+      OldIrql = KeGetCurrentIrql();
+      if (OldIrql < SYNCH_LEVEL)
+       {
+         OldIrql = KfRaiseIrql(SYNCH_LEVEL);
+       }
+      Ret = (*SynchronizeRoutine)(Context);
+      if (OldIrql < SYNCH_LEVEL)
+       {
+         KfLowerIrql(OldIrql);
+       }
+      break;
+    default:
+      Ret = FALSE;
+    }
+
+  return Ret;
 }
 
+
+/*
+ * @implemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortUnmapMemory(IN PVOID  HwDeviceExtension,
@@ -843,6 +1058,10 @@ VideoPortUnmapMemory(IN PVOID  HwDeviceExtension,
   return STATUS_SUCCESS;
 }
 
+
+/*
+ * @unimplemented
+ */
 VP_STATUS 
 STDCALL
 VideoPortVerifyAccessRanges(IN PVOID  HwDeviceExtension,
@@ -853,6 +1072,10 @@ VideoPortVerifyAccessRanges(IN PVOID  HwDeviceExtension,
   return NO_ERROR;
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortUchar(IN PUCHAR  Port, 
@@ -862,6 +1085,10 @@ VideoPortWritePortUchar(IN PUCHAR  Port,
   WRITE_PORT_UCHAR(Port, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortUshort(IN PUSHORT  Port, 
@@ -871,6 +1098,10 @@ VideoPortWritePortUshort(IN PUSHORT  Port,
   WRITE_PORT_USHORT(Port, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortUlong(IN PULONG Port, 
@@ -880,6 +1111,10 @@ VideoPortWritePortUlong(IN PULONG Port,
   WRITE_PORT_ULONG(Port, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortBufferUchar(IN PUCHAR  Port, 
@@ -890,6 +1125,10 @@ VideoPortWritePortBufferUchar(IN PUCHAR  Port,
   WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortBufferUshort(IN PUSHORT  Port, 
@@ -900,6 +1139,10 @@ VideoPortWritePortBufferUshort(IN PUSHORT  Port,
   WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWritePortBufferUlong(IN PULONG  Port, 
@@ -910,6 +1153,10 @@ VideoPortWritePortBufferUlong(IN PULONG  Port,
   WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWriteRegisterUchar(IN PUCHAR  Register, 
@@ -919,6 +1166,10 @@ VideoPortWriteRegisterUchar(IN PUCHAR  Register,
   WRITE_REGISTER_UCHAR(Register, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWriteRegisterUshort(IN PUSHORT  Register, 
@@ -928,6 +1179,10 @@ VideoPortWriteRegisterUshort(IN PUSHORT  Register,
   WRITE_REGISTER_USHORT(Register, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWriteRegisterUlong(IN PULONG  Register, 
@@ -937,6 +1192,10 @@ VideoPortWriteRegisterUlong(IN PULONG  Register,
   WRITE_REGISTER_ULONG(Register, Value);
 }
 
+
+/*
+ * @implemented
+ */
 VOID 
 STDCALL
 VideoPortWriteRegisterBufferUchar(IN PUCHAR  Register, 
@@ -947,6 +1206,10 @@ VideoPortWriteRegisterBufferUchar(IN PUCHAR  Register,
   WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID STDCALL
 VideoPortWriteRegisterBufferUshort(IN PUSHORT  Register,
                                    IN PUSHORT  Buffer,
@@ -956,6 +1219,10 @@ VideoPortWriteRegisterBufferUshort(IN PUSHORT  Register,
   WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID STDCALL
 VideoPortWriteRegisterBufferUlong(IN PULONG  Register,
                                   IN PULONG  Buffer,
@@ -965,6 +1232,10 @@ VideoPortWriteRegisterBufferUlong(IN PULONG  Register,
   WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
 }
 
+
+/*
+ * @implemented
+ */
 VOID STDCALL
 VideoPortZeroDeviceMemory(OUT PVOID  Destination,
                          IN ULONG  Length)
@@ -973,13 +1244,36 @@ VideoPortZeroDeviceMemory(OUT PVOID  Destination,
   RtlZeroMemory(Destination, Length);
 }
 
+/*
+ * Reset display to blue screen
+ */
+static BOOLEAN STDCALL
+VideoPortResetDisplayParameters(Columns, Rows)
+{
+  if (NULL != ResetDisplayParametersDeviceExtension)
+    {
+      return(FALSE);
+    }
+  if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw)
+    {
+      return(FALSE);
+    }
+  if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
+                                                       Columns, Rows))
+    {
+      return(FALSE);
+    }
+
+  ResetDisplayParametersDeviceExtension = NULL;
+
+  return TRUE;
+}
 
-//  -------------------------------------------  Nondiscardable statics
 
-//    VidDispatchOpenClose
+//    VidDispatchOpen
 //
 //  DESCRIPTION:
-//    Answer requests for Open/Close calls: a null operation
+//    Answer requests for Open calls
 //
 //  RUN LEVEL:
 //    PASSIVE_LEVEL
@@ -992,39 +1286,85 @@ VideoPortZeroDeviceMemory(OUT PVOID  Destination,
 //
 
 static NTSTATUS STDCALL
-VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
-                     IN PIRP Irp)
+VidDispatchOpen(IN PDEVICE_OBJECT pDO,
+                IN PIRP Irp)
 {
   PIO_STACK_LOCATION IrpStack;
-  PVIDEO_PORT_DEVICE_EXTENSION  DeviceExtension;
+  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
 
-  DPRINT("VidDispatchOpenClose() called\n");
+  DPRINT("VidDispatchOpen() called\n");
 
   IrpStack = IoGetCurrentIrpStackLocation(Irp);
 
-  if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
-      CsrssInitialized == FALSE)
+  if (! CsrssInitialized)
     {
       DPRINT("Referencing CSRSS\n");
       Csrss = PsGetCurrentProcess();
-      CsrssInitialized = TRUE;
       DPRINT("Csrss %p\n", Csrss);
+    }
+  else
+    {
       DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
       if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
        {
          Irp->IoStatus.Status = STATUS_SUCCESS;
+         /* Storing the device extension pointer in a static variable is an ugly
+          * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
+          * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
+           * parameter. On the bright side, the DISPLAY device is opened
+          * exclusively, so there can be only one device extension active at
+          * any point in time. */
+         ResetDisplayParametersDeviceExtension = DeviceExtension;
+         HalAcquireDisplayOwnership(VideoPortResetDisplayParameters);
        }
       else
        {
          Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        }
     }
+
+  Irp->IoStatus.Information = FILE_OPENED;
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_SUCCESS;
+}
+
+//    VidDispatchClose
+//
+//  DESCRIPTION:
+//    Answer requests for Close calls
+//
+//  RUN LEVEL:
+//    PASSIVE_LEVEL
+//
+//  ARGUMENTS:
+//    Standard dispatch arguments
+//
+//  RETURNS:
+//    NTSTATUS
+//
+
+static NTSTATUS STDCALL
+VidDispatchClose(IN PDEVICE_OBJECT pDO,
+                 IN PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpStack;
+  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+  DPRINT("VidDispatchClose() called\n");
+
+  IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+  if (! CsrssInitialized)
+    {
+      CsrssInitialized = TRUE;
+    }
   else
     {
-    Irp->IoStatus.Status = STATUS_SUCCESS;
+      HalReleaseDisplayOwnership();
     }
 
-  Irp->IoStatus.Information = FILE_OPENED;
+  Irp->IoStatus.Status = STATUS_SUCCESS;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
   return STATUS_SUCCESS;
@@ -1197,12 +1537,8 @@ InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
          AddressMapping->MappingCount--;
          if (0 == AddressMapping->MappingCount)
            {
-#ifdef TODO
              MmUnmapIoSpace(AddressMapping->MappedAddress,
                             AddressMapping->NumberOfUchars);
-#else
-DPRINT("MmUnmapIoSpace(0x%08x, 0x%08x)\n", AddressMapping->MappedAddress, AddressMapping->NumberOfUchars);
-#endif
              RemoveEntryList(Entry);
              ExFreePool(AddressMapping);