REVISON -> REVISION
[reactos.git] / reactos / drivers / video / videoprt / videoprt.c
index be5b1d5..371b93e 100644 (file)
  * If not, write to the Free Software Foundation,
  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * $Id: videoprt.c,v 1.22 2004/03/14 18:35:02 dwelch Exp $
+ * $Id$
  */
 
 #include "videoprt.h"
 
-BOOLEAN CsrssInitialized = FALSE;
-PEPROCESS Csrss = NULL;
-PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
-static PVOID RomImageBuffer = NULL;
+/* GLOBAL VARIABLES ***********************************************************/
 
-VOID STDCALL STATIC
-VideoPortDeferredRoutine(
-   IN PKDPC Dpc,
-   IN PVOID DeferredContext,
-   IN PVOID SystemArgument1,
-   IN PVOID SystemArgument2
-   );
-PVOID STDCALL
-VideoPortGetProcAddress(IN PVOID HwDeviceExtension,
-                       IN PUCHAR FunctionName);
-
-//  -------------------------------------------------------  Public Interface
-
-//    DriverEntry
-//
-//  DESCRIPTION:
-//    This function initializes the driver.
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    IN  PDRIVER_OBJECT   DriverObject  System allocated Driver Object
-//                                       for this driver
-//    IN  PUNICODE_STRING  RegistryPath  Name of registry driver service 
-//                                       key
-//
-//  RETURNS:
-//    NTSTATUS  
-
-NTSTATUS STDCALL
-DriverEntry(IN PDRIVER_OBJECT DriverObject,
-            IN PUNICODE_STRING RegistryPath)
-{
-  DPRINT("DriverEntry()\n");
-  return(STATUS_SUCCESS);
-}
+ULONG CsrssInitialized = FALSE;
+PKPROCESS Csrss = NULL;
 
-/*
- * @implemented
- */
-VOID
-VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel,
-                    IN PCHAR DebugMessage, ...)
-{
-       char Buffer[256];
-       va_list ap;
+/* PRIVATE FUNCTIONS **********************************************************/
 
-/*
-       if (DebugPrintLevel > InternalDebugLevel)
-               return;
-*/
-       va_start (ap, DebugMessage);
-       vsprintf (Buffer, DebugMessage, ap);
-       va_end (ap);
-
-       DbgPrint (Buffer);
+NTSTATUS NTAPI
+DriverEntry(
+   IN PDRIVER_OBJECT DriverObject,
+   IN PUNICODE_STRING RegistryPath)
+{
+   return STATUS_SUCCESS;
 }
 
-
-/*
- * @implemented
- */
-VOID 
-STDCALL
-VideoPortFreeDeviceBase(IN PVOID  HwDeviceExtension, 
-                        IN PVOID  MappedAddress)
+PVOID NTAPI
+IntVideoPortImageDirectoryEntryToData(
+   PVOID BaseAddress,
+   ULONG Directory)
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   PIMAGE_NT_HEADERS NtHeader;
+   ULONG Va;
 
-  DPRINT("VideoPortFreeDeviceBase\n");
+   NtHeader = RtlImageNtHeader(BaseAddress);
+   if (NtHeader == NULL)
+      return NULL;
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+   if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
+      return NULL;
 
-  InternalUnmapMemory(DeviceExtension, MappedAddress);
-}
+   Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
+   if (Va == 0)
+      return NULL;
 
+   return (PVOID)((ULONG_PTR)BaseAddress + Va);
+}
 
-/*
- * @implemented
- */
-ULONG 
-STDCALL
-VideoPortGetBusData(IN PVOID  HwDeviceExtension,
-                    IN BUS_DATA_TYPE  BusDataType,
-                    IN ULONG  SlotNumber,
-                    OUT PVOID  Buffer,
-                    IN ULONG  Offset,
-                    IN ULONG  Length)
+PVOID NTAPI
+IntVideoPortGetProcAddress(
+   IN PVOID HwDeviceExtension,
+   IN PUCHAR FunctionName)
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+   PVOID BaseAddress;
+   PIMAGE_EXPORT_DIRECTORY ExportDir;
+   PUSHORT OrdinalPtr;
+   PULONG NamePtr;
+   PULONG AddressPtr;
+   ULONG i = 0;
+   NTSTATUS Status;
+
+   DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
+
+   RtlInitUnicodeString(&GdiDriverInfo.DriverName, L"videoprt");
+   Status = ZwSetSystemInformation(
+      SystemLoadGdiDriverInformation,
+      &GdiDriverInfo,
+      sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("Couldn't get our own module handle?\n");
+      return NULL;
+   }
 
-  DPRINT("VideoPortGetBusData\n");
+   BaseAddress = GdiDriverInfo.ImageAddress;
+
+   /* Get the pointer to the export directory */
+   ExportDir = (PIMAGE_EXPORT_DIRECTORY)IntVideoPortImageDirectoryEntryToData(
+      BaseAddress,
+      IMAGE_DIRECTORY_ENTRY_EXPORT);
+
+   /* Search by name */
+   AddressPtr = (PULONG)
+      ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions);
+   OrdinalPtr = (PUSHORT)
+      ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
+   NamePtr = (PULONG)
+      ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
+   for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
+   {
+      if (!_strnicmp((PCHAR)FunctionName, (PCHAR)((ULONG_PTR)BaseAddress + *NamePtr),
+                     strlen((PCHAR)FunctionName)))
+      {
+         return (PVOID)((ULONG_PTR)BaseAddress +
+                        (ULONG_PTR)AddressPtr[*OrdinalPtr]);
+      }
+   }
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+   DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName);
 
-  return HalGetBusDataByOffset(BusDataType, 
-                               DeviceExtension->SystemIoBusNumber, 
-                               SlotNumber, 
-                               Buffer, 
-                               Offset, 
-                               Length);
+   return NULL;
 }
 
-
-/*
- * @implemented
- */
-UCHAR 
-STDCALL
-VideoPortGetCurrentIrql(VOID)
+VOID NTAPI
+IntVideoPortDeferredRoutine(
+   IN PKDPC Dpc,
+   IN PVOID DeferredContext,
+   IN PVOID SystemArgument1,
+   IN PVOID SystemArgument2)
 {
-  return KeGetCurrentIrql();
+   PVOID HwDeviceExtension =
+      &((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
+   ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
 }
 
-
-/*
- * @implemented
- */
-PVOID 
-STDCALL
-VideoPortGetDeviceBase(IN PVOID  HwDeviceExtension,
-                       IN PHYSICAL_ADDRESS  IoAddress,
-                       IN ULONG  NumberOfUchars,
-                       IN UCHAR  InIoSpace)
+ULONG NTAPI
+IntVideoPortAllocateDeviceNumber(VOID)
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   NTSTATUS Status;
+   ULONG DeviceNumber;
+   WCHAR SymlinkBuffer[20];
+   UNICODE_STRING SymlinkName;
 
-  DPRINT("VideoPortGetDeviceBase\n");
+   for (DeviceNumber = 0;;)
+   {
+      OBJECT_ATTRIBUTES Obj;
+      HANDLE ObjHandle;
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+      swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1);
+      RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
+      InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL);
+      Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj);
+      if (NT_SUCCESS(Status))
+      {
+         ZwClose(ObjHandle);
+         DeviceNumber++;
+         continue;
+      }
+      else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+         break;
+      else
+      {
+         DPRINT1("ZwOpenSymbolicLinkObject() returned unexpected status: 0x%08lx\n", Status);
+         return 0xFFFFFFFF;
+      }
+   }
 
-  return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace, NULL);
+   return DeviceNumber;
 }
 
-
-/*
- * @unimplemented
- */
-VP_STATUS 
-STDCALL
-VideoPortGetDeviceData(IN PVOID  HwDeviceExtension,
-                       IN VIDEO_DEVICE_DATA_TYPE  DeviceDataType,
-                       IN PMINIPORT_QUERY_DEVICE_ROUTINE  CallbackRoutine,
-                       IN PVOID Context)
+NTSTATUS NTAPI
+IntVideoPortCreateAdapterDeviceObject(
+   IN PDRIVER_OBJECT DriverObject,
+   IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
+   IN PDEVICE_OBJECT PhysicalDeviceObject,
+   OUT PDEVICE_OBJECT *DeviceObject  OPTIONAL)
 {
-  DPRINT("VideoPortGetDeviceData\n");
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
-}
-
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   ULONG DeviceNumber;
+   ULONG Size;
+   NTSTATUS Status;
+   WCHAR DeviceBuffer[20];
+   UNICODE_STRING DeviceName;
+   PDEVICE_OBJECT DeviceObject_;
+
+   if (DeviceObject == NULL)
+      DeviceObject = &DeviceObject_;
+
+   /*
+    * Find the first free device number that can be used for video device
+    * object names and symlinks.
+    */
+
+   DeviceNumber = IntVideoPortAllocateDeviceNumber();
+   if (DeviceNumber == 0xFFFFFFFF)
+   {
+      DPRINT("Can't find free device number\n");
+      return STATUS_UNSUCCESSFUL;
+   }
 
-/*
- * @implemented
- */
-VP_STATUS 
-STDCALL
-VideoPortGetAccessRanges(IN PVOID  HwDeviceExtension,
-                         IN ULONG  NumRequestedResources,
-                         IN PIO_RESOURCE_DESCRIPTOR  RequestedResources OPTIONAL,
-                         IN ULONG  NumAccessRanges,
-                         IN PVIDEO_ACCESS_RANGE  AccessRanges,
-                         IN PVOID  VendorId,
-                         IN PVOID  DeviceId,
-                         IN PULONG  Slot)
-{
-  PCI_SLOT_NUMBER PciSlotNumber;
-  ULONG FunctionNumber;
-  PCI_COMMON_CONFIG Config;
-  PCM_RESOURCE_LIST AllocatedResources;
-  NTSTATUS Status;
-  UINT AssignedCount;
-  CM_FULL_RESOURCE_DESCRIPTOR *FullList;
-  CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  USHORT VendorIdToFind;
-  USHORT DeviceIdToFind;
-  ULONG SlotIdToFind;
-
-  DPRINT("VideoPortGetAccessRanges\n");
-
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-
-  if (0 == NumRequestedResources && 
-      PCIBus == DeviceExtension->AdapterInterfaceType)
-    {
-      VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0;
-      DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0;
-      SlotIdToFind = Slot != NULL ? *Slot : 0;
-
-      DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x SlotId 0x%04x\n", 
-            VendorIdToFind, DeviceIdToFind, SlotIdToFind);
-
-      PciSlotNumber.u.AsULONG = SlotIdToFind;
+   /*
+    * Create the device object.
+    */
+
+   /* Create a unicode device name. */
+   swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
+   RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+   /* Create the device object. */
+   Status = IoCreateDevice(
+      DriverObject,
+      sizeof(VIDEO_PORT_DEVICE_EXTENSION) +
+      DriverExtension->InitializationData.HwDeviceExtensionSize,
+      &DeviceName,
+      FILE_DEVICE_VIDEO,
+      0,
+      TRUE,
+      DeviceObject);
+
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
+      return Status;
+   }
 
-      /*
-       Search for the device id and vendor id on this bus.
-      */
-      for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++)
-       {
-         ULONG ReturnedLength;
-         DPRINT("- Function number: %d\n", FunctionNumber);
-         PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
-         ReturnedLength = HalGetBusData(PCIConfiguration, 
-                                        DeviceExtension->SystemIoBusNumber,
-                                        PciSlotNumber.u.AsULONG,
-                                        &Config,
-                                        sizeof(PCI_COMMON_CONFIG));
-         DPRINT("- Length of data: %x\n", ReturnedLength);
-         if (sizeof(PCI_COMMON_CONFIG) == ReturnedLength)
-           {
-              DPRINT("- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
-                     "DeviceId 0x%04x\n",
-                     PciSlotNumber.u.AsULONG, 
-                     PciSlotNumber.u.bits.DeviceNumber,
-                     PciSlotNumber.u.bits.FunctionNumber,
-                     Config.VendorID,
-                     Config.DeviceID);
-
-             if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) &&
-                 (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind))
-               {
-                 break;
-               }
-           }
-       }
-      if (FunctionNumber == 8)
-       {
-         DPRINT("Didn't find device.\n");
-         return STATUS_UNSUCCESSFUL;
-       }
-
-      Status = HalAssignSlotResources(NULL, NULL, NULL, NULL,
-                                      DeviceExtension->AdapterInterfaceType,
-                                      DeviceExtension->SystemIoBusNumber,
-                                      PciSlotNumber.u.AsULONG, 
-                                     &AllocatedResources);
-      if (! NT_SUCCESS(Status))
-       {
-         return Status;
-       }
-      AssignedCount = 0;
-      for (FullList = AllocatedResources->List;
-           FullList < AllocatedResources->List + AllocatedResources->Count;
-           FullList++)
-       {
-         assert(FullList->InterfaceType == PCIBus &&
-                FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
-                1 == FullList->PartialResourceList.Version &&
-                1 == FullList->PartialResourceList.Revision);
-         for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
-              Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
-              Descriptor++)
-           {
-              if ((CmResourceTypeMemory == Descriptor->Type
-                   || CmResourceTypePort == Descriptor->Type)
-                  && NumAccessRanges <= AssignedCount)
-               {
-                  DPRINT1("Too many access ranges found\n");
-                  ExFreePool(AllocatedResources);
-                  return STATUS_UNSUCCESSFUL;
-                }
-             if (CmResourceTypeMemory == Descriptor->Type)
-               {
-                  if (NumAccessRanges <= AssignedCount)
-                    {
-                      DPRINT1("Too many access ranges found\n");
-                      ExFreePool(AllocatedResources);
-                      return STATUS_UNSUCCESSFUL;
-                    }
-                 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
-                        Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
-                 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
-                 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
-                 AccessRanges[AssignedCount].RangeInIoSpace = 0;
-                 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
-                 AccessRanges[AssignedCount].RangeShareable =
-                   (CmResourceShareShared == Descriptor->ShareDisposition);
-                 AssignedCount++;
-               }
-             else if (CmResourceTypePort == Descriptor->Type)
-               {
-                 DPRINT("Port range starting at 0x%04x length %d\n",
-                        Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
-                 AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
-                 AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
-                 AccessRanges[AssignedCount].RangeInIoSpace = 1;
-                 AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
-                 AccessRanges[AssignedCount].RangeShareable = 0;
-                 AssignedCount++;
-               }
-              else if (CmResourceTypeInterrupt == Descriptor->Type)
-                {
-                  DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
-                  DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
-                }
-           }
-       }
-      ExFreePool(AllocatedResources);
-    }
-  else
-    {
-      UNIMPLEMENTED
-    }
-
-  return STATUS_SUCCESS;
-}
+   /*
+    * Set the buffering strategy here. If you change this, remember
+    * to change VidDispatchDeviceControl too.
+    */
+
+   (*DeviceObject)->Flags |= DO_BUFFERED_IO;
+
+   /*
+    * Initialize device extension.
+    */
+
+   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension);
+   DeviceExtension->DeviceNumber = DeviceNumber;
+   DeviceExtension->DriverObject = DriverObject;
+   DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+   DeviceExtension->FunctionalDeviceObject = *DeviceObject;
+   DeviceExtension->DriverExtension = DriverExtension;
+
+   DeviceExtension->RegistryPath.Length =
+   DeviceExtension->RegistryPath.MaximumLength =
+      DriverExtension->RegistryPath.Length + (9 * sizeof(WCHAR));
+   DeviceExtension->RegistryPath.Length -= sizeof(WCHAR);
+   DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(
+      NonPagedPool,
+      DeviceExtension->RegistryPath.MaximumLength,
+      TAG_VIDEO_PORT);
+   swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
+      DriverExtension->RegistryPath.Buffer);
+
+   if (PhysicalDeviceObject != NULL)
+   {
+      /* Get bus number from the upper level bus driver. */
+      Size = sizeof(ULONG);
+      Status = IoGetDeviceProperty(
+         PhysicalDeviceObject,
+         DevicePropertyBusNumber,
+         Size,
+         &DeviceExtension->SystemIoBusNumber,
+         &Size);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT("Couldn't get an information from bus driver. We will try to\n"
+                "use legacy detection method, but even that doesn't mean that\n"
+                "it will work.\n");
+         DeviceExtension->PhysicalDeviceObject = NULL;
+      }
+   }
 
-typedef struct QueryRegistryCallbackContext
-{
-  PVOID HwDeviceExtension;
-  PVOID HwContext;
-  PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
-} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
+   DeviceExtension->AdapterInterfaceType =
+      DriverExtension->InitializationData.AdapterInterfaceType;
 
-static NTSTATUS STDCALL
-QueryRegistryCallback(IN PWSTR ValueName,
-                      IN ULONG ValueType,
-                      IN PVOID ValueData,
-                      IN ULONG ValueLength,
-                      IN PVOID Context,
-                      IN PVOID EntryContext)
-{
-  PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context;
-
-  DPRINT("Found registry value for name %S: type %d, length %d\n",
-         ValueName, ValueType, ValueLength);
-  return (*(CallbackContext->HwGetRegistryRoutine))(CallbackContext->HwDeviceExtension,
-                                                    CallbackContext->HwContext,
-                                                    ValueName,
-                                                    ValueData,
-                                                    ValueLength);
-}
+   if (PhysicalDeviceObject != NULL)
+   {
+      /* Get bus type from the upper level bus driver. */
+      Size = sizeof(ULONG);
+      IoGetDeviceProperty(
+         PhysicalDeviceObject,
+         DevicePropertyLegacyBusType,
+         Size,
+         &DeviceExtension->AdapterInterfaceType,
+         &Size);
+
+      /* Get bus device address from the upper level bus driver. */
+      Size = sizeof(ULONG);
+      IoGetDeviceProperty(
+         PhysicalDeviceObject,
+         DevicePropertyAddress,
+         Size,
+         &DeviceExtension->SystemIoSlotNumber,
+         &Size);
+   }
 
-/*
- * @unimplemented
- */
-VP_STATUS 
-STDCALL
-VideoPortGetRegistryParameters(IN PVOID  HwDeviceExtension,
-                               IN PWSTR  ParameterName,
-                               IN UCHAR  IsParameterFileName,
-                               IN PMINIPORT_GET_REGISTRY_ROUTINE  GetRegistryRoutine,
-                               IN PVOID  HwContext)
-{
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-  QUERY_REGISTRY_CALLBACK_CONTEXT Context;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   InitializeListHead(&DeviceExtension->AddressMappingListHead);
+   KeInitializeDpc(
+      &DeviceExtension->DpcObject,
+      IntVideoPortDeferredRoutine,
+      DeviceExtension);
 
-  DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName);
+   KeInitializeMutex(&DeviceExtension->DeviceLock, 0);
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+   /* Attach the device. */
+   if (PhysicalDeviceObject != NULL)
+      DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(
+         *DeviceObject, PhysicalDeviceObject);
 
-  if (IsParameterFileName)
-    {
-      UNIMPLEMENTED;
-    }
-
-  Context.HwDeviceExtension = HwDeviceExtension;
-  Context.HwContext = HwContext;
-  Context.HwGetRegistryRoutine = GetRegistryRoutine;
-
-  QueryTable[0].QueryRoutine = QueryRegistryCallback;
-  QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
-  QueryTable[0].Name = ParameterName;
-  QueryTable[0].EntryContext = NULL;
-  QueryTable[0].DefaultType = REG_NONE;
-  QueryTable[0].DefaultData = NULL;
-  QueryTable[0].DefaultLength = 0;
-
-  QueryTable[1].QueryRoutine = NULL;
-  QueryTable[1].Name = NULL;
-
-  return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-                                           DeviceExtension->RegistryPath.Buffer,
-                                           QueryTable, &Context, NULL))
-         ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
+   return STATUS_SUCCESS;
 }
 
 
-/*
- * @implemented
- */ 
-VP_STATUS
-STDCALL
-VideoPortGetVgaStatus(IN PVOID  HwDeviceExtension,
-                     OUT PULONG  VgaStatus)
+/* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
+NTSTATUS NTAPI
+IntVideoPortFindAdapter(
+   IN PDRIVER_OBJECT DriverObject,
+   IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
+   IN PDEVICE_OBJECT DeviceObject)
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   WCHAR DeviceVideoBuffer[20];
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   ULONG Size;
+   NTSTATUS Status;
+   VIDEO_PORT_CONFIG_INFO ConfigInfo;
+   SYSTEM_BASIC_INFORMATION SystemBasicInfo;
+   UCHAR Again = FALSE;
+   WCHAR DeviceBuffer[20];
+   UNICODE_STRING DeviceName;
+   WCHAR SymlinkBuffer[20];
+   UNICODE_STRING SymlinkName;
+   BOOL LegacyDetection = FALSE;
+   ULONG DeviceNumber;
+
+   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+   DeviceNumber = DeviceExtension->DeviceNumber;
+
+   /*
+    * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
+    */
+
+   RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
+   ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
+   ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
+   if (ConfigInfo.AdapterInterfaceType == PCIBus)
+      ConfigInfo.InterruptMode = LevelSensitive;
+   else
+      ConfigInfo.InterruptMode = Latched;
+   ConfigInfo.DriverRegistryPath = DriverExtension->RegistryPath.Buffer;
+   ConfigInfo.VideoPortGetProcAddress = IntVideoPortGetProcAddress;
+   ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
+   ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
+   ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
+
+   Size = sizeof(SystemBasicInfo);
+   Status = ZwQuerySystemInformation(
+      SystemBasicInformation,
+      &SystemBasicInfo,
+      Size,
+      &Size);
+
+   if (NT_SUCCESS(Status))
+   {
+      ConfigInfo.SystemMemorySize =
+         SystemBasicInfo.NumberOfPhysicalPages *
+         SystemBasicInfo.PageSize;
+   }
 
-  DPRINT("VideoPortGetVgaStatus = %x \n", VgaStatus);
+   /*
+    * Call miniport HwVidFindAdapter entry point to detect if
+    * particular device is present. There are two possible code
+    * paths. The first one is for Legacy drivers (NT4) and cases
+    * when we don't have information about what bus we're on. The
+    * second case is the standard one for Plug & Play drivers.
+    */
+   if (DeviceExtension->PhysicalDeviceObject == NULL)
+   {
+      LegacyDetection = TRUE;
+   }
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+   if (LegacyDetection)
+   {
+      ULONG BusNumber, MaxBuses;
 
- if(KeGetCurrentIrql() == PASSIVE_LEVEL)
- {
-  DPRINT("VideoPortGetVgaStatus1 = %x \n", VgaStatus);
+      MaxBuses = DeviceExtension->AdapterInterfaceType == PCIBus ? 8 : 1;
 
-  if ( PCIBus == DeviceExtension->AdapterInterfaceType)
-       {
-/*
-  VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
- */
-  DPRINT("VideoPortGetVgaStatus2 = %x \n", VgaStatus);
-       
-       /* Assumed for now */
-       
-       VgaStatus = (PULONG) 1;
-
-       return  STATUS_SUCCESS;
-       }
-  }    
-  DPRINT("VideoPortGetVgaStatus3 = %x \n", VgaStatus);
-
-  return ERROR_INVALID_FUNCTION;    
-}
+      for (BusNumber = 0; BusNumber < MaxBuses; BusNumber++)
+      {
+         DeviceExtension->SystemIoBusNumber =
+         ConfigInfo.SystemIoBusNumber = BusNumber;
+
+         RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
+                       DriverExtension->InitializationData.HwDeviceExtensionSize);
+
+         /* FIXME: Need to figure out what string to pass as param 3. */
+         Status = DriverExtension->InitializationData.HwFindAdapter(
+            &DeviceExtension->MiniPortDeviceExtension,
+            DriverExtension->HwContext,
+            NULL,
+            &ConfigInfo,
+            &Again);
+
+         if (Status == ERROR_DEV_NOT_EXIST)
+         {
+            continue;
+         }
+         else if (Status == NO_ERROR)
+         {
+            break;
+         }
+         else
+         {
+            DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
+            RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+            IoDeleteDevice(DeviceObject);
+
+            return Status;
+         }
+      }
+   }
+   else
+   {
+      /* FIXME: Need to figure out what string to pass as param 3. */
+      Status = DriverExtension->InitializationData.HwFindAdapter(
+         &DeviceExtension->MiniPortDeviceExtension,
+         DriverExtension->HwContext,
+         NULL,
+         &ConfigInfo,
+         &Again);
+   }
 
-static BOOLEAN STDCALL
-VPInterruptRoutine(IN struct _KINTERRUPT *Interrupt,
-                   IN PVOID ServiceContext)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  
-  DeviceExtension = ServiceContext;
-  assert(NULL != DeviceExtension->HwInterrupt);
+   if (Status != NO_ERROR)
+   {
+      DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
+      RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+      IoDeleteDevice(DeviceObject);
+      return Status;
+   }
 
-  return DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
-}
+   /*
+    * Now we know the device is present, so let's do all additional tasks
+    * such as creating symlinks or setting up interrupts and timer.
+    */
+
+   /* Create a unicode device name. */
+   swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
+   RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+   /* Create symbolic link "\??\DISPLAYx" */
+   swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1);
+   RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
+   IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+
+   /* Add entry to DEVICEMAP\VIDEO key in registry. */
+   swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber);
+   RtlWriteRegistryValue(
+      RTL_REGISTRY_DEVICEMAP,
+      L"VIDEO",
+      DeviceVideoBuffer,
+      REG_SZ,
+      DeviceExtension->RegistryPath.Buffer,
+      DeviceExtension->RegistryPath.MaximumLength);
+
+   /* FIXME: Allocate hardware resources for device. */
+
+   /*
+    * Allocate interrupt for device.
+    */
+
+   if (!IntVideoPortSetupInterrupt(DeviceObject, DriverExtension, &ConfigInfo))
+   {
+      RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+      IoDeleteDevice(DeviceObject);
+      return STATUS_INSUFFICIENT_RESOURCES;
+   }
 
-static VOID STDCALL
-VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
-               IN PVOID Context)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION  DeviceExtension;
-  
-  DeviceExtension = Context;
-  assert(DeviceExtension == DeviceObject->DeviceExtension
-         && NULL != DeviceExtension->HwTimer);
+   /*
+    * Allocate timer for device.
+    */
 
-  DeviceExtension->HwTimer(&DeviceExtension->MiniPortDeviceExtension);
-}
+   if (!IntVideoPortSetupTimer(DeviceObject, DriverExtension))
+   {
+      if (DeviceExtension->InterruptObject != NULL)
+         IoDisconnectInterrupt(DeviceExtension->InterruptObject);
+      RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+      IoDeleteDevice(DeviceObject);
+      DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
+      return STATUS_INSUFFICIENT_RESOURCES;
+   }
 
-/*
- * @implemented
- */
-ULONG STDCALL
-VideoPortInitialize(IN PVOID  Context1,
-                    IN PVOID  Context2,
-                    IN PVIDEO_HW_INITIALIZATION_DATA  HwInitializationData,
-                    IN PVOID  HwContext)
-{
-  PUNICODE_STRING RegistryPath;
-  UCHAR Again = FALSE;
-  WCHAR DeviceBuffer[20];
-  WCHAR SymlinkBuffer[20];
-  WCHAR DeviceVideoBuffer[20];
-  NTSTATUS Status;
-  PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
-  PDEVICE_OBJECT MPDeviceObject;
-  VIDEO_PORT_CONFIG_INFO ConfigInfo;
-  PVIDEO_PORT_DEVICE_EXTENSION  DeviceExtension;
-  ULONG DisplayNumber;
-  UNICODE_STRING DeviceName;
-  UNICODE_STRING SymlinkName;
-  ULONG MaxBus;
-  ULONG MaxLen;
-  KIRQL IRQL;
-  KAFFINITY Affinity;
-  ULONG InterruptVector;
-  OBJECT_ATTRIBUTES Obj;
-  HANDLE ObjHandle;
-
-  DPRINT("VideoPortInitialize\n");
-
-  RegistryPath = (PUNICODE_STRING) Context2;
-
-  /* Build Dispatch table from passed data  */
-  MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
-
-  /* Find the first free device number */
-  for (DisplayNumber = 0;;)
-    {
-      swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
-      RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
-      InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL);
-      Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj);
-      if (NT_SUCCESS(Status))
-        {
-          ZwClose(ObjHandle);
-          DisplayNumber++;
-          continue;
-        }
-      else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL)
-        {
-          break;
-        }
-      else
-        {
-          return Status;
-        }
-    }
-
-  DPRINT("- DisplayNumber: %d\n", DisplayNumber);
-
-  Again = FALSE;
-
-  do
-    {
-      /* Create a unicode device name. */
-      swprintf(DeviceBuffer, L"\\Device\\Video%lu", DisplayNumber);
-      RtlInitUnicodeString(&DeviceName, DeviceBuffer);
-
-      /* Create the device. */
-      Status = IoCreateDevice(
-         MPDriverObject,
-         HwInitializationData->HwDeviceExtensionSize +
-         sizeof(VIDEO_PORT_DEVICE_EXTENSION),
-         &DeviceName,
-         FILE_DEVICE_VIDEO,
-         0,
-         TRUE,
-         &MPDeviceObject);
-      if (!NT_SUCCESS(Status))
-        {
-          DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
-          return Status;
-        }
-
-      MPDriverObject->DeviceObject = MPDeviceObject;
-
-      /* Initialize the miniport drivers dispatch table */
-      MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpen;
-      MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchClose;
-      MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 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;
-      KeInitializeDpc(&DeviceExtension->DpcObject, VideoPortDeferredRoutine,
-                     (PVOID)DeviceExtension);
-      MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
-      DeviceExtension->RegistryPath.MaximumLength = MaxLen;
-      DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
-                                                                   MaxLen,
-                                                                   TAG_VIDEO_PORT);
-      swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
-               RegistryPath->Buffer);
-      DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
-                                             sizeof(WCHAR);
-
-      MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
-      DPRINT("MaxBus: %lu\n", MaxBus);
-      InitializeListHead(&DeviceExtension->AddressMappingListHead);
-      
-      /*  Set the buffering strategy here...  */
-      /*  If you change this, remember to change VidDispatchDeviceControl too */
-      MPDeviceObject->Flags |= DO_BUFFERED_IO;
-
-      do
-       {
-         RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, 
-                       HwInitializationData->HwDeviceExtensionSize);
-         DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
-         /* Setup configuration info */
-         RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
-         ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
-         ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
-         ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
-         ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
-                                     LevelSensitive : Latched;
-         ConfigInfo.DriverRegistryPath = RegistryPath->Buffer;
-         ConfigInfo.VideoPortGetProcAddress = VideoPortGetProcAddress;
-
-         /*  Call HwFindAdapter entry point  */
-         /* FIXME: Need to figure out what string to pass as param 3  */
-         Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
-                                                      Context2,
-                                                      NULL,
-                                                      &ConfigInfo,
-                                                      &Again);
-         if (NO_ERROR != Status)
-           {
-             DPRINT("HwFindAdapter call failed with error %X\n", Status);
-             DeviceExtension->SystemIoBusNumber++;
-           }
-       }
-      while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
-
-      if (NO_ERROR != Status)
-        {
-         RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
-          IoDeleteDevice(MPDeviceObject);
-
-          return  Status;
-        }
-      DPRINT("Found adapter\n");
-
-      /* create symbolic link "\??\DISPLAYx" */
-      swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
-      RtlInitUnicodeString (&SymlinkName,
-                            SymlinkBuffer);
-      IoCreateSymbolicLink (&SymlinkName,
-                            &DeviceName);
-
-      /* Add entry to DEVICEMAP\VIDEO key in registry */
-      swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DisplayNumber);
-      RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
-                            L"VIDEO",
-                            DeviceVideoBuffer,
-                            REG_SZ,
-                            DeviceExtension->RegistryPath.Buffer,
-                            DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
-
-      /* FIXME: Allocate hardware resources for device  */
-
-      /*  Allocate interrupt for device  */
-      DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
-      if (0 == ConfigInfo.BusInterruptVector)
-        {
-          ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
-        }
-      if (0 == ConfigInfo.BusInterruptLevel)
-        {
-          ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
-        }
-      if (NULL != HwInitializationData->HwInterrupt)
-        {
-          InterruptVector = 
-            HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
-                                  ConfigInfo.SystemIoBusNumber,
-                                  ConfigInfo.BusInterruptLevel,
-                                  ConfigInfo.BusInterruptVector,
-                                  &IRQL,
-                                  &Affinity);
-          if (0 == InterruptVector)
-            {
-              DPRINT1("HalGetInterruptVector failed\n");
-              IoDeleteDevice(MPDeviceObject);
-              
-              return STATUS_INSUFFICIENT_RESOURCES;
-            }
-          KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
-          Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
-                                      VPInterruptRoutine,
-                                      DeviceExtension,
-                                      &DeviceExtension->InterruptSpinLock,
-                                      InterruptVector,
-                                      IRQL,
-                                      IRQL,
-                                      ConfigInfo.InterruptMode,
-                                      FALSE,
-                                      Affinity,
-                                      FALSE);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status);
-              IoDeleteDevice(MPDeviceObject);
-              
-              return Status;
-            }
-        }
-      DisplayNumber++;
-    }
-  while (Again);
-
-  DeviceExtension->HwTimer = HwInitializationData->HwTimer;
-  if (HwInitializationData->HwTimer != NULL)
-    {
-      DPRINT("Initializing timer\n");
-      Status = IoInitializeTimer(MPDeviceObject,
-                                 VPTimerRoutine,
-                                 DeviceExtension);
-      if (!NT_SUCCESS(Status))
-        {
-          DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
-          
-          if (HwInitializationData->HwInterrupt != NULL)
-            {
-              IoDisconnectInterrupt(DeviceExtension->InterruptObject);
-            }
-          IoDeleteDevice(MPDeviceObject);
-          
-          return Status;
-        }
-    }
-
-  return  STATUS_SUCCESS;
+   /*
+    * Query children of the device.
+    */
+   VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension, NULL);
+
+   DPRINT("STATUS_SUCCESS\n");
+   return STATUS_SUCCESS;
 }
 
-/*
- * @unimplemented
- */
-VOID 
-STDCALL
-VideoPortLogError(IN PVOID  HwDeviceExtension,
-                  IN PVIDEO_REQUEST_PACKET  Vrp OPTIONAL,
-                  IN VP_STATUS  ErrorCode,
-                  IN ULONG  UniqueId)
+VOID FASTCALL
+IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
 {
-  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);
-    }
+   *CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+   if (*CallingProcess != Csrss)
+   {
+      KeStackAttachProcess(Csrss, ApcState);
+   }
 }
 
-
-/*
- * @unimplemented
- */
-VP_STATUS 
-STDCALL
-VideoPortMapBankedMemory(IN PVOID  HwDeviceExtension,
-                         IN PHYSICAL_ADDRESS  PhysicalAddress,
-                         IN PULONG  Length,
-                         IN PULONG  InIoSpace,
-                         OUT PVOID  *VirtualAddress,
-                         IN ULONG  BankLength,
-                         IN UCHAR  ReadWriteBank,
-                         IN PBANKED_SECTION_ROUTINE  BankRoutine,
-                         IN PVOID  Context)
+VOID FASTCALL
+IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
 {
-   DPRINT("VideoPortMapBankedMemory\n");
-   UNIMPLEMENTED;
-   return STATUS_NOT_IMPLEMENTED;
+   if (*CallingProcess != Csrss)
+   {
+      KeUnstackDetachProcess(ApcState);
+   }
 }
 
+/* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
  * @implemented
  */
-VP_STATUS 
-STDCALL
-VideoPortMapMemory(IN PVOID  HwDeviceExtension,
-                   IN PHYSICAL_ADDRESS  PhysicalAddress,
-                   IN PULONG  Length,
-                   IN PULONG  InIoSpace,
-                   OUT PVOID  *VirtualAddress)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  NTSTATUS Status;
-
-  DPRINT("VideoPortMapMemory\n");
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-  *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress,
-                                      *Length, *InIoSpace, &Status);
+ULONG NTAPI
+VideoPortInitialize(
+   IN PVOID Context1,
+   IN PVOID Context2,
+   IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
+   IN PVOID HwContext)
+{
+   PDRIVER_OBJECT DriverObject = Context1;
+   PUNICODE_STRING RegistryPath = Context2;
+   NTSTATUS Status;
+   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
+   BOOL LegacyDetection = FALSE;
 
-  return Status;
-}
+   DPRINT("VideoPortInitialize\n");
 
+   /*
+    * As a first thing do parameter checks.
+    */
 
-/*
- * @implemented
- */
-BOOLEAN 
-STDCALL
-VideoPortScanRom(IN PVOID  HwDeviceExtension, 
-                 IN PUCHAR  RomBase,
-                 IN ULONG  RomLength,
-                 IN PUCHAR  String)
-{
-  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);
-       }
-    }
+   if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA))
+   {
+      return STATUS_REVISION_MISMATCH;
+   }
 
-  return Found;
-}
+   if (HwInitializationData->HwFindAdapter == NULL ||
+       HwInitializationData->HwInitialize == NULL ||
+       HwInitializationData->HwStartIO == NULL)
+   {
+      return STATUS_INVALID_PARAMETER;
+   }
 
+   /*
+    * NOTE:
+    * The driver extension can be already allocated in case that we were
+    * called by legacy driver and failed detecting device. Some miniport
+    * drivers in that case adjust parameters and call VideoPortInitialize
+    * again.
+    */
 
-/*
- * @implemented
- */
-ULONG 
-STDCALL
-VideoPortSetBusData(IN PVOID  HwDeviceExtension,
-                    IN BUS_DATA_TYPE  BusDataType,
-                    IN ULONG  SlotNumber,
-                    IN PVOID  Buffer,
-                    IN ULONG  Offset,
-                    IN ULONG  Length)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+   if (DriverExtension == NULL)
+   {
+      Status = IoAllocateDriverObjectExtension(
+         DriverObject,
+         DriverObject,
+         sizeof(VIDEO_PORT_DRIVER_EXTENSION),
+         (PVOID *)&DriverExtension);
 
-  DPRINT("VideoPortSetBusData\n");
+      if (!NT_SUCCESS(Status))
+      {
+         return Status;
+      }
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
+      /*
+       * Save the registry path. This should be done only once even if
+       * VideoPortInitialize is called multiple times.
+       */
 
-  return  HalSetBusDataByOffset(BusDataType,
-                                DeviceExtension->SystemIoBusNumber,
-                                SlotNumber,
-                                Buffer,
-                                Offset,
-                                Length);
-}
+      if (RegistryPath->Length != 0)
+      {
+         DriverExtension->RegistryPath.Length = 0;
+         DriverExtension->RegistryPath.MaximumLength =
+            RegistryPath->Length + sizeof(UNICODE_NULL);
+         DriverExtension->RegistryPath.Buffer =
+            ExAllocatePoolWithTag(
+               PagedPool,
+               DriverExtension->RegistryPath.MaximumLength,
+               TAG('U', 'S', 'T', 'R'));
+         if (DriverExtension->RegistryPath.Buffer == NULL)
+         {
+            RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
+            return STATUS_INSUFFICIENT_RESOURCES;
+         }
+
+         RtlCopyUnicodeString(&DriverExtension->RegistryPath, RegistryPath);
+      }
+      else
+      {
+         RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
+      }
+   }
 
+   /*
+    * Copy the correct miniport initializtation data to the device extension.
+    */
 
-/*
- * @implemented
- */
-VP_STATUS 
-STDCALL
-VideoPortSetRegistryParameters(IN PVOID  HwDeviceExtension,
-                               IN PWSTR  ValueName,
-                               IN PVOID  ValueData,
-                               IN ULONG  ValueLength)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   RtlCopyMemory(
+      &DriverExtension->InitializationData,
+      HwInitializationData,
+      HwInitializationData->HwInitDataSize);
+   if (HwInitializationData->HwInitDataSize <
+       sizeof(VIDEO_HW_INITIALIZATION_DATA))
+   {
+      RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData +
+                                       HwInitializationData->HwInitDataSize),
+                    sizeof(VIDEO_HW_INITIALIZATION_DATA) -
+                    HwInitializationData->HwInitDataSize);
+   }
+   DriverExtension->HwContext = HwContext;
 
-  DPRINT("VideoSetRegistryParameters\n");
+   switch (HwInitializationData->HwInitDataSize)
+   {
+      /*
+       * NT4 drivers are special case, because we must use legacy method
+       * of detection instead of the Plug & Play one.
+       */
+
+      case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA:
+         DPRINT("We were loaded by a Windows NT miniport driver.\n");
+         LegacyDetection = TRUE;
+         break;
+
+      case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA:
+         DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
+         break;
+
+      case sizeof(VIDEO_HW_INITIALIZATION_DATA):
+         DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
+         break;
+
+      default:
+         DPRINT("Invalid HwInitializationData size.\n");
+         return STATUS_UNSUCCESSFUL;
+   }
 
-  assert_irql(PASSIVE_LEVEL);
+   DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen;
+   DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose;
+   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IntVideoPortDispatchDeviceControl;
+   DriverObject->DriverUnload = IntVideoPortUnload;
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-  return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
-                               DeviceExtension->RegistryPath.Buffer,
-                               ValueName,
-                               REG_BINARY,
-                               ValueData,
-                               ValueLength);
-}
+   /*
+    * Plug & Play drivers registers the device in AddDevice routine. For
+    * legacy drivers we must do it now.
+    */
 
+   if (LegacyDetection)
+   {
+      PDEVICE_OBJECT DeviceObject;
+      Status = IntVideoPortCreateAdapterDeviceObject(DriverObject, DriverExtension,
+                                                     NULL, &DeviceObject);
+      DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status);
+      if (!NT_SUCCESS(Status))
+         return Status;
+      Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, DeviceObject);
+      DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status);
+      return Status;
+   }
+   else
+   {
+      DriverObject->DriverExtension->AddDevice = IntVideoPortAddDevice;
+      DriverObject->MajorFunction[IRP_MJ_PNP] = IntVideoPortDispatchPnp;
+      DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower;
 
-/*
- * @unimplemented
- */
-VP_STATUS 
-STDCALL
-VideoPortSetTrappedEmulatorPorts(IN PVOID  HwDeviceExtension,
-                                 IN ULONG  NumAccessRanges,
-                                 IN PVIDEO_ACCESS_RANGE  AccessRange)
-{
-  DPRINT("VideoPortSetTrappedEmulatorPorts\n");
-  /* Should store the ranges in the device extension for use by ntvdm. */
-  return STATUS_SUCCESS;
+      return STATUS_SUCCESS;
+   }
 }
 
-
 /*
  * @implemented
  */
-VOID 
-STDCALL
-VideoPortStartTimer(IN PVOID  HwDeviceExtension)
+
+VOID
+VideoPortDebugPrint(
+   IN VIDEO_DEBUG_LEVEL DebugPrintLevel,
+   IN PCHAR DebugMessage, ...)
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   char Buffer[256];
+   va_list ap;
 
-  DPRINT("VideoPortStartTimer\n");
+   va_start(ap, DebugMessage);
+   vsprintf(Buffer, DebugMessage, ap);
+   va_end(ap);
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-  IoStartTimer(DeviceExtension->DeviceObject);
+   DbgPrint(Buffer);
 }
 
-
 /*
- * @implemented
+ * @unimplemented
  */
-VOID 
-STDCALL
-VideoPortStopTimer(IN PVOID  HwDeviceExtension)
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
-  DPRINT("VideoPortStopTimer\n");
 
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-  IoStopTimer(DeviceExtension->DeviceObject);
+VOID NTAPI
+VideoPortLogError(
+   IN PVOID HwDeviceExtension,
+   IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
+   IN VP_STATUS ErrorCode,
+   IN ULONG UniqueId)
+{
+   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);
+   }
 }
 
-
 /*
  * @implemented
  */
-BOOLEAN 
-STDCALL
-VideoPortSynchronizeExecution(IN PVOID  HwDeviceExtension,
-                              IN VIDEO_SYNCHRONIZE_PRIORITY  Priority,
-                              IN PMINIPORT_SYNCHRONIZE_ROUTINE  SynchronizeRoutine,
-                              OUT PVOID  Context)
+
+UCHAR NTAPI
+VideoPortGetCurrentIrql(VOID)
 {
-  BOOLEAN Ret;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  KIRQL OldIrql;
-
-  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;
+   return KeGetCurrentIrql();
 }
 
-
-/*
- * @implemented
- */
-VP_STATUS 
-STDCALL
-VideoPortUnmapMemory(IN PVOID  HwDeviceExtension,
-                     IN PVOID  VirtualAddress,
-                     IN HANDLE  ProcessHandle)
+typedef struct QueryRegistryCallbackContext
 {
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
-  DPRINT("VideoPortFreeDeviceBase\n");
-
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-
-  InternalUnmapMemory(DeviceExtension, VirtualAddress);
+   PVOID HwDeviceExtension;
+   PVOID HwContext;
+   PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
+} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
 
-  return STATUS_SUCCESS;
+static NTSTATUS NTAPI
+QueryRegistryCallback(
+   IN PWSTR ValueName,
+   IN ULONG ValueType,
+   IN PVOID ValueData,
+   IN ULONG ValueLength,
+   IN PVOID Context,
+   IN PVOID EntryContext)
+{
+   PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context;
+
+   DPRINT("Found registry value for name %S: type %d, length %d\n",
+          ValueName, ValueType, ValueLength);
+   return (*(CallbackContext->HwGetRegistryRoutine))(
+      CallbackContext->HwDeviceExtension,
+      CallbackContext->HwContext,
+      ValueName,
+      ValueData,
+      ValueLength);
 }
 
-
 /*
  * @unimplemented
  */
-VP_STATUS 
-STDCALL
-VideoPortVerifyAccessRanges(IN PVOID  HwDeviceExtension,
-                            IN ULONG  NumAccessRanges,
-                            IN PVIDEO_ACCESS_RANGE  AccessRanges)
+
+VP_STATUS NTAPI
+VideoPortGetRegistryParameters(
+   IN PVOID HwDeviceExtension,
+   IN PWSTR ParameterName,
+   IN UCHAR IsParameterFileName,
+   IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
+   IN PVOID HwContext)
 {
-  DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
-  return NO_ERROR;
-}
+   RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+   QUERY_REGISTRY_CALLBACK_CONTEXT Context;
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
 
+   DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName);
 
-/*
- * 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;
+   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+
+   if (IsParameterFileName)
+   {
+      UNIMPLEMENTED;
+   }
+
+   Context.HwDeviceExtension = HwDeviceExtension;
+   Context.HwContext = HwContext;
+   Context.HwGetRegistryRoutine = GetRegistryRoutine;
+
+   QueryTable[0].QueryRoutine = QueryRegistryCallback;
+   QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+   QueryTable[0].Name = ParameterName;
+   QueryTable[0].EntryContext = NULL;
+   QueryTable[0].DefaultType = REG_NONE;
+   QueryTable[0].DefaultData = NULL;
+   QueryTable[0].DefaultLength = 0;
+
+   QueryTable[1].QueryRoutine = NULL;
+   QueryTable[1].Name = NULL;
+
+   return NT_SUCCESS(RtlQueryRegistryValues(
+      RTL_REGISTRY_ABSOLUTE,
+      DeviceExtension->RegistryPath.Buffer,
+      QueryTable,
+      &Context,
+      NULL)) ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
 }
 
 /*
  * @implemented
  */
 
-PVOID
-STDCALL
-VideoPortAllocatePool(
+VP_STATUS NTAPI
+VideoPortSetRegistryParameters(
    IN PVOID HwDeviceExtension,
-   IN VP_POOL_TYPE PoolType,
-   IN SIZE_T NumberOfBytes,
-   IN ULONG Tag)
+   IN PWSTR ValueName,
+   IN PVOID ValueData,
+   IN ULONG ValueLength)
 {
-   return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
+   DPRINT("VideoPortSetRegistryParameters\n");
+   ASSERT_IRQL(PASSIVE_LEVEL);
+   return RtlWriteRegistryValue(
+      RTL_REGISTRY_ABSOLUTE,
+      VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->RegistryPath.Buffer,
+      ValueName,
+      REG_BINARY,
+      ValueData,
+      ValueLength);
 }
 
 /*
  * @implemented
  */
 
-VOID
-STDCALL
-VideoPortFreePool(
+VP_STATUS NTAPI
+VideoPortGetVgaStatus(
    IN PVOID HwDeviceExtension,
-   IN PVOID Ptr)
+   OUT PULONG VgaStatus)
 {
-   ExFreePool(Ptr);
-}
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
 
-//    VidDispatchOpen
-//
-//  DESCRIPTION:
-//    Answer requests for Open calls
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    Standard dispatch arguments
-//
-//  RETURNS:
-//    NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchOpen(IN PDEVICE_OBJECT pDO,
-                IN PIRP Irp)
-{
-  PIO_STACK_LOCATION IrpStack;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
-  DPRINT("VidDispatchOpen() called\n");
-
-  IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
-  if (! CsrssInitialized)
-    {
-      DPRINT("Referencing CSRSS\n");
-      Csrss = PsGetCurrentProcess();
-      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;
-       }
-    }
+   DPRINT("VideoPortGetVgaStatus\n");
 
-  Irp->IoStatus.Information = FILE_OPENED;
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+   if (KeGetCurrentIrql() == PASSIVE_LEVEL)
+   {
+      if (DeviceExtension->AdapterInterfaceType == PCIBus)
+      {
+         /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
+         /* Assumed for now */
+         *VgaStatus = 1;
+         return NO_ERROR;
+      }
+   }
 
-  return STATUS_SUCCESS;
+   return ERROR_INVALID_FUNCTION;
 }
 
-//    VidDispatchClose
-//
-//  DESCRIPTION:
-//    Answer requests for Close calls
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    Standard dispatch arguments
-//
-//  RETURNS:
-//    NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchClose(IN PDEVICE_OBJECT pDO,
-                 IN PIRP Irp)
+/*
+ * @implemented
+ */
+
+PVOID NTAPI
+VideoPortGetRomImage(
+   IN PVOID HwDeviceExtension,
+   IN PVOID Unused1,
+   IN ULONG Unused2,
+   IN ULONG Length)
 {
-  PIO_STACK_LOCATION IrpStack;
+   static PVOID RomImageBuffer = NULL;
+   PKPROCESS CallingProcess;
+   KAPC_STATE ApcState;
 
-  DPRINT("VidDispatchClose() called\n");
+   DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
+          HwDeviceExtension, Length);
 
-  IrpStack = IoGetCurrentIrpStackLocation(Irp);
+   /* If the length is zero then free the existing buffer. */
+   if (Length == 0)
+   {
+      if (RomImageBuffer != NULL)
+      {
+         ExFreePool(RomImageBuffer);
+         RomImageBuffer = NULL;
+      }
+      return NULL;
+   }
+   else
+   {
+      /*
+       * The DDK says we shouldn't use the legacy C0000 method but get the
+       * rom base address from the corresponding pci or acpi register but
+       * lets ignore that and use C0000 anyway. We have already mapped the
+       * bios area into memory so we'll copy from there.
+       */
 
-  if (! CsrssInitialized)
-    {
-      CsrssInitialized = TRUE;
-    }
-  else
-    {
-      HalReleaseDisplayOwnership();
-    }
+      /* Copy the bios. */
+      Length = min(Length, 0x10000);
+      if (RomImageBuffer != NULL)
+      {
+         ExFreePool(RomImageBuffer);
+      }
 
-  Irp->IoStatus.Status = STATUS_SUCCESS;
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      RomImageBuffer = ExAllocatePool(PagedPool, Length);
+      if (RomImageBuffer == NULL)
+      {
+         return NULL;
+      }
 
-  return STATUS_SUCCESS;
-}
+      IntAttachToCSRSS(&CallingProcess, &ApcState);
+      RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
+      IntDetachFromCSRSS(&CallingProcess, &ApcState);
 
-//    VidDispatchDeviceControl
-//
-//  DESCRIPTION:
-//    Answer requests for device control calls
-//
-//  RUN LEVEL:
-//    PASSIVE_LEVEL
-//
-//  ARGUMENTS:
-//    Standard dispatch arguments
-//
-//  RETURNS:
-//    NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
-                         IN PIRP Irp)
-{
-  PIO_STACK_LOCATION IrpStack;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  PVIDEO_REQUEST_PACKET vrp;
-  BOOLEAN Ret;
-
-  DPRINT("VidDispatchDeviceControl\n");
-  IrpStack = IoGetCurrentIrpStackLocation(Irp);
-  DeviceExtension = DeviceObject->DeviceExtension;
-
-  /* Translate the IRP to a VRP */
-  vrp = ExAllocatePool(NonPagedPool, sizeof(VIDEO_REQUEST_PACKET));
-  if (NULL == vrp)
-    {
-    return STATUS_NO_MEMORY;
-    }
-  vrp->StatusBlock        = (PSTATUS_BLOCK) &(Irp->IoStatus);
-  vrp->IoControlCode      = IrpStack->Parameters.DeviceIoControl.IoControlCode;
-
-  DPRINT("- IoControlCode: %x\n", vrp->IoControlCode);
-
-  /* We're assuming METHOD_BUFFERED */
-  vrp->InputBuffer        = Irp->AssociatedIrp.SystemBuffer;
-  vrp->InputBufferLength  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
-  vrp->OutputBuffer       = Irp->AssociatedIrp.SystemBuffer;
-  vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
-  /* Call the Miniport Driver with the VRP */
-  Ret = ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp);
-  assert(Ret);
-
-  /* Free the VRP */
-  ExFreePool(vrp);
-
-  DPRINT("- Returned status: %x/%d\n", Irp->IoStatus.Status,
-        Irp->IoStatus.Information);
-  if (Irp->IoStatus.Status != STATUS_SUCCESS)
-    {
-      if (Irp->IoStatus.Status != ERROR_MORE_DATA)
-       {
-         Irp->IoStatus.Information = 0;
-       }
-      /* Map from win32 error codes to ntstatus values. */
-      switch (Irp->IoStatus.Status)
-       {
-       case ERROR_NOT_ENOUGH_MEMORY: return STATUS_INSUFFICIENT_RESOURCES;
-       case ERROR_MORE_DATA: return STATUS_BUFFER_OVERFLOW;
-       case ERROR_INVALID_FUNCTION: return STATUS_NOT_IMPLEMENTED;
-       case ERROR_INVALID_PARAMETER: return STATUS_INVALID_PARAMETER;
-       case ERROR_INSUFFICIENT_BUFFER: return STATUS_BUFFER_TOO_SMALL;
-       case ERROR_DEV_NOT_EXIST: return STATUS_DEVICE_DOES_NOT_EXIST;
-       case ERROR_IO_PENDING: return STATUS_PENDING;
-       }
-    }
-
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-  return STATUS_SUCCESS;
+      return RomImageBuffer;
+   }
 }
 
-PVOID STDCALL
-InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
-                  IN PHYSICAL_ADDRESS IoAddress,
-                  IN ULONG NumberOfUchars,
-                  IN UCHAR InIoSpace,
-                  OUT NTSTATUS *Status)
-{
-  PHYSICAL_ADDRESS TranslatedAddress;
-  PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
-  ULONG AddressSpace;
-  PVOID MappedAddress;
-  PLIST_ENTRY Entry;
-
-  DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
-  DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
-  DPRINT("- InIoSpace: %x\n", InIoSpace);
-  InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
-  if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE))
-    {
-      DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
-      InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
-    }
-  if (! IsListEmpty(&DeviceExtension->AddressMappingListHead))
-    {
-      Entry = DeviceExtension->AddressMappingListHead.Flink;
-      while (Entry != &DeviceExtension->AddressMappingListHead)
-       {
-         AddressMapping = CONTAINING_RECORD(Entry,
-                                            VIDEO_PORT_ADDRESS_MAPPING,
-                                            List);
-         if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
-             NumberOfUchars <= AddressMapping->NumberOfUchars)
-           {
-             AddressMapping->MappingCount++;
-             if (Status)
-               {
-                  *Status = STATUS_SUCCESS;
-               }
-             return AddressMapping->MappedAddress;
-           }
-         Entry = Entry->Flink;
-       }
-    }
-
-  AddressSpace = (ULONG)InIoSpace;
-  if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType,
-                            DeviceExtension->SystemIoBusNumber,
-                            IoAddress,
-                            &AddressSpace,
-                            &TranslatedAddress) == FALSE)
-    {
-      if (Status)
-        {
-          *Status = STATUS_NO_MEMORY;
-        }
-      return NULL;
-    }
-
-  /* i/o space */
-  if (AddressSpace != 0)
-    {
-      assert(0 == TranslatedAddress.u.HighPart);
-      if (Status)
-        {
-          *Status = STATUS_SUCCESS;
-        }
-      return (PVOID) TranslatedAddress.u.LowPart;
-    }
-
-  MappedAddress = MmMapIoSpace(TranslatedAddress,
-                              NumberOfUchars,
-                              FALSE);
-
-  if (MappedAddress)
-    {
-      if (Status)
-        {
-          *Status = STATUS_SUCCESS;
-        }
-
-      AddressMapping = ExAllocatePoolWithTag(PagedPool,
-                                        sizeof(VIDEO_PORT_ADDRESS_MAPPING),
-                                             TAG_VIDEO_PORT);
-      if (AddressMapping == NULL)
-        return MappedAddress;
-
-      AddressMapping->MappedAddress = MappedAddress;
-      AddressMapping->NumberOfUchars = NumberOfUchars;
-      AddressMapping->IoAddress = IoAddress;
-      AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
-      AddressMapping->MappingCount = 1;
-
-      InsertHeadList(&DeviceExtension->AddressMappingListHead,
-                &AddressMapping->List);
-
-      return MappedAddress;
-    }
-  else
-    {
-      if (Status)
-        {
-          *Status = STATUS_NO_MEMORY;
-        }
-
-      return NULL;
-    }
-}
+/*
+ * @implemented
+ */
 
-VOID STDCALL
-InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
-                    IN PVOID MappedAddress)
+BOOLEAN NTAPI
+VideoPortScanRom(
+   IN PVOID HwDeviceExtension,
+   IN PUCHAR RomBase,
+   IN ULONG RomLength,
+   IN PUCHAR String)
 {
-  PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
-  PLIST_ENTRY Entry;
-
-  Entry = DeviceExtension->AddressMappingListHead.Flink;
-  while (Entry != &DeviceExtension->AddressMappingListHead)
-    {
-      AddressMapping = CONTAINING_RECORD(Entry,
-                                        VIDEO_PORT_ADDRESS_MAPPING,
-                                        List);
-      if (AddressMapping->MappedAddress == MappedAddress)
-       {
-         assert(0 <= AddressMapping->MappingCount);
-         AddressMapping->MappingCount--;
-         if (0 == AddressMapping->MappingCount)
-           {
-             MmUnmapIoSpace(AddressMapping->MappedAddress,
-                            AddressMapping->NumberOfUchars);
-             RemoveEntryList(Entry);
-             ExFreePool(AddressMapping);
-
-             return;
-           }
-       }
-
-      Entry = Entry->Flink;
-    }
-}
+   ULONG StringLength;
+   BOOLEAN Found;
+   PUCHAR SearchLocation;
+
+   DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
+
+   StringLength = strlen((PCHAR)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);
+      }
+   }
 
-BOOLEAN STDCALL
-VideoPortDDCMonitorHelper(
-   PVOID HwDeviceExtension,
-   /*PI2C_FNC_TABLE*/PVOID I2CFunctions,
-   PUCHAR pEdidBuffer,
-   ULONG EdidBufferSize
-   )
-{
-   DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
-   return FALSE;
+   return Found;
 }
 
 /*
  * @implemented
  */
-VP_STATUS
-STDCALL
-VideoPortAllocateBuffer(IN PVOID  HwDeviceExtension,
-                       IN ULONG  Size,
-                       OUT PVOID  *Buffer)
+
+BOOLEAN NTAPI
+VideoPortSynchronizeExecution(
+   IN PVOID HwDeviceExtension,
+   IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
+   IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
+   OUT PVOID Context)
 {
-  DPRINT("VideoPortAllocateBuffer()\n");
-  
-  Buffer = ExAllocatePool(PagedPool, Size);
-  return STATUS_SUCCESS;
-      
+   BOOLEAN Ret;
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   KIRQL OldIrql;
+
+   switch (Priority)
+   {
+      case VpLowPriority:
+         Ret = (*SynchronizeRoutine)(Context);
+         break;
+
+      case VpMediumPriority:
+         DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+         if (DeviceExtension->InterruptObject == NULL)
+            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
  */
-VOID
-STDCALL
-VideoPortReleaseBuffer( IN PVOID HwDeviceExtension,
-                       IN PVOID Ptr)
-{
-  DPRINT("VideoPortReleaseBuffer()\n");
 
-       ExFreePool(Ptr);
-}         
-
-
-VP_STATUS
-STDCALL
-VideoPortEnumerateChildren ( IN PVOID HwDeviceExtension,
-                            IN PVOID Reserved )
-{
-  DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
-  return STATUS_SUCCESS;
-}
-
-PVOID
-STDCALL
-VideoPortGetRomImage ( IN PVOID HwDeviceExtension,
-                      IN PVOID Unused1,
-                      IN ULONG Unused2,
-                      IN ULONG Length )
+VP_STATUS NTAPI
+VideoPortEnumerateChildren(
+   IN PVOID HwDeviceExtension,
+   IN PVOID Reserved)
 {
-  DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
-        HwDeviceExtension, Length);
-
-  /* If the length is zero then free the existing buffer. */
-  if (Length == 0)
-    {
-      if (RomImageBuffer != NULL)
-       {
-         ExFreePool(RomImageBuffer);
-         RomImageBuffer = NULL;
-       }
-      return NULL;
-    }
-  else
-    {
-      PEPROCESS CallingProcess, PrevAttachedProcess;
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   ULONG Status;
+   VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
+   VIDEO_CHILD_TYPE ChildType;
+   UCHAR ChildDescriptor[256];
+   ULONG ChildId;
+   ULONG Unused;
+   INT i;
+
+   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+   if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL)
+   {
+      DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
+      return NO_ERROR;
+   }
 
-      /*
-       The DDK says we shouldn't use the legacy C000 method but get the
-       rom base address from the corresponding pci or acpi register but
-       lets ignore that and use C000 anyway. CSRSS has already mapped the
-       bios area into memory so we'll copy from there.
-      */
-      CallingProcess = PsGetCurrentProcess();
-      if (CallingProcess != Csrss)
-       {
-         if (NULL != PsGetCurrentThread()->OldProcess)
-           {
-             PrevAttachedProcess = CallingProcess;
-             KeDetachProcess();
-           }
-         else
-           {
-             PrevAttachedProcess = NULL;
-           }
-         KeAttachProcess(Csrss);
-       }
+   /* Setup the ChildEnumInfo */
+   ChildEnumInfo.Size = sizeof (ChildEnumInfo);
+   ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor);
+   ChildEnumInfo.ACPIHwId = 0;
+   ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to
+                                                   ChildHwDeviceExtension... */
 
-      /*
-       Copy the bios.
-      */
-      Length = min(Length, 0x10000);
-      if (RomImageBuffer != NULL)
-       {
-         ExFreePool(RomImageBuffer);
-       }
-      RomImageBuffer = ExAllocatePool(PagedPool, Length);
-      if (RomImageBuffer == NULL)
-       {
-         return(NULL);
-       }
-      RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
+   /* Enumerate the children */
+   for (i = 1; ; i++)
+   {
+      ChildEnumInfo.ChildIndex = i;
+      RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor));
+      Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor(
+                  HwDeviceExtension,
+                  &ChildEnumInfo,
+                  &ChildType,
+                  ChildDescriptor,
+                  &ChildId,
+                  &Unused);
+      if (Status == VIDEO_ENUM_INVALID_DEVICE)
+      {
+         DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex);
+         continue;
+      }
+      else if (Status == VIDEO_ENUM_NO_MORE_DEVICES)
+      {
+         DPRINT("End of child enumeration! (%d children enumerated)\n", i - 1);
+         break;
+      }
+      else if (Status != VIDEO_ENUM_MORE_DEVICES)
+      {
+         DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status);
+         break;
+      }
 
-      /*
-       Detach from csrss if we attached.
-      */
-      if (CallingProcess != Csrss)
-       {
-         KeDetachProcess();
-         if (NULL != PrevAttachedProcess)
-           {
-             KeAttachProcess(PrevAttachedProcess);
-           }
-       }
-
-      return(RomImageBuffer);
-    }
-}
+#ifndef NDEBUG
+      if (ChildType == Monitor)
+      {
+         INT j;
+         PUCHAR p = ChildDescriptor;
+         DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId);
+         for (j = 0; j < sizeof (ChildDescriptor); j += 8)
+         {
+            DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
+                   p[j+0], p[j+1], p[j+2], p[j+3],
+                   p[j+4], p[j+5], p[j+6], p[j+7]);
+         }
+      }
+      else if (ChildType == Other)
+      {
+         DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor);
+      }
+      else
+      {
+         DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType);
+      }
+#endif /* NDEBUG */
 
-VOID
-STDCALL
-STATIC
-VideoPortDeferredRoutine ( IN PKDPC Dpc,
-                          IN PVOID DeferredContext,
-                          IN PVOID SystemArgument1,
-                          IN PVOID SystemArgument2 )
-{
-  PVOID HwDeviceExtension = 
-    ((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
-  ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
-}
+   }
 
-BOOLEAN
-STDCALL
-VideoPortQueueDpc ( IN PVOID HwDeviceExtension,
-                   IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
-                   IN PVOID Context )
-{
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-  return KeInsertQueueDpc(&DeviceExtension->DpcObject, 
-                         (PVOID)CallbackRoutine,
-                         (PVOID)Context);
+   return NO_ERROR;
 }
 
-PVOID
-STDCALL
-VideoPortGetAssociatedDeviceExtension ( IN PVOID DeviceObject )
-{
-  DPRINT1("VideoPortGetAssociatedDeviceExtension(): Unimplemented.\n");
-  return(NULL);
-}
+/*
+ * @unimplemented
+ */
 
-PVOID
-STDCALL
-VideoPortAllocateCommonBuffer ( IN PVOID HwDeviceExtension,
-                               IN PVP_DMA_ADAPTER VpDmaAdapter,
-                               IN ULONG DesiredLength,
-                               OUT PPHYSICAL_ADDRESS LogicalAddress,
-                               IN BOOLEAN CacheEnabled,
-                               PVOID Reserved )
+VP_STATUS NTAPI
+VideoPortCreateSecondaryDisplay(
+   IN PVOID HwDeviceExtension,
+   IN OUT PVOID *SecondaryDeviceExtension,
+   IN ULONG Flag)
 {
-  return HalAllocateCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter,
-                                DesiredLength,
-                                LogicalAddress,
-                                CacheEnabled);
+   DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
+   return NO_ERROR;
 }
 
-VOID
-STDCALL
-VideoPortReleaseCommonBuffer ( IN PVOID HwDeviceExtension,
-                              IN PVP_DMA_ADAPTER VpDmaAdapter,
-                              IN ULONG Length,
-                              IN PHYSICAL_ADDRESS LogicalAddress,
-                              IN PVOID VirtualAddress,
-                              IN BOOLEAN CacheEnabled )
-{
-  HalFreeCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter,
-                     Length,
-                     LogicalAddress,
-                     VirtualAddress,
-                     CacheEnabled);
-}
+/*
+ * @implemented
+ */
 
-VP_STATUS
-STDCALL
-VideoPortCreateSecondaryDisplay ( IN PVOID HwDeviceExtension,
-                                 IN OUT PVOID *SecondaryDeviceExtension,
-                                 IN ULONG Flag )
+BOOLEAN NTAPI
+VideoPortQueueDpc(
+   IN PVOID HwDeviceExtension,
+   IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
+   IN PVOID Context)
 {
-  DPRINT1("VideoPortCreateSecondaryDisplay(): Unimplemented.\n");
-  return STATUS_UNSUCCESSFUL;
+   return KeInsertQueueDpc(
+      &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
+      (PVOID)CallbackRoutine,
+      (PVOID)Context);
 }
 
-VOID
-STDCALL
-VideoPortPutDmaAdapter ( IN PVOID HwDeviceExtension,
-                        IN PVP_DMA_ADAPTER VpDmaAdapter )
-{
-  DPRINT("VideoPortPutDmaAdapter(): Unimplemented.\n");
-}
+/*
+ * @unimplemented
+ */
 
-PVP_DMA_ADAPTER
-STDCALL
-VideoPortGetDmaAdapter ( IN PVOID HwDeviceExtension,
-                        IN PVP_DEVICE_DESCRIPTION VpDeviceExtension )
+PVOID NTAPI
+VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
 {
-  DEVICE_DESCRIPTION DeviceDescription;
-  PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-  ULONG NumberOfMapRegisters;
-  PVP_DMA_ADAPTER Adapter;
-
-  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
-                                     VIDEO_PORT_DEVICE_EXTENSION,
-                                     MiniPortDeviceExtension);
-
-  DPRINT("VideoPortGetDmaAdapter()\n");
-  
-  DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
-  DeviceDescription.Master = TRUE /* ?? */;
-  DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather;
-  DeviceDescription.DemandMode = FALSE /* ?? */;
-  DeviceDescription.AutoInitialize = FALSE /* ?? */;
-  DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses;
-  DeviceDescription.IgnoreCount = FALSE /* ?? */;
-  DeviceDescription.Reserved1 = FALSE;
-  DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber;
-  DeviceDescription.DmaChannel = 0 /* ?? */;
-  DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType;
-  DeviceDescription.DmaWidth = Width8Bits;
-  DeviceDescription.DmaSpeed = Compatible;
-  DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength;
-  DeviceDescription.DmaPort = 0;
-
-  Adapter = 
-    (PVP_DMA_ADAPTER)HalGetAdapter(&DeviceDescription, &NumberOfMapRegisters);
-  DPRINT("Adapter %X\n", Adapter);
-  return(Adapter);
+   DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
+   return NULL;
 }
 
-
 /*
  * @implemented
  */
-VP_STATUS
-STDCALL
-VideoPortGetVersion ( IN PVOID HwDeviceExtension,
-                     IN OUT PVPOSVERSIONINFO VpOsVersionInfo )
+
+VP_STATUS NTAPI
+VideoPortGetVersion(
+   IN PVOID HwDeviceExtension,
+   IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
 {
    RTL_OSVERSIONINFOEXW Version;
 
@@ -1676,212 +1142,115 @@ VideoPortGetVersion ( IN PVOID HwDeviceExtension,
          VpOsVersionInfo->BuildNumber = Version.dwBuildNumber;
          VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor;
          VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor;
-         return STATUS_SUCCESS;
+         return NO_ERROR;
       }
-      return STATUS_UNSUCCESSFUL;
+      return ERROR_INVALID_PARAMETER;
 #else
       VpOsVersionInfo->MajorVersion = 5;
       VpOsVersionInfo->MinorVersion = 0;
       VpOsVersionInfo->BuildNumber = 2195;
       VpOsVersionInfo->ServicePackMajor = 4;
       VpOsVersionInfo->ServicePackMinor = 0;
-      return(STATUS_SUCCESS);
+      return NO_ERROR;
 #endif
    }
 
    return ERROR_INVALID_PARAMETER;
 }
 
-PVOID
-STDCALL
-VideoPortLockBuffer ( IN PVOID HwDeviceExtension,
-                     IN PVOID BaseAddress,
-                     IN ULONG Length,
-                     IN VP_LOCK_OPERATION Operation )
-{
-  DPRINT1("VideoPortLockBuffer(): Unimplemented.\n");
-  return NULL;
-}
+/*
+ * @unimplemented
+ */
 
-VOID
-STDCALL
-VideoPortUnlockBuffer ( IN PVOID HwDeviceExtension,
-                       IN PVOID Mdl )
+BOOLEAN NTAPI
+VideoPortCheckForDeviceExistence(
+   IN PVOID HwDeviceExtension,
+   IN USHORT VendorId,
+   IN USHORT DeviceId,
+   IN UCHAR RevisionId,
+   IN USHORT SubVendorId,
+   IN USHORT SubSystemId,
+   IN ULONG Flags)
 {
-  DPRINT1("VideoPortUnlockBuffer(): Unimplemented.\n");
+   DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
+   return TRUE;
 }
 
-VP_STATUS
-STDCALL
-VideoPortCreateEvent ( IN PVOID HwDeviceExtension,
-                      IN ULONG EventFlag,
-                      IN PVOID Unused,
-                      OUT PEVENT *Event)
-{
-  EVENT_TYPE Type;
-  (*Event) = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), 
-                                  TAG_VIDEO_PORT);
-  if ((*Event) == NULL)
-    {
-      return STATUS_NO_MEMORY;
-    }
-  if (EventFlag & NOTIFICATION_EVENT)
-    {
-      Type = NotificationEvent;
-    }
-  else
-    {
-      Type = SynchronizationEvent;
-    }
-  KeInitializeEvent((PKEVENT)*Event, Type, EventFlag & INITIAL_EVENT_SIGNALED);
-  return STATUS_SUCCESS;
-}
+/*
+ * @unimplemented
+ */
 
-VP_STATUS
-STDCALL
-VideoPortDeleteEvent ( IN PVOID HwDeviceExtension,
-                      IN PEVENT Event)
+VP_STATUS NTAPI
+VideoPortRegisterBugcheckCallback(
+   IN PVOID HwDeviceExtension,
+   IN ULONG BugcheckCode,
+   IN PVOID Callback,
+   IN ULONG BugcheckDataSize)
 {
-  ExFreePool(Event);
-  return STATUS_SUCCESS;
+   DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
+   return NO_ERROR;
 }
 
-LONG
-STDCALL
-VideoPortSetEvent ( IN PVOID HwDeviceExtension,
-                   IN PEVENT Event )
-{
-  return KeSetEvent((PKEVENT)Event, IO_NO_INCREMENT, FALSE);
-}
+/*
+ * @implemented
+ */
 
-VOID
-STDCALL
-VideoPortClearEvent ( IN PVOID HwDeviceExtension,
-                     IN PEVENT Event )
+LONGLONG NTAPI
+VideoPortQueryPerformanceCounter(
+   IN PVOID HwDeviceExtension,
+   OUT PLONGLONG PerformanceFrequency OPTIONAL)
 {
-  KeClearEvent((PKEVENT)Event);
-}
+   LARGE_INTEGER Result;
 
-VP_STATUS
-STDCALL
-VideoPortWaitForSingleObject ( IN PVOID HwDeviceExtension,
-                              IN PVOID Object,
-                              IN PLARGE_INTEGER Timeout OPTIONAL )
-{
-  return KeWaitForSingleObject(Object,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              Timeout);
+   DPRINT("VideoPortQueryPerformanceCounter\n");
+   Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency);
+   return Result.QuadPart;
 }
 
-BOOLEAN
-STDCALL
-VideoPortCheckForDeviceExistence ( IN PVOID HwDeviceExtension,
-                                  IN USHORT VendorId,
-                                  IN USHORT DeviceId,
-                                  IN UCHAR RevisionId,
-                                  IN USHORT SubVendorId,
-                                  IN USHORT SubSystemId,
-                                  IN ULONG Flags )
-{
-  DPRINT1("VideoPortCheckForDeviceExistence(): Unimplemented.\n");
-  return TRUE;
-}
+/*
+ * @implemented
+ */
 
-VP_STATUS
-STDCALL
-VideoPortRegisterBugcheckCallback ( IN PVOID HwDeviceExtension,
-                                   IN ULONG BugcheckCode,
-                                   IN PVOID Callback,
-                                   IN ULONG BugcheckDataSize )
+VOID NTAPI
+VideoPortAcquireDeviceLock(
+   IN PVOID  HwDeviceExtension)
 {
-  DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
-  return STATUS_UNSUCCESSFUL;
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   NTSTATUS Status;
+   (void)Status;
+
+   DPRINT("VideoPortAcquireDeviceLock\n");
+   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+   Status = KeWaitForMutexObject(&DeviceExtension->DeviceLock, Executive,
+                                 KernelMode, FALSE, NULL);
+   ASSERT(Status == STATUS_SUCCESS);
 }
 
-PVOID
-STDCALL
-VideoPortImageDirectoryEntryToData ( PVOID     BaseAddress,
-                                    ULONG      Directory )
-{
-  PIMAGE_NT_HEADERS NtHeader;
-  ULONG Va;
-  
-  NtHeader = RtlImageNtHeader (BaseAddress);
-  if (NtHeader == NULL)
-    return NULL;
-  
-  if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
-    return NULL;
-  
-  Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
-  if (Va == 0)
-    return NULL;
-  
-  return (PVOID)(BaseAddress + Va);
-}
+/*
+ * @implemented
+ */
 
-PVOID STDCALL
-VideoPortGetProcAddress(IN PVOID HwDeviceExtension,
-                       IN PUCHAR FunctionName)
+VOID NTAPI
+VideoPortReleaseDeviceLock(
+   IN PVOID  HwDeviceExtension)
 {
-  SYSTEM_LOAD_IMAGE GdiDriverInfo;
-  PVOID BaseAddress;
-  PIMAGE_EXPORT_DIRECTORY ExportDir;
-  PUSHORT OrdinalPtr;
-  PULONG NamePtr;
-  PULONG AddressPtr;
-  ULONG i = 0;
-  NTSTATUS Status;
-
-  DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
-
-  RtlInitUnicodeString(&GdiDriverInfo.ModuleName, L"videoprt");
-  Status = ZwSetSystemInformation(SystemLoadImage, &GdiDriverInfo, 
-                                 sizeof(SYSTEM_LOAD_IMAGE));
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("Couldn't get our own module handle?\n");
-      return NULL;
-    }
-
-  BaseAddress = GdiDriverInfo.ModuleBase;
-
-  /* Get the pointer to the export directory */
-  ExportDir = (PIMAGE_EXPORT_DIRECTORY)
-                VideoPortImageDirectoryEntryToData (BaseAddress,
-                                              IMAGE_DIRECTORY_ENTRY_EXPORT);
-
-  /* search by name */
-  AddressPtr = (PULONG)
-    ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions);
-  OrdinalPtr = (PUSHORT)
-    ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
-  NamePtr = (PULONG)
-    ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
-  for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
-    {
-      if (!_strnicmp(FunctionName, (char*)(BaseAddress + *NamePtr),
-                    strlen(FunctionName)))
-       {
-         return (PVOID)((ULONG_PTR)BaseAddress + 
-                        (ULONG_PTR)AddressPtr[*OrdinalPtr]);     
-       }
-    }
-  DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName);
-  return(NULL);
+   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+   LONG Status;
+   (void)Status;
+
+   DPRINT("VideoPortReleaseDeviceLock\n");
+   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+   Status = KeReleaseMutex(&DeviceExtension->DeviceLock, FALSE);
+   ASSERT(Status == 0);
 }
 
-LONGLONG STDCALL
-VideoPortQueryPerformanceCounter(
-   IN PVOID HwDeviceExtension,
-   OUT PLONGLONG PerformanceFrequency OPTIONAL)
-{
-   LARGE_INTEGER Result;
+/*
+ * @unimplemented
+ */
 
-   DPRINT("VideoPortQueryPerformanceCounter\n");
-   Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency);
-   return Result.QuadPart;
+VOID NTAPI
+VpNotifyEaData(
+   IN PDEVICE_OBJECT DeviceObject,
+   IN PVOID Data)
+{
 }
-