vxdcall calling convention

Patrik Stridvall ps at leissner.se
Mon Nov 18 09:21:37 CST 2002


> Le lun 18/11/2002 à 02:51, Patrik Stridvall a écrit :
> > > Corrects this line in winapi_check:
> > > win32/device.c:544: kernel32: void 
> VxDCall(DWORD,CONTEXT86 *): calling
> > > convention mismatch: cdecl != stdcall
> > 
> > I'm not 100% sure this really is a bug.
> > Don't trust winapi_check too much it is very ad hoc. :-)
> > 
> > It might however be a bug but I never got around to test it 
> properly.
> > 
> > So, have you verified that this really is correct?
> 
> Well, kernel32.spec references them by "stdcall -register -i386".
> Another API referenced the same way is CommonUnimpStub, and 
> in thunk.c,
> it is declared as "void WINAPI".
> 
> Is it sufficient checking?

I'm not sure, it might be the other API(s) that are wrong
or that VxDCall is a special case. That why I haven't dared
changed anything. 

The problem with VxDCall is that is have multiple entries under
different external names.

./dlls/kernel/kernel32.spec:  1 stdcall -register -i386 VxDCall0(long)
VxDCall
./dlls/kernel/kernel32.spec:  2 stdcall -register -i386 VxDCall1(long)
VxDCall
./dlls/kernel/kernel32.spec:  3 stdcall -register -i386 VxDCall2(long)
VxDCall
./dlls/kernel/kernel32.spec:  4 stdcall -register -i386 VxDCall3(long)
VxDCall
./dlls/kernel/kernel32.spec:  5 stdcall -register -i386 VxDCall4(long)
VxDCall
/dlls/kernel/kernel32.spec:  6 stdcall -register -i386 VxDCall5(long)
VxDCall
./dlls/kernel/kernel32.spec:  7 stdcall -register -i386 VxDCall6(long)
VxDCall
./dlls/kernel/kernel32.spec:  8 stdcall -register -i386 VxDCall7(long)
VxDCall
./dlls/kernel/kernel32.spec:  9 stdcall -register -i386 VxDCall8(long)
VxDCall

Searching on the Internet reveals this page:
http://www.mbs.spb.ru/kb/w32mbr.htm

According to this page VxDCall[0-8] really should be stdcall.

---8<---
/* Kernel32 W32-caller prototypes */
DWORD WINAPI VxDCall0(DWORD service);
DWORD WINAPI VxDCall1(DWORD service, DWORD);
DWORD WINAPI VxDCall2(DWORD service, DWORD, DWORD);
DWORD WINAPI VxDCall3(DWORD service, DWORD, DWORD, DWORD);
DWORD WINAPI VxDCall4(DWORD service, DWORD, DWORD, DWORD, DWORD);
DWORD WINAPI VxDCall5(DWORD service, DWORD, DWORD, DWORD, DWORD, DWORD);
DWORD WINAPI VxDCall6(DWORD service, DWORD, DWORD, DWORD, DWORD, DWORD,
DWORD);
DWORD WINAPI VxDCall7(DWORD service, DWORD, DWORD, DWORD, DWORD, DWORD,
DWORD,
                      DWORD);
DWORD WINAPI VxDCall8(DWORD service, DWORD, DWORD, DWORD, DWORD, DWORD,
DWORD,
                      DWORD, DWORD);
---8<---
 
and this

---8<---
vxdcall.def
LIBRARY KERNEL32
EXPORTS
    VxDCall0 at 0              @1
    VxDCall1 at 8              @2
    VxDCall2 at 12             @3
    VxDCall3 at 16             @4
    VxDCall4 at 20             @5
    VxDCall5 at 24             @6
    VxDCall6 at 28             @7
    VxDCall7 at 32             @8
    VxDCall8 at 36             @9
---8<---

However something with VxDCall is wrong nether the less.

WINAPI functions (read: __stdcall) functions expects that
the callee cleans up the argument stack and the number of
arguments is different depending on which function is
called.

Looking at VxDCall (and what it calls) in win32/device.c I see that
the implemented VxDCall pops the stack. 

However the unimplemented VxDCalls doesn't even though they might
have gotten some arguments. This means AFAICS that VxDCall corrupts
the stack in such cases...

So I'm pretty convinced that something is wrong however I don't think
you patch is the solution to the problem. It might possible be part
of a solution though...

Any suggestions?









More information about the wine-devel mailing list