Commit 306e14b9 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

rpcrt4: Perform the INITOUT phase in NdrAsyncServerCall instead of RpcAsyncCompleteCall.

This is required to correctly support out reference parameters, otherwise server method receives not initialized pointers during the CALLSERVER phase and crashes. Signed-off-by: 's avatarDmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 07ee2a7d
...@@ -1632,6 +1632,8 @@ static void do_ndr_async_client_call( const MIDL_STUB_DESC *pStubDesc, PFORMAT_S ...@@ -1632,6 +1632,8 @@ static void do_ndr_async_client_call( const MIDL_STUB_DESC *pStubDesc, PFORMAT_S
pAsync->StubInfo = async_call_data; pAsync->StubInfo = async_call_data;
async_call_data->pHandleFormat = pFormat; async_call_data->pHandleFormat = pFormat;
TRACE("pAsync %p, pAsync->StubInfo %p, NotificationType %d\n", pAsync, pAsync->StubInfo, pAsync->NotificationType);
pFormat += get_handle_desc_size(pProcHeader, pFormat); pFormat += get_handle_desc_size(pProcHeader, pFormat);
async_call_data->hBinding = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat); async_call_data->hBinding = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat);
if (!async_call_data->hBinding) return; if (!async_call_data->hBinding) return;
...@@ -2075,7 +2077,11 @@ void RPC_ENTRY NdrAsyncServerCall(PRPC_MESSAGE pRpcMsg) ...@@ -2075,7 +2077,11 @@ void RPC_ENTRY NdrAsyncServerCall(PRPC_MESSAGE pRpcMsg)
TRACE("UNMARSHAL\n"); TRACE("UNMARSHAL\n");
stub_do_args(async_call_data->pStubMsg, pFormat, STUBLESS_UNMARSHAL, async_call_data->number_of_params); stub_do_args(async_call_data->pStubMsg, pFormat, STUBLESS_UNMARSHAL, async_call_data->number_of_params);
/* 2. CALLSERVER */ /* 2. INITOUT */
TRACE("INITOUT\n");
async_call_data->retval_ptr = stub_do_args(async_call_data->pStubMsg, pFormat, STUBLESS_INITOUT, async_call_data->number_of_params);
/* 3. CALLSERVER */
TRACE("CALLSERVER\n"); TRACE("CALLSERVER\n");
if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum]) if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum])
pServerInfo->ThunkTable[pRpcMsg->ProcNum](async_call_data->pStubMsg); pServerInfo->ThunkTable[pRpcMsg->ProcNum](async_call_data->pStubMsg);
...@@ -2090,8 +2096,6 @@ RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply) ...@@ -2090,8 +2096,6 @@ RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply)
struct async_call_data *async_call_data; struct async_call_data *async_call_data;
/* the type of pass we are currently doing */ /* the type of pass we are currently doing */
enum stubless_phase phase; enum stubless_phase phase;
/* location to put retval into */
LONG_PTR *retval_ptr;
RPC_STATUS status = RPC_S_OK; RPC_STATUS status = RPC_S_OK;
if (!pAsync->StubInfo) if (!pAsync->StubInfo)
...@@ -2102,13 +2106,10 @@ RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply) ...@@ -2102,13 +2106,10 @@ RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply)
TRACE("pAsync %p, pAsync->StubInfo %p, pFormat %p\n", pAsync, pAsync->StubInfo, async_call_data->pHandleFormat); TRACE("pAsync %p, pAsync->StubInfo %p, pFormat %p\n", pAsync, pAsync->StubInfo, async_call_data->pHandleFormat);
/* 3. INITOUT */ if (async_call_data->retval_ptr)
TRACE("INITOUT\n");
retval_ptr = stub_do_args(async_call_data->pStubMsg, async_call_data->pHandleFormat, STUBLESS_INITOUT, async_call_data->number_of_params);
if (retval_ptr)
{ {
TRACE("stub implementation returned 0x%lx\n", *(LONG_PTR *)Reply); TRACE("stub implementation returned 0x%lx\n", *(LONG_PTR *)Reply);
*retval_ptr = *(LONG_PTR *)Reply; *async_call_data->retval_ptr = *(LONG_PTR *)Reply;
} }
else else
TRACE("void stub implementation\n"); TRACE("void stub implementation\n");
......
...@@ -235,6 +235,8 @@ struct async_call_data ...@@ -235,6 +235,8 @@ struct async_call_data
unsigned short stack_size; unsigned short stack_size;
/* number of parameters. optional for client to give it to us */ /* number of parameters. optional for client to give it to us */
unsigned int number_of_params; unsigned int number_of_params;
/* location to put retval into */
LONG_PTR *retval_ptr;
/* correlation cache */ /* correlation cache */
ULONG_PTR NdrCorrCache[256]; ULONG_PTR NdrCorrCache[256];
}; };
......
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