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: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
07ee2a7d82
commit
306e14b956
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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
|
||||||
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];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue