Commit f2f529ae authored by Andrew Nguyen's avatar Andrew Nguyen Committed by Alexandre Julliard

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

parent 2dd0d8ab
......@@ -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");
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment