📄 videoprt.c
字号:
if (Length == 0)
{
if (RomImageBuffer != NULL)
{
ExFreePool(RomImageBuffer);
RomImageBuffer = NULL;
}
return NULL;
}
else
{
/*
* The DDK says we shouldn't use the legacy C0000 method but get the
* rom base address from the corresponding pci or acpi register but
* lets ignore that and use C0000 anyway. We have already mapped the
* bios area into memory so we'll copy from there.
*/
/* Copy the bios. */
Length = min(Length, 0x10000);
if (RomImageBuffer != NULL)
{
ExFreePool(RomImageBuffer);
}
RomImageBuffer = ExAllocatePool(PagedPool, Length);
if (RomImageBuffer == NULL)
{
return NULL;
}
IntAttachToCSRSS(&CallingProcess, &ApcState);
RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
IntDetachFromCSRSS(&CallingProcess, &ApcState);
return RomImageBuffer;
}
}
/*
* @implemented
*/
BOOLEAN NTAPI
VideoPortScanRom(
IN PVOID HwDeviceExtension,
IN PUCHAR RomBase,
IN ULONG RomLength,
IN PUCHAR String)
{
ULONG StringLength;
BOOLEAN Found;
PUCHAR SearchLocation;
DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
StringLength = strlen((PCHAR)String);
Found = FALSE;
SearchLocation = RomBase;
for (SearchLocation = RomBase;
!Found && SearchLocation < RomBase + RomLength - StringLength;
SearchLocation++)
{
Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength);
if (Found)
{
DPRINT("Match found at %p\n", SearchLocation);
}
}
return Found;
}
/*
* @implemented
*/
BOOLEAN NTAPI
VideoPortSynchronizeExecution(
IN PVOID HwDeviceExtension,
IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
OUT PVOID Context)
{
BOOLEAN Ret;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
KIRQL OldIrql;
switch (Priority)
{
case VpLowPriority:
Ret = (*SynchronizeRoutine)(Context);
break;
case VpMediumPriority:
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
if (DeviceExtension->InterruptObject == NULL)
Ret = (*SynchronizeRoutine)(Context);
else
Ret = KeSynchronizeExecution(
DeviceExtension->InterruptObject,
SynchronizeRoutine,
Context);
break;
case VpHighPriority:
OldIrql = KeGetCurrentIrql();
if (OldIrql < SYNCH_LEVEL)
OldIrql = KfRaiseIrql(SYNCH_LEVEL);
Ret = (*SynchronizeRoutine)(Context);
if (OldIrql < SYNCH_LEVEL)
KfLowerIrql(OldIrql);
break;
default:
Ret = FALSE;
}
return Ret;
}
/*
* @implemented
*/
VP_STATUS NTAPI
VideoPortEnumerateChildren(
IN PVOID HwDeviceExtension,
IN PVOID Reserved)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
ULONG Status;
VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
VIDEO_CHILD_TYPE ChildType;
BOOLEAN bHaveLastMonitorID = FALSE;
UCHAR LastMonitorID[10];
UCHAR ChildDescriptor[256];
ULONG ChildId;
ULONG Unused;
INT i;
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL)
{
DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
return NO_ERROR;
}
/* Setup the ChildEnumInfo */
ChildEnumInfo.Size = sizeof (ChildEnumInfo);
ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor);
ChildEnumInfo.ACPIHwId = 0;
ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to
ChildHwDeviceExtension... */
/* Enumerate the children */
for (i = 1; ; i++)
{
ChildEnumInfo.ChildIndex = i;
RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor));
Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor(
HwDeviceExtension,
&ChildEnumInfo,
&ChildType,
ChildDescriptor,
&ChildId,
&Unused);
if (Status == VIDEO_ENUM_MORE_DEVICES)
{
if (ChildType == Monitor)
{
// Check if the EDID is valid
if (ChildDescriptor[0] == 0x00 &&
ChildDescriptor[1] == 0xFF &&
ChildDescriptor[2] == 0xFF &&
ChildDescriptor[3] == 0xFF &&
ChildDescriptor[4] == 0xFF &&
ChildDescriptor[5] == 0xFF &&
ChildDescriptor[6] == 0xFF &&
ChildDescriptor[7] == 0x00)
{
if (bHaveLastMonitorID)
{
// Compare the previous monitor ID with the current one, break the loop if they are identical
if (RtlCompareMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID)) == sizeof(LastMonitorID))
{
DPRINT("Found identical Monitor ID two times, stopping enumeration\n");
break;
}
}
// Copy 10 bytes from the EDID, which can be used to uniquely identify the monitor
RtlCopyMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID));
bHaveLastMonitorID = TRUE;
}
}
}
else if (Status == VIDEO_ENUM_INVALID_DEVICE)
{
DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex);
continue;
}
else if (Status == VIDEO_ENUM_NO_MORE_DEVICES)
{
DPRINT("End of child enumeration! (%d children enumerated)\n", i - 1);
break;
}
else
{
DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status);
break;
}
#ifndef NDEBUG
if (ChildType == Monitor)
{
INT j;
PUCHAR p = ChildDescriptor;
DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId);
for (j = 0; j < sizeof (ChildDescriptor); j += 8)
{
DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
p[j+0], p[j+1], p[j+2], p[j+3],
p[j+4], p[j+5], p[j+6], p[j+7]);
}
}
else if (ChildType == Other)
{
DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor);
}
else
{
DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType);
}
#endif /* NDEBUG */
}
return NO_ERROR;
}
/*
* @unimplemented
*/
VP_STATUS NTAPI
VideoPortCreateSecondaryDisplay(
IN PVOID HwDeviceExtension,
IN OUT PVOID *SecondaryDeviceExtension,
IN ULONG Flag)
{
DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
return NO_ERROR;
}
/*
* @implemented
*/
BOOLEAN NTAPI
VideoPortQueueDpc(
IN PVOID HwDeviceExtension,
IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
IN PVOID Context)
{
return KeInsertQueueDpc(
&VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
(PVOID)CallbackRoutine,
(PVOID)Context);
}
/*
* @implemented
*/
PVOID NTAPI
VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT("VideoPortGetAssociatedDeviceExtension\n");
DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
if (!DeviceExtension)
return NULL;
return DeviceExtension->MiniPortDeviceExtension;
}
/*
* @implemented
*/
VP_STATUS NTAPI
VideoPortGetVersion(
IN PVOID HwDeviceExtension,
IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
{
RTL_OSVERSIONINFOEXW Version;
Version.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
if (VpOsVersionInfo->Size >= sizeof(VPOSVERSIONINFO))
{
#if 1
if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&Version)))
{
VpOsVersionInfo->MajorVersion = Version.dwMajorVersion;
VpOsVersionInfo->MinorVersion = Version.dwMinorVersion;
VpOsVersionInfo->BuildNumber = Version.dwBuildNumber;
VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor;
VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor;
return NO_ERROR;
}
return ERROR_INVALID_PARAMETER;
#else
VpOsVersionInfo->MajorVersion = 5;
VpOsVersionInfo->MinorVersion = 0;
VpOsVersionInfo->BuildNumber = 2195;
VpOsVersionInfo->ServicePackMajor = 4;
VpOsVersionInfo->ServicePackMinor = 0;
return NO_ERROR;
#endif
}
return ERROR_INVALID_PARAMETER;
}
/*
* @implemented
*/
BOOLEAN NTAPI
VideoPortCheckForDeviceExistence(
IN PVOID HwDeviceExtension,
IN USHORT VendorId,
IN USHORT DeviceId,
IN UCHAR RevisionId,
IN USHORT SubVendorId,
IN USHORT SubSystemId,
IN ULONG Flags)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
PCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface;
IO_STATUS_BLOCK IoStatusBlock;
IO_STACK_LOCATION IoStack;
ULONG PciFlags = 0;
NTSTATUS Status;
BOOL DevicePresent;
DPRINT("VideoPortCheckForDeviceExistence\n");
if (Flags & ~(CDE_USE_REVISION | CDE_USE_SUBSYSTEM_IDS))
{
DPRINT1("VideoPortCheckForDeviceExistence: Unknown flags 0x%lx\n", Flags & ~(CDE_USE_REVISION | CDE_USE_SUBSYSTEM_IDS));
return FALSE;
}
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
PciDevicePresentInterface.Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
PciDevicePresentInterface.Version = 1;
IoStack.Parameters.QueryInterface.Size = PciDevicePresentInterface.Size;
IoStack.Parameters.QueryInterface.Version = PciDevicePresentInterface.Version;
IoStack.Parameters.QueryInterface.Interface = (PINTERFACE)&PciDevicePresentInterface;
IoStack.Parameters.QueryInterface.InterfaceType =
&GUID_PCI_DEVICE_PRESENT_INTERFACE;
Status = IopInitiatePnpIrp(DeviceExtension->NextDeviceObject,
&IoStatusBlock, IRP_MN_QUERY_INTERFACE, &IoStack);
if (!NT_SUCCESS(Status))
{
DPRINT("IopInitiatePnpIrp() failed! (Status 0x%lx)\n", Status);
return FALSE;
}
if (Flags & CDE_USE_REVISION)
PciFlags |= PCI_USE_REVISION;
if (Flags & CDE_USE_SUBSYSTEM_IDS)
PciFlags |= PCI_USE_SUBSYSTEM_IDS;
DevicePresent = PciDevicePresentInterface.IsDevicePresent(
VendorId, DeviceId, RevisionId,
SubVendorId, SubSystemId, PciFlags);
PciDevicePresentInterface.InterfaceDereference(PciDevicePresentInterface.Context);
return DevicePresent;
}
/*
* @unimplemented
*/
VP_STATUS NTAPI
VideoPortRegisterBugcheckCallback(
IN PVOID HwDeviceExtension,
IN ULONG BugcheckCode,
IN PVOID Callback,
IN ULONG BugcheckDataSize)
{
DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
return NO_ERROR;
}
/*
* @implemented
*/
LONGLONG NTAPI
VideoPortQueryPerformanceCounter(
IN PVOID HwDeviceExtension,
OUT PLONGLONG PerformanceFrequency OPTIONAL)
{
LARGE_INTEGER Result;
DPRINT("VideoPortQueryPerformanceCounter\n");
Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency);
return Result.QuadPart;
}
/*
* @implemented
*/
VOID NTAPI
VideoPortAcquireDeviceLock(
IN PVOID HwDeviceExtension)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
(void)Status;
DPRINT("VideoPortAcquireDeviceLock\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
Status = KeWaitForMutexObject(&DeviceExtension->DeviceLock, Executive,
KernelMode, FALSE, NULL);
// ASSERT(Status == STATUS_SUCCESS);
}
/*
* @implemented
*/
VOID NTAPI
VideoPortReleaseDeviceLock(
IN PVOID HwDeviceExtension)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
LONG Status;
(void)Status;
DPRINT("VideoPortReleaseDeviceLock\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
Status = KeReleaseMutex(&DeviceExtension->DeviceLock, FALSE);
//ASSERT(Status == 0);
}
/*
* @unimplemented
*/
VOID NTAPI
VpNotifyEaData(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Data)
{
DPRINT1("unimplemented VpNotifyEaData\n");
}
/*
* @implemented
*/
PVOID NTAPI
VideoPortAllocateContiguousMemory(
IN PVOID HwDeviceExtension,
IN ULONG NumberOfBytes,
IN PHYSICAL_ADDRESS HighestAcceptableAddress
)
{
return MmAllocateContiguousMemory(NumberOfBytes, HighestAcceptableAddress);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -