Andrew Nguyen : ddraw: Extend the lifetime of the EnumDevices strings beyond function scope.

Alexandre Julliard julliard at winehq.org
Wed Jun 1 12:11:08 CDT 2011


Module: wine
Branch: master
Commit: f2f529ae38b378b12935d2f7489a1a8f6a7a7a7b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f2f529ae38b378b12935d2f7489a1a8f6a7a7a7b

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Wed Jun  1 07:12:45 2011 -0500

ddraw: Extend the lifetime of the EnumDevices strings beyond function scope.

---

 dlls/ddraw/ddraw.c     |   48 +++++++++++++++++------
 dlls/ddraw/tests/d3d.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 13 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 3365c35..65e70dd 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -39,6 +39,35 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier =
     0
 };
 
+static struct enum_device_entry
+{
+    char interface_name[100];
+    char device_name[100];
+    const GUID *device_guid;
+} device_list7[] =
+{
+    /* T&L HAL device */
+    {
+        "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D",
+        "Wine D3D7 T&L HAL",
+        &IID_IDirect3DTnLHalDevice,
+    },
+
+    /* HAL device */
+    {
+        "WINE Direct3D7 Hardware acceleration using WineD3D",
+        "Wine D3D7 HAL",
+        &IID_IDirect3DHALDevice,
+    },
+
+    /* RGB device */
+    {
+        "WINE Direct3D7 RGB Software Emulation using WineD3D",
+        "Wine D3D7 RGB",
+        &IID_IDirect3DRGBDevice,
+    },
+};
+
 static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {}
 
 const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
@@ -4220,17 +4249,11 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur
  *****************************************************************************/
 static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBACK7 callback, void *context)
 {
-    char interface_name_tnl[] = "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D";
-    char device_name_tnl[] = "Wine D3D7 T&L HAL";
-    char interface_name_hal[] = "WINE Direct3D7 Hardware acceleration using WineD3D";
-    char device_name_hal[] = "Wine D3D7 HAL";
-    char interface_name_rgb[] = "WINE Direct3D7 RGB Software Emulation using WineD3D";
-    char device_name_rgb[] = "Wine D3D7 RGB";
-
     IDirectDrawImpl *This = impl_from_IDirect3D7(iface);
     D3DDEVICEDESC7 device_desc7;
     D3DDEVICEDESC device_desc1;
     HRESULT hr;
+    size_t i;
 
     TRACE("iface %p, callback %p, context %p.\n", iface, callback, context);
 
@@ -4245,13 +4268,12 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
-    callback(interface_name_tnl, device_name_tnl, &device_desc7, context);
 
-    device_desc7.deviceGUID = IID_IDirect3DHALDevice;
-    callback(interface_name_hal, device_name_hal, &device_desc7, context);
-
-    device_desc7.deviceGUID = IID_IDirect3DRGBDevice;
-    callback(interface_name_rgb, device_name_rgb, &device_desc7, context);
+    for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++)
+    {
+        device_desc7.deviceGUID = *device_list7[i].device_guid;
+        callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context);
+    }
 
     TRACE("End of enumeration.\n");
 
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index 4dc2a20..d6b8fb8 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -54,6 +54,16 @@ typedef struct {
     int unk;
 } D3D7ETest;
 
+#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;
+
 /* To compare bad floating point numbers. Not the ideal way to do it,
  * but it should be enough for here */
 #define comparefloat(a, b) ( (((a) - (b)) < 0.0001) && (((a) - (b)) > -0.0001) )
@@ -860,6 +870,24 @@ static HRESULT WINAPI enumDevicesCallbackTest7(LPSTR DeviceDescription, LPSTR De
     return DDENUMRET_OK;
 }
 
+static HRESULT WINAPI enumDevicesLifetimeTest7(LPSTR DeviceDescription, LPSTR DeviceName, LPD3DDEVICEDESC7 lpdd7, LPVOID 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. */
@@ -884,6 +912,75 @@ static void D3D7EnumTest(void)
         ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
 }
 
+static void D3D7EnumLifetimeTest(void)
+{
+    D3D7ELifetimeTest ctx, ctx2;
+    HRESULT hr;
+    unsigned int i;
+
+    ctx.count = 0;
+    hr = IDirect3D7_EnumDevices(lpD3D, 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(lpD3D, 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(lpD3D, 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]);
+        }
+    }
+}
+
 static void CapsTest(void)
 {
     IDirect3D3 *d3d3;
@@ -4093,6 +4190,7 @@ START_TEST(d3d)
         SceneTest();
         LimitTest();
         D3D7EnumTest();
+        D3D7EnumLifetimeTest();
         SetMaterialTest();
         ComputeSphereVisibility();
         CapsTest();




More information about the wine-cvs mailing list