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.
25 #include "internal/ps.h"
27 /* GLOBAL VARIABLES ***********************************************************/
29 ULONG CsrssInitialized
= FALSE
;
30 PEPROCESS Csrss
= NULL
;
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
)(BaseAddress
+ Va
);
65 IntVideoPortGetProcAddress(
66 IN PVOID HwDeviceExtension
,
67 IN PUCHAR FunctionName
)
69 SYSTEM_LOAD_IMAGE GdiDriverInfo
;
71 PIMAGE_EXPORT_DIRECTORY ExportDir
;
78 DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName
);
80 RtlInitUnicodeString(&GdiDriverInfo
.ModuleName
, L
"videoprt");
81 Status
= ZwSetSystemInformation(
84 sizeof(SYSTEM_LOAD_IMAGE
));
85 if (!NT_SUCCESS(Status
))
87 DPRINT("Couldn't get our own module handle?\n");
91 BaseAddress
= GdiDriverInfo
.ModuleBase
;
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
)(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 IntVideoPortAllocateDeviceNumber(VOID
)
137 WCHAR SymlinkBuffer
[20];
138 UNICODE_STRING SymlinkName
;
140 for (DeviceNumber
= 0;;)
142 OBJECT_ATTRIBUTES Obj
;
145 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
146 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
147 InitializeObjectAttributes(&Obj
, &SymlinkName
, 0, NULL
, NULL
);
148 Status
= ZwOpenSymbolicLinkObject(&ObjHandle
, GENERIC_READ
, &Obj
);
149 if (NT_SUCCESS(Status
))
155 else if (Status
== STATUS_OBJECT_NAME_NOT_FOUND
)
159 DPRINT1("ZwOpenSymbolicLinkObject() returned unexpected status: 0x%08lx\n", Status
);
168 IntVideoPortCreateAdapterDeviceObject(
169 IN PDRIVER_OBJECT DriverObject
,
170 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
171 IN PDEVICE_OBJECT PhysicalDeviceObject
,
172 OUT PDEVICE_OBJECT
*DeviceObject OPTIONAL
)
174 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
178 WCHAR DeviceBuffer
[20];
179 UNICODE_STRING DeviceName
;
180 PDEVICE_OBJECT DeviceObject_
;
182 if (DeviceObject
== NULL
)
183 DeviceObject
= &DeviceObject_
;
186 * Find the first free device number that can be used for video device
187 * object names and symlinks.
190 DeviceNumber
= IntVideoPortAllocateDeviceNumber();
191 if (DeviceNumber
== 0xFFFFFFFF)
193 DPRINT("Can't find free device number\n");
194 return STATUS_UNSUCCESSFUL
;
198 * Create the device object.
201 /* Create a unicode device name. */
202 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
203 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
205 /* Create the device object. */
206 Status
= IoCreateDevice(
208 sizeof(VIDEO_PORT_DEVICE_EXTENSION
) +
209 DriverExtension
->InitializationData
.HwDeviceExtensionSize
,
216 if (!NT_SUCCESS(Status
))
218 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
223 * Set the buffering strategy here. If you change this, remember
224 * to change VidDispatchDeviceControl too.
227 (*DeviceObject
)->Flags
|= DO_BUFFERED_IO
;
230 * Initialize device extension.
233 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)((*DeviceObject
)->DeviceExtension
);
234 DeviceExtension
->DeviceNumber
= DeviceNumber
;
235 DeviceExtension
->DriverObject
= DriverObject
;
236 DeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
237 DeviceExtension
->FunctionalDeviceObject
= *DeviceObject
;
238 DeviceExtension
->DriverExtension
= DriverExtension
;
240 DeviceExtension
->RegistryPath
.Length
=
241 DeviceExtension
->RegistryPath
.MaximumLength
=
242 DriverExtension
->RegistryPath
.Length
+ (9 * sizeof(WCHAR
));
243 DeviceExtension
->RegistryPath
.Length
-= sizeof(WCHAR
);
244 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(
246 DeviceExtension
->RegistryPath
.MaximumLength
,
248 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
249 DriverExtension
->RegistryPath
.Buffer
);
251 if (PhysicalDeviceObject
!= NULL
)
253 /* Get bus number from the upper level bus driver. */
254 Size
= sizeof(ULONG
);
255 Status
= IoGetDeviceProperty(
256 PhysicalDeviceObject
,
257 DevicePropertyBusNumber
,
259 &DeviceExtension
->SystemIoBusNumber
,
261 if (!NT_SUCCESS(Status
))
263 DPRINT("Couldn't get an information from bus driver. We will try to\n"
264 "use legacy detection method, but even that doesn't mean that\n"
266 DeviceExtension
->PhysicalDeviceObject
= NULL
;
270 DeviceExtension
->AdapterInterfaceType
=
271 DriverExtension
->InitializationData
.AdapterInterfaceType
;
273 if (PhysicalDeviceObject
!= NULL
)
275 /* Get bus type from the upper level bus driver. */
276 Size
= sizeof(ULONG
);
278 PhysicalDeviceObject
,
279 DevicePropertyLegacyBusType
,
281 &DeviceExtension
->AdapterInterfaceType
,
284 /* Get bus device address from the upper level bus driver. */
285 Size
= sizeof(ULONG
);
287 PhysicalDeviceObject
,
288 DevicePropertyAddress
,
290 &DeviceExtension
->SystemIoSlotNumber
,
294 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
296 &DeviceExtension
->DpcObject
,
297 IntVideoPortDeferredRoutine
,
300 KeInitializeMutex(&DeviceExtension
->DeviceLock
, 0);
302 /* Attach the device. */
303 if (PhysicalDeviceObject
!= NULL
)
304 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(
305 *DeviceObject
, PhysicalDeviceObject
);
307 return STATUS_SUCCESS
;
311 /* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
313 IntVideoPortFindAdapter(
314 IN PDRIVER_OBJECT DriverObject
,
315 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
316 IN PDEVICE_OBJECT DeviceObject
)
318 WCHAR DeviceVideoBuffer
[20];
319 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
322 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
323 SYSTEM_BASIC_INFORMATION SystemBasicInfo
;
325 WCHAR DeviceBuffer
[20];
326 UNICODE_STRING DeviceName
;
327 WCHAR SymlinkBuffer
[20];
328 UNICODE_STRING SymlinkName
;
329 BOOL LegacyDetection
= FALSE
;
332 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
333 DeviceNumber
= DeviceExtension
->DeviceNumber
;
336 * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
339 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
340 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
341 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
342 if (ConfigInfo
.AdapterInterfaceType
== PCIBus
)
343 ConfigInfo
.InterruptMode
= LevelSensitive
;
345 ConfigInfo
.InterruptMode
= Latched
;
346 ConfigInfo
.DriverRegistryPath
= DriverExtension
->RegistryPath
.Buffer
;
347 ConfigInfo
.VideoPortGetProcAddress
= IntVideoPortGetProcAddress
;
348 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
349 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
350 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
352 Size
= sizeof(SystemBasicInfo
);
353 Status
= ZwQuerySystemInformation(
354 SystemBasicInformation
,
359 if (NT_SUCCESS(Status
))
361 ConfigInfo
.SystemMemorySize
=
362 SystemBasicInfo
.NumberOfPhysicalPages
*
363 SystemBasicInfo
.PhysicalPageSize
;
367 * Call miniport HwVidFindAdapter entry point to detect if
368 * particular device is present. There are two possible code
369 * paths. The first one is for Legacy drivers (NT4) and cases
370 * when we don't have information about what bus we're on. The
371 * second case is the standard one for Plug & Play drivers.
373 if (DeviceExtension
->PhysicalDeviceObject
== NULL
)
375 LegacyDetection
= TRUE
;
380 ULONG BusNumber
, MaxBuses
;
382 MaxBuses
= DeviceExtension
->AdapterInterfaceType
== PCIBus
? 8 : 1;
384 for (BusNumber
= 0; BusNumber
< MaxBuses
; BusNumber
++)
386 DeviceExtension
->SystemIoBusNumber
=
387 ConfigInfo
.SystemIoBusNumber
= BusNumber
;
389 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
390 DriverExtension
->InitializationData
.HwDeviceExtensionSize
);
392 /* FIXME: Need to figure out what string to pass as param 3. */
393 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
394 &DeviceExtension
->MiniPortDeviceExtension
,
395 DriverExtension
->HwContext
,
400 if (Status
== ERROR_DEV_NOT_EXIST
)
404 else if (Status
== NO_ERROR
)
410 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
411 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
412 IoDeleteDevice(DeviceObject
);
420 /* FIXME: Need to figure out what string to pass as param 3. */
421 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
422 &DeviceExtension
->MiniPortDeviceExtension
,
423 DriverExtension
->HwContext
,
429 if (Status
!= NO_ERROR
)
431 DPRINT("HwFindAdapter call failed with error 0x%X\n", Status
);
432 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
433 IoDeleteDevice(DeviceObject
);
438 * Now we know the device is present, so let's do all additional tasks
439 * such as creating symlinks or setting up interrupts and timer.
442 /* Create a unicode device name. */
443 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DeviceNumber
);
444 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
446 /* Create symbolic link "\??\DISPLAYx" */
447 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
448 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
449 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
451 /* Add entry to DEVICEMAP\VIDEO key in registry. */
452 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DeviceNumber
);
453 RtlWriteRegistryValue(
454 RTL_REGISTRY_DEVICEMAP
,
458 DeviceExtension
->RegistryPath
.Buffer
,
459 DeviceExtension
->RegistryPath
.MaximumLength
);
461 /* FIXME: Allocate hardware resources for device. */
464 * Allocate interrupt for device.
467 if (!IntVideoPortSetupInterrupt(DeviceObject
, DriverExtension
, &ConfigInfo
))
469 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
470 IoDeleteDevice(DeviceObject
);
471 return STATUS_INSUFFICIENT_RESOURCES
;
475 * Allocate timer for device.
478 if (!IntVideoPortSetupTimer(DeviceObject
, DriverExtension
))
480 if (DeviceExtension
->InterruptObject
!= NULL
)
481 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
482 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
483 IoDeleteDevice(DeviceObject
);
484 DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
485 return STATUS_INSUFFICIENT_RESOURCES
;
489 * Query children of the device.
491 VideoPortEnumerateChildren(&DeviceExtension
->MiniPortDeviceExtension
, NULL
);
493 DPRINT("STATUS_SUCCESS\n");
494 return STATUS_SUCCESS
;
498 IntAttachToCSRSS(PEPROCESS
*CallingProcess
, PEPROCESS
*PrevAttachedProcess
)
500 *CallingProcess
= PsGetCurrentProcess();
501 if (*CallingProcess
!= Csrss
)
503 if (PsGetCurrentThread()->ThreadsProcess
!= *CallingProcess
)
505 *PrevAttachedProcess
= *CallingProcess
;
510 *PrevAttachedProcess
= NULL
;
512 KeAttachProcess(Csrss
);
517 IntDetachFromCSRSS(PEPROCESS
*CallingProcess
, PEPROCESS
*PrevAttachedProcess
)
519 if (*CallingProcess
!= Csrss
)
522 if (NULL
!= *PrevAttachedProcess
)
524 KeAttachProcess(*PrevAttachedProcess
);
529 /* PUBLIC FUNCTIONS ***********************************************************/
539 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
542 PDRIVER_OBJECT DriverObject
= Context1
;
543 PUNICODE_STRING RegistryPath
= Context2
;
545 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
546 BOOL LegacyDetection
= FALSE
;
548 DPRINT("VideoPortInitialize\n");
552 * The driver extension can be already allocated in case that we were
553 * called by legacy driver and failed detecting device. Some miniport
554 * drivers in that case adjust parameters and calls VideoPortInitialize
558 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
559 if (DriverExtension
== NULL
)
561 Status
= IoAllocateDriverObjectExtension(
564 sizeof(VIDEO_PORT_DRIVER_EXTENSION
),
565 (PVOID
*)&DriverExtension
);
567 if (!NT_SUCCESS(Status
))
574 * Copy the correct miniport initializtation data to the device extension.
578 &DriverExtension
->InitializationData
,
579 HwInitializationData
,
580 min(sizeof(VIDEO_HW_INITIALIZATION_DATA
),
581 HwInitializationData
->HwInitDataSize
));
582 if (sizeof(VIDEO_HW_INITIALIZATION_DATA
) > HwInitializationData
->HwInitDataSize
)
584 RtlZeroMemory((PVOID
)((ULONG_PTR
)&DriverExtension
->InitializationData
+
585 HwInitializationData
->HwInitDataSize
),
586 sizeof(VIDEO_HW_INITIALIZATION_DATA
) -
587 HwInitializationData
->HwInitDataSize
);
589 DriverExtension
->HwContext
= HwContext
;
591 /* we can't use RtlDuplicateUnicodeString because only ntdll exposes it... */
592 if (RegistryPath
->Length
!= 0)
594 DriverExtension
->RegistryPath
.Length
= 0;
595 DriverExtension
->RegistryPath
.MaximumLength
= RegistryPath
->Length
+ sizeof(UNICODE_NULL
);
596 DriverExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
597 DriverExtension
->RegistryPath
.MaximumLength
,
598 TAG('U', 'S', 'T', 'R'));
599 if (DriverExtension
->RegistryPath
.Buffer
== NULL
)
601 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
602 return STATUS_INSUFFICIENT_RESOURCES
;
605 RtlCopyUnicodeString(&DriverExtension
->RegistryPath
, RegistryPath
);
609 RtlInitUnicodeString(&DriverExtension
->RegistryPath
, NULL
);
612 switch (HwInitializationData
->HwInitDataSize
)
615 * NT4 drivers are special case, because we must use legacy method
616 * of detection instead of the Plug & Play one.
619 case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA
:
620 DPRINT("We were loaded by a Windows NT miniport driver.\n");
621 LegacyDetection
= TRUE
;
624 case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA
:
625 DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
628 case sizeof(VIDEO_HW_INITIALIZATION_DATA
):
629 DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
633 DPRINT("Invalid HwInitializationData size.\n");
634 return STATUS_UNSUCCESSFUL
;
637 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = IntVideoPortDispatchOpen
;
638 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = IntVideoPortDispatchClose
;
639 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = IntVideoPortDispatchDeviceControl
;
640 DriverObject
->DriverUnload
= IntVideoPortUnload
;
643 * Plug & Play drivers registers the device in AddDevice routine. For
644 * legacy drivers we must do it now.
649 PDEVICE_OBJECT DeviceObject
;
650 Status
= IntVideoPortCreateAdapterDeviceObject(DriverObject
, DriverExtension
,
651 NULL
, &DeviceObject
);
652 DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status
);
653 if (!NT_SUCCESS(Status
))
655 Status
= IntVideoPortFindAdapter(DriverObject
, DriverExtension
, DeviceObject
);
656 DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status
);
661 DriverObject
->DriverExtension
->AddDevice
= IntVideoPortAddDevice
;
662 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = IntVideoPortDispatchPnp
;
663 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = IntVideoPortDispatchPower
;
665 return STATUS_SUCCESS
;
675 IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
676 IN PCHAR DebugMessage
, ...)
681 va_start(ap
, DebugMessage
);
682 vsprintf(Buffer
, DebugMessage
, ap
);
694 IN PVOID HwDeviceExtension
,
695 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
696 IN VP_STATUS ErrorCode
,
699 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
700 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
703 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
712 VideoPortGetCurrentIrql(VOID
)
714 return KeGetCurrentIrql();
717 typedef struct QueryRegistryCallbackContext
719 PVOID HwDeviceExtension
;
721 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
722 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
724 static NTSTATUS STDCALL
725 QueryRegistryCallback(
729 IN ULONG ValueLength
,
731 IN PVOID EntryContext
)
733 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
735 DPRINT("Found registry value for name %S: type %d, length %d\n",
736 ValueName
, ValueType
, ValueLength
);
737 return (*(CallbackContext
->HwGetRegistryRoutine
))(
738 CallbackContext
->HwDeviceExtension
,
739 CallbackContext
->HwContext
,
750 VideoPortGetRegistryParameters(
751 IN PVOID HwDeviceExtension
,
752 IN PWSTR ParameterName
,
753 IN UCHAR IsParameterFileName
,
754 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
757 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
758 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
759 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
761 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
763 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
765 if (IsParameterFileName
)
770 Context
.HwDeviceExtension
= HwDeviceExtension
;
771 Context
.HwContext
= HwContext
;
772 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
774 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
775 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
776 QueryTable
[0].Name
= ParameterName
;
777 QueryTable
[0].EntryContext
= NULL
;
778 QueryTable
[0].DefaultType
= REG_NONE
;
779 QueryTable
[0].DefaultData
= NULL
;
780 QueryTable
[0].DefaultLength
= 0;
782 QueryTable
[1].QueryRoutine
= NULL
;
783 QueryTable
[1].Name
= NULL
;
785 return NT_SUCCESS(RtlQueryRegistryValues(
786 RTL_REGISTRY_ABSOLUTE
,
787 DeviceExtension
->RegistryPath
.Buffer
,
790 NULL
)) ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
798 VideoPortSetRegistryParameters(
799 IN PVOID HwDeviceExtension
,
802 IN ULONG ValueLength
)
804 DPRINT("VideoPortSetRegistryParameters\n");
805 ASSERT_IRQL(PASSIVE_LEVEL
);
806 return RtlWriteRegistryValue(
807 RTL_REGISTRY_ABSOLUTE
,
808 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->RegistryPath
.Buffer
,
820 VideoPortGetVgaStatus(
821 IN PVOID HwDeviceExtension
,
822 OUT PULONG VgaStatus
)
824 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
826 DPRINT("VideoPortGetVgaStatus\n");
828 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
829 if (KeGetCurrentIrql() == PASSIVE_LEVEL
)
831 if (DeviceExtension
->AdapterInterfaceType
== PCIBus
)
833 /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
834 /* Assumed for now */
840 return ERROR_INVALID_FUNCTION
;
848 VideoPortGetRomImage(
849 IN PVOID HwDeviceExtension
,
854 static PVOID RomImageBuffer
= NULL
;
855 PEPROCESS CallingProcess
;
856 PEPROCESS PrevAttachedProcess
;
858 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
859 HwDeviceExtension
, Length
);
861 /* If the length is zero then free the existing buffer. */
864 if (RomImageBuffer
!= NULL
)
866 ExFreePool(RomImageBuffer
);
867 RomImageBuffer
= NULL
;
874 * The DDK says we shouldn't use the legacy C0000 method but get the
875 * rom base address from the corresponding pci or acpi register but
876 * lets ignore that and use C0000 anyway. We have already mapped the
877 * bios area into memory so we'll copy from there.
881 Length
= min(Length
, 0x10000);
882 if (RomImageBuffer
!= NULL
)
884 ExFreePool(RomImageBuffer
);
887 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
888 if (RomImageBuffer
== NULL
)
893 IntAttachToCSRSS(&CallingProcess
, &PrevAttachedProcess
);
894 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
895 IntDetachFromCSRSS(&CallingProcess
, &PrevAttachedProcess
);
897 return RomImageBuffer
;
907 IN PVOID HwDeviceExtension
,
914 PUCHAR SearchLocation
;
916 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
918 StringLength
= strlen((PCHAR
)String
);
920 SearchLocation
= RomBase
;
921 for (SearchLocation
= RomBase
;
922 !Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
925 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
928 DPRINT("Match found at %p\n", SearchLocation
);
940 VideoPortSynchronizeExecution(
941 IN PVOID HwDeviceExtension
,
942 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
943 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
947 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
953 Ret
= (*SynchronizeRoutine
)(Context
);
956 case VpMediumPriority
:
957 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
958 if (DeviceExtension
->InterruptObject
== NULL
)
959 Ret
= (*SynchronizeRoutine
)(Context
);
961 Ret
= KeSynchronizeExecution(
962 DeviceExtension
->InterruptObject
,
968 OldIrql
= KeGetCurrentIrql();
969 if (OldIrql
< SYNCH_LEVEL
)
970 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
972 Ret
= (*SynchronizeRoutine
)(Context
);
974 if (OldIrql
< SYNCH_LEVEL
)
975 KfLowerIrql(OldIrql
);
990 VideoPortEnumerateChildren(
991 IN PVOID HwDeviceExtension
,
994 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
996 VIDEO_CHILD_ENUM_INFO ChildEnumInfo
;
997 VIDEO_CHILD_TYPE ChildType
;
998 UCHAR ChildDescriptor
[256];
1003 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1004 if (DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor
== NULL
)
1006 DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
1010 /* Setup the ChildEnumInfo */
1011 ChildEnumInfo
.Size
= sizeof (ChildEnumInfo
);
1012 ChildEnumInfo
.ChildDescriptorSize
= sizeof (ChildDescriptor
);
1013 ChildEnumInfo
.ACPIHwId
= 0;
1014 ChildEnumInfo
.ChildHwDeviceExtension
= NULL
; /* FIXME: must be set to
1015 ChildHwDeviceExtension... */
1017 /* Enumerate the children */
1020 ChildEnumInfo
.ChildIndex
= i
;
1021 RtlZeroMemory(ChildDescriptor
, sizeof(ChildDescriptor
));
1022 Status
= DeviceExtension
->DriverExtension
->InitializationData
.HwGetVideoChildDescriptor(
1029 if (Status
== VIDEO_ENUM_INVALID_DEVICE
)
1031 DPRINT("Child device %d is invalid!\n", ChildEnumInfo
.ChildIndex
);
1034 else if (Status
== VIDEO_ENUM_NO_MORE_DEVICES
)
1036 DPRINT("End of child enumeration! (%d children enumerated)\n", i
- 1);
1039 else if (Status
!= VIDEO_ENUM_MORE_DEVICES
)
1041 DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status
);
1046 if (ChildType
== Monitor
)
1049 PUCHAR p
= ChildDescriptor
;
1050 DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId
);
1051 for (j
= 0; j
< sizeof (ChildDescriptor
); j
+= 8)
1053 DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1054 p
[j
+0], p
[j
+1], p
[j
+2], p
[j
+3],
1055 p
[j
+4], p
[j
+5], p
[j
+6], p
[j
+7]);
1058 else if (ChildType
== Other
)
1060 DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR
)ChildDescriptor
);
1064 DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType
);
1078 VideoPortCreateSecondaryDisplay(
1079 IN PVOID HwDeviceExtension
,
1080 IN OUT PVOID
*SecondaryDeviceExtension
,
1083 DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
1093 IN PVOID HwDeviceExtension
,
1094 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
1097 return KeInsertQueueDpc(
1098 &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->DpcObject
,
1099 (PVOID
)CallbackRoutine
,
1108 VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject
)
1110 DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
1119 VideoPortGetVersion(
1120 IN PVOID HwDeviceExtension
,
1121 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
1123 RTL_OSVERSIONINFOEXW Version
;
1125 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
1126 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
1129 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
1131 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
1132 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
1133 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1134 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1135 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1138 return ERROR_INVALID_PARAMETER
;
1140 VpOsVersionInfo
->MajorVersion
= 5;
1141 VpOsVersionInfo
->MinorVersion
= 0;
1142 VpOsVersionInfo
->BuildNumber
= 2195;
1143 VpOsVersionInfo
->ServicePackMajor
= 4;
1144 VpOsVersionInfo
->ServicePackMinor
= 0;
1149 return ERROR_INVALID_PARAMETER
;
1157 VideoPortCheckForDeviceExistence(
1158 IN PVOID HwDeviceExtension
,
1161 IN UCHAR RevisionId
,
1162 IN USHORT SubVendorId
,
1163 IN USHORT SubSystemId
,
1166 DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
1175 VideoPortRegisterBugcheckCallback(
1176 IN PVOID HwDeviceExtension
,
1177 IN ULONG BugcheckCode
,
1179 IN ULONG BugcheckDataSize
)
1181 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1190 VideoPortQueryPerformanceCounter(
1191 IN PVOID HwDeviceExtension
,
1192 OUT PLONGLONG PerformanceFrequency OPTIONAL
)
1194 LARGE_INTEGER Result
;
1196 DPRINT("VideoPortQueryPerformanceCounter\n");
1197 Result
= KeQueryPerformanceCounter((PLARGE_INTEGER
)PerformanceFrequency
);
1198 return Result
.QuadPart
;
1206 VideoPortAcquireDeviceLock(
1207 IN PVOID HwDeviceExtension
)
1209 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1213 DPRINT("VideoPortAcquireDeviceLock\n");
1214 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1215 Status
= KeWaitForMutexObject(&DeviceExtension
->DeviceLock
, Executive
,
1216 KernelMode
, FALSE
, NULL
);
1217 ASSERT(Status
== STATUS_SUCCESS
);
1225 VideoPortReleaseDeviceLock(
1226 IN PVOID HwDeviceExtension
)
1228 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1232 DPRINT("VideoPortReleaseDeviceLock\n");
1233 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
1234 Status
= KeReleaseMutex(&DeviceExtension
->DeviceLock
, FALSE
);
1235 ASSERT(Status
== 0);