[HNETCFG] Sync with Wine 3.0. CORE-14225
[reactos.git] / win32ss / drivers / videoprt / dispatch.c
index 35a1b76..34ae107 100644 (file)
 
 #include "videoprt.h"
 
+#include <ndk/inbvfuncs.h>
+#include <ndk/psfuncs.h>
+
+#define NDEBUG
+#include <debug.h>
+
 /* GLOBAL VARIABLES ***********************************************************/
 
 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
+PVIDEO_WIN32K_CALLOUT Win32kCallout;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
 /*
  * Reset display to blue screen
  */
-
-BOOLEAN NTAPI
+BOOLEAN
+NTAPI
 IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows)
 {
-   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
-
-   if (ResetDisplayParametersDeviceExtension == NULL)
-      return FALSE;
-
-   DriverExtension = ResetDisplayParametersDeviceExtension->DriverExtension;
-
-   if (DriverExtension->InitializationData.HwResetHw != NULL)
-   {
-      if (DriverExtension->InitializationData.HwResetHw(
-             &ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
-             Columns, Rows))
-      {
-         ResetDisplayParametersDeviceExtension = NULL;
-         return TRUE;
-      }
-   }
-
-   ResetDisplayParametersDeviceExtension = NULL;
-   return FALSE;
-}
+    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
 
-NTSTATUS NTAPI
-IntVideoPortAddDevice(
-   IN PDRIVER_OBJECT DriverObject,
-   IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
-   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
-   PDEVICE_OBJECT DeviceObject;
-   NTSTATUS Status;
-
-   /*
-    * Get the initialization data we saved in VideoPortInitialize.
-    */
+    if (ResetDisplayParametersDeviceExtension == NULL)
+        return FALSE;
 
-   DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+    DriverExtension = ResetDisplayParametersDeviceExtension->DriverExtension;
 
-   /*
-    * Create adapter device object.
-    */
+    if (DriverExtension->InitializationData.HwResetHw != NULL)
+    {
+        if (DriverExtension->InitializationData.HwResetHw(
+                    &ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
+                    Columns, Rows))
+        {
+            ResetDisplayParametersDeviceExtension = NULL;
+            return TRUE;
+        }
+    }
 
-   Status = IntVideoPortCreateAdapterDeviceObject(
-      DriverObject,
-      DriverExtension,
-      PhysicalDeviceObject,
-      &DeviceObject);
-   if (NT_SUCCESS(Status))
-      VideoPortDeviceNumber++;
+    ResetDisplayParametersDeviceExtension = NULL;
+    return FALSE;
+}
 
-   return Status;
+NTSTATUS
+NTAPI
+IntVideoPortAddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
+    PDEVICE_OBJECT DeviceObject;
+    NTSTATUS Status;
+
+    /* Get the initialization data we saved in VideoPortInitialize. */
+    DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+
+    /* Create adapter device object. */
+    Status = IntVideoPortCreateAdapterDeviceObject(DriverObject,
+                                                   DriverExtension,
+                                                   PhysicalDeviceObject,
+                                                   &DeviceObject);
+    if (NT_SUCCESS(Status))
+        VideoPortDeviceNumber++;
+
+    return Status;
 }
 
 /*
@@ -94,54 +95,50 @@ IntVideoPortAddDevice(
  * Run Level
  *    PASSIVE_LEVEL
  */
-
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchOpen(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
-
-   TRACE_(VIDEOPRT, "IntVideoPortDispatchOpen\n");
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
 
-   if (CsrssInitialized == FALSE)
-   {
-      /*
-       * We know the first open call will be from the CSRSS process
-       * to let us know its handle.
-       */
+    TRACE_(VIDEOPRT, "IntVideoPortDispatchOpen\n");
 
-      INFO_(VIDEOPRT, "Referencing CSRSS\n");
-      Csrss = (PKPROCESS)PsGetCurrentProcess();
-      INFO_(VIDEOPRT, "Csrss %p\n", Csrss);
-
-      CsrssInitialized = TRUE;
+    if (CsrssInitialized == FALSE)
+    {
+        /*
+         * We know the first open call will be from the CSRSS process
+         * to let us know its handle.
+         */
 
-      Irp->IoStatus.Information = FILE_OPENED;
-      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        INFO_(VIDEOPRT, "Referencing CSRSS\n");
+        Csrss = (PKPROCESS)PsGetCurrentProcess();
+        INFO_(VIDEOPRT, "Csrss %p\n", Csrss);
 
-      return STATUS_SUCCESS;
-   }
+        IntInitializeVideoAddressSpace();
 
-   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   DriverExtension = DeviceExtension->DriverExtension;
+        CsrssInitialized = TRUE;
+    }
 
-   if (DriverExtension->InitializationData.HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
-   {
-      Irp->IoStatus.Status = STATUS_SUCCESS;
+    DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    DriverExtension = DeviceExtension->DriverExtension;
 
-      InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
-   }
-   else
-   {
-      Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-   }
+    if (DriverExtension->InitializationData.HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
+    {
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
+    }
+    else
+    {
+        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    }
 
-   Irp->IoStatus.Information = FILE_OPENED;
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    Irp->IoStatus.Information = FILE_OPENED;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-   return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -152,30 +149,292 @@ IntVideoPortDispatchOpen(
  * Run Level
  *    PASSIVE_LEVEL
  */
-
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchClose(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+    TRACE_(VIDEOPRT, "IntVideoPortDispatchClose\n");
+
+    DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    if ((DeviceExtension->DeviceOpened >= 1) &&
+        (InterlockedDecrement((PLONG)&DeviceExtension->DeviceOpened) == 0))
+    {
+        ResetDisplayParametersDeviceExtension = NULL;
+        InbvNotifyDisplayOwnershipLost(NULL);
+        ResetDisplayParametersDeviceExtension = DeviceExtension;
+        IntVideoPortResetDisplayParameters(80, 50);
+    }
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_SUCCESS;
+}
+
+PSTR
+IoctlName(ULONG Ioctl)
+{
+    switch(Ioctl)
+    {
+        case IOCTL_VIDEO_ENABLE_VDM:
+            return "IOCTL_VIDEO_ENABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_DISABLE_VDM:
+            return "IOCTL_VIDEO_DISABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_REGISTER_VDM:
+            return "IOCTL_VIDEO_REGISTER_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE:
+            return "IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE:
+            return "IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_MONITOR_DEVICE:
+            return "IOCTL_VIDEO_MONITOR_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_ENUM_MONITOR_PDO:
+            return "IOCTL_VIDEO_ENUM_MONITOR_PDO"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS:
+            return "IOCTL_VIDEO_INIT_WIN32K_CALLBACKS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS:
+            return "IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_IS_VGA_DEVICE:
+            return "IOCTL_VIDEO_IS_VGA_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_USE_DEVICE_IN_SESSION:
+            return "IOCTL_VIDEO_USE_DEVICE_IN_SESSION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_PREPARE_FOR_EARECOVERY:
+            return "IOCTL_VIDEO_PREPARE_FOR_EARECOVERY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
+            return "IOCTL_VIDEO_SAVE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x80, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
+            return "IOCTL_VIDEO_RESTORE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x81, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_AVAIL_MODES:
+            return "IOCTL_VIDEO_QUERY_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
+            return "IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x101, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_CURRENT_MODE:
+            return "IOCTL_VIDEO_QUERY_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x102, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_CURRENT_MODE:
+            return "IOCTL_VIDEO_SET_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x103, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_RESET_DEVICE:
+            return "IOCTL_VIDEO_RESET_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x104, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_LOAD_AND_SET_FONT:
+            return "IOCTL_VIDEO_LOAD_AND_SET_FONT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x105, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
+            return "IOCTL_VIDEO_SET_PALETTE_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x106, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_COLOR_REGISTERS:
+            return "IOCTL_VIDEO_SET_COLOR_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x107, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_ENABLE_CURSOR:
+            return "IOCTL_VIDEO_ENABLE_CURSOR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x108, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_DISABLE_CURSOR:
+            return "IOCTL_VIDEO_DISABLE_CURSOR"; // CTL_CODE (FILE_DEVICE_VIDEO, 0x109, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_CURSOR_ATTR:
+            return "IOCTL_VIDEO_SET_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
+            return "IOCTL_VIDEO_QUERY_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10b, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_CURSOR_POSITION:
+            return "IOCTL_VIDEO_SET_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10c, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
+            return "IOCTL_VIDEO_QUERY_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10d, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_ENABLE_POINTER:
+            return "IOCTL_VIDEO_ENABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10e, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_DISABLE_POINTER:
+            return "IOCTL_VIDEO_DISABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10f, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_POINTER_ATTR:
+            return "IOCTL_VIDEO_SET_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x110, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_POINTER_ATTR:
+            return "IOCTL_VIDEO_QUERY_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x111, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_POINTER_POSITION:
+            return "IOCTL_VIDEO_SET_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x112, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_POINTER_POSITION:
+            return "IOCTL_VIDEO_QUERY_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x113, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
+            return "IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x114, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
+            return "IOCTL_VIDEO_GET_BANK_SELECT_CODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x115, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
+            return "IOCTL_VIDEO_MAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x116, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
+            return "IOCTL_VIDEO_UNMAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x117, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
+            return "IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x118, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
+            return "IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x119, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
+            return "IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11a, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_POWER_MANAGEMENT:
+            return "IOCTL_VIDEO_SET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11b, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_GET_POWER_MANAGEMENT:
+            return "IOCTL_VIDEO_GET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11c, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
+            return "IOCTL_VIDEO_SHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11d, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
+            return "IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11e, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_COLOR_LUT_DATA:
+            return "IOCTL_VIDEO_SET_COLOR_LUT_DATA"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11f, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_GET_CHILD_STATE:
+            return "IOCTL_VIDEO_GET_CHILD_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x120, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION:
+            return "IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x121, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION:
+            return "IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x122, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SWITCH_DUALVIEW:
+            return "IOCTL_VIDEO_SWITCH_DUALVIEW"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x123, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_BANK_POSITION:
+            return "IOCTL_VIDEO_SET_BANK_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x124, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS:
+            return "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS:
+            return "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
+        case IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS:
+            return "IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
+    }
+
+    return "<unknown ioctl code";
+}
+
+static
+NTSTATUS
+VideoPortUseDeviceInSession(
+    _Inout_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PVIDEO_DEVICE_SESSION_STATUS SessionState,
+    _In_ ULONG BufferLength,
+    _Out_ PULONG_PTR Information)
+{
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+    /* Check buffer size */
+    *Information = sizeof(VIDEO_DEVICE_SESSION_STATUS);
+    if (BufferLength < sizeof(VIDEO_DEVICE_SESSION_STATUS))
+    {
+        ERR_(VIDEOPRT, "Buffer too small for VIDEO_DEVICE_SESSION_STATUS: %lx\n",
+             BufferLength);
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Get the device extension */
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    /* Shall we enable the session? */
+    if (SessionState->bEnable)
+    {
+        /* Check if we have no session yet */
+        if (DeviceExtension->SessionId == -1)
+        {
+            /* Use this session and return success */
+            DeviceExtension->SessionId = PsGetCurrentProcessSessionId();
+            SessionState->bSuccess = TRUE;
+        }
+        else
+        {
+            ERR_(VIDEOPRT, "Requested to set session, but session is already set to: 0x%lx\n",
+                 DeviceExtension->SessionId);
+            SessionState->bSuccess = FALSE;
+        }
+    }
+    else
+    {
+        /* Check if we belong to the current session */
+        if (DeviceExtension->SessionId == PsGetCurrentProcessSessionId())
+        {
+            /* Reset the session and return success */
+            DeviceExtension->SessionId = -1;
+            SessionState->bSuccess = TRUE;
+        }
+        else
+        {
+            ERR_(VIDEOPRT, "Requested to reset session, but session is not set\n");
+            SessionState->bSuccess = FALSE;
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+VideoPortInitWin32kCallbacks(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PVIDEO_WIN32K_CALLBACKS Win32kCallbacks,
+    _In_ ULONG BufferLength,
+    _Out_ PULONG_PTR Information)
+{
+    *Information = sizeof(VIDEO_WIN32K_CALLBACKS);
+    if (BufferLength < sizeof(VIDEO_WIN32K_CALLBACKS))
+    {
+        ERR_(VIDEOPRT, "Buffer too small for VIDEO_WIN32K_CALLBACKS: %lx\n",
+             BufferLength);
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Save the callout function globally */
+    Win32kCallout = Win32kCallbacks->Callout;
+
+    /* Return reasonable values to win32k */
+    Win32kCallbacks->bACPI = FALSE;
+    Win32kCallbacks->pPhysDeviceObject = DeviceObject;
+    Win32kCallbacks->DualviewFlags = 0;
+
+    return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+VideoPortForwardDeviceControl(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    PIO_STACK_LOCATION IrpStack;
+    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    VIDEO_REQUEST_PACKET vrp;
+
+    TRACE_(VIDEOPRT, "VideoPortForwardDeviceControl\n");
 
-   TRACE_(VIDEOPRT, "IntVideoPortDispatchClose\n");
+    IrpStack = IoGetCurrentIrpStackLocation(Irp);
+    DeviceExtension = DeviceObject->DeviceExtension;
+    DriverExtension = DeviceExtension->DriverExtension;
 
-   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   if (DeviceExtension->DeviceOpened >= 1 &&
-       InterlockedDecrement((PLONG)&DeviceExtension->DeviceOpened) == 0)
-   {
-      ResetDisplayParametersDeviceExtension = NULL;
-      InbvNotifyDisplayOwnershipLost(NULL);
-      ResetDisplayParametersDeviceExtension = DeviceExtension;
-      IntVideoPortResetDisplayParameters(80, 50);
-   }
+    /* Translate the IRP to a VRP */
+    vrp.StatusBlock = (PSTATUS_BLOCK)&Irp->IoStatus;
+    vrp.IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
 
-   Irp->IoStatus.Status = STATUS_SUCCESS;
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    INFO_(VIDEOPRT, "- IoControlCode: %x\n", vrp.IoControlCode);
 
-   return STATUS_SUCCESS;
+    /* 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 */
+    DriverExtension->InitializationData.HwStartIO(&DeviceExtension->MiniPortDeviceExtension,
+                                                  &vrp);
+
+    INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
+
+    /* Map from win32 error codes to NT status values. */
+    switch (Irp->IoStatus.Status)
+    {
+        case NO_ERROR:
+            return STATUS_SUCCESS;
+        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;
+        default:
+            return STATUS_UNSUCCESSFUL;
+    }
 }
 
 /*
@@ -186,73 +445,54 @@ IntVideoPortDispatchClose(
  * Run Level
  *    PASSIVE_LEVEL
  */
-
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchDeviceControl(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PIO_STACK_LOCATION IrpStack;
-   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-   PVIDEO_REQUEST_PACKET vrp;
-   NTSTATUS Status;
-
-   TRACE_(VIDEOPRT, "IntVideoPortDispatchDeviceControl\n");
-
-   IrpStack = IoGetCurrentIrpStackLocation(Irp);
-   DeviceExtension = DeviceObject->DeviceExtension;
-   DriverExtension = DeviceExtension->DriverExtension;
-
-   /* Translate the IRP to a VRP */
-   vrp = ExAllocatePoolWithTag(NonPagedPool,
-                               sizeof(VIDEO_REQUEST_PACKET),
-                               TAG_REQUEST_PACKET);
-   if (NULL == vrp)
-   {
-      return STATUS_NO_MEMORY;
-   }
-
-   vrp->StatusBlock = (PSTATUS_BLOCK)&(Irp->IoStatus);
-   vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
-
-   INFO_(VIDEOPRT, "- 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 */
-   DriverExtension->InitializationData.HwStartIO(
-      &DeviceExtension->MiniPortDeviceExtension,
-      vrp);
-
-   /* Free the VRP */
-   ExFreePoolWithTag(vrp, TAG_REQUEST_PACKET);
-
-   INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
-
-   if (Irp->IoStatus.Status != STATUS_SUCCESS)
-   {
-      /* Map from win32 error codes to NT status values. */
-      switch (Irp->IoStatus.Status)
-      {
-         case ERROR_NOT_ENOUGH_MEMORY: Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break;
-         case ERROR_MORE_DATA: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break;
-         case ERROR_INVALID_FUNCTION: Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; break;
-         case ERROR_INVALID_PARAMETER: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break;
-         case ERROR_INSUFFICIENT_BUFFER: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; break;
-         case ERROR_DEV_NOT_EXIST: Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; break;
-         case ERROR_IO_PENDING: Irp->IoStatus.Status = STATUS_PENDING; break;
-      }
-   }
-
-   Status = Irp->IoStatus.Status;
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-   return Status;
+    PIO_STACK_LOCATION IrpStack;
+    NTSTATUS Status;
+    ULONG IoControlCode;
+
+    TRACE_(VIDEOPRT, "IntVideoPortDispatchDeviceControl\n");
+
+    IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+    IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+    INFO_(VIDEOPRT, "- IoControlCode: %x: %s\n", IoControlCode, IoctlName(IoControlCode));
+
+    switch(IoControlCode)
+    {
+        case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS:
+            INFO_(VIDEOPRT, "- IOCTL_VIDEO_INIT_WIN32K_CALLBACKS\n");
+            Status = VideoPortInitWin32kCallbacks(DeviceObject,
+                                                  Irp->AssociatedIrp.SystemBuffer,
+                                                  IrpStack->Parameters.DeviceIoControl.InputBufferLength,
+                                                  &Irp->IoStatus.Information);
+            break;
+
+        case IOCTL_VIDEO_USE_DEVICE_IN_SESSION:
+            INFO_(VIDEOPRT, "- IOCTL_VIDEO_USE_DEVICE_IN_SESSION\n");
+            Status = VideoPortUseDeviceInSession(DeviceObject,
+                                                 Irp->AssociatedIrp.SystemBuffer,
+                                                 IrpStack->Parameters.DeviceIoControl.InputBufferLength,
+                                                 &Irp->IoStatus.Information);
+            break;
+
+        default:
+            /* Forward to the Miniport Driver */
+            Status = VideoPortForwardDeviceControl(DeviceObject, Irp);
+            break;
+    }
+
+    INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
+
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
 }
 
 /*
@@ -272,128 +512,116 @@ IntVideoPortDispatchDeviceControl(
  * Run Level
  *    PASSIVE_LEVEL
  */
-
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchWrite(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-   NTSTATUS nErrCode;
-
-   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-   /*
-    * Storing the device extension pointer in a static variable is an
-    * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
-    * and InbvNotifyDisplayOwnershipLost 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.
-    *
-    * FIXME: We should process all opened display devices in
-    * IntVideoPortResetDisplayParameters.
-    */
-
-   ResetDisplayParametersDeviceExtension = DeviceExtension;
-   InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters);
-
-   nErrCode = STATUS_SUCCESS;
-   Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
-   Irp->IoStatus.Status = nErrCode;
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-   return nErrCode;
+    PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    NTSTATUS nErrCode;
+
+    DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    /*
+     * Storing the device extension pointer in a static variable is an
+     * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
+     * and InbvNotifyDisplayOwnershipLost 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.
+     *
+     * FIXME: We should process all opened display devices in
+     * IntVideoPortResetDisplayParameters.
+     */
+    ResetDisplayParametersDeviceExtension = DeviceExtension;
+    InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters);
+
+    nErrCode = STATUS_SUCCESS;
+    Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
+    Irp->IoStatus.Status = nErrCode;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return nErrCode;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortPnPStartDevice(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
-   PDRIVER_OBJECT DriverObject;
-   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-   PCM_RESOURCE_LIST AllocatedResources;
-
-   /*
-    * Get the initialization data we saved in VideoPortInitialize.
-    */
-
-   DriverObject = DeviceObject->DriverObject;
-   DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
-   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-   /*
-    * Store some resources in the DeviceExtension.
-    */
-
-   AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
-   if (AllocatedResources != NULL)
-   {
-      CM_FULL_RESOURCE_DESCRIPTOR *FullList;
-      CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
-      ULONG ResourceCount;
-      ULONG ResourceListSize;
-
-      /* Save the resource list */
-      ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
-      ResourceListSize =
-         FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
-                      PartialDescriptors[ResourceCount]);
-      DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
-      if (DeviceExtension->AllocatedResources == NULL)
-      {
-         return STATUS_INSUFFICIENT_RESOURCES;
-      }
-
-      RtlCopyMemory(DeviceExtension->AllocatedResources,
-                    AllocatedResources,
-                    ResourceListSize);
-
-      /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
-      for (FullList = AllocatedResources->List;
-           FullList < AllocatedResources->List + AllocatedResources->Count;
-           FullList++)
-      {
-         INFO_(VIDEOPRT, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
-                FullList->InterfaceType, FullList->BusNumber, DeviceExtension->SystemIoBusNumber, FullList->PartialResourceList.Version, FullList->PartialResourceList.Revision);
-
-         /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
-         ASSERT(FullList->InterfaceType == PCIBus);
-         ASSERT(FullList->BusNumber == DeviceExtension->SystemIoBusNumber);
-         ASSERT(1 == FullList->PartialResourceList.Version);
-         ASSERT(1 == FullList->PartialResourceList.Revision);
-        for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
-              Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
-              Descriptor++)
-         {
+    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+    PDRIVER_OBJECT DriverObject;
+    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    PCM_RESOURCE_LIST AllocatedResources;
+
+    /* Get the initialization data we saved in VideoPortInitialize.*/
+    DriverObject = DeviceObject->DriverObject;
+    DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+    DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    /* Store some resources in the DeviceExtension. */
+    AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
+    if (AllocatedResources != NULL)
+    {
+        CM_FULL_RESOURCE_DESCRIPTOR *FullList;
+        CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
+        ULONG ResourceCount;
+        ULONG ResourceListSize;
+
+        /* Save the resource list */
+        ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
+        ResourceListSize =
+            FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
+                         PartialDescriptors[ResourceCount]);
+        DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
+        if (DeviceExtension->AllocatedResources == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        RtlCopyMemory(DeviceExtension->AllocatedResources,
+                      AllocatedResources,
+                      ResourceListSize);
+
+        /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
+        FullList = AllocatedResources->List;
+        ASSERT(AllocatedResources->Count == 1);
+        INFO_(VIDEOPRT, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
+              FullList->InterfaceType, FullList->BusNumber, DeviceExtension->SystemIoBusNumber, FullList->PartialResourceList.Version, FullList->PartialResourceList.Revision);
+
+        /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
+        ASSERT(FullList->InterfaceType == PCIBus);
+        ASSERT(FullList->BusNumber == DeviceExtension->SystemIoBusNumber);
+        ASSERT(1 == FullList->PartialResourceList.Version);
+        ASSERT(1 == FullList->PartialResourceList.Revision);
+        for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
+             Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
+             Descriptor++)
+        {
             if (Descriptor->Type == CmResourceTypeInterrupt)
             {
-               DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
-               DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
-               if (Descriptor->ShareDisposition == CmResourceShareShared)
-                  DeviceExtension->InterruptShared = TRUE;
-               else
-                  DeviceExtension->InterruptShared = FALSE;
+                DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
+                DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
+                if (Descriptor->ShareDisposition == CmResourceShareShared)
+                    DeviceExtension->InterruptShared = TRUE;
+                else
+                    DeviceExtension->InterruptShared = FALSE;
             }
-         }
-      }
-   }
-   INFO_(VIDEOPRT, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
+        }
+    }
+
+    INFO_(VIDEOPRT, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
           DeviceExtension->InterruptLevel,
           DeviceExtension->InterruptVector);
 
-   /*
-    * Create adapter device object.
-    */
-
-   return IntVideoPortFindAdapter(
-      DriverObject,
-      DriverExtension,
-      DeviceObject);
+    /* Create adapter device object. */
+    return IntVideoPortFindAdapter(DriverObject,
+                                   DriverExtension,
+                                   DeviceObject);
 }
 
 
@@ -404,12 +632,12 @@ IntVideoPortForwardIrpAndWaitCompletionRoutine(
     PIRP Irp,
     PVOID Context)
 {
-  PKEVENT Event = Context;
+    PKEVENT Event = Context;
 
-  if (Irp->PendingReturned)
-    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+    if (Irp->PendingReturned)
+        KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
 
-  return STATUS_MORE_PROCESSING_REQUIRED;
+    return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
 NTSTATUS
@@ -434,7 +662,8 @@ IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject, PIRP Irp)
     if (i == 0)
         return Irp->IoStatus.Status;
 
-    DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS) + ((i - 1) * sizeof(PVOID)));
+    DeviceRelations = ExAllocatePool(PagedPool,
+                                     sizeof(DEVICE_RELATIONS) + ((i - 1) * sizeof(PVOID)));
     if (!DeviceRelations) return STATUS_NO_MEMORY;
 
     DeviceRelations->Count = i;
@@ -463,101 +692,109 @@ NTSTATUS
 NTAPI
 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 {
-   KEVENT Event;
-   NTSTATUS Status;
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension =
-                   (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-   KeInitializeEvent(&Event, NotificationEvent, FALSE);
-   IoCopyCurrentIrpStackLocationToNext(Irp);
-   IoSetCompletionRoutine(Irp, IntVideoPortForwardIrpAndWaitCompletionRoutine,
-                          &Event, TRUE, TRUE, TRUE);
-   Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
-   if (Status == STATUS_PENDING)
-   {
-      KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-      Status = Irp->IoStatus.Status;
-   }
-   return Status;
+    KEVENT Event;
+    NTSTATUS Status;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension =
+        (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           IntVideoPortForwardIrpAndWaitCompletionRoutine,
+                           &Event,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = Irp->IoStatus.Status;
+    }
+
+    return Status;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchFdoPnp(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PIO_STACK_LOCATION IrpSp;
-   NTSTATUS Status;
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
-
-   IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
-   switch (IrpSp->MinorFunction)
-   {
-      case IRP_MN_START_DEVICE:
-         Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
-         if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
-            Status = IntVideoPortPnPStartDevice(DeviceObject, Irp);
-         Irp->IoStatus.Status = Status;
-         Irp->IoStatus.Information = 0;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         break;
-
-       case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
-         Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
-         if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
-             Status = IntVideoPortFilterResourceRequirements(DeviceObject, Irp);
-         Irp->IoStatus.Status = Status;
-         Irp->IoStatus.Information = 0;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         break;
-
-       case IRP_MN_QUERY_DEVICE_RELATIONS:
-           if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
-           {
-               IoSkipCurrentIrpStackLocation(Irp);
-               Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
-           }
-           else
-           {
-               Status = IntVideoPortQueryBusRelations(DeviceObject, Irp);
-               Irp->IoStatus.Status = Status;
-               IoCompleteRequest(Irp, IO_NO_INCREMENT);
-           }
-           break;
-
-      case IRP_MN_REMOVE_DEVICE:
-      case IRP_MN_QUERY_REMOVE_DEVICE:
-      case IRP_MN_CANCEL_REMOVE_DEVICE:
-      case IRP_MN_SURPRISE_REMOVAL:
-
-      case IRP_MN_STOP_DEVICE:
-         Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
-         if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+    PIO_STACK_LOCATION IrpSp;
+    NTSTATUS Status;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    switch (IrpSp->MinorFunction)
+    {
+        case IRP_MN_START_DEVICE:
+            Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
+            if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+                Status = IntVideoPortPnPStartDevice(DeviceObject, Irp);
+            Irp->IoStatus.Status = Status;
+            Irp->IoStatus.Information = 0;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+            Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
+            if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+                Status = IntVideoPortFilterResourceRequirements(DeviceObject, Irp);
+            Irp->IoStatus.Status = Status;
+            Irp->IoStatus.Information = 0;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+            if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
+            {
+                IoSkipCurrentIrpStackLocation(Irp);
+                Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+            }
+            else
+            {
+                Status = IntVideoPortQueryBusRelations(DeviceObject, Irp);
+                Irp->IoStatus.Status = Status;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            }
+            break;
+
+        case IRP_MN_REMOVE_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+        case IRP_MN_SURPRISE_REMOVAL:
+
+        case IRP_MN_STOP_DEVICE:
+            Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
+            if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
+                Status = STATUS_SUCCESS;
+            Irp->IoStatus.Status = Status;
+            Irp->IoStatus.Information = 0;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_CANCEL_STOP_DEVICE:
             Status = STATUS_SUCCESS;
-         Irp->IoStatus.Status = Status;
-         Irp->IoStatus.Information = 0;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         break;
-
-      case IRP_MN_QUERY_STOP_DEVICE:
-      case IRP_MN_CANCEL_STOP_DEVICE:
-         Status = STATUS_SUCCESS;
-         Irp->IoStatus.Status = STATUS_SUCCESS;
-         Irp->IoStatus.Information = 0;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         break;
-
-      default:
-         Status = Irp->IoStatus.Status;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         break;
-   }
-
-   return Status;
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = 0;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        default:
+            Status = Irp->IoStatus.Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+    }
+
+    return Status;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchPnp(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
@@ -570,40 +807,82 @@ IntVideoPortDispatchPnp(
         return IntVideoPortDispatchPdoPnp(DeviceObject, Irp);
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchCleanup(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
 
-   DeviceExtension = DeviceObject->DeviceExtension;
-   RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+    DeviceExtension = DeviceObject->DeviceExtension;
+    RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
 
-   Irp->IoStatus.Status = STATUS_SUCCESS;
-   Irp->IoStatus.Information = 0;
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-   return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchPower(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   return STATUS_NOT_IMPLEMENTED;
+    PIO_STACK_LOCATION IrpSp;
+    NTSTATUS Status = Irp->IoStatus.Status;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    if (DeviceExtension->Common.Fdo)
+    {
+        PoStartNextPowerIrp(Irp);
+        IoSkipCurrentIrpStackLocation(Irp);
+        return PoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+    }
+    else
+    {
+        switch (IrpSp->MinorFunction)
+        {
+            case IRP_MN_QUERY_POWER:
+            case IRP_MN_SET_POWER:
+                Status = STATUS_SUCCESS;
+                break;
+        }
+        PoStartNextPowerIrp(Irp);
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 IntVideoPortDispatchSystemControl(
-   IN PDEVICE_OBJECT DeviceObject,
-   IN PIRP Irp)
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
 {
-   return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    if (DeviceExtension->Common.Fdo)
+    {
+        IoSkipCurrentIrpStackLocation(Irp);
+        return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+    }
+    else
+    {
+        Status = Irp->IoStatus.Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
 }
 
-VOID NTAPI
+VOID
+NTAPI
 IntVideoPortUnload(PDRIVER_OBJECT DriverObject)
 {
 }