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.
21 * $Id: videoprt.c,v 1.28 2004/11/24 11:12:19 ekohl Exp $
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(FunctionName
, (char*)(BaseAddress
+ *NamePtr
),
108 strlen(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_NOT_FOUND
|| Status
== STATUS_UNSUCCESSFUL
)
165 IntVideoPortFindAdapter(
166 IN PDRIVER_OBJECT DriverObject
,
167 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
,
168 IN PDEVICE_OBJECT PhysicalDeviceObject
)
170 WCHAR DeviceVideoBuffer
[20];
171 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
175 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
176 SYSTEM_BASIC_INFORMATION SystemBasicInfo
;
178 WCHAR DeviceBuffer
[20];
179 UNICODE_STRING DeviceName
;
180 WCHAR SymlinkBuffer
[20];
181 UNICODE_STRING SymlinkName
;
182 PDEVICE_OBJECT DeviceObject
;
183 BOOL LegacyDetection
= FALSE
;
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, we need it even for calling HwFindAdapter :(
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
->PhysicalDeviceObject
= PhysicalDeviceObject
;
235 DeviceExtension
->FunctionalDeviceObject
= DeviceObject
;
236 DeviceExtension
->DriverExtension
= DriverExtension
;
238 DeviceExtension
->RegistryPath
.Length
=
239 DeviceExtension
->RegistryPath
.MaximumLength
=
240 DriverExtension
->RegistryPath
.Length
+ (9 * sizeof(WCHAR
));
241 DeviceExtension
->RegistryPath
.Length
-= sizeof(WCHAR
);
242 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(
244 DeviceExtension
->RegistryPath
.MaximumLength
,
246 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
247 DriverExtension
->RegistryPath
.Buffer
);
249 if (PhysicalDeviceObject
== NULL
)
251 LegacyDetection
= TRUE
;
255 /* Get bus number from the upper level bus driver. */
256 Size
= sizeof(ULONG
);
257 Status
= IoGetDeviceProperty(
258 PhysicalDeviceObject
,
259 DevicePropertyBusNumber
,
261 &DeviceExtension
->SystemIoBusNumber
,
263 if (!NT_SUCCESS(Status
))
265 DPRINT("Couldn't get an information from bus driver. We will try to\n"
266 "use legacy detection method, but even that doesn't mean that\n"
268 DeviceExtension
->PhysicalDeviceObject
= NULL
;
269 LegacyDetection
= TRUE
;
273 DeviceExtension
->AdapterInterfaceType
=
274 DriverExtension
->InitializationData
.AdapterInterfaceType
;
276 if (PhysicalDeviceObject
!= NULL
)
278 /* Get bus type from the upper level bus driver. */
279 Size
= sizeof(ULONG
);
281 PhysicalDeviceObject
,
282 DevicePropertyLegacyBusType
,
284 &DeviceExtension
->AdapterInterfaceType
,
287 /* Get bus device address from the upper level bus driver. */
288 Size
= sizeof(ULONG
);
290 PhysicalDeviceObject
,
291 DevicePropertyAddress
,
293 &DeviceExtension
->SystemIoSlotNumber
,
297 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
299 &DeviceExtension
->DpcObject
,
300 IntVideoPortDeferredRoutine
,
304 * Uff, the DeviceExtension is setup. Now it's needed to setup
305 * a ConfigInfo structure that we will pass to HwFindAdapter.
308 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
309 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
310 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
311 if (ConfigInfo
.AdapterInterfaceType
== PCIBus
)
312 ConfigInfo
.InterruptMode
= LevelSensitive
;
314 ConfigInfo
.InterruptMode
= Latched
;
315 ConfigInfo
.DriverRegistryPath
= DriverExtension
->RegistryPath
.Buffer
;
316 ConfigInfo
.VideoPortGetProcAddress
= IntVideoPortGetProcAddress
;
317 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
319 Size
= sizeof(SystemBasicInfo
);
320 Status
= ZwQuerySystemInformation(
321 SystemBasicInformation
,
326 if (NT_SUCCESS(Status
))
328 ConfigInfo
.SystemMemorySize
=
329 SystemBasicInfo
.NumberOfPhysicalPages
*
330 SystemBasicInfo
.PhysicalPageSize
;
334 * Call miniport HwVidFindAdapter entry point to detect if
335 * particular device is present. There are two possible code
336 * paths. The first one is for Legacy drivers (NT4) and cases
337 * when we don't have information about what bus we're on. The
338 * second case is the standard one for Plug & Play drivers.
343 ULONG BusNumber
, MaxBuses
;
345 MaxBuses
= DeviceExtension
->AdapterInterfaceType
== PCIBus
? 8 : 1;
347 for (BusNumber
= 0; BusNumber
< MaxBuses
; BusNumber
++)
349 DeviceExtension
->SystemIoBusNumber
=
350 ConfigInfo
.SystemIoBusNumber
= BusNumber
;
352 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
353 DriverExtension
->InitializationData
.HwDeviceExtensionSize
);
355 /* FIXME: Need to figure out what string to pass as param 3. */
356 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
357 &DeviceExtension
->MiniPortDeviceExtension
,
358 DriverExtension
->HwContext
,
363 if (Status
== ERROR_DEV_NOT_EXIST
)
367 else if (Status
== NO_ERROR
)
373 DPRINT("HwFindAdapter call failed with error %X\n", Status
);
374 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
375 IoDeleteDevice(DeviceObject
);
383 /* FIXME: Need to figure out what string to pass as param 3. */
384 Status
= DriverExtension
->InitializationData
.HwFindAdapter(
385 &DeviceExtension
->MiniPortDeviceExtension
,
386 DriverExtension
->HwContext
,
392 if (Status
!= NO_ERROR
)
394 DPRINT("HwFindAdapter call failed with error %X\n", Status
);
395 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
396 IoDeleteDevice(DeviceObject
);
401 * Now we know the device is present, so let's do all additional tasks
402 * such as creating symlinks or setting up interrupts and timer.
405 /* Create symbolic link "\??\DISPLAYx" */
406 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DeviceNumber
+ 1);
407 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
408 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
410 /* Add entry to DEVICEMAP\VIDEO key in registry. */
411 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DeviceNumber
);
412 RtlWriteRegistryValue(
413 RTL_REGISTRY_DEVICEMAP
,
417 DeviceExtension
->RegistryPath
.Buffer
,
418 DeviceExtension
->RegistryPath
.MaximumLength
);
420 /* FIXME: Allocate hardware resources for device. */
423 * Allocate interrupt for device.
426 if (!IntVideoPortSetupInterrupt(DeviceObject
, DriverExtension
, &ConfigInfo
))
428 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
429 IoDeleteDevice(DeviceObject
);
430 return STATUS_INSUFFICIENT_RESOURCES
;
434 * Allocate timer for device.
437 if (!IntVideoPortSetupTimer(DeviceObject
, DriverExtension
))
439 if (DeviceExtension
->InterruptObject
!= NULL
)
440 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
441 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
442 IoDeleteDevice(DeviceObject
);
443 DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
444 return STATUS_INSUFFICIENT_RESOURCES
;
447 if (PhysicalDeviceObject
!= NULL
)
448 IoAttachDeviceToDeviceStack(DeviceObject
, PhysicalDeviceObject
);
450 DPRINT("STATUS_SUCCESS\n");
451 return STATUS_SUCCESS
;
455 IntAttachToCSRSS(PEPROCESS
*CallingProcess
, PEPROCESS
*PrevAttachedProcess
)
457 *CallingProcess
= PsGetCurrentProcess();
458 if (*CallingProcess
!= Csrss
)
460 if (PsGetCurrentThread()->ThreadsProcess
!= *CallingProcess
)
462 *PrevAttachedProcess
= *CallingProcess
;
467 *PrevAttachedProcess
= NULL
;
469 KeAttachProcess(Csrss
);
474 IntDetachFromCSRSS(PEPROCESS
*CallingProcess
, PEPROCESS
*PrevAttachedProcess
)
476 if (*CallingProcess
!= Csrss
)
479 if (NULL
!= *PrevAttachedProcess
)
481 KeAttachProcess(*PrevAttachedProcess
);
486 /* PUBLIC FUNCTIONS ***********************************************************/
496 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
499 PDRIVER_OBJECT DriverObject
= Context1
;
500 PUNICODE_STRING RegistryPath
= Context2
;
502 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
503 BOOL LegacyDetection
= FALSE
;
505 DPRINT("VideoPortInitialize\n");
509 * The driver extension can be already allocated in case that we were
510 * called by legacy driver and failed detecting device. Some miniport
511 * drivers in that case adjust parameters and calls VideoPortInitialize
515 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
516 if (DriverExtension
== NULL
)
518 Status
= IoAllocateDriverObjectExtension(
521 sizeof(VIDEO_PORT_DRIVER_EXTENSION
),
522 (PVOID
*)&DriverExtension
);
524 if (!NT_SUCCESS(Status
))
531 * Copy the correct miniport initializtation data to the device extension.
535 &DriverExtension
->InitializationData
,
536 HwInitializationData
,
537 min(sizeof(VIDEO_HW_INITIALIZATION_DATA
),
538 HwInitializationData
->HwInitDataSize
));
539 DriverExtension
->HwContext
= HwContext
;
541 RtlCopyMemory(&DriverExtension
->RegistryPath
, RegistryPath
, sizeof(UNICODE_STRING
));
543 switch (HwInitializationData
->HwInitDataSize
)
546 * NT4 drivers are special case, because we must use legacy method
547 * of detection instead of the Plug & Play one.
550 case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA
:
551 DPRINT("We were loaded by a Windows NT miniport driver.\n");
552 LegacyDetection
= TRUE
;
555 case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA
:
556 DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
559 case sizeof(VIDEO_HW_INITIALIZATION_DATA
):
560 DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
564 DPRINT("Invalid HwInitializationData size.\n");
565 return STATUS_UNSUCCESSFUL
;
568 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = IntVideoPortDispatchOpen
;
569 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = IntVideoPortDispatchClose
;
570 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = IntVideoPortDispatchDeviceControl
;
571 DriverObject
->DriverUnload
= IntVideoPortUnload
;
574 * Plug & Play drivers registers the device in AddDevice routine. For
575 * legacy drivers we must do it now.
580 Status
= IntVideoPortFindAdapter(DriverObject
, DriverExtension
, NULL
);
581 DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status
);
586 DriverObject
->DriverExtension
->AddDevice
= IntVideoPortAddDevice
;
587 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = IntVideoPortDispatchPnp
;
588 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = IntVideoPortDispatchPower
;
590 return STATUS_SUCCESS
;
600 IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
601 IN PCHAR DebugMessage
, ...)
606 va_start(ap
, DebugMessage
);
607 vsprintf(Buffer
, DebugMessage
, ap
);
619 IN PVOID HwDeviceExtension
,
620 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
621 IN VP_STATUS ErrorCode
,
624 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
625 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
628 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
637 VideoPortGetCurrentIrql(VOID
)
639 return KeGetCurrentIrql();
642 typedef struct QueryRegistryCallbackContext
644 PVOID HwDeviceExtension
;
646 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
647 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
649 static NTSTATUS STDCALL
650 QueryRegistryCallback(
654 IN ULONG ValueLength
,
656 IN PVOID EntryContext
)
658 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
660 DPRINT("Found registry value for name %S: type %d, length %d\n",
661 ValueName
, ValueType
, ValueLength
);
662 return (*(CallbackContext
->HwGetRegistryRoutine
))(
663 CallbackContext
->HwDeviceExtension
,
664 CallbackContext
->HwContext
,
675 VideoPortGetRegistryParameters(
676 IN PVOID HwDeviceExtension
,
677 IN PWSTR ParameterName
,
678 IN UCHAR IsParameterFileName
,
679 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
682 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
683 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
684 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
686 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
688 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
690 if (IsParameterFileName
)
695 Context
.HwDeviceExtension
= HwDeviceExtension
;
696 Context
.HwContext
= HwContext
;
697 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
699 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
700 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
701 QueryTable
[0].Name
= ParameterName
;
702 QueryTable
[0].EntryContext
= NULL
;
703 QueryTable
[0].DefaultType
= REG_NONE
;
704 QueryTable
[0].DefaultData
= NULL
;
705 QueryTable
[0].DefaultLength
= 0;
707 QueryTable
[1].QueryRoutine
= NULL
;
708 QueryTable
[1].Name
= NULL
;
710 return NT_SUCCESS(RtlQueryRegistryValues(
711 RTL_REGISTRY_ABSOLUTE
,
712 DeviceExtension
->RegistryPath
.Buffer
,
715 NULL
)) ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
723 VideoPortSetRegistryParameters(
724 IN PVOID HwDeviceExtension
,
727 IN ULONG ValueLength
)
729 DPRINT("VideoPortSetRegistryParameters\n");
730 ASSERT_IRQL(PASSIVE_LEVEL
);
731 return RtlWriteRegistryValue(
732 RTL_REGISTRY_ABSOLUTE
,
733 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->RegistryPath
.Buffer
,
745 VideoPortGetVgaStatus(
746 IN PVOID HwDeviceExtension
,
747 OUT PULONG VgaStatus
)
749 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
751 DPRINT("VideoPortGetVgaStatus\n");
753 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
754 if (KeGetCurrentIrql() == PASSIVE_LEVEL
)
756 if (DeviceExtension
->AdapterInterfaceType
== PCIBus
)
758 /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
759 /* Assumed for now */
765 return ERROR_INVALID_FUNCTION
;
773 VideoPortGetRomImage(
774 IN PVOID HwDeviceExtension
,
779 static PVOID RomImageBuffer
= NULL
;
780 PEPROCESS CallingProcess
;
781 PEPROCESS PrevAttachedProcess
;
783 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
784 HwDeviceExtension
, Length
);
786 /* If the length is zero then free the existing buffer. */
789 if (RomImageBuffer
!= NULL
)
791 ExFreePool(RomImageBuffer
);
792 RomImageBuffer
= NULL
;
799 * The DDK says we shouldn't use the legacy C0000 method but get the
800 * rom base address from the corresponding pci or acpi register but
801 * lets ignore that and use C0000 anyway. We have already mapped the
802 * bios area into memory so we'll copy from there.
806 Length
= min(Length
, 0x10000);
807 if (RomImageBuffer
!= NULL
)
809 ExFreePool(RomImageBuffer
);
812 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
813 if (RomImageBuffer
== NULL
)
818 IntAttachToCSRSS(&CallingProcess
, &PrevAttachedProcess
);
819 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
820 IntDetachFromCSRSS(&CallingProcess
, &PrevAttachedProcess
);
822 return RomImageBuffer
;
832 IN PVOID HwDeviceExtension
,
839 PUCHAR SearchLocation
;
841 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
843 StringLength
= strlen(String
);
845 SearchLocation
= RomBase
;
846 for (SearchLocation
= RomBase
;
847 !Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
850 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
853 DPRINT("Match found at %p\n", SearchLocation
);
865 VideoPortSynchronizeExecution(
866 IN PVOID HwDeviceExtension
,
867 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
868 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
872 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
878 Ret
= (*SynchronizeRoutine
)(Context
);
881 case VpMediumPriority
:
882 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
883 if (DeviceExtension
->InterruptObject
== NULL
)
884 Ret
= (*SynchronizeRoutine
)(Context
);
886 Ret
= KeSynchronizeExecution(
887 DeviceExtension
->InterruptObject
,
893 OldIrql
= KeGetCurrentIrql();
894 if (OldIrql
< SYNCH_LEVEL
)
895 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
897 Ret
= (*SynchronizeRoutine
)(Context
);
899 if (OldIrql
< SYNCH_LEVEL
)
900 KfLowerIrql(OldIrql
);
915 VideoPortDDCMonitorHelper(
916 PVOID HwDeviceExtension
,
917 /*PI2C_FNC_TABLE*/PVOID I2CFunctions
,
922 DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
931 VideoPortEnumerateChildren(
932 IN PVOID HwDeviceExtension
,
935 DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
944 VideoPortCreateSecondaryDisplay(
945 IN PVOID HwDeviceExtension
,
946 IN OUT PVOID
*SecondaryDeviceExtension
,
949 DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
959 IN PVOID HwDeviceExtension
,
960 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
963 return KeInsertQueueDpc(
964 &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
)->DpcObject
,
965 (PVOID
)CallbackRoutine
,
974 VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject
)
976 DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
986 IN PVOID HwDeviceExtension
,
987 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
989 RTL_OSVERSIONINFOEXW Version
;
991 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
992 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
995 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
997 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
998 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
999 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1000 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1001 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1004 return ERROR_INVALID_PARAMETER
;
1006 VpOsVersionInfo
->MajorVersion
= 5;
1007 VpOsVersionInfo
->MinorVersion
= 0;
1008 VpOsVersionInfo
->BuildNumber
= 2195;
1009 VpOsVersionInfo
->ServicePackMajor
= 4;
1010 VpOsVersionInfo
->ServicePackMinor
= 0;
1015 return ERROR_INVALID_PARAMETER
;
1023 VideoPortCheckForDeviceExistence(
1024 IN PVOID HwDeviceExtension
,
1027 IN UCHAR RevisionId
,
1028 IN USHORT SubVendorId
,
1029 IN USHORT SubSystemId
,
1032 DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
1041 VideoPortRegisterBugcheckCallback(
1042 IN PVOID HwDeviceExtension
,
1043 IN ULONG BugcheckCode
,
1045 IN ULONG BugcheckDataSize
)
1047 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1056 VideoPortQueryPerformanceCounter(
1057 IN PVOID HwDeviceExtension
,
1058 OUT PLONGLONG PerformanceFrequency OPTIONAL
)
1060 LARGE_INTEGER Result
;
1062 DPRINT("VideoPortQueryPerformanceCounter\n");
1063 Result
= KeQueryPerformanceCounter((PLARGE_INTEGER
)PerformanceFrequency
);
1064 return Result
.QuadPart
;