From 31827c43b6faaa88f94dad5dd6caf3cbfa6b9925 Mon Sep 17 00:00:00 2001 From: Stanislav Motylkov Date: Tue, 24 May 2022 02:54:57 +0300 Subject: [PATCH] [WIN32SS] EnumDisplayDevices: Fill DeviceID field properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [VIDEOPRT] Return the real PhysicalDeviceObject in Win32k callbacks. - [WIN32SS:ENG] Pass PhysDeviceObject into the GraphicsDevice structure and rename the destination field accordingly. - [WIN32SS:NTUSER] Request hardware identifiers from device PDO and fill DISPLAY_DEVICE's DeviceID field with the first identifier. Now it's correctly passed to the usermode, and Desktop Propertes applet can open the video adapter device properties. Thanks to Hervé Poussineau for the help. CORE-18197 CORE-11715 --- win32ss/drivers/videoprt/dispatch.c | 4 ++- win32ss/gdi/eng/device.c | 2 +- win32ss/gdi/eng/pdevobj.h | 2 +- win32ss/user/ntuser/display.c | 55 +++++++++++++++++++++++++++-- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/win32ss/drivers/videoprt/dispatch.c b/win32ss/drivers/videoprt/dispatch.c index ac5e5b880d7..1878e797550 100644 --- a/win32ss/drivers/videoprt/dispatch.c +++ b/win32ss/drivers/videoprt/dispatch.c @@ -630,6 +630,8 @@ VideoPortInitWin32kCallbacks( _In_ ULONG BufferLength, _Out_ PULONG_PTR Information) { + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + *Information = sizeof(VIDEO_WIN32K_CALLBACKS); if (BufferLength < sizeof(VIDEO_WIN32K_CALLBACKS)) { @@ -643,7 +645,7 @@ VideoPortInitWin32kCallbacks( /* Return reasonable values to Win32k */ Win32kCallbacks->bACPI = FALSE; - Win32kCallbacks->pPhysDeviceObject = DeviceObject; + Win32kCallbacks->pPhysDeviceObject = DeviceExtension->PhysicalDeviceObject; Win32kCallbacks->DualviewFlags = 0; return STATUS_SUCCESS; diff --git a/win32ss/gdi/eng/device.c b/win32ss/gdi/eng/device.c index 2b96ca409c9..af6bd3e42aa 100644 --- a/win32ss/gdi/eng/device.c +++ b/win32ss/gdi/eng/device.c @@ -349,7 +349,7 @@ EngpRegisterGraphicsDevice( // TODO: Set flags according to the results. // if (Win32kCallbacks.bACPI) // if (Win32kCallbacks.DualviewFlags & ???) - // Win32kCallbacks.pPhysDeviceObject; + pGraphicsDevice->PhysDeviceHandle = Win32kCallbacks.pPhysDeviceObject; /* Copy the device name */ RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, diff --git a/win32ss/gdi/eng/pdevobj.h b/win32ss/gdi/eng/pdevobj.h index 12673ac20f4..b9d439d3dda 100644 --- a/win32ss/gdi/eng/pdevobj.h +++ b/win32ss/gdi/eng/pdevobj.h @@ -61,7 +61,7 @@ typedef struct _GRAPHICS_DEVICE struct _GRAPHICS_DEVICE * pNextGraphicsDevice; struct _GRAPHICS_DEVICE * pVgaDevice; PDEVICE_OBJECT DeviceObject; - PVOID pDeviceHandle; + PDEVICE_OBJECT PhysDeviceHandle; DWORD hkClassDriverConfig; DWORD StateFlags; /* See DISPLAY_DEVICE_* */ ULONG cbdevmodeInfo; diff --git a/win32ss/user/ntuser/display.c b/win32ss/user/ntuser/display.c index 8f15a68e1bf..4d14c6552c1 100644 --- a/win32ss/user/ntuser/display.c +++ b/win32ss/user/ntuser/display.c @@ -237,7 +237,8 @@ UserEnumDisplayDevices( DWORD dwFlags) { PGRAPHICS_DEVICE pGraphicsDevice; - ULONG cbSize; + PWCHAR pHardwareId; + ULONG cbSize, dwLength; HKEY hkey; NTSTATUS Status; @@ -280,9 +281,59 @@ UserEnumDisplayDevices( RtlStringCbCopyW(pdispdev->DeviceName, sizeof(pdispdev->DeviceName), pGraphicsDevice->szWinDeviceName); RtlStringCbCopyW(pdispdev->DeviceString, sizeof(pdispdev->DeviceString), pGraphicsDevice->pwszDescription); pdispdev->StateFlags = pGraphicsDevice->StateFlags; - // FIXME: fill in DEVICE ID pdispdev->DeviceID[0] = UNICODE_NULL; + /* Fill in DeviceID */ + if (pGraphicsDevice->PhysDeviceHandle != NULL) + { + Status = IoGetDeviceProperty(pGraphicsDevice->PhysDeviceHandle, + DevicePropertyHardwareID, + 0, + NULL, + &dwLength); + + if (Status == STATUS_BUFFER_TOO_SMALL) + { + pHardwareId = ExAllocatePoolWithTag(PagedPool, + dwLength, + USERTAG_DISPLAYINFO); + if (!pHardwareId) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = IoGetDeviceProperty(pGraphicsDevice->PhysDeviceHandle, + DevicePropertyHardwareID, + dwLength, + pHardwareId, + &dwLength); + + if (!NT_SUCCESS(Status)) + { + ERR("IoGetDeviceProperty() failed with status 0x%08lx\n", Status); + } + else + { + /* For video adapters it should be the first Hardware ID + * which usually is the longest one and unique enough */ + RtlStringCbCopyW(pdispdev->DeviceID, sizeof(pdispdev->DeviceID), pHardwareId); + + /* For monitors it should be the first Hardware ID + * concatenated with the unique driver registry key */ + + /* FIXME: Handle monitors! */ + TRACE("Hardware ID: %ls\n", pdispdev->DeviceID); + } + + ExFreePoolWithTag(pHardwareId, USERTAG_DISPLAYINFO); + } + else + { + ERR("IoGetDeviceProperty() failed with status 0x%08lx\n", Status); + } + } + return STATUS_SUCCESS; }