* If not, write to the Free Software Foundation,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * $Id: videoprt.c,v 1.27 2004/08/31 20:17:17 hbirr Exp $
+ * $Id$
*/
#include "videoprt.h"
-#include "internal/ps.h"
+#include <wdmguid.h>
/* GLOBAL VARIABLES ***********************************************************/
ULONG CsrssInitialized = FALSE;
-PEPROCESS Csrss = NULL;
+PKPROCESS Csrss = NULL;
+ULONG VideoPortDeviceNumber = 0;
/* PRIVATE FUNCTIONS **********************************************************/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
return STATUS_SUCCESS;
}
-PVOID STDCALL
+PVOID NTAPI
IntVideoPortImageDirectoryEntryToData(
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);
+
+ return (PVOID)((ULONG_PTR)BaseAddress + Va);
}
-PVOID STDCALL
+PVOID NTAPI
IntVideoPortGetProcAddress(
IN PVOID HwDeviceExtension,
IN PUCHAR FunctionName)
{
- SYSTEM_LOAD_IMAGE GdiDriverInfo;
+ SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
PVOID BaseAddress;
PIMAGE_EXPORT_DIRECTORY ExportDir;
PUSHORT OrdinalPtr;
DPRINT("VideoPortGetProcAddress(%s)\n", FunctionName);
- RtlInitUnicodeString(&GdiDriverInfo.ModuleName, L"videoprt");
+ RtlInitUnicodeString(&GdiDriverInfo.DriverName, L"videoprt");
Status = ZwSetSystemInformation(
- SystemLoadImage,
- &GdiDriverInfo,
- sizeof(SYSTEM_LOAD_IMAGE));
+ SystemLoadGdiDriverInformation,
+ &GdiDriverInfo,
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't get our own module handle?\n");
return NULL;
}
- BaseAddress = GdiDriverInfo.ModuleBase;
+ BaseAddress = GdiDriverInfo.ImageAddress;
/* Get the pointer to the export directory */
ExportDir = (PIMAGE_EXPORT_DIRECTORY)IntVideoPortImageDirectoryEntryToData(
((ULONG_PTR)BaseAddress + (ULONG_PTR)ExportDir->AddressOfNames);
for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
{
- if (!_strnicmp(FunctionName, (char*)(BaseAddress + *NamePtr),
- strlen(FunctionName)))
+ if (!_strnicmp((PCHAR)FunctionName, (PCHAR)((ULONG_PTR)BaseAddress + *NamePtr),
+ strlen((PCHAR)FunctionName)))
{
- return (PVOID)((ULONG_PTR)BaseAddress +
- (ULONG_PTR)AddressPtr[*OrdinalPtr]);
+ return (PVOID)((ULONG_PTR)BaseAddress +
+ (ULONG_PTR)AddressPtr[*OrdinalPtr]);
}
}
return NULL;
}
-VOID STDCALL
+VOID NTAPI
IntVideoPortDeferredRoutine(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
- PVOID HwDeviceExtension =
+ PVOID HwDeviceExtension =
&((PVIDEO_PORT_DEVICE_EXTENSION)DeferredContext)->MiniPortDeviceExtension;
((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
}
-ULONG STDCALL
-IntVideoPortAllocateDeviceNumber(VOID)
-{
- NTSTATUS Status;
- ULONG DeviceNumber;
- WCHAR SymlinkBuffer[20];
- UNICODE_STRING SymlinkName;
-
- for (DeviceNumber = 0;;)
- {
- OBJECT_ATTRIBUTES Obj;
- HANDLE ObjHandle;
-
- swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber + 1);
- RtlInitUnicodeString(&SymlinkName, SymlinkBuffer);
- InitializeObjectAttributes(&Obj, &SymlinkName, 0, NULL, NULL);
- Status = ZwOpenSymbolicLinkObject(&ObjHandle, GENERIC_READ, &Obj);
- if (NT_SUCCESS(Status))
- {
- ZwClose(ObjHandle);
- DeviceNumber++;
- continue;
- }
- else if (Status == STATUS_NOT_FOUND || Status == STATUS_UNSUCCESSFUL)
- break;
- else
- return 0xFFFFFFFF;
- }
-
- return DeviceNumber;
-}
-
-NTSTATUS STDCALL
-IntVideoPortFindAdapter(
+NTSTATUS NTAPI
+IntVideoPortCreateAdapterDeviceObject(
IN PDRIVER_OBJECT DriverObject,
IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
- IN PDEVICE_OBJECT PhysicalDeviceObject)
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
{
- WCHAR DeviceVideoBuffer[20];
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
ULONG DeviceNumber;
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;
- PDEVICE_OBJECT DeviceObject;
- BOOL LegacyDetection = FALSE;
+ 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 = IntVideoPortAllocateDeviceNumber();
+ DeviceNumber = VideoPortDeviceNumber++;
if (DeviceNumber == 0xFFFFFFFF)
{
DPRINT("Can't find free device number\n");
}
/*
- * Create the device object, we need it even for calling HwFindAdapter :(
+ * Create the device object.
*/
/* Create a unicode device name. */
FILE_DEVICE_VIDEO,
0,
TRUE,
- &DeviceObject);
+ DeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
}
- /*
+ /*
* Set the buffering strategy here. If you change this, remember
* to change VidDispatchDeviceControl too.
*/
- DeviceObject->Flags |= DO_BUFFERED_IO;
+ (*DeviceObject)->Flags |= DO_BUFFERED_IO;
/*
* Initialize device extension.
*/
- DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)((*DeviceObject)->DeviceExtension);
+ DeviceExtension->DeviceNumber = DeviceNumber;
+ DeviceExtension->DriverObject = DriverObject;
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
- DeviceExtension->FunctionalDeviceObject = DeviceObject;
+ DeviceExtension->FunctionalDeviceObject = *DeviceObject;
DeviceExtension->DriverExtension = DriverExtension;
- DeviceExtension->RegistryPath.Length =
- DeviceExtension->RegistryPath.MaximumLength =
+ 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);
+ TAG_VIDEO_PORT);
swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device0",
DriverExtension->RegistryPath.Buffer);
- if (PhysicalDeviceObject == NULL)
- {
- LegacyDetection = TRUE;
- }
- else
+ if (PhysicalDeviceObject != NULL)
{
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
"use legacy detection method, but even that doesn't mean that\n"
"it will work.\n");
DeviceExtension->PhysicalDeviceObject = NULL;
- LegacyDetection = TRUE;
}
}
- DeviceExtension->AdapterInterfaceType =
+ DeviceExtension->AdapterInterfaceType =
DriverExtension->InitializationData.AdapterInterfaceType;
if (PhysicalDeviceObject != NULL)
DevicePropertyAddress,
Size,
&DeviceExtension->SystemIoSlotNumber,
- &Size);
+ &Size);
}
InitializeListHead(&DeviceExtension->AddressMappingListHead);
IntVideoPortDeferredRoutine,
DeviceExtension);
+ KeInitializeMutex(&DeviceExtension->DeviceLock, 0);
+
+ /* Attach the device. */
+ if (PhysicalDeviceObject != NULL)
+ DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(
+ *DeviceObject, PhysicalDeviceObject);
+
+ return STATUS_SUCCESS;
+}
+
+
+/* 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)
+{
+ 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;
+
/*
- * Uff, the DeviceExtension is setup. Now it's needed to setup
- * a ConfigInfo structure that we will pass to HwFindAdapter.
+ * Setup a ConfigInfo structure that we will pass to HwFindAdapter.
*/
RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
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(
if (NT_SUCCESS(Status))
{
ConfigInfo.SystemMemorySize =
- SystemBasicInfo.NumberOfPhysicalPages *
- SystemBasicInfo.PhysicalPageSize;
+ SystemBasicInfo.NumberOfPhysicalPages *
+ SystemBasicInfo.PageSize;
}
/*
* 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;
+ }
+
if (LegacyDetection)
{
ULONG BusNumber, MaxBuses;
DeviceExtension->SystemIoBusNumber =
ConfigInfo.SystemIoBusNumber = BusNumber;
- RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
+ RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension,
DriverExtension->InitializationData.HwDeviceExtensionSize);
-
+
/* FIXME: Need to figure out what string to pass as param 3. */
Status = DriverExtension->InitializationData.HwFindAdapter(
&DeviceExtension->MiniPortDeviceExtension,
}
else
{
- DPRINT("HwFindAdapter call failed with error %X\n", Status);
+ DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
IoDeleteDevice(DeviceObject);
if (Status != NO_ERROR)
{
- DPRINT("HwFindAdapter call failed with error %X\n", Status);
+ DPRINT("HwFindAdapter call failed with error 0x%X\n", Status);
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
IoDeleteDevice(DeviceObject);
return Status;
* 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);
return STATUS_INSUFFICIENT_RESOURCES;
}
- if (PhysicalDeviceObject != NULL)
- IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+ /*
+ * Query children of the device.
+ */
+ VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension, NULL);
DPRINT("STATUS_SUCCESS\n");
return STATUS_SUCCESS;
}
-VOID FASTCALL
-IntAttachToCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess)
-{
- *CallingProcess = PsGetCurrentProcess();
- if (*CallingProcess != Csrss)
- {
- if (PsGetCurrentThread()->ThreadsProcess != *CallingProcess)
- {
- *PrevAttachedProcess = *CallingProcess;
- KeDetachProcess();
- }
- else
- {
- *PrevAttachedProcess = NULL;
- }
- KeAttachProcess(Csrss);
- }
-}
-
-VOID FASTCALL
-IntDetachFromCSRSS(PEPROCESS *CallingProcess, PEPROCESS *PrevAttachedProcess)
-{
- if (*CallingProcess != Csrss)
- {
- KeDetachProcess();
- if (NULL != *PrevAttachedProcess)
- {
- KeAttachProcess(*PrevAttachedProcess);
- }
- }
-}
+VOID FASTCALL
+IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
+{
+ *CallingProcess = (PKPROCESS)PsGetCurrentProcess();
+ if (*CallingProcess != Csrss)
+ {
+ KeStackAttachProcess(Csrss, ApcState);
+ }
+}
+
+VOID FASTCALL
+IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
+{
+ if (*CallingProcess != Csrss)
+ {
+ KeUnstackDetachProcess(ApcState);
+ }
+}
/* PUBLIC FUNCTIONS ***********************************************************/
* @implemented
*/
-ULONG STDCALL
+ULONG NTAPI
VideoPortInitialize(
IN PVOID Context1,
IN PVOID Context2,
DPRINT("VideoPortInitialize\n");
+ /*
+ * As a first thing do parameter checks.
+ */
+
+ if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA))
+ {
+ return STATUS_REVISION_MISMATCH;
+ }
+
+ if (HwInitializationData->HwFindAdapter == NULL ||
+ HwInitializationData->HwInitialize == NULL ||
+ HwInitializationData->HwStartIO == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
/*
* 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 calls VideoPortInitialize
+ * drivers in that case adjust parameters and call VideoPortInitialize
* again.
*/
{
return Status;
}
+
+ /*
+ * Save the registry path. This should be done only once even if
+ * VideoPortInitialize is called multiple times.
+ */
+
+ 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);
+ }
}
/*
RtlCopyMemory(
&DriverExtension->InitializationData,
HwInitializationData,
- min(sizeof(VIDEO_HW_INITIALIZATION_DATA),
- HwInitializationData->HwInitDataSize));
+ 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;
- RtlCopyMemory(&DriverExtension->RegistryPath, RegistryPath, sizeof(UNICODE_STRING));
-
switch (HwInitializationData->HwInitDataSize)
{
/*
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;
/*
if (LegacyDetection)
{
- Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, NULL);
+ 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;
}
vsprintf(Buffer, DebugMessage, ap);
va_end(ap);
- DbgPrint(Buffer);
+ DbgPrintEx(DPFLTR_IHVVIDEO_ID, DebugPrintLevel, Buffer);
}
/*
* @unimplemented
*/
-VOID STDCALL
+VOID NTAPI
VideoPortLogError(
IN PVOID HwDeviceExtension,
IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
* @implemented
*/
-UCHAR STDCALL
+UCHAR NTAPI
VideoPortGetCurrentIrql(VOID)
{
return KeGetCurrentIrql();
PMINIPORT_GET_REGISTRY_ROUTINE HwGetRegistryRoutine;
} QUERY_REGISTRY_CALLBACK_CONTEXT, *PQUERY_REGISTRY_CALLBACK_CONTEXT;
-static NTSTATUS STDCALL
+static NTSTATUS NTAPI
QueryRegistryCallback(
IN PWSTR ValueName,
IN ULONG ValueType,
* @unimplemented
*/
-VP_STATUS STDCALL
+VP_STATUS NTAPI
VideoPortGetRegistryParameters(
IN PVOID HwDeviceExtension,
IN PWSTR ParameterName,
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
- if (IsParameterFileName)
- {
- UNIMPLEMENTED;
- }
-
Context.HwDeviceExtension = HwDeviceExtension;
Context.HwContext = HwContext;
Context.HwGetRegistryRoutine = GetRegistryRoutine;
QueryTable[1].QueryRoutine = NULL;
QueryTable[1].Name = NULL;
- return NT_SUCCESS(RtlQueryRegistryValues(
+ if (!NT_SUCCESS(RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
DeviceExtension->RegistryPath.Buffer,
QueryTable,
&Context,
- NULL)) ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
+ NULL)))
+ return ERROR_INVALID_PARAMETER;
+
+ if (IsParameterFileName)
+ {
+ /* FIXME: need to read the contents of the file */
+ UNIMPLEMENTED;
+ }
+
+ return ERROR_SUCCESS;
}
/*
* @implemented
*/
-VP_STATUS STDCALL
+VP_STATUS NTAPI
VideoPortSetRegistryParameters(
IN PVOID HwDeviceExtension,
IN PWSTR ValueName,
IN ULONG ValueLength)
{
DPRINT("VideoPortSetRegistryParameters\n");
- assert_irql(PASSIVE_LEVEL);
+ ASSERT_IRQL(PASSIVE_LEVEL);
return RtlWriteRegistryValue(
RTL_REGISTRY_ABSOLUTE,
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->RegistryPath.Buffer,
/*
* @implemented
- */
+ */
-VP_STATUS STDCALL
+VP_STATUS NTAPI
VideoPortGetVgaStatus(
IN PVOID HwDeviceExtension,
OUT PULONG VgaStatus)
}
}
- return ERROR_INVALID_FUNCTION;
+ return ERROR_INVALID_FUNCTION;
}
/*
* @implemented
*/
-PVOID STDCALL
+PVOID NTAPI
VideoPortGetRomImage(
IN PVOID HwDeviceExtension,
IN PVOID Unused1,
IN ULONG Length)
{
static PVOID RomImageBuffer = NULL;
- PEPROCESS CallingProcess;
- PEPROCESS PrevAttachedProcess;
+ PKPROCESS CallingProcess;
+ KAPC_STATE ApcState;
DPRINT("VideoPortGetRomImage(HwDeviceExtension 0x%X Length 0x%X)\n",
HwDeviceExtension, Length);
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
+ * 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.
+ * bios area into memory so we'll copy from there.
*/
/* Copy the bios. */
return NULL;
}
- IntAttachToCSRSS(&CallingProcess, &PrevAttachedProcess);
+ IntAttachToCSRSS(&CallingProcess, &ApcState);
RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
- IntDetachFromCSRSS(&CallingProcess, &PrevAttachedProcess);
+ IntDetachFromCSRSS(&CallingProcess, &ApcState);
return RomImageBuffer;
}
* @implemented
*/
-BOOLEAN STDCALL
+BOOLEAN NTAPI
VideoPortScanRom(
- IN PVOID HwDeviceExtension,
+ IN PVOID HwDeviceExtension,
IN PUCHAR RomBase,
IN ULONG RomLength,
IN PUCHAR String)
DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);
- StringLength = strlen(String);
+ StringLength = strlen((PCHAR)String);
Found = FALSE;
SearchLocation = RomBase;
for (SearchLocation = RomBase;
* @implemented
*/
-BOOLEAN STDCALL
+BOOLEAN NTAPI
VideoPortSynchronizeExecution(
IN PVOID HwDeviceExtension,
IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
case VpLowPriority:
Ret = (*SynchronizeRoutine)(Context);
break;
-
+
case VpMediumPriority:
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
if (DeviceExtension->InterruptObject == NULL)
}
/*
- * @unimplemented
- */
-
-BOOLEAN STDCALL
-VideoPortDDCMonitorHelper(
- PVOID HwDeviceExtension,
- /*PI2C_FNC_TABLE*/PVOID I2CFunctions,
- PUCHAR pEdidBuffer,
- ULONG EdidBufferSize
- )
-{
- DPRINT1("VideoPortDDCMonitorHelper() - Unimplemented.\n");
- return FALSE;
-}
-
-/*
- * @unimplemented
+ * @implemented
*/
-VP_STATUS STDCALL
+VP_STATUS NTAPI
VideoPortEnumerateChildren(
IN PVOID HwDeviceExtension,
IN PVOID Reserved)
{
- DPRINT1("VideoPortEnumerateChildren(): Unimplemented.\n");
+ 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;
+ }
+
+ /* 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_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;
+ }
+
+#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 STDCALL
+VP_STATUS NTAPI
VideoPortCreateSecondaryDisplay(
IN PVOID HwDeviceExtension,
IN OUT PVOID *SecondaryDeviceExtension,
* @implemented
*/
-BOOLEAN STDCALL
+BOOLEAN NTAPI
VideoPortQueueDpc(
IN PVOID HwDeviceExtension,
IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
IN PVOID Context)
{
return KeInsertQueueDpc(
- &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
+ &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
(PVOID)CallbackRoutine,
(PVOID)Context);
}
/*
- * @unimplemented
+ * @implemented
*/
-PVOID STDCALL
+PVOID NTAPI
VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
{
- DPRINT1("VideoPortGetAssociatedDeviceExtension: Unimplemented.\n");
- return NULL;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("VideoPortGetAssociatedDeviceExtension\n");
+ DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
+ if (!DeviceExtension)
+ return NULL;
+ return DeviceExtension->MiniPortDeviceExtension;
}
/*
* @implemented
*/
-VP_STATUS STDCALL
+VP_STATUS NTAPI
VideoPortGetVersion(
IN PVOID HwDeviceExtension,
IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOLEAN STDCALL
+BOOLEAN NTAPI
VideoPortCheckForDeviceExistence(
IN PVOID HwDeviceExtension,
IN USHORT VendorId,
IN USHORT SubSystemId,
IN ULONG Flags)
{
- DPRINT1("VideoPortCheckForDeviceExistence: Unimplemented.\n");
- return TRUE;
+ 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 STDCALL
+VP_STATUS NTAPI
VideoPortRegisterBugcheckCallback(
IN PVOID HwDeviceExtension,
IN ULONG BugcheckCode,
* @implemented
*/
-LONGLONG STDCALL
+LONGLONG NTAPI
VideoPortQueryPerformanceCounter(
IN PVOID HwDeviceExtension,
OUT PLONGLONG PerformanceFrequency OPTIONAL)
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)
+{
+}