Module: wine Branch: master Commit: f2f529ae38b378b12935d2f7489a1a8f6a7a7a7b URL: http://source.winehq.org/git/wine.git/?a=commit;h=f2f529ae38b378b12935d2f748...
Author: Andrew Nguyen anguyen@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();