Zhiyi Zhang : gdi32: Support LUID in D3DKMTOpenAdapterFromGdiDisplayName().
Alexandre Julliard
julliard at winehq.org
Thu Jun 11 15:26:46 CDT 2020
Module: wine
Branch: master
Commit: 0a2d6378d80a1594cae6c7ab0e5d31b8fe11703b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0a2d6378d80a1594cae6c7ab0e5d31b8fe11703b
Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date: Thu Jun 11 22:00:32 2020 +0800
gdi32: Support LUID in D3DKMTOpenAdapterFromGdiDisplayName().
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi32/Makefile.in | 2 +-
dlls/gdi32/driver.c | 92 +++++++++++++++++++++++++++++++++++++++++------
dlls/gdi32/tests/driver.c | 2 ++
3 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in
index e1ac922ce5..32b2e6959c 100644
--- a/dlls/gdi32/Makefile.in
+++ b/dlls/gdi32/Makefile.in
@@ -4,7 +4,7 @@ IMPORTLIB = gdi32
IMPORTS = advapi32
EXTRAINCL = $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS)
EXTRALIBS = $(CARBON_LIBS) $(APPKIT_LIBS)
-DELAYIMPORTS = usp10
+DELAYIMPORTS = usp10 setupapi
C_SRCS = \
bidi.c \
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 90977383a5..39812b5ca0 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -31,10 +31,14 @@
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
+#include "winreg.h"
#include "ddrawgdi.h"
#include "wine/winbase16.h"
#include "winuser.h"
#include "winternl.h"
+#include "initguid.h"
+#include "devguid.h"
+#include "setupapi.h"
#include "ddk/d3dkmthk.h"
#include "gdi_private.h"
@@ -45,6 +49,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(driver);
+DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+
struct graphics_driver
{
struct list entry;
@@ -159,6 +165,20 @@ static BOOL is_display_device( LPCWSTR name )
return TRUE;
}
+static HANDLE get_display_device_init_mutex( void )
+{
+ static const WCHAR init_mutex[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t',0};
+ HANDLE mutex = CreateMutexW( NULL, FALSE, init_mutex );
+
+ WaitForSingleObject( mutex, INFINITE );
+ return mutex;
+}
+
+static void release_display_device_init_mutex( HANDLE mutex )
+{
+ ReleaseMutex( mutex );
+ CloseHandle( mutex );
+}
/**********************************************************************
* DRIVER_load_driver
@@ -1351,17 +1371,35 @@ NTSTATUS WINAPI D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName( D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *desc )
{
static const WCHAR displayW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
+ static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
+ static const WCHAR video_value_fmtW[] = {'\\','D','e','v','i','c','e','\\',
+ 'V','i','d','e','o','%','d',0};
+ static const WCHAR video_keyW[] = {'H','A','R','D','W','A','R','E','\\',
+ 'D','E','V','I','C','E','M','A','P','\\',
+ 'V','I','D','E','O','\\',0};
+ static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
+ WCHAR *end, key_nameW[MAX_PATH], bufferW[MAX_PATH];
+ HDEVINFO devinfo = INVALID_HANDLE_VALUE;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
static D3DKMT_HANDLE handle_start = 0;
struct d3dkmt_adapter *adapter;
- WCHAR *end;
- int id;
+ SP_DEVINFO_DATA device_data;
+ DWORD size, state_flags;
+ DEVPROPTYPE type;
+ HANDLE mutex;
+ LUID luid;
+ int index;
- TRACE("(%p) semi-stub\n", desc);
+ TRACE("(%p)\n", desc);
+
+ if (!desc)
+ return STATUS_UNSUCCESSFUL;
- if (!desc || strncmpiW( desc->DeviceName, displayW, ARRAY_SIZE(displayW) ))
+ TRACE("DeviceName: %s\n", wine_dbgstr_w( desc->DeviceName ));
+ if (strncmpiW( desc->DeviceName, displayW, ARRAY_SIZE(displayW) ))
return STATUS_UNSUCCESSFUL;
- id = strtolW( desc->DeviceName + ARRAY_SIZE(displayW), &end, 10 ) - 1;
+ index = strtolW( desc->DeviceName + ARRAY_SIZE(displayW), &end, 10 ) - 1;
if (*end)
return STATUS_UNSUCCESSFUL;
@@ -1369,6 +1407,35 @@ NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName( D3DKMT_OPENADAPTERFROMGDIDI
if (!adapter)
return STATUS_NO_MEMORY;
+ /* Get adapter LUID from SetupAPI */
+ mutex = get_display_device_init_mutex();
+
+ size = sizeof( bufferW );
+ sprintfW( key_nameW, video_value_fmtW, index );
+ if (RegGetValueW( HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
+ goto done;
+
+ /* Strip \Registry\Machine\ prefix and retrieve Wine specific data set by the display driver */
+ lstrcpyW( key_nameW, bufferW + 18 );
+ size = sizeof( state_flags );
+ if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, state_flagsW, RRF_RT_REG_DWORD, NULL,
+ &state_flags, &size ))
+ goto done;
+
+ if (!(state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+ goto done;
+
+ size = sizeof( bufferW );
+ if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, gpu_idW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
+ goto done;
+
+ devinfo = SetupDiCreateDeviceInfoList( &GUID_DEVCLASS_DISPLAY, NULL );
+ device_data.cbSize = sizeof( device_data );
+ SetupDiOpenDeviceInfoW( devinfo, bufferW, NULL, 0, &device_data );
+ if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &DEVPROPKEY_GPU_LUID, &type,
+ (BYTE *)&luid, sizeof( luid ), NULL, 0))
+ goto done;
+
EnterCriticalSection( &driver_section );
/* D3DKMT_HANDLE is UINT, so we can't use pointer as handle */
adapter->handle = ++handle_start;
@@ -1376,11 +1443,16 @@ NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName( D3DKMT_OPENADAPTERFROMGDIDI
LeaveCriticalSection( &driver_section );
desc->hAdapter = handle_start;
- /* FIXME: Support AdapterLuid */
- desc->AdapterLuid.LowPart = 0;
- desc->AdapterLuid.HighPart = 0;
- desc->VidPnSourceId = id;
- return STATUS_SUCCESS;
+ desc->AdapterLuid = luid;
+ desc->VidPnSourceId = index;
+ status = STATUS_SUCCESS;
+
+done:
+ SetupDiDestroyDeviceInfoList( devinfo );
+ release_display_device_init_mutex( mutex );
+ if (status != STATUS_SUCCESS)
+ heap_free( adapter );
+ return status;
}
/******************************************************************************
diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c
index 6172d4a798..c656eb4245 100644
--- a/dlls/gdi32/tests/driver.c
+++ b/dlls/gdi32/tests/driver.c
@@ -86,6 +86,8 @@ static void test_D3DKMTOpenAdapterFromGdiDisplayName(void)
}
ok(open_adapter_gdi_desc.hAdapter, "Expect not null.\n");
+ ok(open_adapter_gdi_desc.AdapterLuid.LowPart || open_adapter_gdi_desc.AdapterLuid.HighPart,
+ "Expect LUID not zero.\n");
close_adapter_desc.hAdapter = open_adapter_gdi_desc.hAdapter;
status = pD3DKMTCloseAdapter(&close_adapter_desc);
More information about the wine-cvs
mailing list