Based on NdrStubCall2 implementation.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/rpcrt4/ndr_stubless.c | 92 ++++++++++++++++++++++++++++++++++++++ dlls/rpcrt4/ndr_stubless.h | 1 + dlls/rpcrt4/rpc_async.c | 3 +- 3 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c index 70a26dd5b3..10de5a4f44 100644 --- a/dlls/rpcrt4/ndr_stubless.c +++ b/dlls/rpcrt4/ndr_stubless.c @@ -2082,3 +2082,95 @@ void RPC_ENTRY NdrAsyncServerCall(PRPC_MESSAGE pRpcMsg) else call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, async_call_data->stack_size); } + +RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply) +{ + /* pointer to start of stack where arguments start */ + PMIDL_STUB_MESSAGE pStubMsg; + struct async_call_data *async_call_data; + /* the type of pass we are currently doing */ + enum stubless_phase phase; + /* location to put retval into */ + LONG_PTR *retval_ptr; + RPC_STATUS status = RPC_S_OK; + + if (!pAsync->StubInfo) + return RPC_S_INVALID_ASYNC_HANDLE; + + async_call_data = pAsync->StubInfo; + pStubMsg = async_call_data->pStubMsg; + + TRACE("pAsync %p, pAsync->StubInfo %p, pFormat %p\n", pAsync, pAsync->StubInfo, async_call_data->pHandleFormat); + + /* 3. INITOUT */ + 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); + *retval_ptr = *(LONG_PTR *)Reply; + } + else + TRACE("void stub implementation\n"); + + for (phase = STUBLESS_CALCSIZE; phase <= STUBLESS_FREE; phase++) + { + TRACE("phase = %d\n", phase); + switch (phase) + { + case STUBLESS_GETBUFFER: + if (async_call_data->pProcHeader->Oi_flags & Oi_OBJECT_PROC) + { + ERR("objects not supported\n"); + HeapFree(GetProcessHeap(), 0, async_call_data->pStubMsg->StackTop); + I_RpcFree(async_call_data); + I_RpcFree(pAsync); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + else + { + pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; + /* allocate buffer for [out] and [ret] params */ + status = I_RpcGetBuffer(pStubMsg->RpcMsg); + if (status) + RpcRaiseException(status); + pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer; + } + break; + + case STUBLESS_CALCSIZE: + case STUBLESS_MARSHAL: + case STUBLESS_MUSTFREE: + case STUBLESS_FREE: + stub_do_args(pStubMsg, async_call_data->pHandleFormat, phase, async_call_data->number_of_params); + break; + default: + ERR("shouldn't reach here. phase %d\n", phase); + break; + } + } + +#if 0 /* FIXME */ + if (ext_flags.HasNewCorrDesc) + { + /* free extra correlation package */ + NdrCorrelationFree(pStubMsg); + } + + if (Oif_flags.HasPipes) + { + /* NdrPipesDone(...) */ + } + + /* free the full pointer translation tables */ + if (async_call_data->pProcHeader->Oi_flags & Oi_FULL_PTR_USED) + NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables); +#endif + + /* free server function stack */ + HeapFree(GetProcessHeap(), 0, async_call_data->pStubMsg->StackTop); + I_RpcFree(async_call_data); + I_RpcFree(pAsync); + + return S_OK; +} diff --git a/dlls/rpcrt4/ndr_stubless.h b/dlls/rpcrt4/ndr_stubless.h index fc67cf9020..699a6bcfcf 100644 --- a/dlls/rpcrt4/ndr_stubless.h +++ b/dlls/rpcrt4/ndr_stubless.h @@ -261,3 +261,4 @@ PFORMAT_STRING convert_old_args( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFo unsigned int stack_size, BOOL object_proc, void *buffer, unsigned int size, unsigned int *count ) DECLSPEC_HIDDEN; RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) DECLSPEC_HIDDEN; +RPC_STATUS NdrpCompleteAsyncServerCall(RPC_ASYNC_STATE *pAsync, void *Reply) DECLSPEC_HIDDEN; diff --git a/dlls/rpcrt4/rpc_async.c b/dlls/rpcrt4/rpc_async.c index 9c3d90cfba..00c2d6bede 100644 --- a/dlls/rpcrt4/rpc_async.c +++ b/dlls/rpcrt4/rpc_async.c @@ -125,8 +125,7 @@ RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply) if (data->pStubMsg->IsClient) return NdrpCompleteAsyncClientCall(pAsync, Reply);
- FIXME("not implemented for server side\n"); - return RPC_S_CALL_FAILED; + return NdrpCompleteAsyncServerCall(pAsync, Reply); }
/***********************************************************************