mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Implement IntChangeDisplaySettings in a crappy way. Feel free to improve it!
svn path=/trunk/; revision=14325
This commit is contained in:
parent
554ba464bc
commit
f51f04e53e
1 changed files with 105 additions and 2 deletions
|
@ -2538,8 +2538,111 @@ IntChangeDisplaySettings(
|
|||
break;
|
||||
|
||||
case CDS_UPDATEREGISTRY:
|
||||
Ret = DISP_CHANGE_FAILED;
|
||||
break;
|
||||
{
|
||||
UNICODE_STRING ObjectName;
|
||||
UNICODE_STRING KernelModeName;
|
||||
WCHAR KernelModeNameBuffer[256];
|
||||
UNICODE_STRING RegistryKey;
|
||||
WCHAR RegistryKeyBuffer[512];
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status;
|
||||
ULONG LastSlash;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE DevInstRegKey;
|
||||
ULONG NewValue;
|
||||
|
||||
/* Get device name (pDeviceName is "\.\xxx") */
|
||||
for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
|
||||
{
|
||||
if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
|
||||
break;
|
||||
}
|
||||
if (LastSlash == 0) return DISP_CHANGE_FAILED;
|
||||
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--)
|
||||
{
|
||||
if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
|
||||
break;
|
||||
}
|
||||
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; }
|
||||
|
||||
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;
|
||||
|
||||
/* Update needed fields */
|
||||
if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
|
||||
{
|
||||
RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
|
||||
NewValue = DevMode->dmBitsPerPel;
|
||||
Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
|
||||
{
|
||||
RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
|
||||
NewValue = DevMode->dmPelsWidth;
|
||||
Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
|
||||
{
|
||||
RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
|
||||
NewValue = DevMode->dmPelsHeight;
|
||||
Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
|
||||
}
|
||||
|
||||
ZwClose(DevInstRegKey);
|
||||
if (NT_SUCCESS(Status))
|
||||
Ret = DISP_CHANGE_RESTART;
|
||||
else
|
||||
Ret = DISP_CHANGE_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
case CDS_TEST: /* Test if the mode could be set */
|
||||
Ret = DISP_CHANGE_FAILED;
|
||||
|
|
Loading…
Reference in a new issue