Paul Gofman : gdi32: Add a semi-stub for D3DKMTOpenAdapterFromDeviceName().

Alexandre Julliard julliard at winehq.org
Thu Sep 23 15:35:06 CDT 2021


Module: wine
Branch: master
Commit: 3ee036245bfb8de6a1432bc03ffc641b00ee197c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3ee036245bfb8de6a1432bc03ffc641b00ee197c

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Tue Sep 21 18:05:13 2021 +0300

gdi32: Add a semi-stub for D3DKMTOpenAdapterFromDeviceName().

Fixes non functional setting page in Resident Evil Village.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-dx-d3dkmt-l1-1-0.spec               |  2 +-
 dlls/gdi32/driver.c                                | 20 +++++
 dlls/gdi32/gdi32.spec                              |  1 +
 dlls/gdi32/tests/Makefile.in                       |  2 +-
 dlls/gdi32/tests/driver.c                          | 99 ++++++++++++++++++++++
 include/ntgdi.h                                    |  1 +
 6 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/dlls/api-ms-win-dx-d3dkmt-l1-1-0/api-ms-win-dx-d3dkmt-l1-1-0.spec b/dlls/api-ms-win-dx-d3dkmt-l1-1-0/api-ms-win-dx-d3dkmt-l1-1-0.spec
index 609f24fcfde..3c5c8d9b670 100644
--- a/dlls/api-ms-win-dx-d3dkmt-l1-1-0/api-ms-win-dx-d3dkmt-l1-1-0.spec
+++ b/dlls/api-ms-win-dx-d3dkmt-l1-1-0/api-ms-win-dx-d3dkmt-l1-1-0.spec
@@ -45,7 +45,7 @@
 @ stub D3DKMTInvalidateActiveVidPn
 @ stub D3DKMTLock
 @ stub D3DKMTOfferAllocations
-@ stub D3DKMTOpenAdapterFromDeviceName
+@ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) gdi32.D3DKMTOpenAdapterFromDeviceName
 @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) gdi32.D3DKMTOpenAdapterFromGdiDisplayName
 @ stdcall D3DKMTOpenAdapterFromHdc(ptr) gdi32.D3DKMTOpenAdapterFromHdc
 @ stub D3DKMTOpenKeyedMutex
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index f4a9b09eae5..09e369bf27f 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -989,6 +989,26 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
     return status;
 }
 
+/******************************************************************************
+ *           NtGdiDdDDIOpenAdapterFromDeviceName    (win32u.@)
+ */
+NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc )
+{
+    D3DKMT_OPENADAPTERFROMLUID desc_luid;
+    NTSTATUS status;
+
+    FIXME( "desc %p stub.\n", desc );
+
+    if (!desc || !desc->pDeviceName) return STATUS_INVALID_PARAMETER;
+
+    memset( &desc_luid, 0, sizeof( desc_luid ));
+    if ((status = NtGdiDdDDIOpenAdapterFromLuid( &desc_luid ))) return status;
+
+    desc->AdapterLuid = desc_luid.AdapterLuid;
+    desc->hAdapter = desc_luid.hAdapter;
+    return STATUS_SUCCESS;
+}
+
 /******************************************************************************
  *           NtGdiDdDDIOpenAdapterFromLuid    (win32u.@)
  */
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 6dbc8a9bf12..94a5cefdfa4 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -80,6 +80,7 @@
 @ stdcall D3DKMTDestroyDCFromMemory(ptr) NtGdiDdDDIDestroyDCFromMemory
 @ stdcall D3DKMTDestroyDevice(ptr) NtGdiDdDDIDestroyDevice
 @ stdcall D3DKMTEscape(ptr) NtGdiDdDDIEscape
+@ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) NtGdiDdDDIOpenAdapterFromDeviceName
 @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr)
 @ stdcall D3DKMTOpenAdapterFromHdc(ptr) NtGdiDdDDIOpenAdapterFromHdc
 @ stdcall D3DKMTOpenAdapterFromLuid(ptr) NtGdiDdDDIOpenAdapterFromLuid
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 876f6a376a2..3eb478ff765 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = gdi32.dll
-IMPORTS   = user32 gdi32 advapi32
+IMPORTS   = setupapi user32 gdi32 advapi32
 
 C_SRCS = \
 	bitmap.c \
diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c
index eb0da18b32e..54144c44e1c 100644
--- a/dlls/gdi32/tests/driver.c
+++ b/dlls/gdi32/tests/driver.c
@@ -29,16 +29,22 @@
 #include "winternl.h"
 #include "dwmapi.h"
 #include "ddk/d3dkmthk.h"
+#include "initguid.h"
+#include "setupapi.h"
+#include "ntddvdeo.h"
 
 #include "wine/test.h"
 
 static const WCHAR display1W[] = L"\\\\.\\DISPLAY1";
 
+DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2);
+
 static NTSTATUS (WINAPI *pD3DKMTCheckOcclusion)(const D3DKMT_CHECKOCCLUSION *);
 static NTSTATUS (WINAPI *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
 static NTSTATUS (WINAPI *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
 static NTSTATUS (WINAPI *pD3DKMTCreateDevice)(D3DKMT_CREATEDEVICE *);
 static NTSTATUS (WINAPI *pD3DKMTDestroyDevice)(const D3DKMT_DESTROYDEVICE *);
+static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromDeviceName)(D3DKMT_OPENADAPTERFROMDEVICENAME *);
 static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromGdiDisplayName)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *);
 static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromHdc)(D3DKMT_OPENADAPTERFROMHDC *);
 static NTSTATUS (WINAPI *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
@@ -789,6 +795,97 @@ static void test_D3DKMTCheckOcclusion(void)
     DestroyWindow(hwnd);
 }
 
+static void test_D3DKMTOpenAdapterFromDeviceName_deviface(const GUID *devinterface_guid,
+        NTSTATUS expected_status, BOOL todo)
+{
+    BYTE iface_detail_buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + 256 * sizeof(WCHAR)];
+    SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+    SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
+    SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data;
+    D3DKMT_OPENADAPTERFROMDEVICENAME device_name;
+    D3DKMT_CLOSEADAPTER close_adapter_desc;
+    DEVPROPTYPE type;
+    NTSTATUS status;
+    unsigned int i;
+    HDEVINFO set;
+    LUID luid;
+    BOOL ret;
+
+    set = SetupDiGetClassDevsW(devinterface_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
+    ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed, error %u.\n", GetLastError());
+
+    iface_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer;
+    iface_data->cbSize = sizeof(*iface_data);
+    device_name.pDeviceName = iface_data->DevicePath;
+
+    i = 0;
+    while (SetupDiEnumDeviceInterfaces(set, NULL, devinterface_guid, i, &iface))
+    {
+        ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data,
+                sizeof(iface_detail_buffer), NULL, &device_data );
+        ok(ret, "Got unexpected ret %d, GetLastError() %u.\n", ret, GetLastError());
+
+        status = pD3DKMTOpenAdapterFromDeviceName(&device_name);
+        todo_wine_if(todo) ok(status == expected_status, "Got status %#x, expected %#x.\n", status, expected_status);
+
+        if (!status)
+        {
+            ret = SetupDiGetDevicePropertyW(set, &device_data, &DEVPROPKEY_GPU_LUID, &type,
+                    (BYTE *)&luid, sizeof(luid), NULL, 0);
+            ok(ret || GetLastError() == ERROR_NOT_FOUND, "Got unexpected ret %d, GetLastError() %u.\n",
+                    ret, GetLastError());
+
+            if (ret)
+            {
+                ret = RtlEqualLuid( &luid, &device_name.AdapterLuid);
+                todo_wine ok(ret, "Luid does not match.\n");
+            }
+            else
+            {
+                skip("Luid not found.\n");
+            }
+
+            close_adapter_desc.hAdapter = device_name.hAdapter;
+            status = pD3DKMTCloseAdapter(&close_adapter_desc);
+            ok(!status, "Got unexpected status %#x.\n", status);
+        }
+        ++i;
+    }
+    if (!i)
+        win_skip("No devices found.\n");
+
+    SetupDiDestroyDeviceInfoList( set );
+}
+
+static void test_D3DKMTOpenAdapterFromDeviceName(void)
+{
+    D3DKMT_OPENADAPTERFROMDEVICENAME device_name;
+    NTSTATUS status;
+
+    /* Make sure display devices are initialized. */
+    SendMessageW(GetDesktopWindow(), WM_NULL, 0, 0);
+
+    status = pD3DKMTOpenAdapterFromDeviceName(NULL);
+    if (status == STATUS_PROCEDURE_NOT_FOUND)
+    {
+        win_skip("D3DKMTOpenAdapterFromDeviceName() is not supported.\n");
+        return;
+    }
+    ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
+
+    memset(&device_name, 0, sizeof(device_name));
+    status = pD3DKMTOpenAdapterFromDeviceName(&device_name);
+    ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
+
+    winetest_push_context("GUID_DEVINTERFACE_DISPLAY_ADAPTER");
+    test_D3DKMTOpenAdapterFromDeviceName_deviface(&GUID_DEVINTERFACE_DISPLAY_ADAPTER, STATUS_INVALID_PARAMETER, TRUE);
+    winetest_pop_context();
+
+    winetest_push_context("GUID_DISPLAY_DEVICE_ARRIVAL");
+    test_D3DKMTOpenAdapterFromDeviceName_deviface(&GUID_DISPLAY_DEVICE_ARRIVAL, STATUS_SUCCESS, FALSE);
+    winetest_pop_context();
+}
+
 START_TEST(driver)
 {
     HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
@@ -799,6 +896,7 @@ START_TEST(driver)
     pD3DKMTCloseAdapter = (void *)GetProcAddress(gdi32, "D3DKMTCloseAdapter");
     pD3DKMTCreateDevice = (void *)GetProcAddress(gdi32, "D3DKMTCreateDevice");
     pD3DKMTDestroyDevice = (void *)GetProcAddress(gdi32, "D3DKMTDestroyDevice");
+    pD3DKMTOpenAdapterFromDeviceName = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromDeviceName");
     pD3DKMTOpenAdapterFromGdiDisplayName = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromGdiDisplayName");
     pD3DKMTOpenAdapterFromHdc = (void *)GetProcAddress(gdi32, "D3DKMTOpenAdapterFromHdc");
     pD3DKMTSetVidPnSourceOwner = (void *)GetProcAddress(gdi32, "D3DKMTSetVidPnSourceOwner");
@@ -814,6 +912,7 @@ START_TEST(driver)
     test_D3DKMTCheckVidPnExclusiveOwnership();
     test_D3DKMTSetVidPnSourceOwner();
     test_D3DKMTCheckOcclusion();
+    test_D3DKMTOpenAdapterFromDeviceName();
 
     FreeLibrary(dwmapi);
 }
diff --git a/include/ntgdi.h b/include/ntgdi.h
index e1f31a6bb9d..05fe0191f39 100644
--- a/include/ntgdi.h
+++ b/include/ntgdi.h
@@ -442,6 +442,7 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyDCFromMemory( const D3DKMT_DESTROYDCFROMMEMORY
 NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc );
 NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc );
 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc );
+NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc );
 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc );
 NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats );
 NTSTATUS WINAPI NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT *desc );




More information about the wine-cvs mailing list