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