Module: wine Branch: master Commit: a90b698e0cbcdf4f2b0d67e2a35788b66e1baf58 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a90b698e0cbcdf4f2b0d67e2a3...
Author: Andrew Nguyen anguyen@codeweavers.com Date: Wed Jun 1 07:13:03 2011 -0500
ddraw: Handle a callback cancellation attempt in d3d7_EnumDevices.
---
dlls/ddraw/ddraw.c | 10 +++++++++- dlls/ddraw/tests/d3d.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 65e70dd..8fb2ce0 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4271,8 +4271,16 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++) { + HRESULT ret; + device_desc7.deviceGUID = *device_list7[i].device_guid; - callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); + ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); + if (ret != DDENUMRET_OK) + { + TRACE("Application cancelled the enumeration.\n"); + LeaveCriticalSection(&ddraw_cs); + return D3D_OK; + } }
TRACE("End of enumeration.\n"); diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index d6b8fb8..f975612 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -54,6 +54,11 @@ typedef struct { int unk; } D3D7ETest;
+typedef struct { + HRESULT desired_ret; + int total; +} D3D7ECancelTest; + #define MAX_ENUMERATION_COUNT 10 typedef struct { @@ -870,6 +875,15 @@ static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR De return DDENUMRET_OK; }
+static HRESULT WINAPI enumDevicesCancelTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context) +{ + D3D7ECancelTest *d3d7et = Context; + + d3d7et->total++; + + return d3d7et->desired_ret; +} + static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID Context) { D3D7ELifetimeTest *ctx = Context; @@ -895,12 +909,14 @@ static void D3D7EnumTest(void) { HRESULT hr; D3D7ETest d3d7et; + D3D7ECancelTest d3d7_cancel_test;
hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL); ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
memset(&d3d7et, 0, sizeof(d3d7et)); - IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et); + hr = IDirect3D7_EnumDevices(lpD3D, 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"); @@ -910,6 +926,23 @@ static void D3D7EnumTest(void)
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(lpD3D, 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(lpD3D, 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); }
static void D3D7EnumLifetimeTest(void)