On 9/17/21 11:22 PM, Paul Gofman wrote:
Fixes non functional setting page in Resident Evil Village.
Signed-off-by: Paul Gofman pgofman@codeweavers.com
v2: - use GUID_DISPLAY_DEVICE_ARRIVAL directly; - check for NULL device_name->pDeviceName explicitly; - call SetupDiEnumDeviceInterfaces() directly without SetupDiEnumDeviceInfo(); - curly braces around WARN(); - call release_display_device_init_mutex() sooner; - use %d to print BOOL; - send WM_NULL to desktop window to init driver instead of creating window; - actually pass device_name to pD3DKMTOpenAdapterFromDeviceName when testing NULL device_name->pDeviceName.
dlls/gdi32/gdi32.spec | 1 + dlls/gdi32/objects.c | 66 ++++++++++++++++++++++++ dlls/gdi32/tests/Makefile.in | 2 +- dlls/gdi32/tests/driver.c | 98 ++++++++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index 6dbc8a9bf12..46534796317 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) @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) @ stdcall D3DKMTOpenAdapterFromHdc(ptr) NtGdiDdDDIOpenAdapterFromHdc @ stdcall D3DKMTOpenAdapterFromLuid(ptr) NtGdiDdDDIOpenAdapterFromLuid diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c index 7f6893f0952..0acf736786b 100644 --- a/dlls/gdi32/objects.c +++ b/dlls/gdi32/objects.c @@ -30,6 +30,7 @@ #include "initguid.h" #include "devguid.h" #include "setupapi.h" +#include "ntddvdeo.h"
#include "wine/rbtree.h" #include "wine/debug.h" @@ -889,6 +890,71 @@ static void release_display_device_init_mutex( HANDLE mutex ) CloseHandle( mutex ); }
+/******************************************************************************
D3DKMTOpenAdapterFromDeviceName (GDI32.@)
- */
+NTSTATUS WINAPI D3DKMTOpenAdapterFromDeviceName(D3DKMT_OPENADAPTERFROMDEVICENAME *device_name) +{
- SP_DEVICE_INTERFACE_DATA iface_data = {sizeof(iface_data)};
- SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_detail_data;
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- NTSTATUS status = STATUS_INVALID_PARAMETER;
- D3DKMT_OPENADAPTERFROMLUID luid_desc;
- WCHAR iface_detail_buffer[256];
- BOOL found = FALSE;
- DEVPROPTYPE type;
- unsigned int i;
- HDEVINFO set;
- HANDLE mutex;
- TRACE( "device_name %p.\n", device_name );
- if (!device_name || !device_name->pDeviceName) return STATUS_INVALID_PARAMETER;
- TRACE("device path %s.\n", debugstr_w( device_name->pDeviceName ));
- mutex = get_display_device_init_mutex();
- set = SetupDiGetClassDevsW( &GUID_DISPLAY_DEVICE_ARRIVAL, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
- iface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)iface_detail_buffer;
- iface_detail_data->cbSize = sizeof(*iface_detail_data);
- for (i = 0; SetupDiEnumDeviceInterfaces( set, NULL, &GUID_DISPLAY_DEVICE_ARRIVAL, i, &iface_data ); ++i)
- {
if (!SetupDiGetDeviceInterfaceDetailW( set, &iface_data, iface_detail_data,
sizeof(iface_detail_buffer), NULL, &device_data ))
{
ERR( "Could not get interface detail, iface %u.\n", i );
continue;
}
if (lstrcmpiW( device_name->pDeviceName, iface_detail_data->DevicePath )) continue;
if (SetupDiGetDevicePropertyW( set, &device_data, &DEVPROPKEY_GPU_LUID, &type,
(BYTE *)&luid_desc.AdapterLuid,
sizeof( luid_desc.AdapterLuid ), NULL, 0))
found = TRUE;
else
ERR( "Could not get luid.\n" );
break;
- }
- SetupDiDestroyDeviceInfoList( set );
- release_display_device_init_mutex( mutex );
- if (found && !(status = NtGdiDdDDIOpenAdapterFromLuid( &luid_desc )))
- {
device_name->hAdapter = luid_desc.hAdapter;
device_name->AdapterLuid = luid_desc.AdapterLuid;
- }
- else
- {
WARN( "Device %s not found.\n", debugstr_w(device_name->pDeviceName ));
- }
- return status;
+}
/***********************************************************************
D3DKMTOpenAdapterFromGdiDisplayName (GDI32.@)
*/ 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..c05522c0394 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,96 @@ static void test_D3DKMTCheckOcclusion(void) DestroyWindow(hwnd); }
+static void test_D3DKMTOpenAdapterFromDeviceName_deviface(const GUID *devinterface_guid, NTSTATUS expected_status) +{
- 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);
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);
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("pD3DKMTOpenAdapterFromDeviceName() is not supported.\n");
A copy-paste error. Otherwise, This patch looks good to me.
Thanks, Zhiyi
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);
- winetest_pop_context();
- winetest_push_context("GUID_DISPLAY_DEVICE_ARRIVAL");
- test_D3DKMTOpenAdapterFromDeviceName_deviface(&GUID_DISPLAY_DEVICE_ARRIVAL, STATUS_SUCCESS);
- winetest_pop_context();
+}
START_TEST(driver) { HMODULE gdi32 = GetModuleHandleA("gdi32.dll"); @@ -799,6 +895,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 +911,7 @@ START_TEST(driver) test_D3DKMTCheckVidPnExclusiveOwnership(); test_D3DKMTSetVidPnSourceOwner(); test_D3DKMTCheckOcclusion();
test_D3DKMTOpenAdapterFromDeviceName();
FreeLibrary(dwmapi);
}