* If not, write to the Free Software Foundation,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * $Id: videoprt.c,v 1.20 2004/03/12 23:03:21 dwelch Exp $
+ * $Id$
*/
#include "videoprt.h"
+#include <wdmguid.h>
-BOOLEAN CsrssInitialized = FALSE;
-PEPROCESS Csrss = NULL;
-PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
-static PVOID RomImageBuffer = NULL;
+/* GLOBAL VARIABLES ***********************************************************/
-VOID STDCALL STATIC
-VideoPortDeferredRoutine(
- IN PKDPC Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
- );
-PVOID STDCALL
-VideoPortGetProcAddress(IN PVOID HwDeviceExtension,
- IN PUCHAR FunctionName);
-
-// ------------------------------------------------------- Public Interface
-
-// DriverEntry
-//
-// DESCRIPTION:
-// This function initializes the driver.
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
-// for this driver
-// IN PUNICODE_STRING RegistryPath Name of registry driver service
-// key
-//
-// RETURNS:
-// NTSTATUS
-
-NTSTATUS STDCALL
-DriverEntry(IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath)
-{
- DPRINT("DriverEntry()\n");
- return(STATUS_SUCCESS);
-}
+ULONG CsrssInitialized = FALSE;
+PKPROCESS Csrss = NULL;
+ULONG VideoPortDeviceNumber = 0;
-/*
- * @implemented
- */
-VOID
-VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel,
- IN PCHAR DebugMessage, ...)
-{
- char Buffer[256];
- va_list ap;
+/* PRIVATE FUNCTIONS **********************************************************/
-/*
- if (DebugPrintLevel > InternalDebugLevel)
- return;
-*/
- va_start (ap, DebugMessage);
- vsprintf (Buffer, DebugMessage, ap);
- va_end (ap);
-
- DbgPrint (Buffer);
+NTSTATUS NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ return STATUS_SUCCESS;
}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
- IN PVOID MappedAddress)
+PVOID NTAPI
+IntVideoPortImageDirectoryEntryToData(
+ PVOID BaseAddress,
+ ULONG Directory)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ PIMAGE_NT_HEADERS NtHeader;
+ ULONG Va;
- DPRINT("VideoPortFreeDeviceBase\n");
+ NtHeader = RtlImageNtHeader(BaseAddress);
+ if (NtHeader == NULL)
+ return NULL;
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
+ return NULL;
- InternalUnmapMemory(DeviceExtension, MappedAddress);
-}
+ Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
+ if (Va == 0)
+ return NULL;
+ return (PVOID)((ULONG_PTR)BaseAddress + Va);
+}
-/*
- * @implemented
- */
-ULONG
-STDCALL
-VideoPortGetBusData(IN PVOID HwDeviceExtension,
- IN BUS_DATA_TYPE BusDataType,
- IN ULONG SlotNumber,
- OUT PVOID Buffer,
- IN ULONG Offset,
- IN ULONG Length)
+PVOID NTAPI
+IntVideoPortGetProcAddress(
+ IN PVOID HwDeviceExtension,
+ IN PUCHAR FunctionName)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+ PVOID BaseAddress;
+ PIMAGE_EXPORT_DIRECTORY ExportDir;
+ PUSHORT OrdinalPtr;
+ PULONG NamePtr;
+ PULONG AddressPtr;
+ ULONG i = 0;
+ NTSTATUS Status;
+
+ DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
+
+ RtlInitUnicodeString(&GdiDriverInfo.DriverName, L"videoprt");
+ Status = ZwSetSystemInformation(
+ SystemLoadGdiDriverInformation,
+ &GdiDriverInfo,
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Couldn't get our own module handle?\n");
+ return NULL;
+ }
- DPRINT("VideoPortGetBusData\n");
+ BaseAddress = GdiDriverInfo.ImageAddress;
+
+ /* Get the pointer to the export directory */
+ ExportDir = (PIMAGE_EXPORT_DIRECTORY)IntVideoPortImageDirectoryEntryToData(
+ BaseAddress,
+ IMAGE_DIRECTORY_ENTRY_EXPORT);
+
+ /* Search by name */
+ AddressPtr = (PULONG)
+ ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions);
+ OrdinalPtr = (PUSHORT)
+ ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
+ NamePtr = (PULONG)
+ ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
+ for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
+ {
+ if (!_strnicmp((PCHAR)FunctionName, (PCHAR)((ULONG_PTR)BaseAddress + *NamePtr),
+ strlen((PCHAR)FunctionName)))
+ {
+ return (PVOID)((ULONG_PTR)BaseAddress +
+ (ULONG_PTR)AddressPtr[*OrdinalPtr]);
+ }
+ }
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName);
- return HalGetBusDataByOffset(BusDataType,
- DeviceExtension->SystemIoBusNumber,
- SlotNumber,
- Buffer,
- Offset,
- Length);
+ return NULL;
}
-
-/*
- * @implemented
- */
-UCHAR
-STDCALL
-VideoPortGetCurrentIrql(VOID)
+VOID NTAPI
+IntVideoPortDeferredRoutine(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2)
{
- return KeGetCurrentIrql();
+ PVOID HwDeviceExtension =
+ &((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
+ ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
}
-
-/*
- * @implemented
- */
-PVOID
-STDCALL
-VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
- IN PHYSICAL_ADDRESS IoAddress,
- IN ULONG NumberOfUchars,
- IN UCHAR InIoSpace)
+NTSTATUS NTAPI
+IntVideoPortCreateAdapterDeviceObject(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG DeviceNumber;
+ ULONG Size;
+ NTSTATUS Status;
+ WCHAR DeviceBuffer[20];
+ UNICODE_STRING DeviceName;
+ PDEVICE_OBJECT DeviceObject_;
+
+ if (DeviceObject == NULL)
+ DeviceObject = &DeviceObject_;
+
+ /*
+ * Find the first free device number that can be used for video device
+ * object names and symlinks.
+ */
+
+ DeviceNumber = VideoPortDeviceNumber++;
+ if (DeviceNumber == 0xFFFFFFFF)
+ {
+ DPRINT("Can't find free device number\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- DPRINT("VideoPortGetDeviceBase\n");
+ /*
+ * Create the device object.
+ */
+
+ /* Create a unicode device name. */
+ swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
+ RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+ /* Create the device object. */
+ Status = IoCreateDevice(
+ DriverObject,
+ sizeof(VIDEO_PORT_DEVICE_EXTENSION) +
+ DriverExtension->InitializationData.HwDeviceExtensionSize,
+ &DeviceName,
+ FILE_DEVICE_VIDEO,
+ 0,
+ TRUE,
+ DeviceObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
+ return Status;
+ }
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ /*
+ * Set the buffering strategy here. If you change this, remember
+ * to change VidDispatchDeviceControl too.
+ */
+
+ (*DeviceObject)->Flags |= DO_BUFFERED_IO;
+
+ /*
+ * Initialize device extension.
+ */
+
+ DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension);
+ DeviceExtension->DeviceNumber = DeviceNumber;
+ DeviceExtension->DriverObject = DriverObject;
+ DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+ DeviceExtension->FunctionalDeviceObject = *DeviceObject;
+ DeviceExtension->DriverExtension = DriverExtension;
+
+ DeviceExtension->RegistryPath.Length =
+ DeviceExtension->RegistryPath.MaximumLength =
+ DriverExtension->RegistryPath.Length + (9 * sizeof(WCHAR));
+ DeviceExtension->RegistryPath.Length -= sizeof(WCHAR);
+ DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(
+ NonPagedPool,
+ DeviceExtension->RegistryPath.MaximumLength,
+ TAG_VIDEO_PORT);
+ swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
+ DriverExtension->RegistryPath.Buffer);
+
+ if (PhysicalDeviceObject != NULL)
+ {
+ /* Get bus number from the upper level bus driver. */
+ Size = sizeof(ULONG);
+ Status = IoGetDeviceProperty(
+ PhysicalDeviceObject,
+ DevicePropertyBusNumber,
+ Size,
+ &DeviceExtension->SystemIoBusNumber,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Couldn't get an information from bus driver. We will try to\n"
+ "use legacy detection method, but even that doesn't mean that\n"
+ "it will work.\n");
+ DeviceExtension->PhysicalDeviceObject = NULL;
+ }
+ }
- return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace, NULL);
-}
+ DeviceExtension->AdapterInterfaceType =
+ DriverExtension->InitializationData.AdapterInterfaceType;
+ if (PhysicalDeviceObject != NULL)
+ {
+ /* Get bus type from the upper level bus driver. */
+ Size = sizeof(ULONG);
+ IoGetDeviceProperty(
+ PhysicalDeviceObject,
+ DevicePropertyLegacyBusType,
+ Size,
+ &DeviceExtension->AdapterInterfaceType,
+ &Size);
+
+ /* Get bus device address from the upper level bus driver. */
+ Size = sizeof(ULONG);
+ IoGetDeviceProperty(
+ PhysicalDeviceObject,
+ DevicePropertyAddress,
+ Size,
+ &DeviceExtension->SystemIoSlotNumber,
+ &Size);
+ }
-/*
- * @unimplemented
- */
-VP_STATUS
-STDCALL
-VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
- IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
- IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
- IN PVOID Context)
-{
- DPRINT("VideoPortGetDeviceData\n");
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
+ InitializeListHead(&DeviceExtension->AddressMappingListHead);
+ KeInitializeDpc(
+ &DeviceExtension->DpcObject,
+ IntVideoPortDeferredRoutine,
+ DeviceExtension);
+ KeInitializeMutex(&DeviceExtension->DeviceLock, 0);
-/*
- * @implemented
- */
-VP_STATUS
-STDCALL
-VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
- IN ULONG NumRequestedResources,
- IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
- IN ULONG NumAccessRanges,
- IN PVIDEO_ACCESS_RANGE AccessRanges,
- IN PVOID VendorId,
- IN PVOID DeviceId,
- IN PULONG Slot)
-{
- PCI_SLOT_NUMBER PciSlotNumber;
- ULONG FunctionNumber;
- PCI_COMMON_CONFIG Config;
- PCM_RESOURCE_LIST AllocatedResources;
- NTSTATUS Status;
- UINT AssignedCount;
- CM_FULL_RESOURCE_DESCRIPTOR *FullList;
- CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- USHORT VendorIdToFind;
- USHORT DeviceIdToFind;
- ULONG SlotIdToFind;
-
- DPRINT("VideoPortGetAccessRanges\n");
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
-
- if (0 == NumRequestedResources &&
- PCIBus == DeviceExtension->AdapterInterfaceType)
- {
- VendorIdToFind = VendorId != NULL ? *(PUSHORT)VendorId : 0;
- DeviceIdToFind = DeviceId != NULL ? *(PUSHORT)DeviceId : 0;
- SlotIdToFind = Slot != NULL ? *Slot : 0;
-
- DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x SlotId 0x%04x\n",
- VendorIdToFind, DeviceIdToFind, SlotIdToFind);
-
- PciSlotNumber.u.AsULONG = SlotIdToFind;
+ /* Attach the device. */
+ if (PhysicalDeviceObject != NULL)
+ DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(
+ *DeviceObject, PhysicalDeviceObject);
- /*
- Search for the device id and vendor id on this bus.
- */
- for (FunctionNumber = 0; FunctionNumber < 8; FunctionNumber++)
- {
- ULONG ReturnedLength;
- DPRINT("- Function number: %d\n", FunctionNumber);
- PciSlotNumber.u.bits.FunctionNumber = FunctionNumber;
- ReturnedLength = HalGetBusData(PCIConfiguration,
- DeviceExtension->SystemIoBusNumber,
- PciSlotNumber.u.AsULONG,
- &Config,
- sizeof(PCI_COMMON_CONFIG));
- DPRINT("- Length of data: %x\n", ReturnedLength);
- if (sizeof(PCI_COMMON_CONFIG) == ReturnedLength)
- {
- DPRINT("- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
- "DeviceId 0x%04x\n",
- PciSlotNumber.u.AsULONG,
- PciSlotNumber.u.bits.DeviceNumber,
- PciSlotNumber.u.bits.FunctionNumber,
- Config.VendorID,
- Config.DeviceID);
-
- if ((VendorIdToFind == 0 || Config.VendorID == VendorIdToFind) &&
- (DeviceIdToFind == 0 || Config.DeviceID == DeviceIdToFind))
- {
- break;
- }
- }
- }
- if (FunctionNumber == 8)
- {
- DPRINT("Didn't find device.\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = HalAssignSlotResources(NULL, NULL, NULL, NULL,
- DeviceExtension->AdapterInterfaceType,
- DeviceExtension->SystemIoBusNumber,
- PciSlotNumber.u.AsULONG,
- &AllocatedResources);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- AssignedCount = 0;
- for (FullList = AllocatedResources->List;
- FullList < AllocatedResources->List + AllocatedResources->Count;
- FullList++)
- {
- assert(FullList->InterfaceType == PCIBus &&
- FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
- 1 == FullList->PartialResourceList.Version &&
- 1 == FullList->PartialResourceList.Revision);
- for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
- Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
- Descriptor++)
- {
- if ((CmResourceTypeMemory == Descriptor->Type
- || CmResourceTypePort == Descriptor->Type)
- && NumAccessRanges <= AssignedCount)
- {
- DPRINT1("Too many access ranges found\n");
- ExFreePool(AllocatedResources);
- return STATUS_UNSUCCESSFUL;
- }
- if (CmResourceTypeMemory == Descriptor->Type)
- {
- if (NumAccessRanges <= AssignedCount)
- {
- DPRINT1("Too many access ranges found\n");
- ExFreePool(AllocatedResources);
- return STATUS_UNSUCCESSFUL;
- }
- DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
- Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
- AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start;
- AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length;
- AccessRanges[AssignedCount].RangeInIoSpace = 0;
- AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
- AccessRanges[AssignedCount].RangeShareable =
- (CmResourceShareShared == Descriptor->ShareDisposition);
- AssignedCount++;
- }
- else if (CmResourceTypePort == Descriptor->Type)
- {
- DPRINT("Port range starting at 0x%04x length %d\n",
- Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length);
- AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start;
- AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length;
- AccessRanges[AssignedCount].RangeInIoSpace = 1;
- AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */
- AccessRanges[AssignedCount].RangeShareable = 0;
- AssignedCount++;
- }
- else if (CmResourceTypeInterrupt == Descriptor->Type)
- {
- DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
- DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
- }
- }
- }
- ExFreePool(AllocatedResources);
- }
- else
- {
- UNIMPLEMENTED
- }
-
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-typedef struct QueryRegistryCallbackContext
-{
- PVOID HwDeviceExtension;
- PVOID HwContext;
- PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
-} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
-static NTSTATUS STDCALL
-QueryRegistryCallback(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
+/* FIXME: we have to detach the device object in IntVideoPortFindAdapter if it fails */
+NTSTATUS NTAPI
+IntVideoPortFindAdapter(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
+ IN PDEVICE_OBJECT DeviceObject)
{
- PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context;
-
- DPRINT("Found registry value for name %S: type %d, length %d\n",
- ValueName, ValueType, ValueLength);
- return (*(CallbackContext->HwGetRegistryRoutine))(CallbackContext->HwDeviceExtension,
- CallbackContext->HwContext,
- ValueName,
- ValueData,
- ValueLength);
-}
+ WCHAR DeviceVideoBuffer[20];
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG Size;
+ NTSTATUS Status;
+ VIDEO_PORT_CONFIG_INFO ConfigInfo;
+ SYSTEM_BASIC_INFORMATION SystemBasicInfo;
+ UCHAR Again = FALSE;
+ WCHAR DeviceBuffer[20];
+ UNICODE_STRING DeviceName;
+ WCHAR SymlinkBuffer[20];
+ UNICODE_STRING SymlinkName;
+ BOOL LegacyDetection = FALSE;
+ ULONG DeviceNumber;
+
+ DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceNumber = DeviceExtension->DeviceNumber;
+
+ /*
+ * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
+ */
+
+ RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
+ ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
+ ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
+ if (ConfigInfo.AdapterInterfaceType == PCIBus)
+ ConfigInfo.InterruptMode = LevelSensitive;
+ else
+ ConfigInfo.InterruptMode = Latched;
+ ConfigInfo.DriverRegistryPath = DriverExtension->RegistryPath.Buffer;
+ ConfigInfo.VideoPortGetProcAddress = IntVideoPortGetProcAddress;
+ ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
+ ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
+ ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
+
+ Size = sizeof(SystemBasicInfo);
+ Status = ZwQuerySystemInformation(
+ SystemBasicInformation,
+ &SystemBasicInfo,
+ Size,
+ &Size);
+
+ if (NT_SUCCESS(Status))
+ {
+ ConfigInfo.SystemMemorySize =
+ SystemBasicInfo.NumberOfPhysicalPages *
+ SystemBasicInfo.PageSize;
+ }
-/*
- * @unimplemented
- */
-VP_STATUS
-STDCALL
-VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
- IN PWSTR ParameterName,
- IN UCHAR IsParameterFileName,
- IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
- IN PVOID HwContext)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- QUERY_REGISTRY_CALLBACK_CONTEXT Context;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ /*
+ * Call miniport HwVidFindAdapter entry point to detect if
+ * particular device is present. There are two possible code
+ * paths. The first one is for Legacy drivers (NT4) and cases
+ * when we don't have information about what bus we're on. The
+ * second case is the standard one for Plug & Play drivers.
+ */
+ if (DeviceExtension->PhysicalDeviceObject == NULL)
+ {
+ LegacyDetection = TRUE;
+ }
- /*DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName);*/
+ if (LegacyDetection)
+ {
+ ULONG BusNumber, MaxBuses;
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ MaxBuses = DeviceExtension->AdapterInterfaceType == PCIBus ? 8 : 1;
- if (IsParameterFileName)
- {
- UNIMPLEMENTED;
- }
-
- Context.HwDeviceExtension = HwDeviceExtension;
- Context.HwContext = HwContext;
- Context.HwGetRegistryRoutine = GetRegistryRoutine;
-
- QueryTable[0].QueryRoutine = QueryRegistryCallback;
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
- QueryTable[0].Name = ParameterName;
- QueryTable[0].EntryContext = NULL;
- QueryTable[0].DefaultType = REG_NONE;
- QueryTable[0].DefaultData = NULL;
- QueryTable[0].DefaultLength = 0;
-
- QueryTable[1].QueryRoutine = NULL;
- QueryTable[1].Name = NULL;
-
- return NT_SUCCESS(RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- DeviceExtension->RegistryPath.Buffer,
- QueryTable, &Context, NULL))
- ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
-}
+ for (BusNumber = 0; BusNumber < MaxBuses; BusNumber++)
+ {
+ DeviceExtension->SystemIoBusNumber =
+ ConfigInfo.SystemIoBusNumber = BusNumber;
+
+ RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
+ DriverExtension->InitializationData.HwDeviceExtensionSize);
+
+ /* FIXME: Need to figure out what string to pass as param 3. */
+ Status = DriverExtension->InitializationData.HwFindAdapter(
+ &DeviceExtension->MiniPortDeviceExtension,
+ DriverExtension->HwContext,
+ NULL,
+ &ConfigInfo,
+ &Again);
+
+ if (Status == ERROR_DEV_NOT_EXIST)
+ {
+ continue;
+ }
+ else if (Status == NO_ERROR)
+ {
+ break;
+ }
+ else
+ {
+ DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
+ RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+ IoDeleteDevice(DeviceObject);
+
+ return Status;
+ }
+ }
+ }
+ else
+ {
+ /* FIXME: Need to figure out what string to pass as param 3. */
+ Status = DriverExtension->InitializationData.HwFindAdapter(
+ &DeviceExtension->MiniPortDeviceExtension,
+ DriverExtension->HwContext,
+ NULL,
+ &ConfigInfo,
+ &Again);
+ }
+ if (Status != NO_ERROR)
+ {
+ DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
+ RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+ IoDeleteDevice(DeviceObject);
+ return Status;
+ }
-/*
- * @implemented
- */
-VP_STATUS
-STDCALL
-VideoPortGetVgaStatus(IN PVOID HwDeviceExtension,
- OUT PULONG VgaStatus)
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ /*
+ * Now we know the device is present, so let's do all additional tasks
+ * such as creating symlinks or setting up interrupts and timer.
+ */
+
+ /* Create a unicode device name. */
+ swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
+ RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+ /* Create symbolic link "\??\DISPLAYx" */
+ swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1);
+ RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
+ IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+
+ /* Add entry to DEVICEMAP\VIDEO key in registry. */
+ swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber);
+ RtlWriteRegistryValue(
+ RTL_REGISTRY_DEVICEMAP,
+ L"VIDEO",
+ DeviceVideoBuffer,
+ REG_SZ,
+ DeviceExtension->RegistryPath.Buffer,
+ DeviceExtension->RegistryPath.MaximumLength);
+
+ /* FIXME: Allocate hardware resources for device. */
+
+ /*
+ * Allocate interrupt for device.
+ */
+
+ if (!IntVideoPortSetupInterrupt(DeviceObject, DriverExtension, &ConfigInfo))
+ {
+ RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+ IoDeleteDevice(DeviceObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- DPRINT("VideoPortGetVgaStatus = %x \n", VgaStatus);
+ /*
+ * Allocate timer for device.
+ */
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ if (!IntVideoPortSetupTimer(DeviceObject, DriverExtension))
+ {
+ if (DeviceExtension->InterruptObject != NULL)
+ IoDisconnectInterrupt(DeviceExtension->InterruptObject);
+ RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
+ IoDeleteDevice(DeviceObject);
+ DPRINT("STATUS_INSUFFICIENT_RESOURCES\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- if(KeGetCurrentIrql() == PASSIVE_LEVEL)
- {
- DPRINT("VideoPortGetVgaStatus1 = %x \n", VgaStatus);
+ /*
+ * Query children of the device.
+ */
+ VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension, NULL);
- if ( PCIBus == DeviceExtension->AdapterInterfaceType)
- {
-/*
- VgaStatus 0 == VGA not enabled, 1 == VGA enabled.
- */
- DPRINT("VideoPortGetVgaStatus2 = %x \n", VgaStatus);
-
- /* Assumed for now */
-
- VgaStatus = (PULONG) 1;
-
- return STATUS_SUCCESS;
- }
- }
- DPRINT("VideoPortGetVgaStatus3 = %x \n", VgaStatus);
-
- return ERROR_INVALID_FUNCTION;
+ DPRINT("STATUS_SUCCESS\n");
+ return STATUS_SUCCESS;
}
-static BOOLEAN STDCALL
-VPInterruptRoutine(IN struct _KINTERRUPT *Interrupt,
- IN PVOID ServiceContext)
+VOID FASTCALL
+IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = ServiceContext;
- assert(NULL != DeviceExtension->HwInterrupt);
-
- return DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
+ *CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+ if (*CallingProcess != Csrss)
+ {
+ KeStackAttachProcess(Csrss, ApcState);
+ }
}
-static VOID STDCALL
-VPTimerRoutine(IN PDEVICE_OBJECT DeviceObject,
- IN PVOID Context)
+VOID FASTCALL
+IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = Context;
- assert(DeviceExtension == DeviceObject->DeviceExtension
- && NULL != DeviceExtension->HwTimer);
-
- DeviceExtension->HwTimer(&DeviceExtension->MiniPortDeviceExtension);
+ if (*CallingProcess != Csrss)
+ {
+ KeUnstackDetachProcess(ApcState);
+ }
}
+/* PUBLIC FUNCTIONS ***********************************************************/
+
/*
* @implemented
*/
-ULONG STDCALL
-VideoPortInitialize(IN PVOID Context1,
- IN PVOID Context2,
- IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
- IN PVOID HwContext)
-{
- PUNICODE_STRING RegistryPath;
- UCHAR Again = FALSE;
- WCHAR DeviceBuffer[20];
- WCHAR SymlinkBuffer[20];
- WCHAR DeviceVideoBuffer[20];
- NTSTATUS Status;
- PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
- PDEVICE_OBJECT MPDeviceObject;
- VIDEO_PORT_CONFIG_INFO ConfigInfo;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- ULONG DisplayNumber;
- UNICODE_STRING DeviceName;
- UNICODE_STRING SymlinkName;
- ULONG MaxBus;
- ULONG MaxLen;
- KIRQL IRQL;
- KAFFINITY Affinity;
- ULONG InterruptVector;
- OBJECT_ATTRIBUTES Obj;
- HANDLE ObjHandle;
-
- DPRINT("VideoPortInitialize\n");
-
- RegistryPath = (PUNICODE_STRING) Context2;
-
- /* Build Dispatch table from passed data */
- MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
-
- /* Find the first free device number */
- for (DisplayNumber = 0;;)
- {
- swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
- RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
- InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL);
- Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj);
- if (NT_SUCCESS(Status))
- {
- ZwClose(ObjHandle);
- DisplayNumber++;
- continue;
- }
- else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL)
- {
- break;
- }
- else
- {
- return Status;
- }
- }
-
- DPRINT("- DisplayNumber: %d\n", DisplayNumber);
-
- Again = FALSE;
-
- do
- {
- /* Create a unicode device name. */
- swprintf(DeviceBuffer, L"\\Device\\Video%lu", DisplayNumber);
- RtlInitUnicodeString(&DeviceName, DeviceBuffer);
-
- /* Create the device. */
- Status = IoCreateDevice(
- MPDriverObject,
- HwInitializationData->HwDeviceExtensionSize +
- sizeof(VIDEO_PORT_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_VIDEO,
- 0,
- TRUE,
- &MPDeviceObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
- return Status;
- }
-
- MPDriverObject->DeviceObject = MPDeviceObject;
-
- /* Initialize the miniport drivers dispatch table */
- MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpen;
- MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchClose;
- MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
-
- /* Initialize our device extension */
- DeviceExtension =
- (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension;
- DeviceExtension->DeviceObject = MPDeviceObject;
- DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
- DeviceExtension->HwResetHw = HwInitializationData->HwResetHw;
- DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
- DeviceExtension->SystemIoBusNumber = 0;
- KeInitializeDpc(&DeviceExtension->DpcObject, VideoPortDeferredRoutine,
- (PVOID)DeviceExtension);
- MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
- DeviceExtension->RegistryPath.MaximumLength = MaxLen;
- DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
- MaxLen,
- TAG_VIDEO_PORT);
- swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
- RegistryPath->Buffer);
- DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) *
- sizeof(WCHAR);
-
- MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1;
- DPRINT("MaxBus: %lu\n", MaxBus);
- InitializeListHead(&DeviceExtension->AddressMappingListHead);
-
- /* Set the buffering strategy here... */
- /* If you change this, remember to change VidDispatchDeviceControl too */
- MPDeviceObject->Flags |= DO_BUFFERED_IO;
-
- do
- {
- RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
- HwInitializationData->HwDeviceExtensionSize);
- DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber);
- /* Setup configuration info */
- RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
- ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
- ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType;
- ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
- ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ?
- LevelSensitive : Latched;
- ConfigInfo.DriverRegistryPath = RegistryPath->Buffer;
- ConfigInfo.VideoPortGetProcAddress = VideoPortGetProcAddress;
-
- /* Call HwFindAdapter entry point */
- /* FIXME: Need to figure out what string to pass as param 3 */
- DPRINT("FindAdapter %X\n", HwInitializationData->HwFindAdapter);
- Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension,
- Context2,
- NULL,
- &ConfigInfo,
- &Again);
- if (NO_ERROR != Status)
- {
- DPRINT("HwFindAdapter call failed with error %X\n", Status);
- DeviceExtension->SystemIoBusNumber++;
- }
- }
- while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus);
-
- if (NO_ERROR != Status)
- {
- RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- DPRINT("Found adapter\n");
-
- /* create symbolic link "\??\DISPLAYx" */
- swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DisplayNumber + 1);
- RtlInitUnicodeString (&SymlinkName,
- SymlinkBuffer);
- IoCreateSymbolicLink (&SymlinkName,
- &DeviceName);
-
- /* Add entry to DEVICEMAP\VIDEO key in registry */
- swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DisplayNumber);
- RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- DeviceVideoBuffer,
- REG_SZ,
- DeviceExtension->RegistryPath.Buffer,
- DeviceExtension->RegistryPath.Length + sizeof(WCHAR));
-
- /* FIXME: Allocate hardware resources for device */
-
- /* Allocate interrupt for device */
- DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
- if (0 == ConfigInfo.BusInterruptVector)
- {
- ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector;
- }
- if (0 == ConfigInfo.BusInterruptLevel)
- {
- ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel;
- }
- if (NULL != HwInitializationData->HwInterrupt)
- {
- InterruptVector =
- HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
- ConfigInfo.SystemIoBusNumber,
- ConfigInfo.BusInterruptLevel,
- ConfigInfo.BusInterruptVector,
- &IRQL,
- &Affinity);
- if (0 == InterruptVector)
- {
- DPRINT1("HalGetInterruptVector failed\n");
- IoDeleteDevice(MPDeviceObject);
-
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock);
- Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
- VPInterruptRoutine,
- DeviceExtension,
- &DeviceExtension->InterruptSpinLock,
- InterruptVector,
- IRQL,
- IRQL,
- ConfigInfo.InterruptMode,
- FALSE,
- Affinity,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IoConnectInterrupt failed with status 0x%08x\n", Status);
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- }
- DisplayNumber++;
- }
- while (Again);
-
- DeviceExtension->HwTimer = HwInitializationData->HwTimer;
- if (HwInitializationData->HwTimer != NULL)
- {
- DPRINT("Initializing timer\n");
- Status = IoInitializeTimer(MPDeviceObject,
- VPTimerRoutine,
- DeviceExtension);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
-
- if (HwInitializationData->HwInterrupt != NULL)
- {
- IoDisconnectInterrupt(DeviceExtension->InterruptObject);
- }
- IoDeleteDevice(MPDeviceObject);
-
- return Status;
- }
- }
-
- return STATUS_SUCCESS;
-}
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-VideoPortLogError(IN PVOID HwDeviceExtension,
- IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
- IN VP_STATUS ErrorCode,
- IN ULONG UniqueId)
+ULONG NTAPI
+VideoPortInitialize(
+ IN PVOID Context1,
+ IN PVOID Context2,
+ IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
+ IN PVOID HwContext)
{
- DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
- ErrorCode, ErrorCode, UniqueId, UniqueId);
- if (NULL != Vrp)
- {
- DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode);
- }
-}
+ PDRIVER_OBJECT DriverObject = Context1;
+ PUNICODE_STRING RegistryPath = Context2;
+ NTSTATUS Status;
+ PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
+ BOOL LegacyDetection = FALSE;
+ DPRINT("VideoPortInitialize\n");
-/*
- * @unimplemented
- */
-VP_STATUS
-STDCALL
-VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
- IN PHYSICAL_ADDRESS PhysicalAddress,
- IN PULONG Length,
- IN PULONG InIoSpace,
- OUT PVOID *VirtualAddress,
- IN ULONG BankLength,
- IN UCHAR ReadWriteBank,
- IN PBANKED_SECTION_ROUTINE BankRoutine,
- IN PVOID Context)
-{
- DPRINT("VideoPortMapBankedMemory\n");
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
+ /*
+ * As a first thing do parameter checks.
+ */
+ if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA))
+ {
+ return STATUS_REVISION_MISMATCH;
+ }
-/*
- * @implemented
- */
-VP_STATUS
-STDCALL
-VideoPortMapMemory(IN PVOID HwDeviceExtension,
- IN PHYSICAL_ADDRESS PhysicalAddress,
- IN PULONG Length,
- IN PULONG InIoSpace,
- OUT PVOID *VirtualAddress)
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
+ if (HwInitializationData->HwFindAdapter == NULL ||
+ HwInitializationData->HwInitialize == NULL ||
+ HwInitializationData->HwStartIO == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
- DPRINT("VideoPortMapMemory\n");
+ /*
+ * NOTE:
+ * The driver extension can be already allocated in case that we were
+ * called by legacy driver and failed detecting device. Some miniport
+ * drivers in that case adjust parameters and call VideoPortInitialize
+ * again.
+ */
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress,
- *Length, *InIoSpace, &Status);
+ DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+ if (DriverExtension == NULL)
+ {
+ Status = IoAllocateDriverObjectExtension(
+ DriverObject,
+ DriverObject,
+ sizeof(VIDEO_PORT_DRIVER_EXTENSION),
+ (PVOID *)&DriverExtension);
- return Status;
-}
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ /*
+ * Save the registry path. This should be done only once even if
+ * VideoPortInitialize is called multiple times.
+ */
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-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(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);
- }
- }
+ if (RegistryPath->Length != 0)
+ {
+ DriverExtension->RegistryPath.Length = 0;
+ DriverExtension->RegistryPath.MaximumLength =
+ RegistryPath->Length + sizeof(UNICODE_NULL);
+ DriverExtension->RegistryPath.Buffer =
+ ExAllocatePoolWithTag(
+ PagedPool,
+ DriverExtension->RegistryPath.MaximumLength,
+ TAG('U', 'S', 'T', 'R'));
+ if (DriverExtension->RegistryPath.Buffer == NULL)
+ {
+ RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlCopyUnicodeString(&DriverExtension->RegistryPath, RegistryPath);
+ }
+ else
+ {
+ RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
+ }
+ }
- return Found;
-}
+ /*
+ * Copy the correct miniport initializtation data to the device extension.
+ */
+ RtlCopyMemory(
+ &DriverExtension->InitializationData,
+ HwInitializationData,
+ HwInitializationData->HwInitDataSize);
+ if (HwInitializationData->HwInitDataSize <
+ sizeof(VIDEO_HW_INITIALIZATION_DATA))
+ {
+ RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData +
+ HwInitializationData->HwInitDataSize),
+ sizeof(VIDEO_HW_INITIALIZATION_DATA) -
+ HwInitializationData->HwInitDataSize);
+ }
+ DriverExtension->HwContext = HwContext;
-/*
- * @implemented
- */
-ULONG
-STDCALL
-VideoPortSetBusData(IN PVOID HwDeviceExtension,
- IN BUS_DATA_TYPE BusDataType,
- IN ULONG SlotNumber,
- IN PVOID Buffer,
- IN ULONG Offset,
- IN ULONG Length)
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ switch (HwInitializationData->HwInitDataSize)
+ {
+ /*
+ * NT4 drivers are special case, because we must use legacy method
+ * of detection instead of the Plug & Play one.
+ */
+
+ case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA:
+ DPRINT("We were loaded by a Windows NT miniport driver.\n");
+ LegacyDetection = TRUE;
+ break;
+
+ case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA:
+ DPRINT("We were loaded by a Windows 2000 miniport driver.\n");
+ break;
+
+ case sizeof(VIDEO_HW_INITIALIZATION_DATA):
+ DPRINT("We were loaded by a Windows XP or later miniport driver.\n");
+ break;
+
+ default:
+ DPRINT("Invalid HwInitializationData size.\n");
+ return STATUS_UNSUCCESSFUL;
+ }
- DPRINT("VideoPortSetBusData\n");
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IntVideoPortDispatchDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = IntVideoPortDispatchWrite;
+ DriverObject->DriverUnload = IntVideoPortUnload;
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
+ /*
+ * Plug & Play drivers registers the device in AddDevice routine. For
+ * legacy drivers we must do it now.
+ */
- return HalSetBusDataByOffset(BusDataType,
- DeviceExtension->SystemIoBusNumber,
- SlotNumber,
- Buffer,
- Offset,
- Length);
-}
+ if (LegacyDetection)
+ {
+ PDEVICE_OBJECT DeviceObject;
+ Status = IntVideoPortCreateAdapterDeviceObject(DriverObject, DriverExtension,
+ NULL, &DeviceObject);
+ DPRINT("IntVideoPortCreateAdapterDeviceObject returned 0x%x\n", Status);
+ if (!NT_SUCCESS(Status))
+ return Status;
+ Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, DeviceObject);
+ DPRINT("IntVideoPortFindAdapter returned 0x%x\n", Status);
+ return Status;
+ }
+ else
+ {
+ DriverObject->DriverExtension->AddDevice = IntVideoPortAddDevice;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = IntVideoPortDispatchPnp;
+ DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower;
+ return STATUS_SUCCESS;
+ }
+}
/*
* @implemented
*/
-VP_STATUS
-STDCALL
-VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
- IN PWSTR ValueName,
- IN PVOID ValueData,
- IN ULONG ValueLength)
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- DPRINT("VideoSetRegistryParameters\n");
+VOID
+VideoPortDebugPrint(
+ IN VIDEO_DEBUG_LEVEL DebugPrintLevel,
+ IN PCHAR DebugMessage, ...)
+{
+ char Buffer[256];
+ va_list ap;
- assert_irql(PASSIVE_LEVEL);
+ va_start(ap, DebugMessage);
+ vsprintf(Buffer, DebugMessage, ap);
+ va_end(ap);
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
- DeviceExtension->RegistryPath.Buffer,
- ValueName,
- REG_BINARY,
- ValueData,
- ValueLength);
+ DbgPrintEx(DPFLTR_IHVVIDEO_ID, DebugPrintLevel, Buffer);
}
-
/*
* @unimplemented
*/
-VP_STATUS
-STDCALL
-VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
- IN ULONG NumAccessRanges,
- IN PVIDEO_ACCESS_RANGE AccessRange)
-{
- DPRINT("VideoPortSetTrappedEmulatorPorts\n");
- /* Should store the ranges in the device extension for use by ntvdm. */
- return STATUS_SUCCESS;
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-VideoPortStartTimer(IN PVOID HwDeviceExtension)
+VOID NTAPI
+VideoPortLogError(
+ IN PVOID HwDeviceExtension,
+ IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
+ IN VP_STATUS ErrorCode,
+ IN ULONG UniqueId)
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("VideoPortStartTimer\n");
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- IoStartTimer(DeviceExtension->DeviceObject);
+ DPRINT1("VideoPortLogError ErrorCode %d (0x%x) UniqueId %lu (0x%lx)\n",
+ ErrorCode, ErrorCode, UniqueId, UniqueId);
+ if (NULL != Vrp)
+ {
+ DPRINT1("Vrp->IoControlCode %lu (0x%lx)\n", Vrp->IoControlCode, Vrp->IoControlCode);
+ }
}
-
/*
* @implemented
*/
-VOID
-STDCALL
-VideoPortStopTimer(IN PVOID HwDeviceExtension)
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("VideoPortStopTimer\n");
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- IoStopTimer(DeviceExtension->DeviceObject);
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
- IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
- IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
- OUT PVOID Context)
+UCHAR NTAPI
+VideoPortGetCurrentIrql(VOID)
{
- BOOLEAN Ret;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- KIRQL OldIrql;
-
- switch(Priority)
- {
- case VpLowPriority:
- Ret = (*SynchronizeRoutine)(Context);
- break;
- case VpMediumPriority:
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- if (NULL == DeviceExtension->InterruptObject)
- {
- 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;
+ return KeGetCurrentIrql();
}
-
-/*
- * @implemented
- */
-VP_STATUS
-STDCALL
-VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
- IN PVOID VirtualAddress,
- IN HANDLE ProcessHandle)
+typedef struct QueryRegistryCallbackContext
{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("VideoPortFreeDeviceBase\n");
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
-
- InternalUnmapMemory(DeviceExtension, VirtualAddress);
+ PVOID HwDeviceExtension;
+ PVOID HwContext;
+ PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
+} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
- return STATUS_SUCCESS;
+static NTSTATUS NTAPI
+QueryRegistryCallback(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext)
+{
+ PQUERY_REGISTRY_CALLBACK_CONTEXT CallbackContext = (PQUERY_REGISTRY_CALLBACK_CONTEXT) Context;
+
+ DPRINT("Found registry value for name %S: type %d, length %d\n",
+ ValueName, ValueType, ValueLength);
+ return (*(CallbackContext->HwGetRegistryRoutine))(
+ CallbackContext->HwDeviceExtension,
+ CallbackContext->HwContext,
+ ValueName,
+ ValueData,
+ ValueLength);
}
-
/*
* @unimplemented
*/
-VP_STATUS
-STDCALL
-VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
- IN ULONG NumAccessRanges,
- IN PVIDEO_ACCESS_RANGE AccessRanges)
-{
- DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
- return NO_ERROR;
-}
-
-/*
- * Reset display to blue screen
- */
-static BOOLEAN STDCALL
-VideoPortResetDisplayParameters(Columns, Rows)
+VP_STATUS NTAPI
+VideoPortGetRegistryParameters(
+ IN PVOID HwDeviceExtension,
+ IN PWSTR ParameterName,
+ IN UCHAR IsParameterFileName,
+ IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
+ IN PVOID HwContext)
{
- if (NULL == ResetDisplayParametersDeviceExtension)
- {
- return(FALSE);
- }
- if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw)
- {
- return(FALSE);
- }
- if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
- Columns, Rows))
- {
- return(FALSE);
- }
-
- ResetDisplayParametersDeviceExtension = NULL;
-
- return TRUE;
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ QUERY_REGISTRY_CALLBACK_CONTEXT Context;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("VideoPortGetRegistryParameters ParameterName %S\n", ParameterName);
+
+ DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+
+ Context.HwDeviceExtension = HwDeviceExtension;
+ Context.HwContext = HwContext;
+ Context.HwGetRegistryRoutine = GetRegistryRoutine;
+
+ QueryTable[0].QueryRoutine = QueryRegistryCallback;
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].Name = ParameterName;
+ QueryTable[0].EntryContext = NULL;
+ QueryTable[0].DefaultType = REG_NONE;
+ QueryTable[0].DefaultData = NULL;
+ QueryTable[0].DefaultLength = 0;
+
+ QueryTable[1].QueryRoutine = NULL;
+ QueryTable[1].Name = NULL;
+
+ if (!NT_SUCCESS(RtlQueryRegistryValues(
+ RTL_REGISTRY_ABSOLUTE,
+ DeviceExtension->RegistryPath.Buffer,
+ QueryTable,
+ &Context,
+ NULL)))
+ return ERROR_INVALID_PARAMETER;
+
+ if (IsParameterFileName)
+ {
+ /* FIXME: need to read the contents of the file */
+ UNIMPLEMENTED;
+ }
+
+ return ERROR_SUCCESS;
}
/*
* @implemented
*/
-PVOID
-STDCALL
-VideoPortAllocatePool(
+VP_STATUS NTAPI
+VideoPortSetRegistryParameters(
IN PVOID HwDeviceExtension,
- IN VP_POOL_TYPE PoolType,
- IN SIZE_T NumberOfBytes,
- IN ULONG Tag)
+ IN PWSTR ValueName,
+ IN PVOID ValueData,
+ IN ULONG ValueLength)
{
- return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
+ DPRINT("VideoPortSetRegistryParameters\n");
+ ASSERT_IRQL(PASSIVE_LEVEL);
+ return RtlWriteRegistryValue(
+ RTL_REGISTRY_ABSOLUTE,
+ VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->RegistryPath.Buffer,
+ ValueName,
+ REG_BINARY,
+ ValueData,
+ ValueLength);
}
/*
* @implemented
*/
-VOID
-STDCALL
-VideoPortFreePool(
+VP_STATUS NTAPI
+VideoPortGetVgaStatus(
IN PVOID HwDeviceExtension,
- IN PVOID Ptr)
+ OUT PULONG VgaStatus)
{
- ExFreePool(Ptr);
-}
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-// VidDispatchOpen
-//
-// DESCRIPTION:
-// Answer requests for Open calls
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// Standard dispatch arguments
-//
-// RETURNS:
-// NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchOpen(IN PDEVICE_OBJECT pDO,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("VidDispatchOpen() called\n");
-
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
-
- if (! CsrssInitialized)
- {
- DPRINT("Referencing CSRSS\n");
- Csrss = PsGetCurrentProcess();
- DPRINT("Csrss %p\n", Csrss);
- }
- else
- {
- DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension;
- if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
- {
- Irp->IoStatus.Status = STATUS_SUCCESS;
- /* Storing the device extension pointer in a static variable is an ugly
- * hack. Unfortunately, we need it in VideoPortResetDisplayParameters
- * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
- * parameter. On the bright side, the DISPLAY device is opened
- * exclusively, so there can be only one device extension active at
- * any point in time. */
- ResetDisplayParametersDeviceExtension = DeviceExtension;
- HalAcquireDisplayOwnership(VideoPortResetDisplayParameters);
- }
- else
- {
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- }
- }
+ DPRINT("VideoPortGetVgaStatus\n");
- Irp->IoStatus.Information = FILE_OPENED;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
+ if (KeGetCurrentIrql() == PASSIVE_LEVEL)
+ {
+ if (DeviceExtension->AdapterInterfaceType == PCIBus)
+ {
+ /* VgaStatus: 0 == VGA not enabled, 1 == VGA enabled. */
+ /* Assumed for now */
+ *VgaStatus = 1;
+ return NO_ERROR;
+ }
+ }
- return STATUS_SUCCESS;
+ return ERROR_INVALID_FUNCTION;
}
-// VidDispatchClose
-//
-// DESCRIPTION:
-// Answer requests for Close calls
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// Standard dispatch arguments
-//
-// RETURNS:
-// NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchClose(IN PDEVICE_OBJECT pDO,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
-
- DPRINT("VidDispatchClose() called\n");
-
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
+/*
+ * @implemented
+ */
- if (! CsrssInitialized)
- {
- CsrssInitialized = TRUE;
- }
- else
- {
- HalReleaseDisplayOwnership();
- }
+PVOID NTAPI
+VideoPortGetRomImage(
+ IN PVOID HwDeviceExtension,
+ IN PVOID Unused1,
+ IN ULONG Unused2,
+ IN ULONG Length)
+{
+ static PVOID RomImageBuffer = NULL;
+ PKPROCESS CallingProcess;
+ KAPC_STATE ApcState;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
+ HwDeviceExtension, Length);
- return STATUS_SUCCESS;
-}
-
-// VidDispatchDeviceControl
-//
-// DESCRIPTION:
-// Answer requests for device control calls
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// Standard dispatch arguments
-//
-// RETURNS:
-// NTSTATUS
-//
-
-NTSTATUS STDCALL
-VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IrpStack;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- PVIDEO_REQUEST_PACKET vrp;
- BOOLEAN Ret;
-
- DPRINT("VidDispatchDeviceControl\n");
- IrpStack = IoGetCurrentIrpStackLocation(Irp);
- DeviceExtension = DeviceObject->DeviceExtension;
-
- /* Translate the IRP to a VRP */
- vrp = ExAllocatePool(NonPagedPool, sizeof(VIDEO_REQUEST_PACKET));
- if (NULL == vrp)
- {
- return STATUS_NO_MEMORY;
- }
- vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus);
- vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
-
- DPRINT("- IoControlCode: %x\n", vrp->IoControlCode);
- DPRINT("InputBuffer %X (InLength %d OutLength %d) Routine %X\n",
- Irp->AssociatedIrp.SystemBuffer,
- IrpStack->Parameters.DeviceIoControl.InputBufferLength,
- IrpStack->Parameters.DeviceIoControl.OutputBufferLength,
- DeviceObject->DriverObject->DriverStartIo);
- {
- ULONG i;
- for (i = 0; i < IrpStack->Parameters.DeviceIoControl.InputBufferLength; i++)
+ /* If the length is zero then free the existing buffer. */
+ if (Length == 0)
+ {
+ if (RomImageBuffer != NULL)
{
- DbgPrint("%X ", ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[i]);
+ ExFreePool(RomImageBuffer);
+ RomImageBuffer = NULL;
}
- DbgPrint("\n");
- }
-
- /* We're assuming METHOD_BUFFERED */
- vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
- vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
- vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
- vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Call the Miniport Driver with the VRP */
- Ret = ((PDRIVER_STARTIO)DeviceObject->DriverObject->DriverStartIo)((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp);
- assert(Ret);
+ 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.
+ */
- /* Free the VRP */
- ExFreePool(vrp);
+ /* Copy the bios. */
+ Length = min(Length, 0x10000);
+ if (RomImageBuffer != NULL)
+ {
+ ExFreePool(RomImageBuffer);
+ }
- DPRINT("- Returned status: %x\n", Irp->IoStatus.Status);
+ RomImageBuffer = ExAllocatePool(PagedPool, Length);
+ if (RomImageBuffer == NULL)
+ {
+ return NULL;
+ }
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IntAttachToCSRSS(&CallingProcess, &ApcState);
+ RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
+ IntDetachFromCSRSS(&CallingProcess, &ApcState);
- return STATUS_SUCCESS;
+ return RomImageBuffer;
+ }
}
-PVOID STDCALL
-InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
- IN PHYSICAL_ADDRESS IoAddress,
- IN ULONG NumberOfUchars,
- IN UCHAR InIoSpace,
- OUT NTSTATUS *Status)
-{
- PHYSICAL_ADDRESS TranslatedAddress;
- PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
- ULONG AddressSpace;
- PVOID MappedAddress;
- PLIST_ENTRY Entry;
-
- DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
- DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
- DPRINT("- InIoSpace: %x\n", InIoSpace);
- InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
- if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE))
- {
- DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
- InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
- }
- if (! IsListEmpty(&DeviceExtension->AddressMappingListHead))
- {
- Entry = DeviceExtension->AddressMappingListHead.Flink;
- while (Entry != &DeviceExtension->AddressMappingListHead)
- {
- AddressMapping = CONTAINING_RECORD(Entry,
- VIDEO_PORT_ADDRESS_MAPPING,
- List);
- if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
- NumberOfUchars <= AddressMapping->NumberOfUchars)
- {
- AddressMapping->MappingCount++;
- if (Status)
- {
- *Status = STATUS_SUCCESS;
- }
- return AddressMapping->MappedAddress;
- }
- Entry = Entry->Flink;
- }
- }
-
- AddressSpace = (ULONG)InIoSpace;
- if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType,
- DeviceExtension->SystemIoBusNumber,
- IoAddress,
- &AddressSpace,
- &TranslatedAddress) == FALSE)
- {
- if (Status)
- {
- *Status = STATUS_NO_MEMORY;
- }
- return NULL;
- }
-
- /* i/o space */
- if (AddressSpace != 0)
- {
- assert(0 == TranslatedAddress.u.HighPart);
- if (Status)
- {
- *Status = STATUS_SUCCESS;
- }
- return (PVOID) TranslatedAddress.u.LowPart;
- }
-
- MappedAddress = MmMapIoSpace(TranslatedAddress,
- NumberOfUchars,
- FALSE);
-
- if (MappedAddress)
- {
- if (Status)
- {
- *Status = STATUS_SUCCESS;
- }
-
- AddressMapping = ExAllocatePoolWithTag(PagedPool,
- sizeof(VIDEO_PORT_ADDRESS_MAPPING),
- TAG_VIDEO_PORT);
- if (AddressMapping == NULL)
- return MappedAddress;
-
- AddressMapping->MappedAddress = MappedAddress;
- AddressMapping->NumberOfUchars = NumberOfUchars;
- AddressMapping->IoAddress = IoAddress;
- AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
- AddressMapping->MappingCount = 1;
-
- InsertHeadList(&DeviceExtension->AddressMappingListHead,
- &AddressMapping->List);
-
- return MappedAddress;
- }
- else
- {
- if (Status)
- {
- *Status = STATUS_NO_MEMORY;
- }
-
- return NULL;
- }
-}
+/*
+ * @implemented
+ */
-VOID STDCALL
-InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
- IN PVOID MappedAddress)
+BOOLEAN NTAPI
+VideoPortScanRom(
+ IN PVOID HwDeviceExtension,
+ IN PUCHAR RomBase,
+ IN ULONG RomLength,
+ IN PUCHAR String)
{
- PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
- PLIST_ENTRY Entry;
-
- Entry = DeviceExtension->AddressMappingListHead.Flink;
- while (Entry != &DeviceExtension->AddressMappingListHead)
- {
- AddressMapping = CONTAINING_RECORD(Entry,
- VIDEO_PORT_ADDRESS_MAPPING,
- List);
- if (AddressMapping->MappedAddress == MappedAddress)
- {
- assert(0 <= AddressMapping->MappingCount);
- AddressMapping->MappingCount--;
- if (0 == AddressMapping->MappingCount)
- {
- MmUnmapIoSpace(AddressMapping->MappedAddress,
- AddressMapping->NumberOfUchars);
- RemoveEntryList(Entry);
- ExFreePool(AddressMapping);
-
- return;
- }
- }
-
- Entry = Entry->Flink;
- }
-}
+ 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);
+ }
+ }
-BOOLEAN STDCALL
-VideoPortDDCMonitorHelper(
- PVOID HwDeviceExtension,
- /*PI2C_FNC_TABLE*/PVOID I2CFunctions,
- PUCHAR pEdidBuffer,
- ULONG EdidBufferSize
- )
-{
- DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
- return FALSE;
+ return Found;
}
/*
* @implemented
*/
-VP_STATUS
-STDCALL
-VideoPortAllocateBuffer(IN PVOID HwDeviceExtension,
- IN ULONG Size,
- OUT PVOID *Buffer)
+
+BOOLEAN NTAPI
+VideoPortSynchronizeExecution(
+ IN PVOID HwDeviceExtension,
+ IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
+ IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
+ OUT PVOID Context)
{
- DPRINT("VideoPortAllocateBuffer()\n");
-
- Buffer = ExAllocatePool(PagedPool, Size);
- return STATUS_SUCCESS;
-
+ 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
*/
-VOID
-STDCALL
-VideoPortReleaseBuffer( IN PVOID HwDeviceExtension,
- IN PVOID Ptr)
-{
- DPRINT("VideoPortReleaseBuffer()\n");
-
- ExFreePool(Ptr);
-}
-
-
-VP_STATUS
-STDCALL
-VideoPortEnumerateChildren ( IN PVOID HwDeviceExtension,
- IN PVOID Reserved )
-{
- DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
- return STATUS_SUCCESS;
-}
-PVOID
-STDCALL
-VideoPortGetRomImage ( IN PVOID HwDeviceExtension,
- IN PVOID Unused1,
- IN ULONG Unused2,
- IN ULONG Length )
+VP_STATUS NTAPI
+VideoPortEnumerateChildren(
+ IN PVOID HwDeviceExtension,
+ IN PVOID Reserved)
{
- DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
- HwDeviceExtension, Length);
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG Status;
+ VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
+ VIDEO_CHILD_TYPE ChildType;
+ 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;
+ }
- /* If the length is zero then free the existing buffer. */
- if (Length == 0)
- {
- if (RomImageBuffer != NULL)
- {
- ExFreePool(RomImageBuffer);
- RomImageBuffer = NULL;
- }
- return NULL;
- }
- else
- {
- PEPROCESS CallingProcess, PrevAttachedProcess;
+ /* Setup the ChildEnumInfo */
+ ChildEnumInfo.Size = sizeof (ChildEnumInfo);
+ ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor);
+ ChildEnumInfo.ACPIHwId = 0;
+ ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to
+ ChildHwDeviceExtension... */
- /*
- The DDK says we shouldn't use the legacy C000 method but get the
- rom base address from the corresponding pci or acpi register but
- lets ignore that and use C000 anyway. CSRSS has already mapped the
- bios area into memory so we'll copy from there.
- */
- CallingProcess = PsGetCurrentProcess();
- if (CallingProcess != Csrss)
- {
- if (NULL != PsGetCurrentThread()->OldProcess)
- {
- PrevAttachedProcess = CallingProcess;
- KeDetachProcess();
- }
- else
- {
- PrevAttachedProcess = NULL;
- }
- KeAttachProcess(Csrss);
- }
+ /* 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_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 if (Status != VIDEO_ENUM_MORE_DEVICES)
+ {
+ DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status);
+ break;
+ }
- /*
- Copy the bios.
- */
- Length = min(Length, 0x10000);
- if (RomImageBuffer != NULL)
- {
- ExFreePool(RomImageBuffer);
- }
- RomImageBuffer = ExAllocatePool(PagedPool, Length);
- if (RomImageBuffer == NULL)
- {
- return(NULL);
- }
- RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
+#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 */
- /*
- Detach from csrss if we attached.
- */
- if (CallingProcess != Csrss)
- {
- KeDetachProcess();
- if (NULL != PrevAttachedProcess)
- {
- KeAttachProcess(PrevAttachedProcess);
- }
- }
-
- return(RomImageBuffer);
- }
-}
+ }
-VOID
-STDCALL
-STATIC
-VideoPortDeferredRoutine ( IN PKDPC Dpc,
- IN PVOID DeferredContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2 )
-{
- PVOID HwDeviceExtension =
- ((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
- ((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
+ return NO_ERROR;
}
-BOOLEAN
-STDCALL
-VideoPortQueueDpc ( IN PVOID HwDeviceExtension,
- IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
- IN PVOID Context )
-{
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
- return KeInsertQueueDpc(&DeviceExtension->DpcObject,
- (PVOID)CallbackRoutine,
- (PVOID)Context);
-}
+/*
+ * @unimplemented
+ */
-PVOID
-STDCALL
-VideoPortGetAssociatedDeviceExtension ( IN PVOID DeviceObject )
+VP_STATUS NTAPI
+VideoPortCreateSecondaryDisplay(
+ IN PVOID HwDeviceExtension,
+ IN OUT PVOID *SecondaryDeviceExtension,
+ IN ULONG Flag)
{
- DPRINT1("VideoPortGetAssociatedDeviceExtension(): Unimplemented.\n");
- return(NULL);
+ DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
+ return NO_ERROR;
}
-PVOID
-STDCALL
-VideoPortAllocateCommonBuffer ( IN PVOID HwDeviceExtension,
- IN PVP_DMA_ADAPTER VpDmaAdapter,
- IN ULONG DesiredLength,
- OUT PPHYSICAL_ADDRESS LogicalAddress,
- IN BOOLEAN CacheEnabled,
- PVOID Reserved )
-{
- return HalAllocateCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter,
- DesiredLength,
- LogicalAddress,
- CacheEnabled);
-}
+/*
+ * @implemented
+ */
-VOID
-STDCALL
-VideoPortReleaseCommonBuffer ( IN PVOID HwDeviceExtension,
- IN PVP_DMA_ADAPTER VpDmaAdapter,
- IN ULONG Length,
- IN PHYSICAL_ADDRESS LogicalAddress,
- IN PVOID VirtualAddress,
- IN BOOLEAN CacheEnabled )
+BOOLEAN NTAPI
+VideoPortQueueDpc(
+ IN PVOID HwDeviceExtension,
+ IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
+ IN PVOID Context)
{
- HalFreeCommonBuffer((PADAPTER_OBJECT)VpDmaAdapter,
- Length,
- LogicalAddress,
- VirtualAddress,
- CacheEnabled);
+ return KeInsertQueueDpc(
+ &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
+ (PVOID)CallbackRoutine,
+ (PVOID)Context);
}
-VP_STATUS
-STDCALL
-VideoPortCreateSecondaryDisplay ( IN PVOID HwDeviceExtension,
- IN OUT PVOID *SecondaryDeviceExtension,
- IN ULONG Flag )
-{
- DPRINT1("VideoPortCreateSecondaryDisplay(): Unimplemented.\n");
- return STATUS_UNSUCCESSFUL;
-}
+/*
+ * @implemented
+ */
-VOID
-STDCALL
-VideoPortPutDmaAdapter ( IN PVOID HwDeviceExtension,
- IN PVP_DMA_ADAPTER VpDmaAdapter )
+PVOID NTAPI
+VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
{
- DPRINT("VideoPortPutDmaAdapter(): Unimplemented.\n");
-}
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
-PVP_DMA_ADAPTER
-STDCALL
-VideoPortGetDmaAdapter ( IN PVOID HwDeviceExtension,
- IN PVP_DEVICE_DESCRIPTION VpDeviceExtension )
-{
- DEVICE_DESCRIPTION DeviceDescription;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- ULONG NumberOfMapRegisters;
- PVP_DMA_ADAPTER Adapter;
-
- DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
- VIDEO_PORT_DEVICE_EXTENSION,
- MiniPortDeviceExtension);
-
- DPRINT("VideoPortGetDmaAdapter()\n");
-
- DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
- DeviceDescription.Master = TRUE /* ?? */;
- DeviceDescription.ScatterGather = VpDeviceExtension->ScatterGather;
- DeviceDescription.DemandMode = FALSE /* ?? */;
- DeviceDescription.AutoInitialize = FALSE /* ?? */;
- DeviceDescription.Dma32BitAddresses = VpDeviceExtension->Dma32BitAddresses;
- DeviceDescription.IgnoreCount = FALSE /* ?? */;
- DeviceDescription.Reserved1 = FALSE;
- DeviceDescription.BusNumber = DeviceExtension->SystemIoBusNumber;
- DeviceDescription.DmaChannel = 0 /* ?? */;
- DeviceDescription.InterfaceType = DeviceExtension->AdapterInterfaceType;
- DeviceDescription.DmaWidth = Width8Bits;
- DeviceDescription.DmaSpeed = Compatible;
- DeviceDescription.MaximumLength = VpDeviceExtension->MaximumLength;
- DeviceDescription.DmaPort = 0;
-
- Adapter =
- (PVP_DMA_ADAPTER)HalGetAdapter(&DeviceDescription, &NumberOfMapRegisters);
- DPRINT("Adapter %X\n", Adapter);
- return(Adapter);
+ DPRINT("VideoPortGetAssociatedDeviceExtension\n");
+ DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
+ if (!DeviceExtension)
+ return NULL;
+ return DeviceExtension->MiniPortDeviceExtension;
}
-
/*
* @implemented
*/
-VP_STATUS
-STDCALL
-VideoPortGetVersion ( IN PVOID HwDeviceExtension,
- IN OUT PVPOSVERSIONINFO VpOsVersionInfo )
+
+VP_STATUS NTAPI
+VideoPortGetVersion(
+ IN PVOID HwDeviceExtension,
+ IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
{
RTL_OSVERSIONINFOEXW Version;
VpOsVersionInfo->BuildNumber = Version.dwBuildNumber;
VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor;
VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor;
- return STATUS_SUCCESS;
+ return NO_ERROR;
}
- return STATUS_UNSUCCESSFUL;
+ return ERROR_INVALID_PARAMETER;
#else
VpOsVersionInfo->MajorVersion = 5;
VpOsVersionInfo->MinorVersion = 0;
VpOsVersionInfo->BuildNumber = 2195;
VpOsVersionInfo->ServicePackMajor = 4;
VpOsVersionInfo->ServicePackMinor = 0;
- return(STATUS_SUCCESS);
+ return NO_ERROR;
#endif
}
return ERROR_INVALID_PARAMETER;
}
-PVOID
-STDCALL
-VideoPortLockBuffer ( IN PVOID HwDeviceExtension,
- IN PVOID BaseAddress,
- IN ULONG Length,
- IN VP_LOCK_OPERATION Operation )
-{
- DPRINT1("VideoPortLockBuffer(): Unimplemented.\n");
- return NULL;
-}
+/*
+ * @implemented
+ */
-VOID
-STDCALL
-VideoPortUnlockBuffer ( IN PVOID HwDeviceExtension,
- IN PVOID Mdl )
+BOOLEAN NTAPI
+VideoPortCheckForDeviceExistence(
+ IN PVOID HwDeviceExtension,
+ IN USHORT VendorId,
+ IN USHORT DeviceId,
+ IN UCHAR RevisionId,
+ IN USHORT SubVendorId,
+ IN USHORT SubSystemId,
+ IN ULONG Flags)
{
- DPRINT1("VideoPortUnlockBuffer(): Unimplemented.\n");
-}
+ 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;
-VP_STATUS
-STDCALL
-VideoPortCreateEvent ( IN PVOID HwDeviceExtension,
- IN ULONG EventFlag,
- IN PVOID Unused,
- OUT PEVENT *Event)
-{
- EVENT_TYPE Type;
- (*Event) = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT),
- TAG_VIDEO_PORT);
- if ((*Event) == NULL)
- {
- return STATUS_NO_MEMORY;
- }
- if (EventFlag & NOTIFICATION_EVENT)
- {
- Type = NotificationEvent;
- }
- else
- {
- Type = SynchronizationEvent;
- }
- KeInitializeEvent((PKEVENT)*Event, Type, EventFlag & INITIAL_EVENT_SIGNALED);
- return STATUS_SUCCESS;
-}
+ DPRINT("VideoPortCheckForDeviceExistence\n");
-VP_STATUS
-STDCALL
-VideoPortDeleteEvent ( IN PVOID HwDeviceExtension,
- IN PEVENT Event)
-{
- ExFreePool(Event);
- return STATUS_SUCCESS;
-}
+ 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;
+ }
-LONG
-STDCALL
-VideoPortSetEvent ( IN PVOID HwDeviceExtension,
- IN PEVENT Event )
-{
- return KeSetEvent((PKEVENT)Event, IO_NO_INCREMENT, 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;
+ }
-VOID
-STDCALL
-VideoPortClearEvent ( IN PVOID HwDeviceExtension,
- IN PEVENT Event )
-{
- KeClearEvent((PKEVENT)Event);
-}
+ if (Flags & CDE_USE_REVISION)
+ PciFlags |= PCI_USE_REVISION;
+ if (Flags & CDE_USE_SUBSYSTEM_IDS)
+ PciFlags |= PCI_USE_SUBSYSTEM_IDS;
-VP_STATUS
-STDCALL
-VideoPortWaitForSingleObject ( IN PVOID HwDeviceExtension,
- IN PVOID Object,
- IN PLARGE_INTEGER Timeout OPTIONAL )
-{
- return KeWaitForSingleObject(Object,
- Executive,
- KernelMode,
- FALSE,
- Timeout);
-}
+ DevicePresent = PciDevicePresentInterface.IsDevicePresent(
+ VendorId, DeviceId, RevisionId,
+ SubVendorId, SubSystemId, PciFlags);
-BOOLEAN
-STDCALL
-VideoPortCheckForDeviceExistence ( IN PVOID HwDeviceExtension,
- IN USHORT VendorId,
- IN USHORT DeviceId,
- IN UCHAR RevisionId,
- IN USHORT SubVendorId,
- IN USHORT SubSystemId,
- IN ULONG Flags )
-{
- DPRINT1("VideoPortCheckForDeviceExistence(): Unimplemented.\n");
- return TRUE;
-}
+ PciDevicePresentInterface.InterfaceDereference(PciDevicePresentInterface.Context);
-VP_STATUS
-STDCALL
-VideoPortRegisterBugcheckCallback ( IN PVOID HwDeviceExtension,
- IN ULONG BugcheckCode,
- IN PVOID Callback,
- IN ULONG BugcheckDataSize )
-{
- DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
- return STATUS_UNSUCCESSFUL;
+ return DevicePresent;
}
-PVOID
-STDCALL
-VideoPortImageDirectoryEntryToData ( PVOID BaseAddress,
- ULONG Directory )
-{
- PIMAGE_NT_HEADERS NtHeader;
- ULONG Va;
-
- NtHeader = RtlImageNtHeader (BaseAddress);
- if (NtHeader == NULL)
- return NULL;
-
- if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
- return NULL;
-
- Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
- if (Va == 0)
- return NULL;
-
- return (PVOID)(BaseAddress + Va);
-}
+/*
+ * @unimplemented
+ */
-PVOID STDCALL
-VideoPortGetProcAddress(IN PVOID HwDeviceExtension,
- IN PUCHAR FunctionName)
+VP_STATUS NTAPI
+VideoPortRegisterBugcheckCallback(
+ IN PVOID HwDeviceExtension,
+ IN ULONG BugcheckCode,
+ IN PVOID Callback,
+ IN ULONG BugcheckDataSize)
{
- SYSTEM_LOAD_IMAGE GdiDriverInfo;
- PVOID BaseAddress;
- PIMAGE_EXPORT_DIRECTORY ExportDir;
- PUSHORT OrdinalPtr;
- PULONG NamePtr;
- PULONG AddressPtr;
- ULONG i = 0;
- NTSTATUS Status;
-
- DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
-
- RtlInitUnicodeString(&GdiDriverInfo.ModuleName, L"videoprt");
- Status = ZwSetSystemInformation(SystemLoadImage, &GdiDriverInfo,
- sizeof(SYSTEM_LOAD_IMAGE));
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Couldn't get our own module handle?\n");
- return NULL;
- }
-
- BaseAddress = GdiDriverInfo.ModuleBase;
-
- /* Get the pointer to the export directory */
- ExportDir = (PIMAGE_EXPORT_DIRECTORY)
- VideoPortImageDirectoryEntryToData (BaseAddress,
- IMAGE_DIRECTORY_ENTRY_EXPORT);
-
- /* search by name */
- AddressPtr = (PULONG)
- ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfFunctions);
- OrdinalPtr = (PUSHORT)
- ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNameOrdinals);
- NamePtr = (PULONG)
- ((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
- for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
- {
- if (!_strnicmp(FunctionName, (char*)(BaseAddress + *NamePtr),
- strlen(FunctionName)))
- {
- return (PVOID)((ULONG_PTR)BaseAddress +
- (ULONG_PTR)AddressPtr[*OrdinalPtr]);
- }
- }
- DPRINT("VideoPortGetProcAddress: Can't resolve symbol %s\n", FunctionName);
- return(NULL);
+ DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
+ return NO_ERROR;
}
-LONGLONG STDCALL
+/*
+ * @implemented
+ */
+
+LONGLONG NTAPI
VideoPortQueryPerformanceCounter(
IN PVOID HwDeviceExtension,
OUT PLONGLONG PerformanceFrequency OPTIONAL)
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)
+{
+}