Inform HAL about the switch to graphics mode as late as possible. Fixes bug 880.
[reactos.git] / reactos / drivers / video / videoprt / videoprt.c
index 5a86705..6c1dbac 100644 (file)
  */
 
 #include "videoprt.h"
-#include "internal/ps.h"
 
 /* GLOBAL VARIABLES ***********************************************************/
 
 ULONG CsrssInitialized = FALSE;
-PEPROCESS Csrss = NULL;
+PKPROCESS Csrss = NULL;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath)
@@ -39,34 +38,34 @@ DriverEntry(
    return STATUS_SUCCESS;
 }
 
-PVOID STDCALL
+PVOID NTAPI
 IntVideoPortImageDirectoryEntryToData(
    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);
+
+   return (PVOID)((ULONG_PTR)BaseAddress + Va);
 }
 
-PVOID STDCALL
+PVOID NTAPI
 IntVideoPortGetProcAddress(
    IN PVOID HwDeviceExtension,
    IN PUCHAR FunctionName)
 {
-   SYSTEM_LOAD_IMAGE GdiDriverInfo;
+   SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
    PVOID BaseAddress;
    PIMAGE_EXPORT_DIRECTORY ExportDir;
    PUSHORT OrdinalPtr;
@@ -77,18 +76,18 @@ IntVideoPortGetProcAddress(
 
    DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
 
-   RtlInitUnicodeString(&GdiDriverInfo.ModuleName, L"videoprt");
+   RtlInitUnicodeString(&GdiDriverInfo.DriverName, L"videoprt");
    Status = ZwSetSystemInformation(
-      SystemLoadImage,
-      &GdiDriverInfo, 
-      sizeof(SYSTEM_LOAD_IMAGE));
+      SystemLoadGdiDriverInformation,
+      &GdiDriverInfo,
+      sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Couldn't get our own module handle?\n");
       return NULL;
    }
 
-   BaseAddress = GdiDriverInfo.ModuleBase;
+   BaseAddress = GdiDriverInfo.ImageAddress;
 
    /* Get the pointer to the export directory */
    ExportDir = (PIMAGE_EXPORT_DIRECTORY)IntVideoPortImageDirectoryEntryToData(
@@ -104,11 +103,11 @@ IntVideoPortGetProcAddress(
       ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
    for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
    {
-      if (!_strnicmp((PCHAR)FunctionName, (PCHAR)(BaseAddress + *NamePtr),
+      if (!_strnicmp((PCHAR)FunctionName, (PCHAR)((ULONG_PTR)BaseAddress + *NamePtr),
                      strlen((PCHAR)FunctionName)))
       {
-         return (PVOID)((ULONG_PTR)BaseAddress + 
-                        (ULONG_PTR)AddressPtr[*OrdinalPtr]);     
+         return (PVOID)((ULONG_PTR)BaseAddress +
+                        (ULONG_PTR)AddressPtr[*OrdinalPtr]);
       }
    }
 
@@ -117,19 +116,19 @@ IntVideoPortGetProcAddress(
    return NULL;
 }
 
-VOID STDCALL
+VOID NTAPI
 IntVideoPortDeferredRoutine(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2)
 {
-   PVOID HwDeviceExtension = 
+   PVOID HwDeviceExtension =
       &((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
    ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
 }
 
-ULONG STDCALL
+ULONG NTAPI
 IntVideoPortAllocateDeviceNumber(VOID)
 {
    NTSTATUS Status;
@@ -152,16 +151,19 @@ IntVideoPortAllocateDeviceNumber(VOID)
          DeviceNumber++;
          continue;
       }
-      else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL)
+      else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
          break;
       else
+      {
+         DPRINT1("ZwOpenSymbolicLinkObject() returned unexpected status: 0x%08lx\n", Status);
          return 0xFFFFFFFF;
+      }
    }
 
    return DeviceNumber;
 }
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortCreateAdapterDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
@@ -175,7 +177,7 @@ IntVideoPortCreateAdapterDeviceObject(
    WCHAR DeviceBuffer[20];
    UNICODE_STRING DeviceName;
    PDEVICE_OBJECT DeviceObject_;
-   
+
    if (DeviceObject == NULL)
       DeviceObject = &DeviceObject_;
 
@@ -229,6 +231,7 @@ IntVideoPortCreateAdapterDeviceObject(
 
    DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension);
    DeviceExtension->DeviceNumber = DeviceNumber;
+   DeviceExtension->DriverObject = DriverObject;
    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    DeviceExtension->FunctionalDeviceObject = *DeviceObject;
    DeviceExtension->DriverExtension = DriverExtension;
@@ -305,7 +308,7 @@ IntVideoPortCreateAdapterDeviceObject(
 
 
 /* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortFindAdapter(
    IN PDRIVER_OBJECT DriverObject,
    IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
@@ -355,8 +358,8 @@ IntVideoPortFindAdapter(
    if (NT_SUCCESS(Status))
    {
       ConfigInfo.SystemMemorySize =
-         SystemBasicInfo.NumberOfPhysicalPages * 
-         SystemBasicInfo.PhysicalPageSize;
+         SystemBasicInfo.NumberOfPhysicalPages *
+         SystemBasicInfo.PageSize;
    }
 
    /*
@@ -370,7 +373,7 @@ IntVideoPortFindAdapter(
    {
       LegacyDetection = TRUE;
    }
-   
+
    if (LegacyDetection)
    {
       ULONG BusNumber, MaxBuses;
@@ -382,9 +385,9 @@ IntVideoPortFindAdapter(
          DeviceExtension->SystemIoBusNumber =
          ConfigInfo.SystemIoBusNumber = BusNumber;
 
-         RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, 
+         RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
                        DriverExtension->InitializationData.HwDeviceExtensionSize);
-   
+
          /* FIXME: Need to figure out what string to pass as param 3. */
          Status = DriverExtension->InitializationData.HwFindAdapter(
             &DeviceExtension->MiniPortDeviceExtension,
@@ -490,37 +493,24 @@ IntVideoPortFindAdapter(
    return STATUS_SUCCESS;
 }
 
-VOID FASTCALL 
-IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) 
-{ 
-   *CallingProcess = PsGetCurrentProcess(); 
-   if (*CallingProcess != Csrss) 
-   { 
-      if (PsGetCurrentThread()->ThreadsProcess != *CallingProcess)
-      { 
-         *PrevAttachedProcess = *CallingProcess; 
-         KeDetachProcess(); 
-      } 
-      else 
-      { 
-         *PrevAttachedProcess = NULL; 
-      } 
-      KeAttachProcess(Csrss); 
-   } 
-} 
-VOID FASTCALL 
-IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess) 
-{ 
-   if (*CallingProcess != Csrss) 
-   { 
-      KeDetachProcess(); 
-      if (NULL != *PrevAttachedProcess) 
-      { 
-         KeAttachProcess(*PrevAttachedProcess); 
-      } 
-   } 
-} 
+VOID FASTCALL
+IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
+{
+   *CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+   if (*CallingProcess != Csrss)
+   {
+      KeStackAttachProcess(Csrss, ApcState);
+   }
+}
+
+VOID FASTCALL
+IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
+{
+   if (*CallingProcess != Csrss)
+   {
+      KeUnstackDetachProcess(ApcState);
+   }
+}
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
@@ -528,7 +518,7 @@ IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess)
  * @implemented
  */
 
-ULONG STDCALL
+ULONG NTAPI
 VideoPortInitialize(
    IN PVOID Context1,
    IN PVOID Context2,
@@ -543,11 +533,27 @@ VideoPortInitialize(
 
    DPRINT("VideoPortInitialize\n");
 
+   /*
+    * As a first thing do parameter checks.
+    */
+
+   if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA))
+   {
+      return STATUS_REVISION_MISMATCH;
+   }
+
+   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 calls VideoPortInitialize
+    * drivers in that case adjust parameters and call VideoPortInitialize
     * again.
     */
 
@@ -564,6 +570,34 @@ VideoPortInitialize(
       {
          return Status;
       }
+
+      /*
+       * Save the registry path. This should be done only once even if
+       * VideoPortInitialize is called multiple times.
+       */
+
+      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);
+      }
    }
 
    /*
@@ -573,9 +607,9 @@ VideoPortInitialize(
    RtlCopyMemory(
       &DriverExtension->InitializationData,
       HwInitializationData,
-      min(sizeof(VIDEO_HW_INITIALIZATION_DATA),
-          HwInitializationData->HwInitDataSize));
-   if (sizeof(VIDEO_HW_INITIALIZATION_DATA) > HwInitializationData->HwInitDataSize)
+      HwInitializationData->HwInitDataSize);
+   if (HwInitializationData->HwInitDataSize <
+       sizeof(VIDEO_HW_INITIALIZATION_DATA))
    {
       RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData +
                                        HwInitializationData->HwInitDataSize),
@@ -584,8 +618,6 @@ VideoPortInitialize(
    }
    DriverExtension->HwContext = HwContext;
 
-   RtlCopyMemory(&DriverExtension->RegistryPath, RegistryPath, sizeof(UNICODE_STRING));
-
    switch (HwInitializationData->HwInitDataSize)
    {
       /*
@@ -614,6 +646,7 @@ VideoPortInitialize(
    DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IntVideoPortDispatchDeviceControl;
+   DriverObject->MajorFunction[IRP_MJ_WRITE] = IntVideoPortDispatchWrite;
    DriverObject->DriverUnload = IntVideoPortUnload;
 
    /*
@@ -666,7 +699,7 @@ VideoPortDebugPrint(
  * @unimplemented
  */
 
-VOID STDCALL
+VOID NTAPI
 VideoPortLogError(
    IN PVOID HwDeviceExtension,
    IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
@@ -685,7 +718,7 @@ VideoPortLogError(
  * @implemented
  */
 
-UCHAR STDCALL
+UCHAR NTAPI
 VideoPortGetCurrentIrql(VOID)
 {
    return KeGetCurrentIrql();
@@ -698,7 +731,7 @@ typedef struct QueryRegistryCallbackContext
    PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
 } QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
 
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
 QueryRegistryCallback(
    IN PWSTR ValueName,
    IN ULONG ValueType,
@@ -723,7 +756,7 @@ QueryRegistryCallback(
  * @unimplemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortGetRegistryParameters(
    IN PVOID HwDeviceExtension,
    IN PWSTR ParameterName,
@@ -771,7 +804,7 @@ VideoPortGetRegistryParameters(
  * @implemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortSetRegistryParameters(
    IN PVOID HwDeviceExtension,
    IN PWSTR ValueName,
@@ -791,9 +824,9 @@ VideoPortSetRegistryParameters(
 
 /*
  * @implemented
- */ 
+ */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortGetVgaStatus(
    IN PVOID HwDeviceExtension,
    OUT PULONG VgaStatus)
@@ -814,14 +847,14 @@ VideoPortGetVgaStatus(
       }
    }
 
-   return ERROR_INVALID_FUNCTION;    
+   return ERROR_INVALID_FUNCTION;
 }
 
 /*
  * @implemented
  */
 
-PVOID STDCALL
+PVOID NTAPI
 VideoPortGetRomImage(
    IN PVOID HwDeviceExtension,
    IN PVOID Unused1,
@@ -829,8 +862,8 @@ VideoPortGetRomImage(
    IN ULONG Length)
 {
    static PVOID RomImageBuffer = NULL;
-   PEPROCESS CallingProcess; 
-   PEPROCESS PrevAttachedProcess; 
+   PKPROCESS CallingProcess;
+   KAPC_STATE ApcState;
 
    DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
           HwDeviceExtension, Length);
@@ -848,10 +881,10 @@ VideoPortGetRomImage(
    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  
+       * 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.                   
+       * bios area into memory so we'll copy from there.
        */
 
       /* Copy the bios. */
@@ -867,9 +900,9 @@ VideoPortGetRomImage(
          return NULL;
       }
 
-      IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess);
+      IntAttachToCSRSS(&CallingProcess, &ApcState);
       RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
-      IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess);
+      IntDetachFromCSRSS(&CallingProcess, &ApcState);
 
       return RomImageBuffer;
    }
@@ -879,9 +912,9 @@ VideoPortGetRomImage(
  * @implemented
  */
 
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 VideoPortScanRom(
-   IN PVOID HwDeviceExtension, 
+   IN PVOID HwDeviceExtension,
    IN PUCHAR RomBase,
    IN ULONG RomLength,
    IN PUCHAR String)
@@ -913,7 +946,7 @@ VideoPortScanRom(
  * @implemented
  */
 
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 VideoPortSynchronizeExecution(
    IN PVOID HwDeviceExtension,
    IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
@@ -929,7 +962,7 @@ VideoPortSynchronizeExecution(
       case VpLowPriority:
          Ret = (*SynchronizeRoutine)(Context);
          break;
-   
+
       case VpMediumPriority:
          DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
          if (DeviceExtension->InterruptObject == NULL)
@@ -963,7 +996,7 @@ VideoPortSynchronizeExecution(
  * @implemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortEnumerateChildren(
    IN PVOID HwDeviceExtension,
    IN PVOID Reserved)
@@ -1019,6 +1052,7 @@ VideoPortEnumerateChildren(
          break;
       }
 
+#ifndef NDEBUG
       if (ChildType == Monitor)
       {
          INT j;
@@ -1039,6 +1073,7 @@ VideoPortEnumerateChildren(
       {
          DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType);
       }
+#endif /* NDEBUG */
 
    }
 
@@ -1049,7 +1084,7 @@ VideoPortEnumerateChildren(
  * @unimplemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortCreateSecondaryDisplay(
    IN PVOID HwDeviceExtension,
    IN OUT PVOID *SecondaryDeviceExtension,
@@ -1063,14 +1098,14 @@ VideoPortCreateSecondaryDisplay(
  * @implemented
  */
 
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 VideoPortQueueDpc(
    IN PVOID HwDeviceExtension,
    IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
    IN PVOID Context)
 {
    return KeInsertQueueDpc(
-      &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject, 
+      &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
       (PVOID)CallbackRoutine,
       (PVOID)Context);
 }
@@ -1079,7 +1114,7 @@ VideoPortQueueDpc(
  * @unimplemented
  */
 
-PVOID STDCALL
+PVOID NTAPI
 VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
 {
    DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
@@ -1090,7 +1125,7 @@ VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
  * @implemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortGetVersion(
    IN PVOID HwDeviceExtension,
    IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
@@ -1128,7 +1163,7 @@ VideoPortGetVersion(
  * @unimplemented
  */
 
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 VideoPortCheckForDeviceExistence(
    IN PVOID HwDeviceExtension,
    IN USHORT VendorId,
@@ -1146,7 +1181,7 @@ VideoPortCheckForDeviceExistence(
  * @unimplemented
  */
 
-VP_STATUS STDCALL
+VP_STATUS NTAPI
 VideoPortRegisterBugcheckCallback(
    IN PVOID HwDeviceExtension,
    IN ULONG BugcheckCode,
@@ -1161,7 +1196,7 @@ VideoPortRegisterBugcheckCallback(
  * @implemented
  */
 
-LONGLONG STDCALL
+LONGLONG NTAPI
 VideoPortQueryPerformanceCounter(
    IN PVOID HwDeviceExtension,
    OUT PLONGLONG PerformanceFrequency OPTIONAL)
@@ -1176,8 +1211,8 @@ VideoPortQueryPerformanceCounter(
 /*
  * @implemented
  */
-VOID STDCALL
+
+VOID NTAPI
 VideoPortAcquireDeviceLock(
    IN PVOID  HwDeviceExtension)
 {
@@ -1196,7 +1231,7 @@ VideoPortAcquireDeviceLock(
  * @implemented
  */
 
-VOID STDCALL
+VOID NTAPI
 VideoPortReleaseDeviceLock(
    IN PVOID  HwDeviceExtension)
 {
@@ -1210,3 +1245,13 @@ VideoPortReleaseDeviceLock(
    ASSERT(Status == 0);
 }
 
+/*
+ * @unimplemented
+ */
+
+VOID NTAPI
+VpNotifyEaData(
+   IN PDEVICE_OBJECT DeviceObject,
+   IN PVOID Data)
+{
+}