[PATCH 2/2] rpcrt4: Implement RpcAsyncCompleteCall for server side.
Dmitry Timoshkov
dmitry at baikal.ru
Fri Sep 13 00:34:40 CDT 2019
Based on NdrStubCall2 implementation.
Signed-off-by: Dmitry Timoshkov <dmitry at 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);
}
/***********************************************************************
--
2.20.1
More information about the wine-devel
mailing list