Author: hpoussin Date: Fri Jun 2 01:45:50 2006 New Revision: 22169
URL: http://svn.reactos.ru/svn/reactos?rev=22169&view=rev Log: Store real parameters registry key in DEVICEMAP\VIDEO Use it in win32k when loading and storing settings (SetupDevMode and IntChangeDisplaySettings)
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c trunk/reactos/subsystems/win32/win32k/objects/dc.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/drivers/video/videoprt/video... ============================================================================== --- trunk/reactos/drivers/video/videoprt/videoprt.c (original) +++ trunk/reactos/drivers/video/videoprt/videoprt.c Fri Jun 2 01:45:50 2006 @@ -130,6 +130,94 @@ ((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 @@ 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) {
Modified: trunk/reactos/subsystems/win32/win32k/objects/dc.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/obje... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/dc.c (original) +++ trunk/reactos/subsystems/win32/win32k/objects/dc.c Fri Jun 2 01:45:50 2006 @@ -265,14 +265,14 @@ 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 @@ 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 @@ 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; - - if (! GetRegistryPath(&RegistryPath, DisplayNumber)) + BOOLEAN Valid = TRUE; + + if (!GetRegistryPath(&RegistryPath, DisplayNumber)) { DPRINT("GetRegistryPath failed\n"); return FALSE; }
- Valid = (0 == _wcsnicmp(RegistryPath.Buffer, RegistryMachineSystem, - wcslen(RegistryMachineSystem))); - if (Valid) - { - AfterControlSet = RegistryPath.Buffer + wcslen(RegistryMachineSystem); - if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet))) + 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)) + { + DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n", + &RegistryPath, 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) { - 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 - { + DPRINT("Not all required devmode members are set\n"); 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; - } - } - else - { - DPRINT1("Unparsable registry path %S in DEVICEMAP\VIDEO0", RegistryPath.Buffer); }
RtlFreeUnicodeString(&RegistryPath); @@ -2734,6 +2679,137 @@
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 @@ 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 @@
dwflags &= ~CDS_UPDATEREGISTRY;
- /* 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_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--) - { - 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; } + Status = GetVideoDeviceName(&DeviceName, pDeviceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status); + return DISP_CHANGE_FAILED; + } + Status = GetVideoRegistryKey(&RegistryKey, &DeviceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status); + ExFreePoolWithTag(DeviceName.Buffer, TAG_DC); + 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)