*/
#include <errors.h>
-#include <ddk/ntddk.h>
+#include <roskrnl.h>
#include <ddk/ntddvid.h>
#include "../../../ntoskrnl/include/internal/v86m.h"
KIRQL IRQL;
KAFFINITY Affinity;
PVIDEO_HW_INITIALIZE HwInitialize;
+ PVIDEO_HW_RESET_HW HwResetHw;
LIST_ENTRY AddressMappingListHead;
INTERFACE_TYPE AdapterInterfaceType;
ULONG SystemIoBusNumber;
static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchOpen(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
IN PHYSICAL_ADDRESS IoAddress,
IN PVOID MappedAddress);
static BOOLEAN CsrssInitialized = FALSE;
-static HANDLE CsrssHandle = 0;
-static struct _EPROCESS* Csrss = NULL;
+static PEPROCESS Csrss = NULL;
+static PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
PBYTE ReturnCsrssAddress(void)
{
return(STATUS_SUCCESS);
}
+/*
+ * @implemented
+ */
VOID
VideoPortDebugPrint(IN ULONG DebugPrintLevel,
IN PCHAR DebugMessage, ...)
DbgPrint (Buffer);
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
UNIMPLEMENTED;
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
UNIMPLEMENTED;
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
InternalUnmapMemory(DeviceExtension, MappedAddress);
}
+
+/*
+ * @implemented
+ */
ULONG
STDCALL
VideoPortGetBusData(IN PVOID HwDeviceExtension,
Length);
}
+
+/*
+ * @implemented
+ */
UCHAR
STDCALL
VideoPortGetCurrentIrql(VOID)
return KeGetCurrentIrql();
}
+
+/*
+ * @implemented
+ */
PVOID
STDCALL
VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace);
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
UNIMPLEMENTED;
}
+
+/*
+ * @implemented
+ */
VP_STATUS
STDCALL
VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
return STATUS_SUCCESS;
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
*/
}
+
+/*
+ * @implemented
+ */
ULONG STDCALL
VideoPortInitialize(IN PVOID Context1,
IN PVOID Context2,
MPDriverObject->DeviceObject = MPDeviceObject;
/* Initialize the miniport drivers dispatch table */
- MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
- MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
- MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
+ MPDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH) VidDispatchOpen;
+ MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) VidDispatchClose;
+ MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) 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;
MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR);
return STATUS_SUCCESS;
}
+
+/*
+ * @implemented
+ */
VP_STATUS STDCALL
VideoPortInt10(IN PVOID HwDeviceExtension,
IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
{
KV86M_REGISTERS Regs;
NTSTATUS Status;
+ PEPROCESS CallingProcess;
DPRINT("VideoPortInt10\n");
- KeAttachProcess(Csrss);
+
+ CallingProcess = PsGetCurrentProcess();
+ if (CallingProcess != Csrss)
+ {
+ KeAttachProcess(Csrss);
+ }
memset(&Regs, 0, sizeof(Regs));
Regs.Eax = BiosArguments->Eax;
Regs.Ebp = BiosArguments->Ebp;
Status = Ke386CallBios(0x10, &Regs);
- KeDetachProcess();
+ if (CallingProcess != Csrss)
+ {
+ KeDetachProcess();
+ }
return(Status);
}
+
+/*
+ * @unimplemented
+ */
VOID
STDCALL
VideoPortLogError(IN PVOID HwDeviceExtension,
IN VP_STATUS ErrorCode,
IN ULONG UniqueId)
{
- DPRINT("VideoPortLogError\n");
- UNIMPLEMENTED;
+ 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);
+ }
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
UNIMPLEMENTED;
}
+
+/*
+ * @implemented
+ */
VP_STATUS
STDCALL
VideoPortMapMemory(IN PVOID HwDeviceExtension,
return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS;
}
+
+/*
+ * @implemented
+ */
UCHAR
STDCALL
VideoPortReadPortUchar(IN PUCHAR Port)
return READ_PORT_UCHAR(Port);
}
+
+/*
+ * @implemented
+ */
USHORT
STDCALL
VideoPortReadPortUshort(IN PUSHORT Port)
return READ_PORT_USHORT(Port);
}
+
+/*
+ * @implemented
+ */
ULONG
STDCALL
VideoPortReadPortUlong(IN PULONG Port)
return READ_PORT_ULONG(Port);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadPortBufferUchar(IN PUCHAR Port,
READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadPortBufferUshort(IN PUSHORT Port,
READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadPortBufferUlong(IN PULONG Port,
READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
UCHAR
STDCALL
VideoPortReadRegisterUchar(IN PUCHAR Register)
return READ_REGISTER_UCHAR(Register);
}
+
+/*
+ * @implemented
+ */
USHORT
STDCALL
VideoPortReadRegisterUshort(IN PUSHORT Register)
return READ_REGISTER_USHORT(Register);
}
+
+/*
+ * @implemented
+ */
ULONG
STDCALL
VideoPortReadRegisterUlong(IN PULONG Register)
return READ_REGISTER_ULONG(Register);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadRegisterBufferUchar(IN PUCHAR Register,
READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadRegisterBufferUshort(IN PUSHORT Register,
READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortReadRegisterBufferUlong(IN PULONG Register,
READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
VideoPortScanRom(IN PVOID HwDeviceExtension,
IN ULONG RomLength,
IN PUCHAR String)
{
- DPRINT("VideoPortScanRom\n");
- UNIMPLEMENTED;
+ 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);
+ }
+ }
+
+ return Found;
}
+
+/*
+ * @implemented
+ */
ULONG
STDCALL
VideoPortSetBusData(IN PVOID HwDeviceExtension,
Length);
}
+
+/*
+ * @implemented
+ */
VP_STATUS
STDCALL
VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
ValueLength);
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
UNIMPLEMENTED;
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortStartTimer(IN PVOID HwDeviceExtension)
IoStartTimer(DeviceExtension->DeviceObject);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortStopTimer(IN PVOID HwDeviceExtension)
IoStopTimer(DeviceExtension->DeviceObject);
}
+
+/*
+ * @implemented
+ */
BOOLEAN
STDCALL
VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
OUT PVOID Context)
{
+ BOOLEAN Ret;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ KIRQL OldIrql;
+
DPRINT("VideoPortSynchronizeExecution\n");
- UNIMPLEMENTED;
+
+ 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;
}
+
+/*
+ * @implemented
+ */
VP_STATUS
STDCALL
VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
return STATUS_SUCCESS;
}
+
+/*
+ * @unimplemented
+ */
VP_STATUS
STDCALL
VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
return NO_ERROR;
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortUchar(IN PUCHAR Port,
WRITE_PORT_UCHAR(Port, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortUshort(IN PUSHORT Port,
WRITE_PORT_USHORT(Port, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortUlong(IN PULONG Port,
WRITE_PORT_ULONG(Port, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortBufferUchar(IN PUCHAR Port,
WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortBufferUshort(IN PUSHORT Port,
WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWritePortBufferUlong(IN PULONG Port,
WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWriteRegisterUchar(IN PUCHAR Register,
WRITE_REGISTER_UCHAR(Register, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWriteRegisterUshort(IN PUSHORT Register,
WRITE_REGISTER_USHORT(Register, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWriteRegisterUlong(IN PULONG Register,
WRITE_REGISTER_ULONG(Register, Value);
}
+
+/*
+ * @implemented
+ */
VOID
STDCALL
VideoPortWriteRegisterBufferUchar(IN PUCHAR Register,
WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID STDCALL
VideoPortWriteRegisterBufferUshort(IN PUSHORT Register,
IN PUSHORT Buffer,
WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID STDCALL
VideoPortWriteRegisterBufferUlong(IN PULONG Register,
IN PULONG Buffer,
WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
}
+
+/*
+ * @implemented
+ */
VOID STDCALL
VideoPortZeroDeviceMemory(OUT PVOID Destination,
IN ULONG Length)
RtlZeroMemory(Destination, Length);
}
+/*
+ * Reset display to blue screen
+ */
+static BOOLEAN STDCALL
+VideoPortResetDisplayParameters(Columns, Rows)
+{
+ if (NULL != ResetDisplayParametersDeviceExtension)
+ {
+ return(FALSE);
+ }
+ if (NULL == ResetDisplayParametersDeviceExtension->HwResetHw)
+ {
+ return(FALSE);
+ }
+ if (!ResetDisplayParametersDeviceExtension->HwResetHw(&ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
+ Columns, Rows))
+ {
+ return(FALSE);
+ }
+
+ ResetDisplayParametersDeviceExtension = NULL;
+
+ return TRUE;
+}
-// ------------------------------------------- Nondiscardable statics
-// VidDispatchOpenClose
+// VidDispatchOpen
//
// DESCRIPTION:
-// Answer requests for Open/Close calls: a null operation
+// Answer requests for Open calls
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
static NTSTATUS STDCALL
-VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
- IN PIRP Irp)
+VidDispatchOpen(IN PDEVICE_OBJECT pDO,
+ IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
- PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
- DPRINT("VidDispatchOpenClose() called\n");
+ DPRINT("VidDispatchOpen() called\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp);
- if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
- CsrssInitialized == FALSE)
+ if (! CsrssInitialized)
{
DPRINT("Referencing CSRSS\n");
Csrss = PsGetCurrentProcess();
- CsrssInitialized = TRUE;
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;
}
}
+
+ Irp->IoStatus.Information = FILE_OPENED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+// VidDispatchClose
+//
+// DESCRIPTION:
+// Answer requests for Close calls
+//
+// RUN LEVEL:
+// PASSIVE_LEVEL
+//
+// ARGUMENTS:
+// Standard dispatch arguments
+//
+// RETURNS:
+// NTSTATUS
+//
+
+static NTSTATUS STDCALL
+VidDispatchClose(IN PDEVICE_OBJECT pDO,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpStack;
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("VidDispatchClose() called\n");
+
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (! CsrssInitialized)
+ {
+ CsrssInitialized = TRUE;
+ }
else
{
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ HalReleaseDisplayOwnership();
}
- Irp->IoStatus.Information = FILE_OPENED;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
AddressMapping->MappingCount--;
if (0 == AddressMapping->MappingCount)
{
-#ifdef TODO
MmUnmapIoSpace(AddressMapping->MappedAddress,
AddressMapping->NumberOfUchars);
-#else
-DPRINT("MmUnmapIoSpace(0x%08x, 0x%08x)\n", AddressMapping->MappedAddress, AddressMapping->NumberOfUchars);
-#endif
RemoveEntryList(Entry);
ExFreePool(AddressMapping);