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