Andrew Nguyen : ddraw: Handle a callback cancellation attempt in d3d7_EnumDevices.
Alexandre Julliard
julliard at winehq.org
Wed Jun 1 12:11:08 CDT 2011
Module: wine
Branch: master
Commit: a90b698e0cbcdf4f2b0d67e2a35788b66e1baf58
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a90b698e0cbcdf4f2b0d67e2a35788b66e1baf58
Author: Andrew Nguyen <anguyen at 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)
More information about the wine-cvs
mailing list