This is a summary of my recent probs with Winelib in the hope that someone who knows the COM stuff can fix them quickly, because hacking through the jungle of include files and definitions is hard work
In short, I've built the latest wine cvs with the ICOM_MSVTABLE_COMPAT flag set in include/wine/obj_base.h, so each vtable has two dummy words at the start for g++'s benefit.
I then added these statements to the start of my WinMain to cause a segfault:
IDirectDraw* dd; DirectDrawCreate(0, &dd, NULL;)
and for good measure, wrapped the call to IDirectDraw7_QueryInterface in DDRAW_Create (which is where the segfault occurs) in ddraw/main.c with these two warnings:
WARN("about to call IDirectDraw7_QueryInterface vtbl size = %d\n", sizeof(DDCF_Vtbl));
hr = IDirectDraw7_QueryInterface(pDD, iid, lplpDD);
WARN("called IDirectDraw7_QueryInterface\n");
and when running the program, the trace clearly shows that the Release entry point is being called instead, and crashing, though the vtable is the expected size (5 entry points, plus 2 dummy dwords):
warn:ddraw:DDRAW_Create about to call IDirectDraw7_QueryInterface vtbl size = 28 warn:ddraw:DDRAW_Create offset is 12271064 trace:ddraw:Main_DirectDraw_Release (0x403a7c70)->() decrementing from 1. warn:ddraw:Main_DirectDraw_Release doing final release
Looking at the pre-processor output from compiling ddraw/main.c, I can see that IDirectDraw7Vtbl type has the two extra words grafted onto the front, as it should:
struct IDirectDraw7Vtbl { long dummyRTTI1; long dummyRTTI2; HRESULT (__attribute__((__stdcall__)) *QueryInterface)(IDirectDraw7* me, const IID* const a, LPVOID* b); ULONG (__attribute__((__stdcall__)) *AddRef)(IDirectDraw7* me); ULONG (__attribute__((__stdcall__)) *Release)(IDirectDraw7* me); ...
The problem seems to be that the call is offset not just by two table entries, but four. Somewhere in that jungle of macros, the "vtable base adjustment" of +2 is being applied twice, I'm sure of it. But I'm buggered if I can find out where this is happening; I'm still looking but it's slow progress and I believe it's a winelib bug.
Any suggestions on how to fix it would be welcome. cheers,
I think I'm closer now...
trace:ddraw:User_DirectDraw_Construct (0x403a7c70,0)
Program received signal SIGINT, Interrupt. [Switching to Thread 16384 (LWP 2877)] 0x40f510e4 in DDRAW_Create (lpGUID=0x0, lplpDD=0x40c92d38, pUnkOuter=0x0, iid=0x40f585d0, ex=0) at main.c:264 264 while(1); (gdb) print pDD $1 = (struct IDirectDraw7 *) 0x403a7c70 (gdb) print *pDD $2 = {lpVtbl = 0x40f5a960} (gdb) print *pDD->lpVtbl $3 = {dummyRTTI1 = 1089756760, dummyRTTI2 = 1089756316, QueryInterface = 0x40f45cf0 <Main_DirectDraw_Release>, AddRef = 0x40f45f8c <Main_DirectDraw_Compact>, Release = 0x40f45fd4 <Main_DirectDraw_CreateClipper>,
So the create function is apparently unaware of the dummy values and is filling them in regardless... more later...
trace:ddraw:User_DirectDraw_Construct (0x403a7c70,0)
Well, if you look here in files dlls/ddraw/ddraw/hal.c and user.c you see that the 'ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE' line is missing in both vtable definitions...
Could you try adding this line (an example in file ddls/ddraw/main.c), recompile, and tell me if it works better now.
If yes, I will grep all DDraw code and submit a patch fixing those everywhere I find them.
Lionel
On Sat, 2 Nov 2002, Matthew Bloch wrote:
I think I'm closer now...
trace:ddraw:User_DirectDraw_Construct (0x403a7c70,0)
Program received signal SIGINT, Interrupt. [Switching to Thread 16384 (LWP 2877)] 0x40f510e4 in DDRAW_Create (lpGUID=0x0, lplpDD=0x40c92d38, pUnkOuter=0x0, iid=0x40f585d0, ex=0) at main.c:264 264 while(1); (gdb) print pDD $1 = (struct IDirectDraw7 *) 0x403a7c70 (gdb) print *pDD $2 = {lpVtbl = 0x40f5a960} (gdb) print *pDD->lpVtbl $3 = {dummyRTTI1 = 1089756760, dummyRTTI2 = 1089756316, QueryInterface = 0x40f45cf0 <Main_DirectDraw_Release>, AddRef = 0x40f45f8c <Main_DirectDraw_Compact>, Release = 0x40f45fd4 <Main_DirectDraw_CreateClipper>,
So the create function is apparently unaware of the dummy values and is filling them in regardless... more later...
Your particular problem is probably that the ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE isn't in the vtables found in ddraw/user.c and ddraw/hal.c, but I'd still just use ICOM_USE_COM_INTERFACE_ATTRIBUTE to avoid this kind of problem, unless you really want to fix all the places someone forgot this stuff...
On Saturday 02 November 2002 16:15, Ove Kaaven wrote:
Your particular problem is probably that the ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE isn't in the vtables found in ddraw/user.c and ddraw/hal.c, but I'd still just use ICOM_USE_COM_INTERFACE_ATTRIBUTE to avoid this kind of problem, unless you really want to fix all the places someone forgot this stuff...
I tried the attribute setting but gcc 2.95.4 doesn't support it, at least it warned me it was ignoring an unknown attribute. Maybe I should be using gcc-3.2 by now but I don't want to cause any more problems, and couldn't face another full recompile, nearly an hour for both WINE and the game on my laptop.
cheers,