[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