diff --git a/dlls/rpcrt4/cproxy.c b/dlls/rpcrt4/cproxy.c index 8352ba36c57..6a73953e420 100644 --- a/dlls/rpcrt4/cproxy.c +++ b/dlls/rpcrt4/cproxy.c @@ -37,6 +37,7 @@ #include "cpsf.h" #include "ndr_misc.h" +#include "ndr_stubless.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -95,19 +96,20 @@ __ASM_GLOBAL_FUNC(call_stubless_func, "addl %edx,%esp\n\t" "jmp *%ecx" ); -CLIENT_CALL_RETURN WINAPI ObjectStubless(DWORD *args) +LONG_PTR WINAPI ObjectStubless(void **args) { - DWORD index = args[0]; + DWORD index = (DWORD)args[0]; void **iface = (void **)args[2]; const void **vtbl = (const void **)*iface; const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2); const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index]; + DWORD arg_size = *(const WORD*)(fs + 8); /* store bytes to remove from stack */ - args[0] = *(const WORD*)(fs + 8); - TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]); + args[0] = (void *)arg_size; + TRACE("(%p)->(%d)([%d bytes]) ret=%p\n", iface, index, arg_size, args[1]); - return NdrClientCall2(stubless->pStubDesc, fs, args + 2); + return ndr_client_call(stubless->pStubDesc, fs, args + 2); } #define BLOCK_SIZE 1024 diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c index f01977646ef..9591f2d540a 100644 --- a/dlls/rpcrt4/ndr_stubless.c +++ b/dlls/rpcrt4/ndr_stubless.c @@ -565,7 +565,7 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, } } -CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...) +LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, void **stack_top ) { /* pointer to start of stack where arguments start */ RPC_MESSAGE rpcMsg; @@ -594,7 +594,6 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STR PFORMAT_STRING pHandleFormat; /* correlation cache */ ULONG_PTR NdrCorrCache[256]; - __ms_va_list args; TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); @@ -623,7 +622,7 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STR if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) { /* object is always the first argument */ - This = **(void *const **)(&pFormat+1); + This = stack_top[0]; NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); } else @@ -632,11 +631,7 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STR TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); - /* needed for conformance of top-level objects */ - __ms_va_start( args, pFormat ); - stubMsg.StackTop = va_arg( args, unsigned char * ); - __ms_va_end( args ); - + stubMsg.StackTop = (unsigned char *)stack_top; pHandleFormat = pFormat; /* we only need a handle if this isn't an object method */ @@ -915,9 +910,24 @@ CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STR done: TRACE("RetVal = 0x%lx\n", RetVal); - return *(CLIENT_CALL_RETURN *)&RetVal; + return RetVal; } +/*********************************************************************** + * NdrClientCall2 [RPCRT4.@] + */ +CLIENT_CALL_RETURN WINAPIV NdrClientCall2( PMIDL_STUB_DESC desc, PFORMAT_STRING format, ... ) +{ + __ms_va_list args; + LONG_PTR ret; + + __ms_va_start( args, format ); + ret = ndr_client_call( desc, format, va_arg( args, void ** )); + __ms_va_end( args ); + return *(CLIENT_CALL_RETURN *)&ret; +} + + /* Calls a function with the specified arguments, restoring the stack * properly afterwards as we don't know the calling convention of the * function */ @@ -1650,20 +1660,6 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); } -/*********************************************************************** - * NdrClientCall [RPCRT4.@] - */ -CLIENT_CALL_RETURN WINAPIV NdrClientCall( PMIDL_STUB_DESC desc, PFORMAT_STRING format, ... ) -{ - __ms_va_list args; - CLIENT_CALL_RETURN ret; - - __ms_va_start( args, format ); - ret = NdrClientCall2( desc, format, va_arg( args, unsigned char * )); - __ms_va_end( args ); - return ret; -} - /*********************************************************************** * NdrStubCall [RPCRT4.@] */ diff --git a/dlls/rpcrt4/ndr_stubless.h b/dlls/rpcrt4/ndr_stubless.h index b672554ccfd..baa1f3e4a54 100644 --- a/dlls/rpcrt4/ndr_stubless.h +++ b/dlls/rpcrt4/ndr_stubless.h @@ -236,6 +236,8 @@ typedef struct _NDR_EHD_CONTEXT #include "poppack.h" +LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, + void **stack_top ) DECLSPEC_HIDDEN; void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, int phase, unsigned char *args, unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index bacef8c4c0d..b88c16de5e5 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -127,7 +127,7 @@ @ stdcall NdrCStdStubBuffer_Release(ptr ptr) @ stdcall NdrClearOutParameters(ptr ptr ptr) @ varargs NdrClientCall2(ptr ptr) -@ varargs NdrClientCall(ptr ptr) +@ varargs -arch=i386 NdrClientCall(ptr ptr) NdrClientCall2 @ stdcall NdrClientContextMarshall(ptr ptr long) @ stdcall NdrClientContextUnmarshall(ptr ptr ptr) @ stub NdrClientInitialize