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
;
30 ULONG VideoPortDeviceNumber
= 0;
32 /* PRIVATE FUNCTIONS **********************************************************/
36 IN PDRIVER_OBJECT DriverObject
,
37 IN PUNICODE_STRING RegistryPath
)
39 return STATUS_SUCCESS
;
43 IntVideoPortImageDirectoryEntryToData(
47 PIMAGE_NT_HEADERS NtHeader
;
50 NtHeader
= RtlImageNtHeader(BaseAddress
);
54 if (Directory
>= NtHeader
->OptionalHeader
.NumberOfRvaAndSizes
)
57 Va
= NtHeader
->OptionalHeader
.DataDirectory
[Directory
].VirtualAddress
;
61 return (PVOID
)((ULONG_PTR
)BaseAddress
+ Va
);
65 IntVideoPortGetProcAddress(
66 IN PVOID HwDeviceExtension
,
67 IN PUCHAR FunctionName
)
69 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo
;
71 PIMAGE_EXPORT_DIRECTORY ExportDir
;
78 DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName
);
80 RtlInitUnicodeString(&GdiDriverInfo
.DriverName
, L
"videoprt");
81 Status
= ZwSetSystemInformation(
82 SystemLoadGdiDriverInformation
,
84 sizeof(SYSTEM_GDI_DRIVER_INFORMATION
));
85 if (!NT_SUCCESS(Status
))
87 DPRINT("Couldn't get our own module handle?\n");
91 BaseAddress
= GdiDriverInfo
.ImageAddress
;
93 /* Get the pointer to the export directory */
94 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)IntVideoPortImageDirectoryEntryToData(
96 IMAGE_DIRECTORY_ENTRY_EXPORT
);
100 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfFunctions
);
101 OrdinalPtr
= (PUSHORT
)
102 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNameOrdinals
);
104 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNames
);
105 for (i
= 0; i
< ExportDir
->NumberOfNames
; i
++, NamePtr
++, OrdinalPtr
++)
107 if (!_strnicmp((PCHAR
)FunctionName
, (PCHAR
)((ULONG_PTR
)BaseAddress
+ *NamePtr
),
108 strlen((PCHAR
)FunctionName
)))
110 return (PVOID
)((ULONG_PTR
)BaseAddress
+
111 (ULONG_PTR
)AddressPtr
[*OrdinalPtr
]);
115 DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName
);
121 IntVideoPortDeferredRoutine(
123 IN PVOID DeferredContext
,
124 IN PVOID SystemArgument1
,
125 IN PVOID SystemArgument2
)
127 PVOID HwDeviceExtension
=
128 &((PVIDEO_PORT_DEVICE_EXTENSION
)DeferredContext
)->MiniPortDeviceExtension
;
129 ((PMINIPORT_DPC_ROUTINE
)SystemArgument1
)(HwDeviceExtension
, SystemArgument2
);
133 IntVideoPortCreateAdapterDeviceObject(
134 IN PDRIVER_OBJECT DriverObject
,
135 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
136 IN PDEVICE_OBJECT PhysicalDeviceObject
,
137 OUT PDEVICE_OBJECT
*DeviceObject OPTIONAL
)
139 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
143 WCHAR DeviceBuffer
[20];
144 UNICODE_STRING DeviceName
;
145 PDEVICE_OBJECT DeviceObject_
;
147 if (DeviceObject
== NULL
)
148 DeviceObject
= &DeviceObject_
;
151 * Find the first free device number that can be used for video device
152 * object names and symlinks.
155 DeviceNumber
= VideoPortDeviceNumber
++;
156 if (DeviceNumber
== 0xFFFFFFFF)
158 DPRINT("Can't find free device number\n");
159 return STATUS_UNSUCCESSFUL
;
163 * Create the device object.
166 /* Create a unicode device name. */
167 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
168 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
170 /* Create the device object. */
171 Status
= IoCreateDevice(
173 sizeof(VIDEO_PORT_DEVICE_EXTENSION
) +
174 DriverExtension
->InitializationData
.HwDeviceExtensionSize
,
181 if (!NT_SUCCESS(Status
))
183 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
188 * Set the buffering strategy here. If you change this, remember
189 * to change VidDispatchDeviceControl too.
192 (*DeviceObject
)->Flags
|= DO_BUFFERED_IO
;
195 * Initialize device extension.
198 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)((*DeviceObject
)->DeviceExtension
);
199 DeviceExtension
->DeviceNumber
= DeviceNumber
;
200 DeviceExtension
->DriverObject
= DriverObject
;
201 DeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
202 DeviceExtension
->FunctionalDeviceObject
= *DeviceObject
;
203 DeviceExtension
->DriverExtension
= DriverExtension
;
205 DeviceExtension
->RegistryPath
.Length
=
206 DeviceExtension
->RegistryPath
.MaximumLength
=
207 DriverExtension
->RegistryPath
.Length
+ (9 * sizeof(WCHAR
));
208 DeviceExtension
->RegistryPath
.Length
-= sizeof(WCHAR
);
209 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(
211 DeviceExtension
->RegistryPath
.MaximumLength
,
213 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
214 DriverExtension
->RegistryPath
.Buffer
);
216 if (PhysicalDeviceObject
!= NULL
)
218 /* Get bus number from the upper level bus driver. */
219 Size
= sizeof(ULONG
);
220 Status
= IoGetDeviceProperty(
221 PhysicalDeviceObject
,
222 DevicePropertyBusNumber
,
224 &DeviceExtension
->SystemIoBusNumber
,
226 if (!NT_SUCCESS(Status
))
228 DPRINT("Couldn't get an information from bus driver. We will try to\n"
229 "use legacy detection method, but even that doesn't mean that\n"
231 DeviceExtension
->PhysicalDeviceObject
= NULL
;
235 DeviceExtension
->AdapterInterfaceType
=
236 DriverExtension
->InitializationData
.AdapterInterfaceType
;
238 if (PhysicalDeviceObject
!= NULL
)
240 /* Get bus type from the upper level bus driver. */
241 Size
= sizeof(ULONG
);
243 PhysicalDeviceObject
,
244 DevicePropertyLegacyBusType
,
246 &DeviceExtension
->AdapterInterfaceType
,
249 /* Get bus device address from the upper level bus driver. */
250 Size
= sizeof(ULONG
);
252 PhysicalDeviceObject
,
253 DevicePropertyAddress
,
255 &DeviceExtension
->SystemIoSlotNumber
,
259 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
261 &DeviceExtension
->DpcObject
,
262 IntVideoPortDeferredRoutine
,
265 KeInitializeMutex(&DeviceExtension
->DeviceLock
, 0);
267 /* Attach the device. */
268 if (PhysicalDeviceObject
!= NULL
)
269 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(
270 *DeviceObject
, PhysicalDeviceObject
);
272 return STATUS_SUCCESS
;
276 /* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
278 IntVideoPortFindAdapter(
279 IN PDRIVER_OBJECT DriverObject
,
280 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
281 IN PDEVICE_OBJECT DeviceObject
)
283 WCHAR DeviceVideoBuffer
[20];
284 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
287 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
288 SYSTEM_BASIC_INFORMATION SystemBasicInfo
;
290 WCHAR DeviceBuffer
[20];
291 UNICODE_STRING DeviceName
;
292 WCHAR SymlinkBuffer
[20];
293 UNICODE_STRING SymlinkName
;
294 BOOL LegacyDetection
= FALSE
;
297 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
298 DeviceNumber
= DeviceExtension
->DeviceNumber
;
301 * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
304 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
305 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
306 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
307 if (ConfigInfo
.AdapterInterfaceType
== PCIBus
)
308 ConfigInfo
.InterruptMode
= LevelSensitive
;
310 ConfigInfo
.InterruptMode
= Latched
;
311 ConfigInfo
.DriverRegistryPath
= DriverExtension
->RegistryPath
.Buffer
;
312 ConfigInfo
.VideoPortGetProcAddress
= IntVideoPortGetProcAddress
;
313 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
314 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
315 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
317 Size
= sizeof(SystemBasicInfo
);
318 Status
= ZwQuerySystemInformation(
319 SystemBasicInformation
,
324 if (NT_SUCCESS(Status
))
326 ConfigInfo
.SystemMemorySize
=
327 SystemBasicInfo
.NumberOfPhysicalPages
*
328 SystemBasicInfo
.PageSize
;
332 * Call miniport HwVidFindAdapter entry point to detect if
333 * particular device is present. There are two possible code
334 * paths. The first one is for Legacy drivers (NT4) and cases
335 * when we don't have information about what bus we're on. The
336 * second case is the standard one for Plug & Play drivers.
338 if (DeviceExtension
->PhysicalDeviceObject
== NULL
)
340 LegacyDetection
= TRUE
;
345 ULONG BusNumber
, MaxBuses
;
347 MaxBuses
= DeviceExtension
->AdapterInterfaceType
== PCIBus
? 8 : 1;
349 for (BusNumber
= 0; BusNumber
< MaxBuses
; BusNumber
++)
351 DeviceExtension
->SystemIoBusNumber
=
352 ConfigInfo
.SystemIoBusNumber
= BusNumber
;
354 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
355 DriverExtension
->InitializationData
.HwDeviceExtensionSize
);
357 /* FIXME: Need to figure out what string to pass as param 3. */
358 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
359 &DeviceExtension
->MiniPortDeviceExtension
,
360 DriverExtension
->HwContext
,
365 if (Status
== ERROR_DEV_NOT_EXIST
)
369 else if (Status
== NO_ERROR
)
375 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
376 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
377 IoDeleteDevice(DeviceObject
);
385 /* FIXME: Need to figure out what string to pass as param 3. */
386 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
387 &DeviceExtension
->MiniPortDeviceExtension
,
388 DriverExtension
->HwContext
,
394 if (Status
!= NO_ERROR
)
396 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
397 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
398 IoDeleteDevice(DeviceObject
);
403 * Now we know the device is present, so let's do all additional tasks
404 * such as creating symlinks or setting up interrupts and timer.
407 /* Create a unicode device name. */
408 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
409 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
411 /* Create symbolic link "\??\DISPLAYx" */
412 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
413 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
414 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
416 /* Add entry to DEVICEMAP\VIDEO key in registry. */
417 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DeviceNumber
);
418 RtlWriteRegistryValue(
419 RTL_REGISTRY_DEVICEMAP
,
423 DeviceExtension
->RegistryPath
.Buffer
,
424 DeviceExtension
->RegistryPath
.MaximumLength
);
426 /* FIXME: Allocate hardware resources for device. */
429 * Allocate interrupt for device.
432 if (!IntVideoPortSetupInterrupt(DeviceObject
, DriverExtension
, &ConfigInfo
))
434 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
435 IoDeleteDevice(DeviceObject
);
436 return STATUS_INSUFFICIENT_RESOURCES
;
440 * Allocate timer for device.
443 if (!IntVideoPortSetupTimer(DeviceObject
, DriverExtension
))
445 if (DeviceExtension
->InterruptObject
!= NULL
)
446 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
447 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
448 IoDeleteDevice(DeviceObject
);
449 DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
450 return STATUS_INSUFFICIENT_RESOURCES
;
454 * Query children of the device.
456 VideoPortEnumerateChildren(&DeviceExtension
->MiniPortDeviceExtension
, NULL
);
458 DPRINT("STATUS_SUCCESS\n");
459 return STATUS_SUCCESS
;
463 IntAttachToCSRSS(PKPROCESS
*CallingProcess
, PKAPC_STATE ApcState
)
465 *CallingProcess
= (PKPROCESS
)PsGetCurrentProcess();
466 if (*CallingProcess
!= Csrss
)
468 KeStackAttachProcess(Csrss
, ApcState
);
473 IntDetachFromCSRSS(PKPROCESS
*CallingProcess
, PKAPC_STATE ApcState
)
475 if (*CallingProcess
!= Csrss
)
477 KeUnstackDetachProcess(ApcState
);
481 /* PUBLIC FUNCTIONS ***********************************************************/
491 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
494 PDRIVER_OBJECT DriverObject
= Context1
;
495 PUNICODE_STRING RegistryPath
= Context2
;
497 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
498 BOOL LegacyDetection
= FALSE
;
500 DPRINT("VideoPortInitialize\n");
503 * As a first thing do parameter checks.
506 if (HwInitializationData
->HwInitDataSize
> sizeof(VIDEO_HW_INITIALIZATION_DATA
))
508 return STATUS_REVISION_MISMATCH
;
511 if (HwInitializationData
->HwFindAdapter
== NULL
||
512 HwInitializationData
->HwInitialize
== NULL
||
513 HwInitializationData
->HwStartIO
== NULL
)
515 return STATUS_INVALID_PARAMETER
;
520 * The driver extension can be already allocated in case that we were
521 * called by legacy driver and failed detecting device. Some miniport
522 * drivers in that case adjust parameters and call VideoPortInitialize
526 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
527 if (DriverExtension
== NULL
)
529 Status
= IoAllocateDriverObjectExtension(
532 sizeof(VIDEO_PORT_DRIVER_EXTENSION
),
533 (PVOID
*)&DriverExtension
);
535 if (!NT_SUCCESS(Status
))
541 * Save the registry path. This should be done only once even if
542 * VideoPortInitialize is called multiple times.
545 if (RegistryPath
->Length
!= 0)
547 DriverExtension
->RegistryPath
.Length
= 0;
548 DriverExtension
->RegistryPath
.MaximumLength
=
549 RegistryPath
->Length
+ sizeof(UNICODE_NULL
);
550 DriverExtension
->RegistryPath
.Buffer
=
551 ExAllocatePoolWithTag(
553 DriverExtension
->RegistryPath
.MaximumLength
,
554 TAG('U', 'S', 'T', 'R'));
555 if (DriverExtension
->RegistryPath
.Buffer
== NULL
)
557 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
558 return STATUS_INSUFFICIENT_RESOURCES
;
561 RtlCopyUnicodeString(&DriverExtension
->RegistryPath
, RegistryPath
);
565 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
570 * Copy the correct miniport initializtation data to the device extension.
574 &DriverExtension
->InitializationData
,
575 HwInitializationData
,
576 HwInitializationData
->HwInitDataSize
);
577 if (HwInitializationData
->HwInitDataSize
<
578 sizeof(VIDEO_HW_INITIALIZATION_DATA
))
580 RtlZeroMemory((PVOID
)((ULONG_PTR
)&DriverExtension
->InitializationData
+
581 HwInitializationData
->HwInitDataSize
),
582 sizeof(VIDEO_HW_INITIALIZATION_DATA
) -
583 HwInitializationData
->HwInitDataSize
);
585 DriverExtension
->HwContext
= HwContext
;
587 switch (HwInitializationData
->HwInitDataSize
)
590 * NT4 drivers are special case, because we must use legacy method
591 * of detection instead of the Plug & Play one.
594 case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA
:
595 DPRINT("We were loaded by a Windows NT miniport driver.\n");
596 LegacyDetection
= TRUE
;
599 case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA
:
600 DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
603 case sizeof(VIDEO_HW_INITIALIZATION_DATA
):
604 DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
608 DPRINT("Invalid HwInitializationData size.\n");
609 return STATUS_UNSUCCESSFUL
;
612 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = IntVideoPortDispatchOpen
;
613 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = IntVideoPortDispatchClose
;
614 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = IntVideoPortDispatchDeviceControl
;
615 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = IntVideoPortDispatchWrite
;
616 DriverObject
->DriverUnload
= IntVideoPortUnload
;
619 * Plug & Play drivers registers the device in AddDevice routine. For
620 * legacy drivers we must do it now.
625 PDEVICE_OBJECT DeviceObject
;
626 Status
= IntVideoPortCreateAdapterDeviceObject(DriverObject
, DriverExtension
,
627 NULL
, &DeviceObject
);
628 DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status
);
629 if (!NT_SUCCESS(Status
))
631 Status
= IntVideoPortFindAdapter(DriverObject
, DriverExtension
, DeviceObject
);
632 DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status
);
637 DriverObject
->DriverExtension
->AddDevice
= IntVideoPortAddDevice
;
638 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = IntVideoPortDispatchPnp
;
639 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = IntVideoPortDispatchPower
;
641 return STATUS_SUCCESS
;
651 IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
652 IN PCHAR DebugMessage
, ...)
657 va_start(ap
, DebugMessage
);
658 vsprintf(Buffer
, DebugMessage
, ap
);
661 DbgPrintEx(DPFLTR_IHVVIDEO_ID
, DebugPrintLevel
, Buffer
);
670 IN PVOID HwDeviceExtension
,
671 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
672 IN VP_STATUS ErrorCode
,
675 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
676 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
679 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
688 VideoPortGetCurrentIrql(VOID
)
690 return KeGetCurrentIrql();
693 typedef struct QueryRegistryCallbackContext
695 PVOID HwDeviceExtension
;
697 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
698 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
700 static NTSTATUS NTAPI
701 QueryRegistryCallback(
705 IN ULONG ValueLength
,
707 IN PVOID EntryContext
)
709 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
711 DPRINT("Found registry value for name %S: type %d, length %d\n",
712 ValueName
, ValueType
, ValueLength
);
713 return (*(CallbackContext
->HwGetRegistryRoutine
))(
714 CallbackContext
->HwDeviceExtension
,
715 CallbackContext
->HwContext
,
726 VideoPortGetRegistryParameters(
727 IN PVOID HwDeviceExtension
,
728 IN PWSTR ParameterName
,
729 IN UCHAR IsParameterFileName
,
730 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
733 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
734 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
735 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
737 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
739 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
741 if (IsParameterFileName
)
746 Context
.HwDeviceExtension
= HwDeviceExtension
;
747 Context
.HwContext
= HwContext
;
748 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
750 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
751 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
752 QueryTable
[0].Name
= ParameterName
;
753 QueryTable
[0].EntryContext
= NULL
;
754 QueryTable
[0].DefaultType
= REG_NONE
;
755 QueryTable
[0].DefaultData
= NULL
;
756 QueryTable
[0].DefaultLength
= 0;
758 QueryTable
[1].QueryRoutine
= NULL
;
759 QueryTable
[1].Name
= NULL
;
761 return NT_SUCCESS(RtlQueryRegistryValues(
762 RTL_REGISTRY_ABSOLUTE
,
763 DeviceExtension
->RegistryPath
.Buffer
,
766 NULL
)) ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
774 VideoPortSetRegistryParameters(
775 IN PVOID HwDeviceExtension
,
778 IN ULONG ValueLength
)
780 DPRINT("VideoPortSetRegistryParameters\n");
781 ASSERT_IRQL(PASSIVE_LEVEL
);
782 return RtlWriteRegistryValue(
783 RTL_REGISTRY_ABSOLUTE
,
784 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->RegistryPath
.Buffer
,
796 VideoPortGetVgaStatus(
797 IN PVOID HwDeviceExtension
,
798 OUT PULONG VgaStatus
)
800 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
802 DPRINT("VideoPortGetVgaStatus\n");
804 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
805 if (KeGetCurrentIrql() == PASSIVE_LEVEL
)
807 if (DeviceExtension
->AdapterInterfaceType
== PCIBus
)
809 /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
810 /* Assumed for now */
816 return ERROR_INVALID_FUNCTION
;
824 VideoPortGetRomImage(
825 IN PVOID HwDeviceExtension
,
830 static PVOID RomImageBuffer
= NULL
;
831 PKPROCESS CallingProcess
;
834 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
835 HwDeviceExtension
, Length
);
837 /* If the length is zero then free the existing buffer. */
840 if (RomImageBuffer
!= NULL
)
842 ExFreePool(RomImageBuffer
);
843 RomImageBuffer
= NULL
;
850 * The DDK says we shouldn't use the legacy C0000 method but get the
851 * rom base address from the corresponding pci or acpi register but
852 * lets ignore that and use C0000 anyway. We have already mapped the
853 * bios area into memory so we'll copy from there.
857 Length
= min(Length
, 0x10000);
858 if (RomImageBuffer
!= NULL
)
860 ExFreePool(RomImageBuffer
);
863 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
864 if (RomImageBuffer
== NULL
)
869 IntAttachToCSRSS(&CallingProcess
, &ApcState
);
870 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
871 IntDetachFromCSRSS(&CallingProcess
, &ApcState
);
873 return RomImageBuffer
;
883 IN PVOID HwDeviceExtension
,
890 PUCHAR SearchLocation
;
892 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
894 StringLength
= strlen((PCHAR
)String
);
896 SearchLocation
= RomBase
;
897 for (SearchLocation
= RomBase
;
898 !Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
901 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
904 DPRINT("Match found at %p\n", SearchLocation
);
916 VideoPortSynchronizeExecution(
917 IN PVOID HwDeviceExtension
,
918 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
919 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
923 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
929 Ret
= (*SynchronizeRoutine
)(Context
);
932 case VpMediumPriority
:
933 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
934 if (DeviceExtension
->InterruptObject
== NULL
)
935 Ret
= (*SynchronizeRoutine
)(Context
);
937 Ret
= KeSynchronizeExecution(
938 DeviceExtension
->InterruptObject
,
944 OldIrql
= KeGetCurrentIrql();
945 if (OldIrql
< SYNCH_LEVEL
)
946 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
948 Ret
= (*SynchronizeRoutine
)(Context
);
950 if (OldIrql
< SYNCH_LEVEL
)
951 KfLowerIrql(OldIrql
);
966 VideoPortEnumerateChildren(
967 IN PVOID HwDeviceExtension
,
970 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
972 VIDEO_CHILD_ENUM_INFO ChildEnumInfo
;
973 VIDEO_CHILD_TYPE ChildType
;
974 UCHAR ChildDescriptor
[256];
979 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
980 if (DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor
== NULL
)
982 DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
986 /* Setup the ChildEnumInfo */
987 ChildEnumInfo
.Size
= sizeof (ChildEnumInfo
);
988 ChildEnumInfo
.ChildDescriptorSize
= sizeof (ChildDescriptor
);
989 ChildEnumInfo
.ACPIHwId
= 0;
990 ChildEnumInfo
.ChildHwDeviceExtension
= NULL
; /* FIXME: must be set to
991 ChildHwDeviceExtension... */
993 /* Enumerate the children */
996 ChildEnumInfo
.ChildIndex
= i
;
997 RtlZeroMemory(ChildDescriptor
, sizeof(ChildDescriptor
));
998 Status
= DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor(
1005 if (Status
== VIDEO_ENUM_INVALID_DEVICE
)
1007 DPRINT("Child device %d is invalid!\n", ChildEnumInfo
.ChildIndex
);
1010 else if (Status
== VIDEO_ENUM_NO_MORE_DEVICES
)
1012 DPRINT("End of child enumeration! (%d children enumerated)\n", i
- 1);
1015 else if (Status
!= VIDEO_ENUM_MORE_DEVICES
)
1017 DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status
);
1022 if (ChildType
== Monitor
)
1025 PUCHAR p
= ChildDescriptor
;
1026 DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId
);
1027 for (j
= 0; j
< sizeof (ChildDescriptor
); j
+= 8)
1029 DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1030 p
[j
+0], p
[j
+1], p
[j
+2], p
[j
+3],
1031 p
[j
+4], p
[j
+5], p
[j
+6], p
[j
+7]);
1034 else if (ChildType
== Other
)
1036 DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR
)ChildDescriptor
);
1040 DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType
);
1054 VideoPortCreateSecondaryDisplay(
1055 IN PVOID HwDeviceExtension
,
1056 IN OUT PVOID
*SecondaryDeviceExtension
,
1059 DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
1069 IN PVOID HwDeviceExtension
,
1070 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
1073 return KeInsertQueueDpc(
1074 &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->DpcObject
,
1075 (PVOID
)CallbackRoutine
,
1084 VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject
)
1086 DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
1095 VideoPortGetVersion(
1096 IN PVOID HwDeviceExtension
,
1097 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
1099 RTL_OSVERSIONINFOEXW Version
;
1101 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
1102 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
1105 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
1107 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
1108 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
1109 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1110 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1111 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1114 return ERROR_INVALID_PARAMETER
;
1116 VpOsVersionInfo
->MajorVersion
= 5;
1117 VpOsVersionInfo
->MinorVersion
= 0;
1118 VpOsVersionInfo
->BuildNumber
= 2195;
1119 VpOsVersionInfo
->ServicePackMajor
= 4;
1120 VpOsVersionInfo
->ServicePackMinor
= 0;
1125 return ERROR_INVALID_PARAMETER
;
1133 VideoPortCheckForDeviceExistence(
1134 IN PVOID HwDeviceExtension
,
1137 IN UCHAR RevisionId
,
1138 IN USHORT SubVendorId
,
1139 IN USHORT SubSystemId
,
1142 DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
1151 VideoPortRegisterBugcheckCallback(
1152 IN PVOID HwDeviceExtension
,
1153 IN ULONG BugcheckCode
,
1155 IN ULONG BugcheckDataSize
)
1157 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1166 VideoPortQueryPerformanceCounter(
1167 IN PVOID HwDeviceExtension
,
1168 OUT PLONGLONG PerformanceFrequency OPTIONAL
)
1170 LARGE_INTEGER Result
;
1172 DPRINT("VideoPortQueryPerformanceCounter\n");
1173 Result
= KeQueryPerformanceCounter((PLARGE_INTEGER
)PerformanceFrequency
);
1174 return Result
.QuadPart
;
1182 VideoPortAcquireDeviceLock(
1183 IN PVOID HwDeviceExtension
)
1185 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1189 DPRINT("VideoPortAcquireDeviceLock\n");
1190 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1191 Status
= KeWaitForMutexObject(&DeviceExtension
->DeviceLock
, Executive
,
1192 KernelMode
, FALSE
, NULL
);
1193 ASSERT(Status
== STATUS_SUCCESS
);
1201 VideoPortReleaseDeviceLock(
1202 IN PVOID HwDeviceExtension
)
1204 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1208 DPRINT("VideoPortReleaseDeviceLock\n");
1209 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1210 Status
= KeReleaseMutex(&DeviceExtension
->DeviceLock
, FALSE
);
1211 ASSERT(Status
== 0);
1220 IN PDEVICE_OBJECT DeviceObject
,