From: Zhiyi Zhang Subject: [PATCH 1/8] winex11.drv: Register GUID_DEVINTERFACE_DISPLAY_ADAPTER interface for GPUs. Message-Id: <18036e27-ca7f-618c-a788-d24be8aec559@codeweavers.com> Date: Thu, 16 Sep 2021 15:10:20 +0800 Signed-off-by: Zhiyi Zhang --- dlls/winex11.drv/display.c | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index ca81f169f9f..1ef728791fa 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -27,9 +27,11 @@ #include "winuser.h" #include "rpc.h" #include "winreg.h" +#include "cfgmgr32.h" #include "initguid.h" #include "devguid.h" #include "devpkey.h" +#include "ntddvdeo.h" #include "setupapi.h" #define WIN32_NO_STATUS #include "winternl.h" @@ -405,6 +407,57 @@ void X11DRV_DisplayDevices_Update(BOOL send_display_change) } } +/* Set device interface link state to enabled. The link state should be set via + * IoSetDeviceInterfaceState(). However, IoSetDeviceInterfaceState() requires a PnP driver, which + * currently doesn't exist for display devices. */ +static BOOL link_device(const WCHAR *instance, const GUID *guid) +{ + static const WCHAR device_instanceW[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0}; + static const WCHAR hash_controlW[] = {'#','\\','C','o','n','t','r','o','l',0}; + static const WCHAR linkedW[] = {'L','i','n','k','e','d',0}; + static const DWORD enabled = 1; + WCHAR device_key_name[MAX_PATH], device_instance[MAX_PATH]; + HKEY iface_key, device_key, control_key; + DWORD length, index = 0; + BOOL ret = FALSE; + LSTATUS lr; + + iface_key = SetupDiOpenClassRegKeyExW(guid, KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL); + while (1) + { + length = ARRAY_SIZE(device_key_name); + lr = RegEnumKeyExW(iface_key, index++, device_key_name, &length, NULL, NULL, NULL, NULL); + if (lr) + break; + + lr = RegOpenKeyExW(iface_key, device_key_name, 0, KEY_ALL_ACCESS, &device_key); + if (lr) + continue; + + length = ARRAY_SIZE(device_instance); + lr = RegQueryValueExW(device_key, device_instanceW, NULL, NULL, (BYTE *)device_instance, &length); + if (lr || lstrcmpiW(device_instance, instance)) + { + RegCloseKey(device_key); + continue; + } + + lr = RegCreateKeyExW(device_key, hash_controlW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &control_key, NULL); + RegCloseKey(device_key); + if (lr) + break; + + lr = RegSetValueExW(control_key, linkedW, 0, REG_DWORD, (const BYTE *)&enabled, sizeof(enabled)); + if (!lr) + ret = TRUE; + + RegCloseKey(control_key); + break; + } + RegCloseKey(iface_key); + return ret; +} + /* Initialize a GPU instance. * Return its GUID string in guid_string, driver value in driver parameter and LUID in gpu_luid */ static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct x11drv_gpu *gpu, INT gpu_index, WCHAR *guid_string, @@ -434,6 +487,13 @@ static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct x11drv_gpu *gpu, INT g goto done; } + /* Register GUID_DEVINTERFACE_DISPLAY_ADAPTER */ + if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, 0, NULL)) + goto done; + + if (!link_device(instanceW, &GUID_DEVINTERFACE_DISPLAY_ADAPTER)) + goto done; + /* Write HardwareID registry property, REG_MULTI_SZ */ written = sprintfW(bufferW, gpu_hardware_id_fmtW, gpu->vendor_id, gpu->device_id); bufferW[written + 1] = 0; -- 2.30.2