4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; see the file COPYING.LIB.
18 * If not, write to the Free Software Foundation,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* GLOBAL VARIABLES ***********************************************************/
28 ULONG CsrssInitialized
= FALSE
;
29 PKPROCESS Csrss
= NULL
;
31 /* PRIVATE FUNCTIONS **********************************************************/
35 IN PDRIVER_OBJECT DriverObject
,
36 IN PUNICODE_STRING RegistryPath
)
38 return STATUS_SUCCESS
;
42 IntVideoPortImageDirectoryEntryToData(
46 PIMAGE_NT_HEADERS NtHeader
;
49 NtHeader
= RtlImageNtHeader(BaseAddress
);
53 if (Directory
>= NtHeader
->OptionalHeader
.NumberOfRvaAndSizes
)
56 Va
= NtHeader
->OptionalHeader
.DataDirectory
[Directory
].VirtualAddress
;
60 return (PVOID
)((ULONG_PTR
)BaseAddress
+ Va
);
64 IntVideoPortGetProcAddress(
65 IN PVOID HwDeviceExtension
,
66 IN PUCHAR FunctionName
)
68 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo
;
70 PIMAGE_EXPORT_DIRECTORY ExportDir
;
77 DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName
);
79 RtlInitUnicodeString(&GdiDriverInfo
.DriverName
, L
"videoprt");
80 Status
= ZwSetSystemInformation(
81 SystemLoadGdiDriverInformation
,
83 sizeof(SYSTEM_GDI_DRIVER_INFORMATION
));
84 if (!NT_SUCCESS(Status
))
86 DPRINT("Couldn't get our own module handle?\n");
90 BaseAddress
= GdiDriverInfo
.ImageAddress
;
92 /* Get the pointer to the export directory */
93 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)IntVideoPortImageDirectoryEntryToData(
95 IMAGE_DIRECTORY_ENTRY_EXPORT
);
99 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfFunctions
);
100 OrdinalPtr
= (PUSHORT
)
101 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNameOrdinals
);
103 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNames
);
104 for (i
= 0; i
< ExportDir
->NumberOfNames
; i
++, NamePtr
++, OrdinalPtr
++)
106 if (!_strnicmp((PCHAR
)FunctionName
, (PCHAR
)((ULONG_PTR
)BaseAddress
+ *NamePtr
),
107 strlen((PCHAR
)FunctionName
)))
109 return (PVOID
)((ULONG_PTR
)BaseAddress
+
110 (ULONG_PTR
)AddressPtr
[*OrdinalPtr
]);
114 DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName
);
120 IntVideoPortDeferredRoutine(
122 IN PVOID DeferredContext
,
123 IN PVOID SystemArgument1
,
124 IN PVOID SystemArgument2
)
126 PVOID HwDeviceExtension
=
127 &((PVIDEO_PORT_DEVICE_EXTENSION
)DeferredContext
)->MiniPortDeviceExtension
;
128 ((PMINIPORT_DPC_ROUTINE
)SystemArgument1
)(HwDeviceExtension
, SystemArgument2
);
132 IntVideoPortAllocateDeviceNumber(VOID
)
136 WCHAR SymlinkBuffer
[20];
137 UNICODE_STRING SymlinkName
;
139 for (DeviceNumber
= 0;;)
141 OBJECT_ATTRIBUTES Obj
;
144 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
145 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
146 InitializeObjectAttributes(&Obj
, &SymlinkName
, 0, NULL
, NULL
);
147 Status
= ZwOpenSymbolicLinkObject(&ObjHandle
, GENERIC_READ
, &Obj
);
148 if (NT_SUCCESS(Status
))
154 else if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
158 DPRINT1("ZwOpenSymbolicLinkObject() returned unexpected status: 0x%08lx\n", Status
);
167 IntVideoPortCreateAdapterDeviceObject(
168 IN PDRIVER_OBJECT DriverObject
,
169 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
170 IN PDEVICE_OBJECT PhysicalDeviceObject
,
171 OUT PDEVICE_OBJECT
*DeviceObject OPTIONAL
)
173 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
177 WCHAR DeviceBuffer
[20];
178 UNICODE_STRING DeviceName
;
179 PDEVICE_OBJECT DeviceObject_
;
181 if (DeviceObject
== NULL
)
182 DeviceObject
= &DeviceObject_
;
185 * Find the first free device number that can be used for video device
186 * object names and symlinks.
189 DeviceNumber
= IntVideoPortAllocateDeviceNumber();
190 if (DeviceNumber
== 0xFFFFFFFF)
192 DPRINT("Can't find free device number\n");
193 return STATUS_UNSUCCESSFUL
;
197 * Create the device object.
200 /* Create a unicode device name. */
201 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
202 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
204 /* Create the device object. */
205 Status
= IoCreateDevice(
207 sizeof(VIDEO_PORT_DEVICE_EXTENSION
) +
208 DriverExtension
->InitializationData
.HwDeviceExtensionSize
,
215 if (!NT_SUCCESS(Status
))
217 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
222 * Set the buffering strategy here. If you change this, remember
223 * to change VidDispatchDeviceControl too.
226 (*DeviceObject
)->Flags
|= DO_BUFFERED_IO
;
229 * Initialize device extension.
232 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)((*DeviceObject
)->DeviceExtension
);
233 DeviceExtension
->DeviceNumber
= DeviceNumber
;
234 DeviceExtension
->DriverObject
= DriverObject
;
235 DeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
236 DeviceExtension
->FunctionalDeviceObject
= *DeviceObject
;
237 DeviceExtension
->DriverExtension
= DriverExtension
;
239 DeviceExtension
->RegistryPath
.Length
=
240 DeviceExtension
->RegistryPath
.MaximumLength
=
241 DriverExtension
->RegistryPath
.Length
+ (9 * sizeof(WCHAR
));
242 DeviceExtension
->RegistryPath
.Length
-= sizeof(WCHAR
);
243 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(
245 DeviceExtension
->RegistryPath
.MaximumLength
,
247 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
248 DriverExtension
->RegistryPath
.Buffer
);
250 if (PhysicalDeviceObject
!= NULL
)
252 /* Get bus number from the upper level bus driver. */
253 Size
= sizeof(ULONG
);
254 Status
= IoGetDeviceProperty(
255 PhysicalDeviceObject
,
256 DevicePropertyBusNumber
,
258 &DeviceExtension
->SystemIoBusNumber
,
260 if (!NT_SUCCESS(Status
))
262 DPRINT("Couldn't get an information from bus driver. We will try to\n"
263 "use legacy detection method, but even that doesn't mean that\n"
265 DeviceExtension
->PhysicalDeviceObject
= NULL
;
269 DeviceExtension
->AdapterInterfaceType
=
270 DriverExtension
->InitializationData
.AdapterInterfaceType
;
272 if (PhysicalDeviceObject
!= NULL
)
274 /* Get bus type from the upper level bus driver. */
275 Size
= sizeof(ULONG
);
277 PhysicalDeviceObject
,
278 DevicePropertyLegacyBusType
,
280 &DeviceExtension
->AdapterInterfaceType
,
283 /* Get bus device address from the upper level bus driver. */
284 Size
= sizeof(ULONG
);
286 PhysicalDeviceObject
,
287 DevicePropertyAddress
,
289 &DeviceExtension
->SystemIoSlotNumber
,
293 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
295 &DeviceExtension
->DpcObject
,
296 IntVideoPortDeferredRoutine
,
299 KeInitializeMutex(&DeviceExtension
->DeviceLock
, 0);
301 /* Attach the device. */
302 if (PhysicalDeviceObject
!= NULL
)
303 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(
304 *DeviceObject
, PhysicalDeviceObject
);
306 return STATUS_SUCCESS
;
310 /* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
312 IntVideoPortFindAdapter(
313 IN PDRIVER_OBJECT DriverObject
,
314 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
315 IN PDEVICE_OBJECT DeviceObject
)
317 WCHAR DeviceVideoBuffer
[20];
318 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
321 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
322 SYSTEM_BASIC_INFORMATION SystemBasicInfo
;
324 WCHAR DeviceBuffer
[20];
325 UNICODE_STRING DeviceName
;
326 WCHAR SymlinkBuffer
[20];
327 UNICODE_STRING SymlinkName
;
328 BOOL LegacyDetection
= FALSE
;
331 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
332 DeviceNumber
= DeviceExtension
->DeviceNumber
;
335 * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
338 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
339 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
340 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
341 if (ConfigInfo
.AdapterInterfaceType
== PCIBus
)
342 ConfigInfo
.InterruptMode
= LevelSensitive
;
344 ConfigInfo
.InterruptMode
= Latched
;
345 ConfigInfo
.DriverRegistryPath
= DriverExtension
->RegistryPath
.Buffer
;
346 ConfigInfo
.VideoPortGetProcAddress
= IntVideoPortGetProcAddress
;
347 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
348 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
349 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
351 Size
= sizeof(SystemBasicInfo
);
352 Status
= ZwQuerySystemInformation(
353 SystemBasicInformation
,
358 if (NT_SUCCESS(Status
))
360 ConfigInfo
.SystemMemorySize
=
361 SystemBasicInfo
.NumberOfPhysicalPages
*
362 SystemBasicInfo
.PageSize
;
366 * Call miniport HwVidFindAdapter entry point to detect if
367 * particular device is present. There are two possible code
368 * paths. The first one is for Legacy drivers (NT4) and cases
369 * when we don't have information about what bus we're on. The
370 * second case is the standard one for Plug & Play drivers.
372 if (DeviceExtension
->PhysicalDeviceObject
== NULL
)
374 LegacyDetection
= TRUE
;
379 ULONG BusNumber
, MaxBuses
;
381 MaxBuses
= DeviceExtension
->AdapterInterfaceType
== PCIBus
? 8 : 1;
383 for (BusNumber
= 0; BusNumber
< MaxBuses
; BusNumber
++)
385 DeviceExtension
->SystemIoBusNumber
=
386 ConfigInfo
.SystemIoBusNumber
= BusNumber
;
388 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
389 DriverExtension
->InitializationData
.HwDeviceExtensionSize
);
391 /* FIXME: Need to figure out what string to pass as param 3. */
392 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
393 &DeviceExtension
->MiniPortDeviceExtension
,
394 DriverExtension
->HwContext
,
399 if (Status
== ERROR_DEV_NOT_EXIST
)
403 else if (Status
== NO_ERROR
)
409 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
410 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
411 IoDeleteDevice(DeviceObject
);
419 /* FIXME: Need to figure out what string to pass as param 3. */
420 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
421 &DeviceExtension
->MiniPortDeviceExtension
,
422 DriverExtension
->HwContext
,
428 if (Status
!= NO_ERROR
)
430 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
431 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
432 IoDeleteDevice(DeviceObject
);
437 * Now we know the device is present, so let's do all additional tasks
438 * such as creating symlinks or setting up interrupts and timer.
441 /* Create a unicode device name. */
442 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
443 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
445 /* Create symbolic link "\??\DISPLAYx" */
446 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
447 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
448 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
450 /* Add entry to DEVICEMAP\VIDEO key in registry. */
451 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DeviceNumber
);
452 RtlWriteRegistryValue(
453 RTL_REGISTRY_DEVICEMAP
,
457 DeviceExtension
->RegistryPath
.Buffer
,
458 DeviceExtension
->RegistryPath
.MaximumLength
);
460 /* FIXME: Allocate hardware resources for device. */
463 * Allocate interrupt for device.
466 if (!IntVideoPortSetupInterrupt(DeviceObject
, DriverExtension
, &ConfigInfo
))
468 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
469 IoDeleteDevice(DeviceObject
);
470 return STATUS_INSUFFICIENT_RESOURCES
;
474 * Allocate timer for device.
477 if (!IntVideoPortSetupTimer(DeviceObject
, DriverExtension
))
479 if (DeviceExtension
->InterruptObject
!= NULL
)
480 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
481 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
482 IoDeleteDevice(DeviceObject
);
483 DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
484 return STATUS_INSUFFICIENT_RESOURCES
;
488 * Query children of the device.
490 VideoPortEnumerateChildren(&DeviceExtension
->MiniPortDeviceExtension
, NULL
);
492 DPRINT("STATUS_SUCCESS\n");
493 return STATUS_SUCCESS
;
497 IntAttachToCSRSS(PKPROCESS
*CallingProcess
, PKAPC_STATE ApcState
)
499 *CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
500 if (*CallingProcess
!= Csrss
)
502 KeStackAttachProcess(Csrss
, ApcState
);
507 IntDetachFromCSRSS(PKPROCESS
*CallingProcess
, PKAPC_STATE ApcState
)
509 if (*CallingProcess
!= Csrss
)
511 KeUnstackDetachProcess(ApcState
);
515 /* PUBLIC FUNCTIONS ***********************************************************/
525 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
528 PDRIVER_OBJECT DriverObject
= Context1
;
529 PUNICODE_STRING RegistryPath
= Context2
;
531 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
532 BOOL LegacyDetection
= FALSE
;
534 DPRINT("VideoPortInitialize\n");
537 * As a first thing do parameter checks.
540 if (HwInitializationData
->HwInitDataSize
> sizeof(VIDEO_HW_INITIALIZATION_DATA
))
542 return STATUS_REVISION_MISMATCH
;
545 if (HwInitializationData
->HwFindAdapter
== NULL
||
546 HwInitializationData
->HwInitialize
== NULL
||
547 HwInitializationData
->HwStartIO
== NULL
)
549 return STATUS_INVALID_PARAMETER
;
554 * The driver extension can be already allocated in case that we were
555 * called by legacy driver and failed detecting device. Some miniport
556 * drivers in that case adjust parameters and call VideoPortInitialize
560 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
561 if (DriverExtension
== NULL
)
563 Status
= IoAllocateDriverObjectExtension(
566 sizeof(VIDEO_PORT_DRIVER_EXTENSION
),
567 (PVOID
*)&DriverExtension
);
569 if (!NT_SUCCESS(Status
))
575 * Save the registry path. This should be done only once even if
576 * VideoPortInitialize is called multiple times.
579 if (RegistryPath
->Length
!= 0)
581 DriverExtension
->RegistryPath
.Length
= 0;
582 DriverExtension
->RegistryPath
.MaximumLength
=
583 RegistryPath
->Length
+ sizeof(UNICODE_NULL
);
584 DriverExtension
->RegistryPath
.Buffer
=
585 ExAllocatePoolWithTag(
587 DriverExtension
->RegistryPath
.MaximumLength
,
588 TAG('U', 'S', 'T', 'R'));
589 if (DriverExtension
->RegistryPath
.Buffer
== NULL
)
591 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
592 return STATUS_INSUFFICIENT_RESOURCES
;
595 RtlCopyUnicodeString(&DriverExtension
->RegistryPath
, RegistryPath
);
599 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
604 * Copy the correct miniport initializtation data to the device extension.
608 &DriverExtension
->InitializationData
,
609 HwInitializationData
,
610 HwInitializationData
->HwInitDataSize
);
611 if (HwInitializationData
->HwInitDataSize
<
612 sizeof(VIDEO_HW_INITIALIZATION_DATA
))
614 RtlZeroMemory((PVOID
)((ULONG_PTR
)&DriverExtension
->InitializationData
+
615 HwInitializationData
->HwInitDataSize
),
616 sizeof(VIDEO_HW_INITIALIZATION_DATA
) -
617 HwInitializationData
->HwInitDataSize
);
619 DriverExtension
->HwContext
= HwContext
;
621 switch (HwInitializationData
->HwInitDataSize
)
624 * NT4 drivers are special case, because we must use legacy method
625 * of detection instead of the Plug & Play one.
628 case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA
:
629 DPRINT("We were loaded by a Windows NT miniport driver.\n");
630 LegacyDetection
= TRUE
;
633 case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA
:
634 DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
637 case sizeof(VIDEO_HW_INITIALIZATION_DATA
):
638 DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
642 DPRINT("Invalid HwInitializationData size.\n");
643 return STATUS_UNSUCCESSFUL
;
646 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = IntVideoPortDispatchOpen
;
647 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = IntVideoPortDispatchClose
;
648 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = IntVideoPortDispatchDeviceControl
;
649 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = IntVideoPortDispatchWrite
;
650 DriverObject
->DriverUnload
= IntVideoPortUnload
;
653 * Plug & Play drivers registers the device in AddDevice routine. For
654 * legacy drivers we must do it now.
659 PDEVICE_OBJECT DeviceObject
;
660 Status
= IntVideoPortCreateAdapterDeviceObject(DriverObject
, DriverExtension
,
661 NULL
, &DeviceObject
);
662 DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status
);
663 if (!NT_SUCCESS(Status
))
665 Status
= IntVideoPortFindAdapter(DriverObject
, DriverExtension
, DeviceObject
);
666 DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status
);
671 DriverObject
->DriverExtension
->AddDevice
= IntVideoPortAddDevice
;
672 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = IntVideoPortDispatchPnp
;
673 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = IntVideoPortDispatchPower
;
675 return STATUS_SUCCESS
;
685 IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
686 IN PCHAR DebugMessage
, ...)
691 va_start(ap
, DebugMessage
);
692 vsprintf(Buffer
, DebugMessage
, ap
);
704 IN PVOID HwDeviceExtension
,
705 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
706 IN VP_STATUS ErrorCode
,
709 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
710 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
713 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
722 VideoPortGetCurrentIrql(VOID
)
724 return KeGetCurrentIrql();
727 typedef struct QueryRegistryCallbackContext
729 PVOID HwDeviceExtension
;
731 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
732 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
734 static NTSTATUS NTAPI
735 QueryRegistryCallback(
739 IN ULONG ValueLength
,
741 IN PVOID EntryContext
)
743 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
745 DPRINT("Found registry value for name %S: type %d, length %d\n",
746 ValueName
, ValueType
, ValueLength
);
747 return (*(CallbackContext
->HwGetRegistryRoutine
))(
748 CallbackContext
->HwDeviceExtension
,
749 CallbackContext
->HwContext
,
760 VideoPortGetRegistryParameters(
761 IN PVOID HwDeviceExtension
,
762 IN PWSTR ParameterName
,
763 IN UCHAR IsParameterFileName
,
764 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
767 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
768 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
769 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
771 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
773 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
775 if (IsParameterFileName
)
780 Context
.HwDeviceExtension
= HwDeviceExtension
;
781 Context
.HwContext
= HwContext
;
782 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
784 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
785 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
786 QueryTable
[0].Name
= ParameterName
;
787 QueryTable
[0].EntryContext
= NULL
;
788 QueryTable
[0].DefaultType
= REG_NONE
;
789 QueryTable
[0].DefaultData
= NULL
;
790 QueryTable
[0].DefaultLength
= 0;
792 QueryTable
[1].QueryRoutine
= NULL
;
793 QueryTable
[1].Name
= NULL
;
795 return NT_SUCCESS(RtlQueryRegistryValues(
796 RTL_REGISTRY_ABSOLUTE
,
797 DeviceExtension
->RegistryPath
.Buffer
,
800 NULL
)) ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
808 VideoPortSetRegistryParameters(
809 IN PVOID HwDeviceExtension
,
812 IN ULONG ValueLength
)
814 DPRINT("VideoPortSetRegistryParameters\n");
815 ASSERT_IRQL(PASSIVE_LEVEL
);
816 return RtlWriteRegistryValue(
817 RTL_REGISTRY_ABSOLUTE
,
818 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->RegistryPath
.Buffer
,
830 VideoPortGetVgaStatus(
831 IN PVOID HwDeviceExtension
,
832 OUT PULONG VgaStatus
)
834 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
836 DPRINT("VideoPortGetVgaStatus\n");
838 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
839 if (KeGetCurrentIrql() == PASSIVE_LEVEL
)
841 if (DeviceExtension
->AdapterInterfaceType
== PCIBus
)
843 /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
844 /* Assumed for now */
850 return ERROR_INVALID_FUNCTION
;
858 VideoPortGetRomImage(
859 IN PVOID HwDeviceExtension
,
864 static PVOID RomImageBuffer
= NULL
;
865 PKPROCESS CallingProcess
;
868 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
869 HwDeviceExtension
, Length
);
871 /* If the length is zero then free the existing buffer. */
874 if (RomImageBuffer
!= NULL
)
876 ExFreePool(RomImageBuffer
);
877 RomImageBuffer
= NULL
;
884 * The DDK says we shouldn't use the legacy C0000 method but get the
885 * rom base address from the corresponding pci or acpi register but
886 * lets ignore that and use C0000 anyway. We have already mapped the
887 * bios area into memory so we'll copy from there.
891 Length
= min(Length
, 0x10000);
892 if (RomImageBuffer
!= NULL
)
894 ExFreePool(RomImageBuffer
);
897 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
898 if (RomImageBuffer
== NULL
)
903 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
904 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
905 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
907 return RomImageBuffer
;
917 IN PVOID HwDeviceExtension
,
924 PUCHAR SearchLocation
;
926 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
928 StringLength
= strlen((PCHAR
)String
);
930 SearchLocation
= RomBase
;
931 for (SearchLocation
= RomBase
;
932 !Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
935 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
938 DPRINT("Match found at %p\n", SearchLocation
);
950 VideoPortSynchronizeExecution(
951 IN PVOID HwDeviceExtension
,
952 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
953 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
957 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
963 Ret
= (*SynchronizeRoutine
)(Context
);
966 case VpMediumPriority
:
967 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
968 if (DeviceExtension
->InterruptObject
== NULL
)
969 Ret
= (*SynchronizeRoutine
)(Context
);
971 Ret
= KeSynchronizeExecution(
972 DeviceExtension
->InterruptObject
,
978 OldIrql
= KeGetCurrentIrql();
979 if (OldIrql
< SYNCH_LEVEL
)
980 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
982 Ret
= (*SynchronizeRoutine
)(Context
);
984 if (OldIrql
< SYNCH_LEVEL
)
985 KfLowerIrql(OldIrql
);
1000 VideoPortEnumerateChildren(
1001 IN PVOID HwDeviceExtension
,
1004 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1006 VIDEO_CHILD_ENUM_INFO ChildEnumInfo
;
1007 VIDEO_CHILD_TYPE ChildType
;
1008 UCHAR ChildDescriptor
[256];
1013 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1014 if (DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor
== NULL
)
1016 DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
1020 /* Setup the ChildEnumInfo */
1021 ChildEnumInfo
.Size
= sizeof (ChildEnumInfo
);
1022 ChildEnumInfo
.ChildDescriptorSize
= sizeof (ChildDescriptor
);
1023 ChildEnumInfo
.ACPIHwId
= 0;
1024 ChildEnumInfo
.ChildHwDeviceExtension
= NULL
; /* FIXME: must be set to
1025 ChildHwDeviceExtension... */
1027 /* Enumerate the children */
1030 ChildEnumInfo
.ChildIndex
= i
;
1031 RtlZeroMemory(ChildDescriptor
, sizeof(ChildDescriptor
));
1032 Status
= DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor(
1039 if (Status
== VIDEO_ENUM_INVALID_DEVICE
)
1041 DPRINT("Child device %d is invalid!\n", ChildEnumInfo
.ChildIndex
);
1044 else if (Status
== VIDEO_ENUM_NO_MORE_DEVICES
)
1046 DPRINT("End of child enumeration! (%d children enumerated)\n", i
- 1);
1049 else if (Status
!= VIDEO_ENUM_MORE_DEVICES
)
1051 DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status
);
1056 if (ChildType
== Monitor
)
1059 PUCHAR p
= ChildDescriptor
;
1060 DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId
);
1061 for (j
= 0; j
< sizeof (ChildDescriptor
); j
+= 8)
1063 DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1064 p
[j
+0], p
[j
+1], p
[j
+2], p
[j
+3],
1065 p
[j
+4], p
[j
+5], p
[j
+6], p
[j
+7]);
1068 else if (ChildType
== Other
)
1070 DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR
)ChildDescriptor
);
1074 DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType
);
1088 VideoPortCreateSecondaryDisplay(
1089 IN PVOID HwDeviceExtension
,
1090 IN OUT PVOID
*SecondaryDeviceExtension
,
1093 DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
1103 IN PVOID HwDeviceExtension
,
1104 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
1107 return KeInsertQueueDpc(
1108 &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->DpcObject
,
1109 (PVOID
)CallbackRoutine
,
1118 VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject
)
1120 DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
1129 VideoPortGetVersion(
1130 IN PVOID HwDeviceExtension
,
1131 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
1133 RTL_OSVERSIONINFOEXW Version
;
1135 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
1136 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
1139 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
1141 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
1142 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
1143 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1144 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1145 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1148 return ERROR_INVALID_PARAMETER
;
1150 VpOsVersionInfo
->MajorVersion
= 5;
1151 VpOsVersionInfo
->MinorVersion
= 0;
1152 VpOsVersionInfo
->BuildNumber
= 2195;
1153 VpOsVersionInfo
->ServicePackMajor
= 4;
1154 VpOsVersionInfo
->ServicePackMinor
= 0;
1159 return ERROR_INVALID_PARAMETER
;
1167 VideoPortCheckForDeviceExistence(
1168 IN PVOID HwDeviceExtension
,
1171 IN UCHAR RevisionId
,
1172 IN USHORT SubVendorId
,
1173 IN USHORT SubSystemId
,
1176 DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
1185 VideoPortRegisterBugcheckCallback(
1186 IN PVOID HwDeviceExtension
,
1187 IN ULONG BugcheckCode
,
1189 IN ULONG BugcheckDataSize
)
1191 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1200 VideoPortQueryPerformanceCounter(
1201 IN PVOID HwDeviceExtension
,
1202 OUT PLONGLONG PerformanceFrequency OPTIONAL
)
1204 LARGE_INTEGER Result
;
1206 DPRINT("VideoPortQueryPerformanceCounter\n");
1207 Result
= KeQueryPerformanceCounter((PLARGE_INTEGER
)PerformanceFrequency
);
1208 return Result
.QuadPart
;
1216 VideoPortAcquireDeviceLock(
1217 IN PVOID HwDeviceExtension
)
1219 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1223 DPRINT("VideoPortAcquireDeviceLock\n");
1224 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1225 Status
= KeWaitForMutexObject(&DeviceExtension
->DeviceLock
, Executive
,
1226 KernelMode
, FALSE
, NULL
);
1227 ASSERT(Status
== STATUS_SUCCESS
);
1235 VideoPortReleaseDeviceLock(
1236 IN PVOID HwDeviceExtension
)
1238 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1242 DPRINT("VideoPortReleaseDeviceLock\n");
1243 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1244 Status
= KeReleaseMutex(&DeviceExtension
->DeviceLock
, FALSE
);
1245 ASSERT(Status
== 0);
1254 IN PDEVICE_OBJECT DeviceObject
,