mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-31 12:23:31 +00:00
Store real parameters registry key in DEVICEMAP\VIDEO
Use it in win32k when loading and storing settings (SetupDevMode and IntChangeDisplaySettings) svn path=/trunk/; revision=22169
This commit is contained in:
@@ -130,6 +130,94 @@ IntVideoPortDeferredRoutine(
|
||||
((PMINIPORT_DPC_ROUTINE)SystemArgument1)(HwDeviceExtension, SystemArgument2);
|
||||
}
|
||||
|
||||
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";
|
||||
LPWSTR ProfilePath = NULL;
|
||||
BOOLEAN Valid;
|
||||
PWCHAR AfterControlSet;
|
||||
|
||||
Valid = (0 == _wcsnicmp(DriverRegistryPath->Buffer, RegistryMachineSystem,
|
||||
wcslen(RegistryMachineSystem)));
|
||||
{
|
||||
AfterControlSet = DriverRegistryPath->Buffer + wcslen(RegistryMachineSystem);
|
||||
if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet)))
|
||||
{
|
||||
AfterControlSet += wcslen(CurrentControlSet);
|
||||
}
|
||||
else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet)))
|
||||
{
|
||||
AfterControlSet += wcslen(ControlSet);
|
||||
while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet)
|
||||
{
|
||||
AfterControlSet++;
|
||||
}
|
||||
Valid = (L'\\' == *AfterControlSet);
|
||||
AfterControlSet++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Valid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Valid)
|
||||
{
|
||||
ProfilePath = ExAllocatePoolWithTag(PagedPool,
|
||||
(wcslen(DriverRegistryPath->Buffer) +
|
||||
wcslen(Insert1) + wcslen(Insert2) + 1) * sizeof(WCHAR),
|
||||
TAG_VIDEO_PORT);
|
||||
if (NULL != ProfilePath)
|
||||
{
|
||||
wcsncpy(ProfilePath, DriverRegistryPath->Buffer, AfterControlSet - DriverRegistryPath->Buffer);
|
||||
wcscpy(ProfilePath + (AfterControlSet - DriverRegistryPath->Buffer), Insert1);
|
||||
wcscat(ProfilePath, AfterControlSet);
|
||||
wcscat(ProfilePath, Insert2);
|
||||
|
||||
Valid = NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ProfilePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
Valid = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Unparsable registry path %wZ", DriverRegistryPath);
|
||||
}
|
||||
|
||||
if (Valid)
|
||||
{
|
||||
RtlInitUnicodeString(DeviceRegistryPath, ProfilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ProfilePath)
|
||||
ExFreePoolWithTag(ProfilePath, TAG_VIDEO_PORT);
|
||||
|
||||
DeviceRegistryPath->Length =
|
||||
DeviceRegistryPath->MaximumLength =
|
||||
DriverRegistryPath->Length + (9 * sizeof(WCHAR));
|
||||
DeviceRegistryPath->Length -= sizeof(WCHAR);
|
||||
DeviceRegistryPath->Buffer = ExAllocatePoolWithTag(
|
||||
NonPagedPool,
|
||||
DeviceRegistryPath->MaximumLength,
|
||||
TAG_VIDEO_PORT);
|
||||
if (!DeviceRegistryPath->Buffer)
|
||||
return STATUS_NO_MEMORY;
|
||||
swprintf(DeviceRegistryPath->Buffer, L"%s\\Device0",
|
||||
DriverRegistryPath->Buffer);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
IntVideoPortCreateAdapterDeviceObject(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
@@ -203,16 +291,20 @@ IntVideoPortCreateAdapterDeviceObject(
|
||||
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);
|
||||
/*
|
||||
* Get the registry path associated with this driver.
|
||||
*/
|
||||
|
||||
Status = IntCreateRegistryPath(
|
||||
&DriverExtension->RegistryPath,
|
||||
&DeviceExtension->RegistryPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IntCreateRegistryPath() call failed with status 0x%08x\n", Status);
|
||||
IoDeleteDevice(*DeviceObject);
|
||||
*DeviceObject = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (PhysicalDeviceObject != NULL)
|
||||
{
|
||||
|
||||
@@ -265,14 +265,14 @@ NtGdiCreateCompatibleDC(HDC hDC)
|
||||
return hNewDC;
|
||||
}
|
||||
|
||||
static BOOL FASTCALL
|
||||
static BOOLEAN FASTCALL
|
||||
GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
WCHAR DeviceNameBuffer[20];
|
||||
NTSTATUS Status;
|
||||
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Video%d", DisplayNumber);
|
||||
swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber);
|
||||
RtlInitUnicodeString(RegistryPath, NULL);
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
|
||||
@@ -286,11 +286,11 @@ GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
|
||||
NULL);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("No \\Device\\Video%d value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
|
||||
DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("RegistryPath %S\n", RegistryPath->Buffer);
|
||||
DPRINT("RegistryPath %wZ\n", RegistryPath);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -381,103 +381,48 @@ DevModeCallback(IN PWSTR ValueName,
|
||||
static BOOL FASTCALL
|
||||
SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
|
||||
{
|
||||
static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
|
||||
static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
|
||||
static WCHAR ControlSet[] = L"CONTROLSET";
|
||||
static WCHAR Insert[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
|
||||
UNICODE_STRING RegistryPath;
|
||||
BOOL Valid;
|
||||
PWCHAR AfterControlSet;
|
||||
PWCHAR ProfilePath;
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
NTSTATUS Status;
|
||||
BOOLEAN Valid = TRUE;
|
||||
|
||||
if (! GetRegistryPath(&RegistryPath, DisplayNumber))
|
||||
if (!GetRegistryPath(&RegistryPath, DisplayNumber))
|
||||
{
|
||||
DPRINT("GetRegistryPath failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Valid = (0 == _wcsnicmp(RegistryPath.Buffer, RegistryMachineSystem,
|
||||
wcslen(RegistryMachineSystem)));
|
||||
if (Valid)
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].QueryRoutine = DevModeCallback;
|
||||
QueryTable[0].Flags = 0;
|
||||
QueryTable[0].Name = NULL;
|
||||
QueryTable[0].EntryContext = NULL;
|
||||
QueryTable[0].DefaultType = REG_NONE;
|
||||
QueryTable[0].DefaultData = NULL;
|
||||
QueryTable[0].DefaultLength = 0;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
RegistryPath.Buffer,
|
||||
QueryTable,
|
||||
DevMode,
|
||||
NULL);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
AfterControlSet = RegistryPath.Buffer + wcslen(RegistryMachineSystem);
|
||||
if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet)))
|
||||
{
|
||||
AfterControlSet += wcslen(CurrentControlSet);
|
||||
}
|
||||
else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet)))
|
||||
{
|
||||
AfterControlSet += wcslen(ControlSet);
|
||||
while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet)
|
||||
{
|
||||
AfterControlSet++;
|
||||
}
|
||||
Valid = (L'\\' == *AfterControlSet);
|
||||
AfterControlSet++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Valid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Valid)
|
||||
{
|
||||
ProfilePath = ExAllocatePoolWithTag(PagedPool,
|
||||
(wcslen(RegistryPath.Buffer) +
|
||||
wcslen(Insert) + 1) * sizeof(WCHAR),
|
||||
TAG_DC);
|
||||
if (NULL != ProfilePath)
|
||||
{
|
||||
wcsncpy(ProfilePath, RegistryPath.Buffer, AfterControlSet - RegistryPath.Buffer);
|
||||
wcscpy(ProfilePath + (AfterControlSet - RegistryPath.Buffer), Insert);
|
||||
wcscat(ProfilePath, AfterControlSet);
|
||||
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].QueryRoutine = DevModeCallback;
|
||||
QueryTable[0].Flags = 0;
|
||||
QueryTable[0].Name = NULL;
|
||||
QueryTable[0].EntryContext = NULL;
|
||||
QueryTable[0].DefaultType = REG_NONE;
|
||||
QueryTable[0].DefaultData = NULL;
|
||||
QueryTable[0].DefaultLength = 0;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
|
||||
ProfilePath,
|
||||
QueryTable,
|
||||
DevMode,
|
||||
NULL);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("RtlQueryRegistryValues for %S failed with status 0x%08x\n",
|
||||
ProfilePath, Status);
|
||||
Valid = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
|
||||
DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
|
||||
DevMode->dmPelsWidth, DevMode->dmPelsHeight);
|
||||
if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
|
||||
|| 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
|
||||
{
|
||||
DPRINT("Not all required devmode members are set\n");
|
||||
Valid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(ProfilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Valid = FALSE;
|
||||
}
|
||||
DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n",
|
||||
&RegistryPath, Status);
|
||||
Valid = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Unparsable registry path %S in DEVICEMAP\\VIDEO0", RegistryPath.Buffer);
|
||||
DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
|
||||
DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
|
||||
DevMode->dmPelsWidth, DevMode->dmPelsHeight);
|
||||
if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
|
||||
|| 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
|
||||
{
|
||||
DPRINT("Not all required devmode members are set\n");
|
||||
Valid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&RegistryPath);
|
||||
@@ -2734,6 +2679,137 @@ IntEnumDisplaySettings(
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NTSTATUS FASTCALL
|
||||
GetVideoDeviceName(
|
||||
OUT PUNICODE_STRING VideoDeviceName,
|
||||
IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */
|
||||
{
|
||||
UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\");
|
||||
UNICODE_STRING ObjectName;
|
||||
UNICODE_STRING KernelModeName = { 0, };
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
USHORT LastSlash;
|
||||
ULONG Length;
|
||||
HANDLE LinkHandle = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(VideoDeviceName, NULL);
|
||||
|
||||
/* Get device name (DisplayDevice is "\.\xxx") */
|
||||
for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
|
||||
{
|
||||
if (DisplayDevice->Buffer[LastSlash - 1] == L'\\')
|
||||
break;
|
||||
}
|
||||
|
||||
if (LastSlash == 0)
|
||||
{
|
||||
DPRINT1("Invalid device name '%wZ'\n", DisplayDevice);
|
||||
Status = STATUS_OBJECT_NAME_INVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
ObjectName = *DisplayDevice;
|
||||
ObjectName.Length -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.Buffer += LastSlash;
|
||||
|
||||
/* Create "\??\xxx" (ex: "\??\DISPLAY1") */
|
||||
KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL);
|
||||
KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||
KernelModeName.MaximumLength,
|
||||
TAG_DC);
|
||||
if (!KernelModeName.Buffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
RtlCopyUnicodeString(&KernelModeName, &Prefix);
|
||||
Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
|
||||
/* Open \??\xxx (ex: "\??\DISPLAY1") */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KernelModeName,
|
||||
OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenSymbolicLinkObject(&LinkHandle,
|
||||
GENERIC_READ,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
|
||||
Status = STATUS_NO_SUCH_DEVICE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
|
||||
Status = STATUS_NO_SUCH_DEVICE;
|
||||
goto cleanup;
|
||||
}
|
||||
VideoDeviceName->MaximumLength = Length;
|
||||
VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool,
|
||||
VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL),
|
||||
TAG_DC);
|
||||
if (!VideoDeviceName->Buffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL);
|
||||
VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
|
||||
Status = STATUS_NO_SUCH_DEVICE;
|
||||
goto cleanup;
|
||||
}
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer)
|
||||
ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC);
|
||||
if (KernelModeName.Buffer)
|
||||
ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC);
|
||||
if (LinkHandle)
|
||||
ZwClose(LinkHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS FASTCALL
|
||||
GetVideoRegistryKey(
|
||||
OUT PUNICODE_STRING RegistryPath,
|
||||
IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */
|
||||
{
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitUnicodeString(RegistryPath, NULL);
|
||||
RtlZeroMemory(QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
|
||||
QueryTable[0].Name = DeviceName->Buffer;
|
||||
QueryTable[0].EntryContext = RegistryPath;
|
||||
|
||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
|
||||
L"VIDEO",
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status);
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
DPRINT("RegistryPath %wZ\n", RegistryPath);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
FASTCALL
|
||||
IntChangeDisplaySettings(
|
||||
@@ -2827,13 +2903,8 @@ IntChangeDisplaySettings(
|
||||
if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
|
||||
{
|
||||
|
||||
UNICODE_STRING ObjectName;
|
||||
UNICODE_STRING KernelModeName;
|
||||
WCHAR KernelModeNameBuffer[256];
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING RegistryKey;
|
||||
WCHAR RegistryKeyBuffer[512];
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
ULONG LastSlash;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE DevInstRegKey;
|
||||
ULONG NewValue;
|
||||
@@ -2842,76 +2913,31 @@ IntChangeDisplaySettings(
|
||||
|
||||
dwflags &= ~CDS_UPDATEREGISTRY;
|
||||
|
||||
/* Get device name (pDeviceName is "\.\xxx") */
|
||||
for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
|
||||
Status = GetVideoDeviceName(&DeviceName, pDeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
|
||||
break;
|
||||
DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status);
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
if (LastSlash == 0) return DISP_CHANGE_RESTART;
|
||||
ObjectName = *pDeviceName;
|
||||
ObjectName.Length -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.Buffer += LastSlash;
|
||||
|
||||
KernelModeName.Length = 0;
|
||||
KernelModeName.MaximumLength = sizeof(KernelModeNameBuffer);
|
||||
KernelModeName.Buffer = KernelModeNameBuffer;
|
||||
|
||||
/* Open \??\xxx (ex: "\??\DISPLAY1") */
|
||||
Status = RtlAppendUnicodeToString(&KernelModeName, L"\\??\\");
|
||||
|
||||
if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
|
||||
Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
|
||||
|
||||
if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
|
||||
Status = ObReferenceObjectByName(
|
||||
&KernelModeName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
0,
|
||||
IoDeviceObjectType,
|
||||
KernelMode,
|
||||
NULL,
|
||||
(PVOID*)&DeviceObject);
|
||||
|
||||
if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
|
||||
/* Get associated driver name (ex: "VBE") */
|
||||
for (LastSlash = DeviceObject->DriverObject->DriverName.Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
|
||||
Status = GetVideoRegistryKey(&RegistryKey, &DeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
|
||||
break;
|
||||
DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status);
|
||||
ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
if (LastSlash == 0) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
|
||||
ObjectName = DeviceObject->DriverObject->DriverName;
|
||||
ObjectName.Length -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
|
||||
ObjectName.Buffer += LastSlash;
|
||||
|
||||
RegistryKey.Length = 0;
|
||||
RegistryKey.MaximumLength = sizeof(RegistryKeyBuffer);
|
||||
RegistryKey.Buffer = RegistryKeyBuffer;
|
||||
|
||||
/* Open registry key */
|
||||
Status = RtlAppendUnicodeToString(&RegistryKey,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\");
|
||||
|
||||
if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
|
||||
Status = RtlAppendUnicodeStringToString(&RegistryKey, &ObjectName);
|
||||
|
||||
if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
|
||||
Status = RtlAppendUnicodeToString(&RegistryKey,
|
||||
L"\\Device0");
|
||||
|
||||
if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
|
||||
ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
|
||||
OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
Status = ZwOpenKey(&DevInstRegKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes);
|
||||
ObDereferenceObject(DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status);
|
||||
ExFreePoolWithTag(RegistryKey.Buffer, TAG_DC);
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
ExFreePoolWithTag(RegistryKey.Buffer, TAG_DC);
|
||||
|
||||
/* Update needed fields */
|
||||
if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
|
||||
|
||||
Reference in New Issue
Block a user