[VIDEOPRT/WINSERV] Move mapping the BIOS memory from winsrv to videoprt, where it belongs.

[VIDEOPRT] Implement some registry support routines to create new style (XP+) registry keys. Handle IOCTL_VIDEO_INIT_WIN32K_CALLBACKS in videoprt, reorganize the code to dispatch ioctls. Simplify failure path in IntVideoPortFindAdapter

svn path=/trunk/; revision=61013
This commit is contained in:
Timo Kreuzer 2013-11-16 18:40:24 +00:00
parent 21c33d59ee
commit 6abf558a05
7 changed files with 1054 additions and 377 deletions

View file

@ -15,6 +15,7 @@ list(APPEND SOURCE
funclist.c
int10.c
interrupt.c
registry.c
resource.c
services.c
spinlock.c

View file

@ -24,6 +24,7 @@
/* GLOBAL VARIABLES ***********************************************************/
PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
PVIDEO_WIN32K_CALLOUT Win32kCallout;
/* PRIVATE FUNCTIONS **********************************************************/
@ -110,12 +111,9 @@ IntVideoPortDispatchOpen(
Csrss = (PKPROCESS)PsGetCurrentProcess();
INFO_(VIDEOPRT, "Csrss %p\n", Csrss);
IntInitializeVideoAddressSpace();
CsrssInitialized = TRUE;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -171,6 +169,206 @@ IntVideoPortDispatchClose(
return STATUS_SUCCESS;
}
PSTR
IoctlName(ULONG Ioctl)
{
switch(Ioctl)
{
case IOCTL_VIDEO_ENABLE_VDM:
return "IOCTL_VIDEO_ENABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_DISABLE_VDM:
return "IOCTL_VIDEO_DISABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_REGISTER_VDM:
return "IOCTL_VIDEO_REGISTER_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE:
return "IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE:
return "IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_MONITOR_DEVICE:
return "IOCTL_VIDEO_MONITOR_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_ENUM_MONITOR_PDO:
return "IOCTL_VIDEO_ENUM_MONITOR_PDO"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS:
return "IOCTL_VIDEO_INIT_WIN32K_CALLBACKS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS:
return "IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_IS_VGA_DEVICE:
return "IOCTL_VIDEO_IS_VGA_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_USE_DEVICE_IN_SESSION:
return "IOCTL_VIDEO_USE_DEVICE_IN_SESSION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_PREPARE_FOR_EARECOVERY:
return "IOCTL_VIDEO_PREPARE_FOR_EARECOVERY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
return "IOCTL_VIDEO_SAVE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x80, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
return "IOCTL_VIDEO_RESTORE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x81, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
return "IOCTL_VIDEO_QUERY_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
return "IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x101, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
return "IOCTL_VIDEO_QUERY_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x102, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_CURRENT_MODE:
return "IOCTL_VIDEO_SET_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x103, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_RESET_DEVICE:
return "IOCTL_VIDEO_RESET_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x104, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_LOAD_AND_SET_FONT:
return "IOCTL_VIDEO_LOAD_AND_SET_FONT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x105, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
return "IOCTL_VIDEO_SET_PALETTE_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x106, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
return "IOCTL_VIDEO_SET_COLOR_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x107, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_ENABLE_CURSOR:
return "IOCTL_VIDEO_ENABLE_CURSOR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x108, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_DISABLE_CURSOR:
return "IOCTL_VIDEO_DISABLE_CURSOR"; // CTL_CODE (FILE_DEVICE_VIDEO, 0x109, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_CURSOR_ATTR:
return "IOCTL_VIDEO_SET_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10a, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
return "IOCTL_VIDEO_QUERY_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10b, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_CURSOR_POSITION:
return "IOCTL_VIDEO_SET_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10c, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
return "IOCTL_VIDEO_QUERY_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10d, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_ENABLE_POINTER:
return "IOCTL_VIDEO_ENABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10e, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_DISABLE_POINTER:
return "IOCTL_VIDEO_DISABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10f, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_POINTER_ATTR:
return "IOCTL_VIDEO_SET_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x110, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_POINTER_ATTR:
return "IOCTL_VIDEO_QUERY_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x111, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_POINTER_POSITION:
return "IOCTL_VIDEO_SET_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x112, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_POINTER_POSITION:
return "IOCTL_VIDEO_QUERY_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x113, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
return "IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x114, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
return "IOCTL_VIDEO_GET_BANK_SELECT_CODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x115, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
return "IOCTL_VIDEO_MAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x116, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
return "IOCTL_VIDEO_UNMAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x117, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
return "IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x118, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
return "IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x119, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
return "IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11a, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_POWER_MANAGEMENT:
return "IOCTL_VIDEO_SET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11b, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_GET_POWER_MANAGEMENT:
return "IOCTL_VIDEO_GET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11c, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
return "IOCTL_VIDEO_SHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11d, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
return "IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11e, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_COLOR_LUT_DATA:
return "IOCTL_VIDEO_SET_COLOR_LUT_DATA"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11f, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_GET_CHILD_STATE:
return "IOCTL_VIDEO_GET_CHILD_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x120, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION:
return "IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x121, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION:
return "IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x122, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SWITCH_DUALVIEW:
return "IOCTL_VIDEO_SWITCH_DUALVIEW"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x123, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_BANK_POSITION:
return "IOCTL_VIDEO_SET_BANK_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x124, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS:
return "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS:
return "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
case IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS:
return "IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
}
return "<unknown ioctl code";
}
static
NTSTATUS
VideoPortInitWin32kCallbacks(
IN PDEVICE_OBJECT DeviceObject,
PVIDEO_WIN32K_CALLBACKS Win32kCallbacks,
ULONG BufferLength)
{
if (BufferLength < sizeof(VIDEO_WIN32K_CALLBACKS))
{
return STATUS_BUFFER_TOO_SMALL;
}
/* Save the callout function globally */
Win32kCallout = Win32kCallbacks->Callout;
/* Return reasonable values to win32k */
Win32kCallbacks->bACPI = FALSE;
Win32kCallbacks->pPhysDeviceObject = DeviceObject;
Win32kCallbacks->DualviewFlags = 0;
return STATUS_SUCCESS;
}
static
NTSTATUS
VideoPortForwardDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
VIDEO_REQUEST_PACKET vrp;
TRACE_(VIDEOPRT, "VideoPortForwardDeviceControl\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
DriverExtension = DeviceExtension->DriverExtension;
/* Translate the IRP to a VRP */
vrp.StatusBlock = (PSTATUS_BLOCK)&Irp->IoStatus;
vrp.IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
INFO_(VIDEOPRT, "- IoControlCode: %x\n", vrp.IoControlCode);
/* 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 */
DriverExtension->InitializationData.HwStartIO(&DeviceExtension->MiniPortDeviceExtension,
&vrp);
INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
/* Map from win32 error codes to NT status values. */
switch (Irp->IoStatus.Status)
{
case NO_ERROR:
return STATUS_SUCCESS;
case ERROR_NOT_ENOUGH_MEMORY:
return STATUS_INSUFFICIENT_RESOURCES;
case ERROR_MORE_DATA:
return STATUS_BUFFER_OVERFLOW;
case ERROR_INVALID_FUNCTION:
return STATUS_NOT_IMPLEMENTED;
case ERROR_INVALID_PARAMETER:
return STATUS_INVALID_PARAMETER;
case ERROR_INSUFFICIENT_BUFFER:
return STATUS_BUFFER_TOO_SMALL;
case ERROR_DEV_NOT_EXIST:
return STATUS_DEVICE_DOES_NOT_EXIST;
case ERROR_IO_PENDING:
return STATUS_PENDING;
default:
return STATUS_UNSUCCESSFUL;
}
}
/*
* IntVideoPortDispatchDeviceControl
*
@ -186,76 +384,35 @@ IntVideoPortDispatchDeviceControl(
IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
PVIDEO_REQUEST_PACKET vrp;
NTSTATUS Status;
ULONG IoControlCode;
TRACE_(VIDEOPRT, "IntVideoPortDispatchDeviceControl\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
DriverExtension = DeviceExtension->DriverExtension;
/* Translate the IRP to a VRP */
vrp = ExAllocatePoolWithTag(NonPagedPool,
sizeof(VIDEO_REQUEST_PACKET),
TAG_REQUEST_PACKET);
if (vrp == NULL)
IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
INFO_(VIDEOPRT, "- IoControlCode: %x: %s\n", IoControlCode, IoctlName(IoControlCode));
switch(IoControlCode)
{
return STATUS_NO_MEMORY;
case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS:
INFO_(VIDEOPRT, "- IOCTL_VIDEO_INIT_WIN32K_CALLBACKS\n");
Status = VideoPortInitWin32kCallbacks(DeviceObject,
Irp->AssociatedIrp.SystemBuffer,
IrpStack->Parameters.DeviceIoControl.InputBufferLength);
break;
default:
/* Forward to the Miniport Driver */
Status = VideoPortForwardDeviceControl(DeviceObject, Irp);
break;
}
vrp->StatusBlock = (PSTATUS_BLOCK) & (Irp->IoStatus);
vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
INFO_(VIDEOPRT, "- IoControlCode: %x\n", vrp->IoControlCode);
/* 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 */
DriverExtension->InitializationData.HwStartIO(
&DeviceExtension->MiniPortDeviceExtension,
vrp);
/* Free the VRP */
ExFreePoolWithTag(vrp, TAG_REQUEST_PACKET);
INFO_(VIDEOPRT, "- Returned status: %x\n", Irp->IoStatus.Status);
if (Irp->IoStatus.Status != STATUS_SUCCESS)
{
switch (Irp->IoStatus.Status)
{
case ERROR_NOT_ENOUGH_MEMORY:
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
break;
case ERROR_MORE_DATA:
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
break;
case ERROR_INVALID_FUNCTION:
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
break;
case ERROR_INVALID_PARAMETER:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
case ERROR_INSUFFICIENT_BUFFER:
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
break;
case ERROR_DEV_NOT_EXIST:
Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
break;
case ERROR_IO_PENDING:
Irp->IoStatus.Status = STATUS_PENDING;
break;
}
}
Status = Irp->IoStatus.Status;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
@ -278,7 +435,6 @@ IntVideoPortDispatchDeviceControl(
* Run Level
* PASSIVE_LEVEL
*/
NTSTATUS
NTAPI
IntVideoPortDispatchWrite(

View file

@ -23,6 +23,115 @@
/* PRIVATE FUNCTIONS **********************************************************/
#if defined(_M_IX86) || defined(_M_AMD64)
NTSTATUS
NTAPI
IntInitializeVideoAddressSpace(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
NTSTATUS Status;
HANDLE PhysMemHandle;
PVOID BaseAddress;
LARGE_INTEGER Offset;
SIZE_T ViewSize;
CHAR IVTAndBda[1024+256];
/* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
BaseAddress = 0;
ViewSize = 1024 * 1024;
Status = ZwFreeVirtualMemory(NtCurrentProcess(),
&BaseAddress,
&ViewSize,
MEM_RELEASE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
return 0;
}
/* Open the physical memory section */
InitializeObjectAttributes(&ObjectAttributes,
&PhysMemName,
0,
NULL,
NULL);
Status = ZwOpenSection(&PhysMemHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
return Status;
}
/* Map the BIOS and device registers into the address space */
Offset.QuadPart = 0xa0000;
ViewSize = 0x100000 - 0xa0000;
BaseAddress = (PVOID)0xa0000;
Status = ZwMapViewOfSection(PhysMemHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&Offset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't map physical memory (%x)\n", Status);
ZwClose(PhysMemHandle);
return Status;
}
/* Close physical memory section handle */
ZwClose(PhysMemHandle);
if (BaseAddress != (PVOID)0xa0000)
{
DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
BaseAddress);
return STATUS_UNSUCCESSFUL;
}
/* Allocate some low memory to use for the non-BIOS
* parts of the v86 mode address space
*/
BaseAddress = (PVOID)0x1;
ViewSize = 0xa0000 - 0x1000;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&BaseAddress,
0,
&ViewSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
return Status;
}
if (BaseAddress != (PVOID)0x0)
{
DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
BaseAddress);
return 0;
}
/* Get the real mode IVT and BDA from the kernel */
Status = NtVdmControl(VdmInitialize, IVTAndBda);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtVdmControl failed (status %x)\n", Status);
return Status;
}
/* Return success */
return STATUS_SUCCESS;
}
#endif
#if defined(_M_IX86)
VP_STATUS NTAPI
IntInt10AllocateBuffer(

View file

@ -0,0 +1,636 @@
/*
* VideoPort driver
*
* Copyright (C) 2002-2004, 2007 ReactOS Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "videoprt.h"
NTSTATUS
NTAPI
IntCopyRegistryKey(
_In_ HANDLE SourceKeyHandle,
_In_ HANDLE DestKeyHandle)
{
PVOID InfoBuffer;
PKEY_BASIC_INFORMATION KeyInformation;
PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG Index, InformationLength, RequiredLength;
UNICODE_STRING NameString;
NTSTATUS Status;
HANDLE SourceSubKeyHandle, DestSubKeyHandle;
/* Start with no buffer, set initial size */
InfoBuffer = NULL;
InformationLength = 256;
/* Start looping with key index 0 */
Index = 0;
while (TRUE)
{
/* Check if we have no buffer */
if (InfoBuffer == NULL)
{
/* Allocate a new buffer */
InfoBuffer = ExAllocatePoolWithTag(PagedPool,
InformationLength,
TAG_VIDEO_PORT_BUFFER);
if (InfoBuffer == NULL)
{
ERR_(VIDEOPRT, "Could not allocate buffer for key info\n");
return Status;
}
}
/* Enumerate the next sub-key */
KeyInformation = InfoBuffer;
Status = ZwEnumerateKey(SourceKeyHandle,
Index,
KeyBasicInformation,
KeyInformation,
InformationLength,
&RequiredLength);
if ((Status == STATUS_BUFFER_OVERFLOW) ||
(Status == STATUS_BUFFER_TOO_SMALL))
{
/* Free the buffer and remember the required size */
ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
InfoBuffer = NULL;
InformationLength = RequiredLength;
/* Try again */
continue;
}
else if (Status == STATUS_NO_MORE_ENTRIES)
{
/* We are done with the sub-keys */
break;
}
else if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "ZwEnumerateKey failed, status 0x%lx\n", Status);
goto Cleanup;
}
/* Initialize a unicode string from the key name */
NameString.Buffer = KeyInformation->Name;
NameString.Length = (USHORT)KeyInformation->NameLength;
NameString.MaximumLength = NameString.Length;
/* Initialize object attributes and open the source sub-key */
InitializeObjectAttributes(&ObjectAttributes,
&NameString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
SourceKeyHandle,
NULL);
Status = ZwOpenKey(&SourceSubKeyHandle, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "failed to open the source key.\n");
goto Cleanup;
}
/* Initialize object attributes and create the dest sub-key */
InitializeObjectAttributes(&ObjectAttributes,
&NameString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
DestKeyHandle,
NULL);
Status = ZwCreateKey(&DestSubKeyHandle,
KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
NULL);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "failed to create the destination key.\n");
ObCloseHandle(SourceSubKeyHandle, KernelMode);
goto Cleanup;
}
/* Recursively copy the sub-key */
Status = IntCopyRegistryKey(SourceSubKeyHandle, DestSubKeyHandle);
if (!NT_SUCCESS(Status))
{
/* Just warn, but continue with the remaining sub-keys */
WARN_(VIDEOPRT, "failed to copy subkey '%wZ'.\n", &NameString);
}
/* Close the sub-key handles */
ObCloseHandle(SourceSubKeyHandle, KernelMode);
ObCloseHandle(DestSubKeyHandle, KernelMode);
/* Next sub-key */
Index++;
}
/* Start looping with value index 0 */
Index = 0;
while (TRUE)
{
/* Check if we have no buffer */
if (InfoBuffer == NULL)
{
/* Allocate a new buffer */
InfoBuffer = ExAllocatePoolWithTag(PagedPool,
InformationLength,
TAG_VIDEO_PORT_BUFFER);
if (InfoBuffer == NULL)
{
ERR_(VIDEOPRT, "Could not allocate buffer for key values\n");
return Status;
}
}
/* Enumerate the next value */
KeyValueInformation = InfoBuffer;
Status = ZwEnumerateValueKey(SourceKeyHandle,
Index,
KeyValueFullInformation,
KeyValueInformation,
InformationLength,
&RequiredLength);
if ((Status == STATUS_BUFFER_OVERFLOW) ||
(Status == STATUS_BUFFER_TOO_SMALL))
{
/* Free the buffer and remember the required size */
ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
InfoBuffer = NULL;
InformationLength = RequiredLength;
/* Try again */
continue;
}
else if (Status == STATUS_NO_MORE_ENTRIES)
{
/* We are done with the values */
Status = STATUS_SUCCESS;
break;
}
else if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "ZwEnumerateValueKey failed, status 0x%lx\n", Status);
goto Cleanup;
}
/* Initialize a unicode string from the value name */
NameString.Buffer = KeyValueInformation->Name;
NameString.Length = (USHORT)KeyValueInformation->NameLength;
NameString.MaximumLength = NameString.Length;
/* Create the key value in the destination key */
Status = ZwSetValueKey(DestKeyHandle,
&NameString,
KeyValueInformation->TitleIndex,
KeyValueInformation->Type,
(PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset,
KeyValueInformation->DataLength);
if (!NT_SUCCESS(Status))
{
/* Just warn, but continue with the remaining sub-keys */
WARN_(VIDEOPRT, "failed to set value '%wZ'.\n", NameString);
}
/* Next subkey */
Index++;
}
Cleanup:
/* Free the buffer and return the failure code */
if (InfoBuffer != NULL)
ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
return Status;
}
NTSTATUS
NTAPI
IntCopyRegistryValue(
HANDLE SourceKeyHandle,
HANDLE DestKeyHandle,
PWSTR ValueName)
{
PKEY_VALUE_PARTIAL_INFORMATION ValueInformation;
UNICODE_STRING ValueNameString;
ULONG Length;
NTSTATUS Status;
RtlInitUnicodeString(&ValueNameString, ValueName);
/* Query the value length */
Status = ZwQueryValueKey(SourceKeyHandle,
&ValueNameString,
KeyValuePartialInformation,
NULL,
0,
&Length);
if ((Status != STATUS_BUFFER_OVERFLOW) &&
(Status != STATUS_BUFFER_TOO_SMALL))
{
/* The key seems not present */
NT_ASSERT(!NT_SUCCESS(Status));
return Status;
}
/* Allocate a buffer */
ValueInformation = ExAllocatePoolWithTag(PagedPool, Length, TAG_VIDEO_PORT_BUFFER);
if (ValueInformation == NULL)
{
return Status;
}
/* Query the value */
Status = ZwQueryValueKey(SourceKeyHandle,
&ValueNameString,
KeyValuePartialInformation,
ValueInformation,
Length,
&Length);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(ValueInformation, TAG_VIDEO_PORT_BUFFER);
return Status;
}
/* Write the registry value */
Status = ZwSetValueKey(DestKeyHandle,
&ValueNameString,
ValueInformation->TitleIndex,
ValueInformation->Type,
ValueInformation->Data,
ValueInformation->DataLength);
ExFreePoolWithTag(ValueInformation, TAG_VIDEO_PORT_BUFFER);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status);
}
return Status;
}
NTSTATUS
NTAPI
IntSetupDeviceSettingsKey(
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension)
{
static UNICODE_STRING SettingsKeyName = RTL_CONSTANT_STRING(L"Settings");
HANDLE DevInstRegKey, SourceKeyHandle, DestKeyHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
/* Open the software key: HKLM\System\CurrentControlSet\Control\Class\<ClassGUID>\<n> */
Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DRIVER,
KEY_ALL_ACCESS,
&DevInstRegKey);
if (Status != STATUS_SUCCESS)
{
ERR_(VIDEOPRT, "Failed to open device software key. Status 0x%lx", Status);
return Status;
}
/* Open the 'Settings' sub-key */
InitializeObjectAttributes(&ObjectAttributes,
&SettingsKeyName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
DevInstRegKey,
NULL);
Status = ZwOpenKey(&DestKeyHandle, KEY_WRITE, &ObjectAttributes);
/* Close the device software key */
ObCloseHandle(DevInstRegKey, KernelMode);
if (Status != STATUS_SUCCESS)
{
ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx", Status);
return Status;
}
/* Open the device profile key */
InitializeObjectAttributes(&ObjectAttributes,
&DeviceExtension->RegistryPath,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&SourceKeyHandle, KEY_WRITE, &ObjectAttributes);
if (Status != STATUS_SUCCESS)
{
ERR_(VIDEOPRT, "ZwOpenKey failed for settings key: status 0x%lx", Status);
ObCloseHandle(DestKeyHandle, KernelMode);
return Status;
}
IntCopyRegistryValue(SourceKeyHandle, DestKeyHandle, L"InstalledDisplayDrivers");
IntCopyRegistryValue(SourceKeyHandle, DestKeyHandle, L"Attach.ToDesktop");
ObCloseHandle(SourceKeyHandle, KernelMode);
ObCloseHandle(DestKeyHandle, KernelMode);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
IntCreateNewRegistryPath(
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension)
{
static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId");
static UNICODE_STRING ControlVideoPathName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\");
HANDLE DevInstRegKey, SettingsKey, NewKey;
UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH];
UNICODE_STRING VideoIdString;
UUID VideoId;
PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ;
NTSTATUS Status;
ULONG ResultLength;
USHORT KeyMaxLength;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */
Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DEVICE,
KEY_ALL_ACCESS,
&DevInstRegKey);
if (Status != STATUS_SUCCESS)
{
ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status);
return Status;
}
/* Query the VideoId value */
ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer;
Status = ZwQueryValueKey(DevInstRegKey,
&VideoIdValueName,
KeyValuePartialInformation,
ValueInformation,
sizeof(VideoIdBuffer),
&ResultLength);
if (!NT_SUCCESS(Status))
{
/* Create a new video Id */
Status = ExUuidCreate(&VideoId);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status);
ObCloseHandle(DevInstRegKey, KernelMode);
return Status;
}
/* Convert the GUID into a string */
Status = RtlStringFromGUID(&VideoId, &VideoIdString);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status);
ObCloseHandle(DevInstRegKey, KernelMode);
return Status;
}
/* Copy the GUID String to our buffer */
ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH);
RtlCopyMemory(ValueInformation->Data,
VideoIdString.Buffer,
ValueInformation->DataLength);
/* Free the GUID string */
RtlFreeUnicodeString(&VideoIdString);
/* Write the VideoId registry value */
Status = ZwSetValueKey(DevInstRegKey,
&VideoIdValueName,
0,
REG_SZ,
ValueInformation->Data,
ValueInformation->DataLength);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status);
ObCloseHandle(DevInstRegKey, KernelMode);
return Status;
}
}
/* Initialize the VideoId string from the registry data */
VideoIdString.Buffer = (PWCHAR)ValueInformation->Data;
VideoIdString.Length = (USHORT)ValueInformation->DataLength;
VideoIdString.MaximumLength = VideoIdString.Length;
/* Close the hardware key */
ObCloseHandle(DevInstRegKey, KernelMode);
/* Calculate the size needed for the new registry path name */
KeyMaxLength = ControlVideoPathName.Length +
VideoIdString.Length +
sizeof(L"\\0000");
/* Allocate the path name buffer */
DeviceExtension->NewRegistryPath.Length = 0;
DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength;
DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
KeyMaxLength,
TAG_VIDEO_PORT);
if (DeviceExtension->NewRegistryPath.Buffer == NULL)
{
ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Copy the root key name and append the VideoId string */
RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath,
&ControlVideoPathName);
RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath,
&VideoIdString);
/* Check if we have the key already */
Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
DeviceExtension->NewRegistryPath.Buffer);
if (Status != STATUS_SUCCESS)
{
/* Try to create the new key */
Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
DeviceExtension->NewRegistryPath.Buffer);
}
/* Append a the instance path */ /// \todo HACK
RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\");
RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000");
/* Check this key again */
Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
DeviceExtension->NewRegistryPath.Buffer);
if (Status != STATUS_SUCCESS)
{
/* Try to create the new key */
Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
DeviceExtension->NewRegistryPath.Buffer);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath);
return Status;
}
/* Open the new key */
InitializeObjectAttributes(&ObjectAttributes,
&DeviceExtension->NewRegistryPath,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
return Status;
}
/* Open the device profile key */
InitializeObjectAttributes(&ObjectAttributes,
&DeviceExtension->RegistryPath,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
ObCloseHandle(NewKey, KernelMode);
return Status;
}
/* Copy the registry data from the legacy key */
Status = IntCopyRegistryKey(SettingsKey, NewKey);
}
return Status;
}
NTSTATUS
NTAPI
IntCreateRegistryPath(
IN PCUNICODE_STRING DriverRegistryPath,
OUT PUNICODE_STRING DeviceRegistryPath)
{
static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
static WCHAR ControlSet[] = L"CONTROLSET";
static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
static WCHAR Insert2[] = L"\\Device0";
BOOLEAN Valid;
UNICODE_STRING AfterControlSet;
AfterControlSet = *DriverRegistryPath;
/* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */
Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) &&
0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem,
wcslen(RegistryMachineSystem)));
if (Valid)
{
AfterControlSet.Buffer += wcslen(RegistryMachineSystem);
AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL);
/* Check if path contains CURRENTCONTROLSET */
if (AfterControlSet.Length > sizeof(CurrentControlSet) &&
0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet)))
{
AfterControlSet.Buffer += wcslen(CurrentControlSet);
AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL);
}
/* Check if path contains CONTROLSETnum */
else if (AfterControlSet.Length > sizeof(ControlSet) &&
0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet)))
{
AfterControlSet.Buffer += wcslen(ControlSet);
AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL);
while (AfterControlSet.Length > 0 &&
*AfterControlSet.Buffer >= L'0' &&
*AfterControlSet.Buffer <= L'9')
{
AfterControlSet.Buffer++;
AfterControlSet.Length -= sizeof(WCHAR);
}
Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer);
AfterControlSet.Buffer++;
AfterControlSet.Length -= sizeof(WCHAR);
AfterControlSet.MaximumLength = AfterControlSet.Length;
}
else
{
Valid = FALSE;
}
}
if (Valid)
{
DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2);
DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool,
DeviceRegistryPath->MaximumLength,
TAG_VIDEO_PORT);
if (DeviceRegistryPath->Buffer != NULL)
{
/* Build device path */
wcsncpy(DeviceRegistryPath->Buffer,
DriverRegistryPath->Buffer,
AfterControlSet.Buffer - DriverRegistryPath->Buffer);
DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert1);
RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);
/* Check if registry key exists */
Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceRegistryPath->Buffer));
if (!Valid)
ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT);
}
else
{
Valid = FALSE;
}
}
else
{
WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath);
}
/* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */
if (!Valid)
{
DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2);
DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
DeviceRegistryPath->MaximumLength,
TAG_VIDEO_PORT);
if (!DeviceRegistryPath->Buffer)
return STATUS_NO_MEMORY;
RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);
}
DbgPrint("Formatted registry key '%wZ' -> '%wZ'\n",
DriverRegistryPath, DeviceRegistryPath);
return STATUS_SUCCESS;
}

View file

@ -75,114 +75,6 @@ IntVideoPortDeferredRoutine(
((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
}
static
NTSTATUS
IntCreateRegistryPath(
IN PCUNICODE_STRING DriverRegistryPath,
OUT PUNICODE_STRING DeviceRegistryPath)
{
static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
static WCHAR ControlSet[] = L"CONTROLSET";
static WCHAR Insert1[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
static WCHAR Insert2[] = L"\\Device0";
BOOLEAN Valid;
UNICODE_STRING AfterControlSet;
AfterControlSet = *DriverRegistryPath;
/* Check if path begins with \\REGISTRY\\MACHINE\\SYSTEM\\ */
Valid = (DriverRegistryPath->Length > sizeof(RegistryMachineSystem) &&
0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem,
wcslen(RegistryMachineSystem)));
if (Valid)
{
AfterControlSet.Buffer += wcslen(RegistryMachineSystem);
AfterControlSet.Length -= sizeof(RegistryMachineSystem) - sizeof(UNICODE_NULL);
/* Check if path contains CURRENTCONTROLSET */
if (AfterControlSet.Length > sizeof(CurrentControlSet) &&
0 == _wcsnicmp(AfterControlSet.Buffer, CurrentControlSet, wcslen(CurrentControlSet)))
{
AfterControlSet.Buffer += wcslen(CurrentControlSet);
AfterControlSet.Length -= sizeof(CurrentControlSet) - sizeof(UNICODE_NULL);
}
/* Check if path contains CONTROLSETnum */
else if (AfterControlSet.Length > sizeof(ControlSet) &&
0 == _wcsnicmp(AfterControlSet.Buffer, ControlSet, wcslen(ControlSet)))
{
AfterControlSet.Buffer += wcslen(ControlSet);
AfterControlSet.Length -= sizeof(ControlSet) - sizeof(UNICODE_NULL);
while (AfterControlSet.Length > 0 &&
*AfterControlSet.Buffer >= L'0' &&
*AfterControlSet.Buffer <= L'9')
{
AfterControlSet.Buffer++;
AfterControlSet.Length -= sizeof(WCHAR);
}
Valid = (AfterControlSet.Length > 0 && L'\\' == *AfterControlSet.Buffer);
AfterControlSet.Buffer++;
AfterControlSet.Length -= sizeof(WCHAR);
AfterControlSet.MaximumLength = AfterControlSet.Length;
}
else
{
Valid = FALSE;
}
}
if (Valid)
{
DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert1) + sizeof(Insert2);
DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(PagedPool,
DeviceRegistryPath->MaximumLength,
TAG_VIDEO_PORT);
if (DeviceRegistryPath->Buffer != NULL)
{
/* Build device path */
wcsncpy(DeviceRegistryPath->Buffer,
DriverRegistryPath->Buffer,
AfterControlSet.Buffer - DriverRegistryPath->Buffer);
DeviceRegistryPath->Length = (AfterControlSet.Buffer - DriverRegistryPath->Buffer) * sizeof(WCHAR);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert1);
RtlAppendUnicodeStringToString(DeviceRegistryPath, &AfterControlSet);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);
/* Check if registry key exists */
Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceRegistryPath->Buffer));
if (!Valid)
ExFreePoolWithTag(DeviceRegistryPath->Buffer, TAG_VIDEO_PORT);
}
else
{
Valid = FALSE;
}
}
else
{
WARN_(VIDEOPRT, "Unparsable registry path %wZ", DriverRegistryPath);
}
/* If path doesn't point to *ControlSet*, use DriverRegistryPath directly */
if (!Valid)
{
DeviceRegistryPath->MaximumLength = DriverRegistryPath->Length + sizeof(Insert2);
DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
DeviceRegistryPath->MaximumLength,
TAG_VIDEO_PORT);
if (!DeviceRegistryPath->Buffer)
return STATUS_NO_MEMORY;
RtlCopyUnicodeString(DeviceRegistryPath, DriverRegistryPath);
RtlAppendUnicodeToString(DeviceRegistryPath, Insert2);
}
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
IntVideoPortCreateAdapterDeviceObject(
@ -227,10 +119,10 @@ IntVideoPortCreateAdapterDeviceObject(
DriverExtension->InitializationData.HwDeviceExtensionSize);
/* Create the device object. */
Status = IoCreateDevice(
DriverObject,
sizeof(VIDEO_PORT_DEVICE_EXTENSION) +
DriverExtension->InitializationData.HwDeviceExtensionSize,
Size = sizeof(VIDEO_PORT_DEVICE_EXTENSION) +
DriverExtension->InitializationData.HwDeviceExtensionSize;
Status = IoCreateDevice(DriverObject,
Size,
&DeviceName,
FILE_DEVICE_VIDEO,
0,
@ -261,7 +153,7 @@ IntVideoPortCreateAdapterDeviceObject(
InitializeListHead(&DeviceExtension->ChildDeviceList);
/* Get the registry path associated with this driver. */
/* Get the registry path associated with this device. */
Status = IntCreateRegistryPath(&DriverExtension->RegistryPath,
&DeviceExtension->RegistryPath);
if (!NT_SUCCESS(Status))
@ -276,8 +168,7 @@ IntVideoPortCreateAdapterDeviceObject(
{
/* Get bus number from the upper level bus driver. */
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(
PhysicalDeviceObject,
Status = IoGetDeviceProperty(PhysicalDeviceObject,
DevicePropertyBusNumber,
Size,
&DeviceExtension->SystemIoBusNumber,
@ -334,6 +225,9 @@ IntVideoPortCreateAdapterDeviceObject(
*DeviceObject,
PhysicalDeviceObject);
IntCreateNewRegistryPath(DeviceExtension);
IntSetupDeviceSettingsKey(DeviceExtension);
/* Remove the initailizing flag */
(*DeviceObject)->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
@ -434,12 +328,7 @@ IntVideoPortFindAdapter(
else
{
ERR_(VIDEOPRT, "HwFindAdapter call failed with error 0x%X\n", Status);
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
if (DeviceExtension->NextDeviceObject)
IoDetachDevice(DeviceExtension->NextDeviceObject);
IoDeleteDevice(DeviceObject);
return Status;
goto Failure;
}
}
}
@ -457,11 +346,7 @@ IntVideoPortFindAdapter(
if (Status != NO_ERROR)
{
ERR_(VIDEOPRT, "HwFindAdapter call failed with error 0x%X\n", Status);
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
if (DeviceExtension->NextDeviceObject)
IoDetachDevice(DeviceExtension->NextDeviceObject);
IoDeleteDevice(DeviceObject);
return Status;
goto Failure;
}
/*
@ -501,27 +386,18 @@ IntVideoPortFindAdapter(
/* Allocate interrupt for device. */
if (!IntVideoPortSetupInterrupt(DeviceObject, DriverExtension, &ConfigInfo))
{
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
if (DeviceExtension->NextDeviceObject)
IoDetachDevice(DeviceExtension->NextDeviceObject);
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Failure;
}
/*
* Allocate timer for device.
*/
/* Allocate timer for device. */
if (!IntVideoPortSetupTimer(DeviceObject, DriverExtension))
{
if (DeviceExtension->InterruptObject != NULL)
IoDisconnectInterrupt(DeviceExtension->InterruptObject);
if (DeviceExtension->NextDeviceObject)
IoDetachDevice(DeviceExtension->NextDeviceObject);
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
IoDeleteDevice(DeviceObject);
ERR_(VIDEOPRT, "IntVideoPortSetupTimer failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Failure;
}
/* Query children of the device. */
@ -529,6 +405,13 @@ IntVideoPortFindAdapter(
INFO_(VIDEOPRT, "STATUS_SUCCESS\n");
return STATUS_SUCCESS;
Failure:
RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
if (DeviceExtension->NextDeviceObject)
IoDetachDevice(DeviceExtension->NextDeviceObject);
IoDeleteDevice(DeviceObject);
return Status;
}
VOID
@ -584,9 +467,9 @@ VideoPortInitialize(
return STATUS_REVISION_MISMATCH;
}
if (HwInitializationData->HwFindAdapter == NULL ||
HwInitializationData->HwInitialize == NULL ||
HwInitializationData->HwStartIO == NULL)
if ((HwInitializationData->HwFindAdapter == NULL) ||
(HwInitializationData->HwInitialize == NULL) ||
(HwInitializationData->HwStartIO == NULL))
{
ERR_(VIDEOPRT, "Invalid HwInitializationData\n");
return STATUS_INVALID_PARAMETER;
@ -628,10 +511,10 @@ VideoPortInitialize(
/* Determine type of the miniport driver */
if ((HwInitializationData->HwInitDataSize >=
FIELD_OFFSET(VIDEO_HW_INITIALIZATION_DATA, HwQueryInterface))
&& HwInitializationData->HwSetPowerState
&& HwInitializationData->HwGetPowerState
&& HwInitializationData->HwGetVideoChildDescriptor)
FIELD_OFFSET(VIDEO_HW_INITIALIZATION_DATA, HwQueryInterface)) &&
(HwInitializationData->HwSetPowerState != NULL) &&
(HwInitializationData->HwGetPowerState != NULL) &&
(HwInitializationData->HwGetVideoChildDescriptor != NULL))
{
INFO_(VIDEOPRT, "The miniport is a PnP miniport driver\n");
PnpDriver = TRUE;
@ -658,12 +541,10 @@ VideoPortInitialize(
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
if (DriverExtension == NULL)
{
Status = IoAllocateDriverObjectExtension(
DriverObject,
Status = IoAllocateDriverObjectExtension(DriverObject,
DriverObject,
sizeof(VIDEO_PORT_DRIVER_EXTENSION),
(PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
ERR_(VIDEOPRT, "IoAllocateDriverObjectExtension failed 0x%x\n", Status);
@ -699,9 +580,7 @@ VideoPortInitialize(
}
}
/*
* Copy the correct miniport initialization data to the device extension.
*/
/* Copy the correct miniport initialization data to the device extension. */
RtlCopyMemory(&DriverExtension->InitializationData,
HwInitializationData,
HwInitializationData->HwInitDataSize);
@ -728,6 +607,7 @@ VideoPortInitialize(
/* power management */
DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower;
}
Status = IntVideoPortCreateAdapterDeviceObject(DriverObject,
DriverExtension,
NULL,

View file

@ -30,6 +30,7 @@
#include <ndk/inbvfuncs.h>
#include <ndk/kefuncs.h>
#include <ndk/rtlfuncs.h>
#include <ndk/obfuncs.h>
#define __BROKEN__
#include <miniport.h>
@ -46,6 +47,8 @@
#define TAG_VIDEO_PORT_BUFFER '\0mpV'
#define TAG_REQUEST_PACKET 'qRpV'
#define GUID_STRING_LENGTH 38 * sizeof(WCHAR)
typedef struct _VIDEO_PORT_ADDRESS_MAPPING
{
LIST_ENTRY List;
@ -93,6 +96,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
PDEVICE_OBJECT FunctionalDeviceObject;
PDEVICE_OBJECT NextDeviceObject;
UNICODE_STRING RegistryPath;
UNICODE_STRING NewRegistryPath;
PKINTERRUPT InterruptObject;
KSPIN_LOCK InterruptSpinLock;
PCM_RESOURCE_LIST AllocatedResources;
@ -280,6 +284,10 @@ IntVideoPortGetProcAddress(
/* int10.c */
NTSTATUS
NTAPI
IntInitializeVideoAddressSpace(VOID);
VP_STATUS NTAPI
IntInt10AllocateBuffer(
IN PVOID Context,
@ -314,4 +322,36 @@ IntInt10CallBios(
IN PVOID Context,
IN OUT PINT10_BIOS_ARGUMENTS BiosArguments);
/* registry.c */
NTSTATUS
NTAPI
IntCopyRegistryKey(
_In_ HANDLE SourceKeyHandle,
_In_ HANDLE DestKeyHandle);
NTSTATUS
NTAPI
IntCopyRegistryValue(
HANDLE SourceKeyHandle,
HANDLE DestKeyHandle,
PWSTR ValueName);
NTSTATUS
NTAPI
IntSetupDeviceSettingsKey(
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension);
NTSTATUS
NTAPI
IntCreateNewRegistryPath(
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension);
NTSTATUS
NTAPI
IntCreateRegistryPath(
IN PCUNICODE_STRING DriverRegistryPath,
OUT PUNICODE_STRING DeviceRegistryPath);
#endif /* VIDEOPRT_H */

View file

@ -89,150 +89,6 @@ BOOL WINAPI _UserSoundSentry(VOID)
return TRUE;
}
ULONG
InitializeVideoAddressSpace(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
NTSTATUS Status;
HANDLE PhysMemHandle;
PVOID BaseAddress;
LARGE_INTEGER Offset;
SIZE_T ViewSize;
CHAR IVTAndBda[1024+256];
/* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
BaseAddress = 0;
ViewSize = 1024 * 1024;
Status = ZwFreeVirtualMemory(NtCurrentProcess(),
&BaseAddress,
&ViewSize,
MEM_RELEASE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
return 0;
}
/* Open the physical memory section */
InitializeObjectAttributes(&ObjectAttributes,
&PhysMemName,
0,
NULL,
NULL);
Status = ZwOpenSection(&PhysMemHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
return 0;
}
/* Map the BIOS and device registers into the address space */
Offset.QuadPart = 0xa0000;
ViewSize = 0x100000 - 0xa0000;
BaseAddress = (PVOID)0xa0000;
Status = ZwMapViewOfSection(PhysMemHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&Offset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't map physical memory (%x)\n", Status);
ZwClose(PhysMemHandle);
return 0;
}
/* Close physical memory section handle */
ZwClose(PhysMemHandle);
if (BaseAddress != (PVOID)0xa0000)
{
DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
BaseAddress);
return 0;
}
/* Allocate some low memory to use for the non-BIOS
* parts of the v86 mode address space
*/
BaseAddress = (PVOID)0x1;
ViewSize = 0xa0000 - 0x1000;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&BaseAddress,
0,
&ViewSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
return 0;
}
if (BaseAddress != (PVOID)0x0)
{
DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
BaseAddress);
return 0;
}
/* Get the real mode IVT and BDA from the kernel */
Status = NtVdmControl(VdmInitialize, IVTAndBda);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtVdmControl failed (status %x)\n", Status);
return 0;
}
/* Return success */
return 1;
}
/**********************************************************************
* UserpInitVideo
*
* TODO: we need a virtual device for sessions other than
* TODO: the console one
*/
NTSTATUS
UserpInitVideo(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
IO_STATUS_BLOCK Iosb;
HANDLE VideoHandle = (HANDLE) 0;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s called\n", __FUNCTION__);
InitializeVideoAddressSpace();
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);
Status = NtOpenFile(&VideoHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
0,
0);
if (NT_SUCCESS(Status))
{
NtClose(VideoHandle);
}
return Status;
}
// From win32ss/user/win32csr/dllmain.c
VOID
WINAPI
@ -287,8 +143,7 @@ CSR_SERVER_DLL_INIT(UserServerDllInitialization)
UserServerHeap = RtlGetProcessHeap();
/* Initialize the video */
UserpInitVideo();
NtUserInitialize(0, NULL, NULL);
NtUserInitialize(0, NULL, NULL); //
PrivateCsrssManualGuiCheck(0);
/* Setup the DLL Object */