From: David Adam Subject: patch [1/5] ddraw: Port Enumdevices to ddraw7 Message-Id: Date: Tue, 2 Apr 2019 20:37:53 -1000

From a409daf2170c006860562f88eacebc3b8dd11b61 Mon Sep 17 00:00:00 2001 From: David Adam Date: Tue, 2 Apr 2019 18:41:48 -1000 Subject: [PATCH 1/4] Port Enumdevices tests to ddraw7 Signed-off-by: David Adam --- dlls/ddraw/tests/ddraw7.c | 213 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 423dba57c9..9a663c2833 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -15822,6 +15822,217 @@ static void test_clipper_refcount(void) DestroyWindow(window); } +typedef struct { + int total; + int rgb; + int hal; + int tnlhal; + int unk; +} D3D7ETest; + +typedef struct { + HRESULT desired_ret; + int total; +} D3D7ECancelTest; + +#define MAX_ENUMERATION_COUNT 10 +typedef struct +{ + unsigned int count; + char *callback_description_ptrs[MAX_ENUMERATION_COUNT]; + char callback_description_strings[MAX_ENUMERATION_COUNT][100]; + char *callback_name_ptrs[MAX_ENUMERATION_COUNT]; + char callback_name_strings[MAX_ENUMERATION_COUNT][100]; +} D3D7ELifetimeTest; + +static HRESULT WINAPI enumDevicesCallbackTest7(char *DeviceDescription, char *DeviceName, + D3DDEVICEDESC7 *lpdd7, void *Context) +{ + D3D7ETest *d3d7et = Context; + + if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice)) + d3d7et->rgb++; + else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice)) + d3d7et->hal++; + else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice)) + d3d7et->tnlhal++; + else + d3d7et->unk++; + + d3d7et->total++; + + return DDENUMRET_OK; +} + +static HRESULT WINAPI enumDevicesCancelTest7(char *DeviceDescription, char *DeviceName, + D3DDEVICEDESC7 *lpdd7, void *Context) +{ + D3D7ECancelTest *d3d7et = Context; + + d3d7et->total++; + + return d3d7et->desired_ret; +} + +static HRESULT WINAPI enumDevicesLifetimeTest7(char *DeviceDescription, char *DeviceName, + D3DDEVICEDESC7 *lpdd7, void *Context) +{ + D3D7ELifetimeTest *ctx = Context; + + if (ctx->count == MAX_ENUMERATION_COUNT) + { + ok(0, "Enumerated too many devices for context in callback\n"); + return DDENUMRET_CANCEL; + } + + ctx->callback_description_ptrs[ctx->count] = DeviceDescription; + strcpy(ctx->callback_description_strings[ctx->count], DeviceDescription); + ctx->callback_name_ptrs[ctx->count] = DeviceName; + strcpy(ctx->callback_name_strings[ctx->count], DeviceName); + + ctx->count++; + return DDENUMRET_OK; +} + +/* Check the deviceGUID of devices enumerated by + IDirect3D7_EnumDevices. */ +static void test_enum_devices(void) +{ + IDirectDraw7 *ddraw; + IDirect3D7 *d3d7; + HRESULT hr; + D3D7ETest d3d7et; + D3D7ECancelTest d3d7_cancel_test; + + if (!(ddraw = create_ddraw())) + return; + + hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7); + IDirectDraw7_Release(ddraw); + if (FAILED(hr)) + { + return; + } + + hr = IDirect3D7_EnumDevices(d3d7, NULL, NULL); + ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + memset(&d3d7et, 0, sizeof(d3d7et)); + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesCallbackTest7, &d3d7et); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + /* A couple of games (Delta Force LW and TFD) rely on this behaviour */ + ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n"); + + /* We make two additional assumptions. */ + ok(d3d7et.rgb, "No RGB Device enumerated.\n"); + + if(d3d7et.tnlhal) + ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n"); + + d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL; + d3d7_cancel_test.total = 0; + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesCancelTest7, &d3d7_cancel_test); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n", + d3d7_cancel_test.total); + + /* An enumeration callback can return any value besides DDENUMRET_OK to stop enumeration. */ + d3d7_cancel_test.desired_ret = E_INVALIDARG; + d3d7_cancel_test.total = 0; + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesCancelTest7, &d3d7_cancel_test); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + ok(d3d7_cancel_test.total == 1, "Enumerated a total of %u devices\n", + d3d7_cancel_test.total); + + IDirect3D7_Release(d3d7); +} + +static void test_enum_devices_life_time(void) +{ + IDirectDraw7 *ddraw; + IDirect3D7 *d3d7; + HRESULT hr; + D3D7ELifetimeTest ctx, ctx2; + unsigned int i; + + if (!(ddraw = create_ddraw())) + return; + + hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7); + IDirectDraw7_Release(ddraw); + if (FAILED(hr)) + { + return; + } + + ctx.count = 0; + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesLifetimeTest7, &ctx); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + /* The enumeration strings remain valid even after IDirect3D7_EnumDevices finishes. */ + for (i = 0; i < ctx.count; i++) + { + ok(!strcmp(ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]), + "Got '%s' and '%s'\n", ctx.callback_description_ptrs[i], ctx.callback_description_strings[i]); + ok(!strcmp(ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]), + "Got '%s' and '%s'\n", ctx.callback_name_ptrs[i], ctx.callback_name_strings[i]); + } + + ctx2.count = 0; + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesLifetimeTest7, &ctx2); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + /* The enumeration strings and their order are identical across enumerations. */ + ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count); + if (ctx.count == ctx2.count) + { + for (i = 0; i < ctx.count; i++) + { + ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i], + "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]); + ok(!strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]), + "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]); + ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i], + "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]); + ok(!strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]), + "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]); + } + } + + /* Try altering the contents of the enumeration strings. */ + for (i = 0; i < ctx2.count; i++) + { + strcpy(ctx2.callback_description_ptrs[i], "Fake Description"); + strcpy(ctx2.callback_name_ptrs[i], "Fake Device"); + } + + ctx2.count = 0; + hr = IDirect3D7_EnumDevices(d3d7, enumDevicesLifetimeTest7, &ctx2); + ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr); + + /* The original contents of the enumeration strings are not restored. */ + ok(ctx.count == ctx2.count, "Enumerated %u and %u devices\n", ctx.count, ctx2.count); + if (ctx.count == ctx2.count) + { + for (i = 0; i < ctx.count; i++) + { + ok(ctx.callback_description_ptrs[i] == ctx2.callback_description_ptrs[i], + "Unequal description pointers %p and %p\n", ctx.callback_description_ptrs[i], ctx2.callback_description_ptrs[i]); + ok(strcmp(ctx.callback_description_strings[i], ctx2.callback_description_strings[i]) != 0, + "Got '%s' and '%s'\n", ctx.callback_description_strings[i], ctx2.callback_description_strings[i]); + ok(ctx.callback_name_ptrs[i] == ctx2.callback_name_ptrs[i], + "Unequal name pointers %p and %p\n", ctx.callback_name_ptrs[i], ctx2.callback_name_ptrs[i]); + ok(strcmp(ctx.callback_name_strings[i], ctx2.callback_name_strings[i]) != 0, + "Got '%s' and '%s'\n", ctx.callback_name_strings[i], ctx2.callback_name_strings[i]); + } + } + + IDirect3D7_Release(d3d7); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -15966,4 +16177,6 @@ START_TEST(ddraw7) test_multiply_transform(); test_alphatest(); test_clipper_refcount(); + test_enum_devices(); + test_enum_devices_life_time(); } -- 2.19.1