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.14 2004/03/08 20:27:33 dwelch Exp $
26 BOOLEAN CsrssInitialized
= FALSE
;
27 PEPROCESS Csrss
= NULL
;
28 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
29 static PVOID RomImageBuffer
= NULL
;
32 VideoPortDeferredRoutine(
34 IN PVOID DeferredContext
,
35 IN PVOID SystemArgument1
,
36 IN PVOID SystemArgument2
39 VideoPortGetProcAddress(IN PVOID HwDeviceExtension
,
40 IN PUCHAR FunctionName
);
42 // ------------------------------------------------------- Public Interface
47 // This function initializes the driver.
53 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
55 // IN PUNICODE_STRING RegistryPath Name of registry driver service
62 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
63 IN PUNICODE_STRING RegistryPath
)
65 DPRINT("DriverEntry()\n");
66 return(STATUS_SUCCESS
);
73 VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel
,
74 IN PCHAR DebugMessage
, ...)
80 if (DebugPrintLevel > InternalDebugLevel)
83 va_start (ap
, DebugMessage
);
84 vsprintf (Buffer
, DebugMessage
, ap
);
96 VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension
,
97 IN PVOID MappedAddress
)
99 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
101 DPRINT("VideoPortFreeDeviceBase\n");
103 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
104 VIDEO_PORT_DEVICE_EXTENSION
,
105 MiniPortDeviceExtension
);
107 InternalUnmapMemory(DeviceExtension
, MappedAddress
);
116 VideoPortGetBusData(IN PVOID HwDeviceExtension
,
117 IN BUS_DATA_TYPE BusDataType
,
123 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
125 DPRINT("VideoPortGetBusData\n");
127 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
128 VIDEO_PORT_DEVICE_EXTENSION
,
129 MiniPortDeviceExtension
);
131 return HalGetBusDataByOffset(BusDataType
,
132 DeviceExtension
->SystemIoBusNumber
,
145 VideoPortGetCurrentIrql(VOID
)
147 return KeGetCurrentIrql();
156 VideoPortGetDeviceBase(IN PVOID HwDeviceExtension
,
157 IN PHYSICAL_ADDRESS IoAddress
,
158 IN ULONG NumberOfUchars
,
161 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
163 DPRINT("VideoPortGetDeviceBase\n");
165 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
166 VIDEO_PORT_DEVICE_EXTENSION
,
167 MiniPortDeviceExtension
);
169 return InternalMapMemory(DeviceExtension
, IoAddress
, NumberOfUchars
, InIoSpace
, NULL
);
178 VideoPortGetDeviceData(IN PVOID HwDeviceExtension
,
179 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
180 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
183 DPRINT("VideoPortGetDeviceData\n");
185 return STATUS_NOT_IMPLEMENTED
;
194 VideoPortGetAccessRanges(IN PVOID HwDeviceExtension
,
195 IN ULONG NumRequestedResources
,
196 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
197 IN ULONG NumAccessRanges
,
198 IN PVIDEO_ACCESS_RANGE AccessRanges
,
203 PCI_SLOT_NUMBER PciSlotNumber
;
204 ULONG FunctionNumber
;
205 PCI_COMMON_CONFIG Config
;
206 PCM_RESOURCE_LIST AllocatedResources
;
209 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
210 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
211 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
212 USHORT VendorIdToFind
;
213 USHORT DeviceIdToFind
;
215 DPRINT("VideoPortGetAccessRanges\n");
217 if (VendorId
!= NULL
)
219 VendorIdToFind
= *(PUSHORT
)VendorId
;
225 if (DeviceId
!= NULL
)
227 DeviceIdToFind
= *(PUSHORT
)DeviceId
;
234 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
235 VIDEO_PORT_DEVICE_EXTENSION
,
236 MiniPortDeviceExtension
);
238 if (0 == NumRequestedResources
&&
239 PCIBus
== DeviceExtension
->AdapterInterfaceType
)
241 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n",
242 VendorIdToFind
, DeviceIdToFind
);
244 PciSlotNumber
.u
.AsULONG
= *Slot
;
247 Search for the device id and vendor id on this bus.
249 for (FunctionNumber
= 0; FunctionNumber
< 8; FunctionNumber
++)
251 ULONG ReturnedLength
;
252 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
253 ReturnedLength
= HalGetBusData(PCIConfiguration
,
254 DeviceExtension
->SystemIoBusNumber
,
255 PciSlotNumber
.u
.AsULONG
,
257 sizeof(PCI_COMMON_CONFIG
));
258 if (sizeof(PCI_COMMON_CONFIG
) == ReturnedLength
)
260 if (DeviceId
!= NULL
&& VendorId
!= NULL
)
262 DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
264 PciSlotNumber
.u
.AsULONG
,
265 PciSlotNumber
.u
.bits
.DeviceNumber
,
266 PciSlotNumber
.u
.bits
.FunctionNumber
, Config
.VendorID
,
270 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
271 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
277 if (FunctionNumber
== 8)
279 DPRINT("Didn't find device.\n");
280 return STATUS_UNSUCCESSFUL
;
283 Status
= HalAssignSlotResources(NULL
, NULL
, NULL
, NULL
,
284 DeviceExtension
->AdapterInterfaceType
,
285 DeviceExtension
->SystemIoBusNumber
,
286 PciSlotNumber
.u
.AsULONG
,
287 &AllocatedResources
);
288 if (! NT_SUCCESS(Status
))
293 for (FullList
= AllocatedResources
->List
;
294 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
297 assert(FullList
->InterfaceType
== PCIBus
&&
298 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
299 1 == FullList
->PartialResourceList
.Version
&&
300 1 == FullList
->PartialResourceList
.Revision
);
301 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
302 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
305 if ((CmResourceTypeMemory
== Descriptor
->Type
306 || CmResourceTypePort
== Descriptor
->Type
)
307 && NumAccessRanges
<= AssignedCount
)
309 DPRINT1("Too many access ranges found\n");
310 ExFreePool(AllocatedResources
);
311 return STATUS_UNSUCCESSFUL
;
313 if (CmResourceTypeMemory
== Descriptor
->Type
)
315 if (NumAccessRanges
<= AssignedCount
)
317 DPRINT1("Too many access ranges found\n");
318 ExFreePool(AllocatedResources
);
319 return STATUS_UNSUCCESSFUL
;
321 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
322 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
323 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
324 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
325 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
326 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
327 AccessRanges
[AssignedCount
].RangeShareable
=
328 (CmResourceShareShared
== Descriptor
->ShareDisposition
);
331 else if (CmResourceTypePort
== Descriptor
->Type
)
333 DPRINT("Port range starting at 0x%04x length %d\n",
334 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
335 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
336 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
337 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
338 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
339 AccessRanges
[AssignedCount
].RangeShareable
= 0;
342 else if (CmResourceTypeInterrupt
== Descriptor
->Type
)
344 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
345 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
349 ExFreePool(AllocatedResources
);
356 return STATUS_SUCCESS
;
359 typedef struct QueryRegistryCallbackContext
361 PVOID HwDeviceExtension
;
363 PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine
;
364 } QUERY_REGISTRY_CALLBACK_CONTEXT
, *PQUERY_REGISTRY_CALLBACK_CONTEXT
;
366 static NTSTATUS STDCALL
367 QueryRegistryCallback(IN PWSTR ValueName
,
370 IN ULONG ValueLength
,
372 IN PVOID EntryContext
)
374 PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext
= (PQUERY_REGISTRY_CALLBACK_CONTEXT
) Context
;
376 DPRINT("Found registry value for name %S: type %d, length %d\n",
377 ValueName
, ValueType
, ValueLength
);
378 return (*(CallbackContext
->HwGetRegistryRoutine
))(CallbackContext
->HwDeviceExtension
,
379 CallbackContext
->HwContext
,
390 VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension
,
391 IN PWSTR ParameterName
,
392 IN UCHAR IsParameterFileName
,
393 IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine
,
396 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
397 QUERY_REGISTRY_CALLBACK_CONTEXT Context
;
398 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
400 DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName
);
402 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
403 VIDEO_PORT_DEVICE_EXTENSION
,
404 MiniPortDeviceExtension
);
406 if (IsParameterFileName
)
411 Context
.HwDeviceExtension
= HwDeviceExtension
;
412 Context
.HwContext
= HwContext
;
413 Context
.HwGetRegistryRoutine
= GetRegistryRoutine
;
415 QueryTable
[0].QueryRoutine
= QueryRegistryCallback
;
416 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
;
417 QueryTable
[0].Name
= ParameterName
;
418 QueryTable
[0].EntryContext
= NULL
;
419 QueryTable
[0].DefaultType
= REG_NONE
;
420 QueryTable
[0].DefaultData
= NULL
;
421 QueryTable
[0].DefaultLength
= 0;
423 QueryTable
[1].QueryRoutine
= NULL
;
424 QueryTable
[1].Name
= NULL
;
426 return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
427 DeviceExtension
->RegistryPath
.Buffer
,
428 QueryTable
, &Context
, NULL
))
429 ? ERROR_SUCCESS
: ERROR_INVALID_PARAMETER
;
438 VideoPortGetVgaStatus(IN PVOID HwDeviceExtension
,
439 OUT PULONG VgaStatus
)
441 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
443 DPRINT1("VideoPortGetVgaStatus = %S \n", VgaStatus
);
445 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
446 VIDEO_PORT_DEVICE_EXTENSION
,
447 MiniPortDeviceExtension
);
449 if(KeGetCurrentIrql() == PASSIVE_LEVEL
)
451 DPRINT1("VideoPortGetVgaStatus1 = %S \n", VgaStatus
);
453 if ( PCIBus
== DeviceExtension
->AdapterInterfaceType
)
456 VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
458 DPRINT1("VideoPortGetVgaStatus2 = %S \n", VgaStatus
);
460 /* Assumed for now */
462 VgaStatus
= (PULONG
) 1;
464 return STATUS_SUCCESS
;
467 DPRINT1("VideoPortGetVgaStatus3 = %S \n", VgaStatus
);
469 return ERROR_INVALID_FUNCTION
;
473 VPInterruptRoutine(IN
struct _KINTERRUPT
*Interrupt
,
474 IN PVOID ServiceContext
)
476 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
478 DeviceExtension
= ServiceContext
;
479 assert(NULL
!= DeviceExtension
->HwInterrupt
);
481 return DeviceExtension
->HwInterrupt(&DeviceExtension
->MiniPortDeviceExtension
);
485 VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject
,
488 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
490 DeviceExtension
= Context
;
491 assert(DeviceExtension
== DeviceObject
->DeviceExtension
492 && NULL
!= DeviceExtension
->HwTimer
);
494 DeviceExtension
->HwTimer(&DeviceExtension
->MiniPortDeviceExtension
);
501 VideoPortInitialize(IN PVOID Context1
,
503 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData
,
506 PUNICODE_STRING RegistryPath
;
508 WCHAR DeviceBuffer
[20];
509 WCHAR SymlinkBuffer
[20];
510 WCHAR DeviceVideoBuffer
[20];
512 PDRIVER_OBJECT MPDriverObject
= (PDRIVER_OBJECT
) Context1
;
513 PDEVICE_OBJECT MPDeviceObject
;
514 VIDEO_PORT_CONFIG_INFO ConfigInfo
;
515 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
517 UNICODE_STRING DeviceName
;
518 UNICODE_STRING SymlinkName
;
523 ULONG InterruptVector
;
524 OBJECT_ATTRIBUTES Obj
;
527 DPRINT("VideoPortInitialize\n");
529 RegistryPath
= (PUNICODE_STRING
) Context2
;
531 /* Build Dispatch table from passed data */
532 MPDriverObject
->DriverStartIo
= (PDRIVER_STARTIO
) HwInitializationData
->HwStartIO
;
534 /* Find the first free device number */
535 for (DisplayNumber
= 0;;)
537 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
538 RtlInitUnicodeString(&SymlinkName
, SymlinkBuffer
);
539 InitializeObjectAttributes(&Obj
, &SymlinkName
, 0, NULL
, NULL
);
540 Status
= ZwOpenSymbolicLinkObject(&ObjHandle
, GENERIC_READ
, &Obj
);
541 if (NT_SUCCESS(Status
))
547 else if (Status
== STATUS_NOT_FOUND
|| Status
== STATUS_UNSUCCESSFUL
)
557 DPRINT("- DisplayNumber: %d\n", DisplayNumber
);
563 /* Create a unicode device name. */
564 swprintf(DeviceBuffer
, L
"\\Device\\Video%lu", DisplayNumber
);
565 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
567 /* Create the device. */
568 Status
= IoCreateDevice(
570 HwInitializationData
->HwDeviceExtensionSize
+
571 sizeof(VIDEO_PORT_DEVICE_EXTENSION
),
577 if (!NT_SUCCESS(Status
))
579 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
583 MPDriverObject
->DeviceObject
= MPDeviceObject
;
585 /* Initialize the miniport drivers dispatch table */
586 MPDriverObject
->MajorFunction
[IRP_MJ_CREATE
] = VidDispatchOpen
;
587 MPDriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = VidDispatchClose
;
588 MPDriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = VidDispatchDeviceControl
;
590 /* Initialize our device extension */
592 (PVIDEO_PORT_DEVICE_EXTENSION
) MPDeviceObject
->DeviceExtension
;
593 DeviceExtension
->DeviceObject
= MPDeviceObject
;
594 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
595 DeviceExtension
->HwResetHw
= HwInitializationData
->HwResetHw
;
596 DeviceExtension
->AdapterInterfaceType
= HwInitializationData
->AdapterInterfaceType
;
597 DeviceExtension
->SystemIoBusNumber
= 0;
598 KeInitializeDpc(&DeviceExtension
->DpcObject
, VideoPortDeferredRoutine
,
599 (PVOID
)DeviceExtension
);
600 MaxLen
= (wcslen(RegistryPath
->Buffer
) + 10) * sizeof(WCHAR
);
601 DeviceExtension
->RegistryPath
.MaximumLength
= MaxLen
;
602 DeviceExtension
->RegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
605 swprintf(DeviceExtension
->RegistryPath
.Buffer
, L
"%s\\Device0",
606 RegistryPath
->Buffer
);
607 DeviceExtension
->RegistryPath
.Length
= wcslen(DeviceExtension
->RegistryPath
.Buffer
) *
610 MaxBus
= (DeviceExtension
->AdapterInterfaceType
== PCIBus
) ? 8 : 1;
611 DPRINT("MaxBus: %lu\n", MaxBus
);
612 InitializeListHead(&DeviceExtension
->AddressMappingListHead
);
614 /* Set the buffering strategy here... */
615 /* If you change this, remember to change VidDispatchDeviceControl too */
616 MPDeviceObject
->Flags
|= DO_BUFFERED_IO
;
620 RtlZeroMemory(&DeviceExtension
->MiniPortDeviceExtension
,
621 HwInitializationData
->HwDeviceExtensionSize
);
622 DPRINT("Searching on bus %d\n", DeviceExtension
->SystemIoBusNumber
);
623 /* Setup configuration info */
624 RtlZeroMemory(&ConfigInfo
, sizeof(VIDEO_PORT_CONFIG_INFO
));
625 ConfigInfo
.Length
= sizeof(VIDEO_PORT_CONFIG_INFO
);
626 ConfigInfo
.AdapterInterfaceType
= DeviceExtension
->AdapterInterfaceType
;
627 ConfigInfo
.SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
628 ConfigInfo
.InterruptMode
= (PCIBus
== DeviceExtension
->AdapterInterfaceType
) ?
629 LevelSensitive
: Latched
;
630 ConfigInfo
.DriverRegistryPath
= RegistryPath
->Buffer
;
631 ConfigInfo
.VideoPortGetProcAddress
= VideoPortGetProcAddress
;
633 /* Call HwFindAdapter entry point */
634 /* FIXME: Need to figure out what string to pass as param 3 */
635 DPRINT("FindAdapter %X\n", HwInitializationData
->HwFindAdapter
);
636 Status
= HwInitializationData
->HwFindAdapter(&DeviceExtension
->MiniPortDeviceExtension
,
641 if (NO_ERROR
!= Status
)
643 DPRINT("HwFindAdapter call failed with error %X\n", Status
);
644 DeviceExtension
->SystemIoBusNumber
++;
647 while (NO_ERROR
!= Status
&& DeviceExtension
->SystemIoBusNumber
< MaxBus
);
649 if (NO_ERROR
!= Status
)
651 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
652 IoDeleteDevice(MPDeviceObject
);
656 DPRINT("Found adapter\n");
658 /* create symbolic link "\??\DISPLAYx" */
659 swprintf(SymlinkBuffer
, L
"\\??\\DISPLAY%lu", DisplayNumber
+ 1);
660 RtlInitUnicodeString (&SymlinkName
,
662 IoCreateSymbolicLink (&SymlinkName
,
665 /* Add entry to DEVICEMAP\VIDEO key in registry */
666 swprintf(DeviceVideoBuffer
, L
"\\Device\\Video%d", DisplayNumber
);
667 RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP
,
671 DeviceExtension
->RegistryPath
.Buffer
,
672 DeviceExtension
->RegistryPath
.Length
+ sizeof(WCHAR
));
674 /* FIXME: Allocate hardware resources for device */
676 /* Allocate interrupt for device */
677 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
678 if (0 == ConfigInfo
.BusInterruptVector
)
680 ConfigInfo
.BusInterruptVector
= DeviceExtension
->InterruptVector
;
682 if (0 == ConfigInfo
.BusInterruptLevel
)
684 ConfigInfo
.BusInterruptLevel
= DeviceExtension
->InterruptLevel
;
686 if (NULL
!= HwInitializationData
->HwInterrupt
)
689 HalGetInterruptVector(ConfigInfo
.AdapterInterfaceType
,
690 ConfigInfo
.SystemIoBusNumber
,
691 ConfigInfo
.BusInterruptLevel
,
692 ConfigInfo
.BusInterruptVector
,
695 if (0 == InterruptVector
)
697 DPRINT1("HalGetInterruptVector failed\n");
698 IoDeleteDevice(MPDeviceObject
);
700 return STATUS_INSUFFICIENT_RESOURCES
;
702 KeInitializeSpinLock(&DeviceExtension
->InterruptSpinLock
);
703 Status
= IoConnectInterrupt(&DeviceExtension
->InterruptObject
,
706 &DeviceExtension
->InterruptSpinLock
,
710 ConfigInfo
.InterruptMode
,
714 if (!NT_SUCCESS(Status
))
716 DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status
);
717 IoDeleteDevice(MPDeviceObject
);
726 DeviceExtension
->HwTimer
= HwInitializationData
->HwTimer
;
727 if (HwInitializationData
->HwTimer
!= NULL
)
729 DPRINT("Initializing timer\n");
730 Status
= IoInitializeTimer(MPDeviceObject
,
733 if (!NT_SUCCESS(Status
))
735 DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status
);
737 if (HwInitializationData
->HwInterrupt
!= NULL
)
739 IoDisconnectInterrupt(DeviceExtension
->InterruptObject
);
741 IoDeleteDevice(MPDeviceObject
);
747 return STATUS_SUCCESS
;
755 VideoPortLogError(IN PVOID HwDeviceExtension
,
756 IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL
,
757 IN VP_STATUS ErrorCode
,
760 DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
761 ErrorCode
, ErrorCode
, UniqueId
, UniqueId
);
764 DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp
->IoControlCode
, Vrp
->IoControlCode
);
774 VideoPortMapBankedMemory(IN PVOID HwDeviceExtension
,
775 IN PHYSICAL_ADDRESS PhysicalAddress
,
778 OUT PVOID
*VirtualAddress
,
780 IN UCHAR ReadWriteBank
,
781 IN PBANKED_SECTION_ROUTINE BankRoutine
,
784 DPRINT("VideoPortMapBankedMemory\n");
786 return STATUS_NOT_IMPLEMENTED
;
795 VideoPortMapMemory(IN PVOID HwDeviceExtension
,
796 IN PHYSICAL_ADDRESS PhysicalAddress
,
799 OUT PVOID
*VirtualAddress
)
801 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
804 DPRINT("VideoPortMapMemory\n");
806 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
807 VIDEO_PORT_DEVICE_EXTENSION
,
808 MiniPortDeviceExtension
);
809 *VirtualAddress
= InternalMapMemory(DeviceExtension
, PhysicalAddress
,
810 *Length
, *InIoSpace
, &Status
);
821 VideoPortScanRom(IN PVOID HwDeviceExtension
,
828 PUCHAR SearchLocation
;
830 DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase
, RomLength
, String
);
832 StringLength
= strlen(String
);
834 SearchLocation
= RomBase
;
835 for (SearchLocation
= RomBase
;
836 ! Found
&& SearchLocation
< RomBase
+ RomLength
- StringLength
;
839 Found
= (RtlCompareMemory(SearchLocation
, String
, StringLength
) == StringLength
);
842 DPRINT("Match found at %p\n", SearchLocation
);
855 VideoPortSetBusData(IN PVOID HwDeviceExtension
,
856 IN BUS_DATA_TYPE BusDataType
,
862 DPRINT("VideoPortSetBusData\n");
863 return HalSetBusDataByOffset(BusDataType
,
877 VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension
,
880 IN ULONG ValueLength
)
882 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
884 DPRINT("VideoSetRegistryParameters\n");
886 assert_irql(PASSIVE_LEVEL
);
888 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
889 VIDEO_PORT_DEVICE_EXTENSION
,
890 MiniPortDeviceExtension
);
891 return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE
,
892 DeviceExtension
->RegistryPath
.Buffer
,
905 VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension
,
906 IN ULONG NumAccessRanges
,
907 IN PVIDEO_ACCESS_RANGE AccessRange
)
909 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
910 /* Should store the ranges in the device extension for use by ntvdm. */
911 return STATUS_SUCCESS
;
920 VideoPortStartTimer(IN PVOID HwDeviceExtension
)
922 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
924 DPRINT("VideoPortStartTimer\n");
926 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
927 VIDEO_PORT_DEVICE_EXTENSION
,
928 MiniPortDeviceExtension
);
929 IoStartTimer(DeviceExtension
->DeviceObject
);
938 VideoPortStopTimer(IN PVOID HwDeviceExtension
)
940 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
942 DPRINT("VideoPortStopTimer\n");
944 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
945 VIDEO_PORT_DEVICE_EXTENSION
,
946 MiniPortDeviceExtension
);
947 IoStopTimer(DeviceExtension
->DeviceObject
);
956 VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension
,
957 IN VIDEO_SYNCHRONIZE_PRIORITY Priority
,
958 IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine
,
962 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
968 Ret
= (*SynchronizeRoutine
)(Context
);
970 case VpMediumPriority
:
971 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
972 VIDEO_PORT_DEVICE_EXTENSION
,
973 MiniPortDeviceExtension
);
974 if (NULL
== DeviceExtension
->InterruptObject
)
976 Ret
= (*SynchronizeRoutine
)(Context
);
980 Ret
= KeSynchronizeExecution(DeviceExtension
->InterruptObject
,
986 OldIrql
= KeGetCurrentIrql();
987 if (OldIrql
< SYNCH_LEVEL
)
989 OldIrql
= KfRaiseIrql(SYNCH_LEVEL
);
991 Ret
= (*SynchronizeRoutine
)(Context
);
992 if (OldIrql
< SYNCH_LEVEL
)
994 KfLowerIrql(OldIrql
);
1010 VideoPortUnmapMemory(IN PVOID HwDeviceExtension
,
1011 IN PVOID VirtualAddress
,
1012 IN HANDLE ProcessHandle
)
1014 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1016 DPRINT("VideoPortFreeDeviceBase\n");
1018 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1019 VIDEO_PORT_DEVICE_EXTENSION
,
1020 MiniPortDeviceExtension
);
1022 InternalUnmapMemory(DeviceExtension
, VirtualAddress
);
1024 return STATUS_SUCCESS
;
1033 VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension
,
1034 IN ULONG NumAccessRanges
,
1035 IN PVIDEO_ACCESS_RANGE AccessRanges
)
1037 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
1043 * Reset display to blue screen
1045 static BOOLEAN STDCALL
1046 VideoPortResetDisplayParameters(Columns
, Rows
)
1048 if (NULL
== ResetDisplayParametersDeviceExtension
)
1052 if (NULL
== ResetDisplayParametersDeviceExtension
->HwResetHw
)
1056 if (!ResetDisplayParametersDeviceExtension
->HwResetHw(&ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
1062 ResetDisplayParametersDeviceExtension
= NULL
;
1073 VideoPortAllocatePool(
1074 IN PVOID HwDeviceExtension
,
1075 IN VP_POOL_TYPE PoolType
,
1076 IN SIZE_T NumberOfBytes
,
1079 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
1089 IN PVOID HwDeviceExtension
,
1098 // Answer requests for Open calls
1104 // Standard dispatch arguments
1111 VidDispatchOpen(IN PDEVICE_OBJECT pDO
,
1114 PIO_STACK_LOCATION IrpStack
;
1115 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1117 DPRINT("VidDispatchOpen() called\n");
1119 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1121 if (! CsrssInitialized
)
1123 DPRINT("Referencing CSRSS\n");
1124 Csrss
= PsGetCurrentProcess();
1125 DPRINT("Csrss %p\n", Csrss
);
1129 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
) pDO
->DeviceExtension
;
1130 if (DeviceExtension
->HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
1132 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1133 /* Storing the device extension pointer in a static variable is an ugly
1134 * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
1135 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
1136 * parameter. On the bright side, the DISPLAY device is opened
1137 * exclusively, so there can be only one device extension active at
1138 * any point in time. */
1139 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
1140 HalAcquireDisplayOwnership(VideoPortResetDisplayParameters
);
1144 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1148 Irp
->IoStatus
.Information
= FILE_OPENED
;
1149 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1151 return STATUS_SUCCESS
;
1157 // Answer requests for Close calls
1163 // Standard dispatch arguments
1170 VidDispatchClose(IN PDEVICE_OBJECT pDO
,
1173 PIO_STACK_LOCATION IrpStack
;
1175 DPRINT("VidDispatchClose() called\n");
1177 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1179 if (! CsrssInitialized
)
1181 CsrssInitialized
= TRUE
;
1185 HalReleaseDisplayOwnership();
1188 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1189 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1191 return STATUS_SUCCESS
;
1194 // VidDispatchDeviceControl
1197 // Answer requests for device control calls
1203 // Standard dispatch arguments
1210 VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
1213 PIO_STACK_LOCATION IrpStack
;
1214 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1215 PVIDEO_REQUEST_PACKET vrp
;
1217 DPRINT("VidDispatchDeviceControl\n");
1218 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
1219 DeviceExtension
= DeviceObject
->DeviceExtension
;
1221 /* Translate the IRP to a VRP */
1222 vrp
= ExAllocatePool(NonPagedPool
, sizeof(VIDEO_REQUEST_PACKET
));
1225 return STATUS_NO_MEMORY
;
1227 vrp
->StatusBlock
= (PSTATUS_BLOCK
) &(Irp
->IoStatus
);
1228 vrp
->IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1230 DPRINT("- IoControlCode: %x\n", vrp
->IoControlCode
);
1232 /* We're assuming METHOD_BUFFERED */
1233 vrp
->InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1234 vrp
->InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
1235 vrp
->OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
1236 vrp
->OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1238 /* Call the Miniport Driver with the VRP */
1239 ((PDRIVER_STARTIO
)DeviceObject
->DriverObject
->DriverStartIo
)((PVOID
) &DeviceExtension
->MiniPortDeviceExtension
, (PIRP
)vrp
);
1244 DPRINT("- Returned status: %x\n", Irp
->IoStatus
.Status
);
1246 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1248 return STATUS_SUCCESS
;
1252 InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1253 IN PHYSICAL_ADDRESS IoAddress
,
1254 IN ULONG NumberOfUchars
,
1256 OUT NTSTATUS
*Status
)
1258 PHYSICAL_ADDRESS TranslatedAddress
;
1259 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1261 PVOID MappedAddress
;
1264 DPRINT("- IoAddress: %lx\n", IoAddress
.u
.LowPart
);
1265 DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars
);
1266 DPRINT("- InIoSpace: %x\n", InIoSpace
);
1267 if (0 != (InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
))
1269 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
1270 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
1272 if (! IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
1274 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1275 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1277 AddressMapping
= CONTAINING_RECORD(Entry
,
1278 VIDEO_PORT_ADDRESS_MAPPING
,
1280 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
1281 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
1283 AddressMapping
->MappingCount
++;
1286 *Status
= STATUS_SUCCESS
;
1288 return AddressMapping
->MappedAddress
;
1290 Entry
= Entry
->Flink
;
1294 AddressSpace
= (ULONG
)InIoSpace
;
1295 if (HalTranslateBusAddress(DeviceExtension
->AdapterInterfaceType
,
1296 DeviceExtension
->SystemIoBusNumber
,
1299 &TranslatedAddress
) == FALSE
)
1303 *Status
= STATUS_NO_MEMORY
;
1309 if (AddressSpace
!= 0)
1311 assert(0 == TranslatedAddress
.u
.HighPart
);
1314 *Status
= STATUS_SUCCESS
;
1316 return (PVOID
) TranslatedAddress
.u
.LowPart
;
1319 MappedAddress
= MmMapIoSpace(TranslatedAddress
,
1327 *Status
= STATUS_SUCCESS
;
1330 AddressMapping
= ExAllocatePoolWithTag(PagedPool
,
1331 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
1333 if (AddressMapping
== NULL
)
1334 return MappedAddress
;
1336 AddressMapping
->MappedAddress
= MappedAddress
;
1337 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
1338 AddressMapping
->IoAddress
= IoAddress
;
1339 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
1340 AddressMapping
->MappingCount
= 1;
1342 InsertHeadList(&DeviceExtension
->AddressMappingListHead
,
1343 &AddressMapping
->List
);
1345 return MappedAddress
;
1351 *Status
= STATUS_NO_MEMORY
;
1359 InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
1360 IN PVOID MappedAddress
)
1362 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
1365 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
1366 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
1368 AddressMapping
= CONTAINING_RECORD(Entry
,
1369 VIDEO_PORT_ADDRESS_MAPPING
,
1371 if (AddressMapping
->MappedAddress
== MappedAddress
)
1373 assert(0 <= AddressMapping
->MappingCount
);
1374 AddressMapping
->MappingCount
--;
1375 if (0 == AddressMapping
->MappingCount
)
1377 MmUnmapIoSpace(AddressMapping
->MappedAddress
,
1378 AddressMapping
->NumberOfUchars
);
1379 RemoveEntryList(Entry
);
1380 ExFreePool(AddressMapping
);
1386 Entry
= Entry
->Flink
;
1391 VideoPortDDCMonitorHelper(
1392 PVOID HwDeviceExtension
,
1393 /*PI2C_FNC_TABLE*/PVOID I2CFunctions
,
1395 ULONG EdidBufferSize
1398 DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
1407 VideoPortAllocateBuffer(IN PVOID HwDeviceExtension
,
1411 DPRINT("VideoPortAllocateBuffer()\n");
1413 Buffer
= ExAllocatePool(PagedPool
, Size
);
1414 return STATUS_SUCCESS
;
1423 VideoPortReleaseBuffer( IN PVOID HwDeviceExtension
,
1426 DPRINT("VideoPortReleaseBuffer()\n");
1434 VideoPortEnumerateChildren ( IN PVOID HwDeviceExtension
,
1437 DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
1438 return STATUS_SUCCESS
;
1443 VideoPortGetRomImage ( IN PVOID HwDeviceExtension
,
1448 DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
1449 HwDeviceExtension
, Length
);
1451 /* If the length is zero then free the existing buffer. */
1454 if (RomImageBuffer
!= NULL
)
1456 ExFreePool(RomImageBuffer
);
1457 RomImageBuffer
= NULL
;
1463 PEPROCESS CallingProcess
, PrevAttachedProcess
;
1466 The DDK says we shouldn't use the legacy C000 method but get the
1467 rom base address from the corresponding pci or acpi register but
1468 lets ignore that and use C000 anyway. CSRSS has already mapped the
1469 bios area into memory so we'll copy from there.
1471 CallingProcess
= PsGetCurrentProcess();
1472 if (CallingProcess
!= Csrss
)
1474 if (NULL
!= PsGetCurrentThread()->OldProcess
)
1476 PrevAttachedProcess
= CallingProcess
;
1481 PrevAttachedProcess
= NULL
;
1483 KeAttachProcess(Csrss
);
1489 Length
= min(Length
, 0x10000);
1490 if (RomImageBuffer
!= NULL
)
1492 ExFreePool(RomImageBuffer
);
1494 RomImageBuffer
= ExAllocatePool(PagedPool
, Length
);
1495 if (RomImageBuffer
== NULL
)
1499 RtlCopyMemory(RomImageBuffer
, (PUCHAR
)0xC0000, Length
);
1502 Detach from csrss if we attached.
1504 if (CallingProcess
!= Csrss
)
1507 if (NULL
!= PrevAttachedProcess
)
1509 KeAttachProcess(PrevAttachedProcess
);
1513 return(RomImageBuffer
);
1520 VideoPortDeferredRoutine ( IN PKDPC Dpc
,
1521 IN PVOID DeferredContext
,
1522 IN PVOID SystemArgument1
,
1523 IN PVOID SystemArgument2
)
1525 PVOID HwDeviceExtension
=
1526 ((PVIDEO_PORT_DEVICE_EXTENSION
)DeferredContext
)->MiniPortDeviceExtension
;
1527 ((PMINIPORT_DPC_ROUTINE
)SystemArgument1
)(HwDeviceExtension
, SystemArgument2
);
1532 VideoPortQueueDpc ( IN PVOID HwDeviceExtension
,
1533 IN PMINIPORT_DPC_ROUTINE CallbackRoutine
,
1536 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1538 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1539 VIDEO_PORT_DEVICE_EXTENSION
,
1540 MiniPortDeviceExtension
);
1541 return KeInsertQueueDpc(&DeviceExtension
->DpcObject
,
1542 (PVOID
)CallbackRoutine
,
1548 VideoPortGetAssociatedDeviceExtension ( IN PVOID DeviceObject
)
1550 DPRINT1("VideoPortGetAssociatedDeviceExtension(): Unimplemented.\n");
1556 VideoPortAllocateCommonBuffer ( IN PVOID HwDeviceExtension
,
1557 IN PVP_DMA_ADAPTER VpDmaAdapter
,
1558 IN ULONG DesiredLength
,
1559 OUT PPHYSICAL_ADDRESS LogicalAddress
,
1560 IN BOOLEAN CacheEnabled
,
1563 return HalAllocateCommonBuffer((PADAPTER_OBJECT
)VpDmaAdapter
,
1571 VideoPortReleaseCommonBuffer ( IN PVOID HwDeviceExtension
,
1572 IN PVP_DMA_ADAPTER VpDmaAdapter
,
1574 IN PHYSICAL_ADDRESS LogicalAddress
,
1575 IN PVOID VirtualAddress
,
1576 IN BOOLEAN CacheEnabled
)
1578 HalFreeCommonBuffer((PADAPTER_OBJECT
)VpDmaAdapter
,
1587 VideoPortCreateSecondaryDisplay ( IN PVOID HwDeviceExtension
,
1588 IN OUT PVOID
*SecondaryDeviceExtension
,
1591 DPRINT1("VideoPortCreateSecondaryDisplay(): Unimplemented.\n");
1592 return STATUS_UNSUCCESSFUL
;
1597 VideoPortPutDmaAdapter ( IN PVOID HwDeviceExtension
,
1598 IN PVP_DMA_ADAPTER VpDmaAdapter
)
1600 DPRINT("VideoPortPutDmaAdapter(): Unimplemented.\n");
1605 VideoPortGetDmaAdapter ( IN PVOID HwDeviceExtension
,
1606 IN PVP_DEVICE_DESCRIPTION VpDeviceExtension
)
1608 DEVICE_DESCRIPTION DeviceDescription
;
1609 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
1610 ULONG NumberOfMapRegisters
;
1611 PVP_DMA_ADAPTER Adapter
;
1613 DeviceExtension
= CONTAINING_RECORD(HwDeviceExtension
,
1614 VIDEO_PORT_DEVICE_EXTENSION
,
1615 MiniPortDeviceExtension
);
1617 DPRINT("VideoPortGetDmaAdapter()\n");
1619 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
1620 DeviceDescription
.Master
= TRUE
/* ?? */;
1621 DeviceDescription
.ScatterGather
= TRUE
/* ?? */;
1622 DeviceDescription
.DemandMode
= FALSE
/* ?? */;
1623 DeviceDescription
.AutoInitialize
= FALSE
/* ?? */;
1624 DeviceDescription
.Dma32BitAddresses
= TRUE
/* ?? */;
1625 DeviceDescription
.IgnoreCount
= FALSE
/* ?? */;
1626 DeviceDescription
.Reserved1
= FALSE
;
1627 DeviceDescription
.BusNumber
= DeviceExtension
->SystemIoBusNumber
;
1628 DeviceDescription
.DmaChannel
= 0 /* ?? */;
1629 DeviceDescription
.InterfaceType
= DeviceExtension
->AdapterInterfaceType
;
1630 DeviceDescription
.DmaWidth
= Width8Bits
;
1631 DeviceDescription
.DmaSpeed
= Compatible
;
1632 DeviceDescription
.MaximumLength
= 65536 /* ?? */;
1633 DeviceDescription
.DmaPort
= 0;
1636 (PVP_DMA_ADAPTER
)HalGetAdapter(&DeviceDescription
, &NumberOfMapRegisters
);
1637 DPRINT("Adapter %X\n", Adapter
);
1647 VideoPortGetVersion ( IN PVOID HwDeviceExtension
,
1648 IN OUT PVPOSVERSIONINFO VpOsVersionInfo
)
1650 RTL_OSVERSIONINFOEXW Version
;
1652 Version
.dwOSVersionInfoSize
= sizeof(RTL_OSVERSIONINFOEXW
);
1653 if (VpOsVersionInfo
->Size
>= sizeof(VPOSVERSIONINFO
))
1656 if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW
)&Version
)))
1658 VpOsVersionInfo
->MajorVersion
= Version
.dwMajorVersion
;
1659 VpOsVersionInfo
->MinorVersion
= Version
.dwMinorVersion
;
1660 VpOsVersionInfo
->BuildNumber
= Version
.dwBuildNumber
;
1661 VpOsVersionInfo
->ServicePackMajor
= Version
.wServicePackMajor
;
1662 VpOsVersionInfo
->ServicePackMinor
= Version
.wServicePackMinor
;
1663 return STATUS_SUCCESS
;
1665 return STATUS_UNSUCCESSFUL
;
1667 VpOsVersionInfo
->MajorVersion
= 5;
1668 VpOsVersionInfo
->MinorVersion
= 0;
1669 VpOsVersionInfo
->BuildNumber
= 2195;
1670 VpOsVersionInfo
->ServicePackMajor
= 4;
1671 VpOsVersionInfo
->ServicePackMinor
= 0;
1672 return(STATUS_SUCCESS
);
1676 return ERROR_INVALID_PARAMETER
;
1681 VideoPortLockBuffer ( IN PVOID HwDeviceExtension
,
1682 IN PVOID BaseAddress
,
1684 IN VP_LOCK_OPERATION Operation
)
1686 DPRINT1("VideoPortLockBuffer(): Unimplemented.\n");
1692 VideoPortUnlockBuffer ( IN PVOID HwDeviceExtension
,
1695 DPRINT1("VideoPortUnlockBuffer(): Unimplemented.\n");
1700 VideoPortCreateEvent ( IN PVOID HwDeviceExtension
,
1706 (*Event
) = ExAllocatePoolWithTag(NonPagedPool
, sizeof(KEVENT
),
1708 if ((*Event
) == NULL
)
1710 return STATUS_NO_MEMORY
;
1712 if (EventFlag
& NOTIFICATION_EVENT
)
1714 Type
= NotificationEvent
;
1718 Type
= SynchronizationEvent
;
1720 KeInitializeEvent((PKEVENT
)*Event
, Type
, EventFlag
& INITIAL_EVENT_SIGNALED
);
1721 return STATUS_SUCCESS
;
1726 VideoPortDeleteEvent ( IN PVOID HwDeviceExtension
,
1730 return STATUS_SUCCESS
;
1735 VideoPortSetEvent ( IN PVOID HwDeviceExtension
,
1738 return KeSetEvent((PKEVENT
)Event
, IO_NO_INCREMENT
, FALSE
);
1743 VideoPortClearEvent ( IN PVOID HwDeviceExtension
,
1746 KeClearEvent((PKEVENT
)Event
);
1751 VideoPortWaitForSingleObject ( IN PVOID HwDeviceExtension
,
1753 IN PLARGE_INTEGER Timeout OPTIONAL
)
1755 return KeWaitForSingleObject(Object
,
1764 VideoPortCheckForDeviceExistence ( IN PVOID HwDeviceExtension
,
1767 IN UCHAR RevisionId
,
1768 IN USHORT SubVendorId
,
1769 IN USHORT SubSystemId
,
1772 DPRINT1("VideoPortCheckForDeviceExistence(): Unimplemented.\n");
1778 VideoPortRegisterBugcheckCallback ( IN PVOID HwDeviceExtension
,
1779 IN ULONG BugcheckCode
,
1781 IN ULONG BugcheckDataSize
)
1783 DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
1784 return STATUS_UNSUCCESSFUL
;
1789 VideoPortImageDirectoryEntryToData ( PVOID BaseAddress
,
1792 PIMAGE_NT_HEADERS NtHeader
;
1795 NtHeader
= RtlImageNtHeader (BaseAddress
);
1796 if (NtHeader
== NULL
)
1799 if (Directory
>= NtHeader
->OptionalHeader
.NumberOfRvaAndSizes
)
1802 Va
= NtHeader
->OptionalHeader
.DataDirectory
[Directory
].VirtualAddress
;
1806 return (PVOID
)(BaseAddress
+ Va
);
1810 VideoPortGetProcAddress(IN PVOID HwDeviceExtension
,
1811 IN PUCHAR FunctionName
)
1813 SYSTEM_LOAD_IMAGE GdiDriverInfo
;
1815 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1822 DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName
);
1824 RtlInitUnicodeString(&GdiDriverInfo
.ModuleName
, L
"videoprt");
1825 Status
= ZwSetSystemInformation(SystemLoadImage
, &GdiDriverInfo
,
1826 sizeof(SYSTEM_LOAD_IMAGE
));
1827 if (!NT_SUCCESS(Status
))
1829 DPRINT("Couldn't get our own module handle?\n");
1833 BaseAddress
= GdiDriverInfo
.ModuleBase
;
1835 /* Get the pointer to the export directory */
1836 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)
1837 VideoPortImageDirectoryEntryToData (BaseAddress
,
1838 IMAGE_DIRECTORY_ENTRY_EXPORT
);
1840 /* search by name */
1841 AddressPtr
= (PULONG
)
1842 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfFunctions
);
1843 OrdinalPtr
= (PUSHORT
)
1844 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNameOrdinals
);
1846 ((ULONG_PTR
)BaseAddress
+ (ULONG_PTR
)ExportDir
->AddressOfNames
);
1847 for (i
= 0; i
< ExportDir
->NumberOfNames
; i
++, NamePtr
++, OrdinalPtr
++)
1849 if (!_strnicmp(FunctionName
, (char*)(BaseAddress
+ *NamePtr
),
1850 strlen(FunctionName
)))
1852 return (PVOID
)((ULONG_PTR
)BaseAddress
+
1853 (ULONG_PTR
)AddressPtr
[*OrdinalPtr
]);
1856 DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName
);