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

Alexandre Julliard julliard at winehq.org
Thu Sep 19 16:35:18 CDT 2019


Module: wine
Branch: master
Commit: 306e14b956551570f3a13f2f9c38945c02ac9f1f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=306e14b956551570f3a13f2f9c38945c02ac9f1f

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Thu Sep 19 09:43:27 2019 +0800

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 at baikal.ru>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/rpcrt4/ndr_stubless.c | 17 +++++++++--------
 dlls/rpcrt4/ndr_stubless.h |  2 ++
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c
index 10de5a4f44..bceecdc827 100644
--- a/dlls/rpcrt4/ndr_stubless.c
+++ b/dlls/rpcrt4/ndr_stubless.c
@@ -1632,6 +1632,8 @@ static void do_ndr_async_client_call( const MIDL_STUB_DESC *pStubDesc, PFORMAT_S
     pAsync->StubInfo = async_call_data;
     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);
     async_call_data->hBinding = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat);
     if (!async_call_data->hBinding) return;
@@ -2075,7 +2077,11 @@ void RPC_ENTRY NdrAsyncServerCall(PRPC_MESSAGE pRpcMsg)
     TRACE("UNMARSHAL\n");
     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");
     if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum])
         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;
     /* 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)
@@ -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);
 
-    /* 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)
+    if (async_call_data->retval_ptr)
     {
         TRACE("stub implementation returned 0x%lx\n", *(LONG_PTR *)Reply);
-        *retval_ptr = *(LONG_PTR *)Reply;
+        *async_call_data->retval_ptr = *(LONG_PTR *)Reply;
     }
     else
         TRACE("void stub implementation\n");
diff --git a/dlls/rpcrt4/ndr_stubless.h b/dlls/rpcrt4/ndr_stubless.h
index 699a6bcfcf..63bc656990 100644
--- a/dlls/rpcrt4/ndr_stubless.h
+++ b/dlls/rpcrt4/ndr_stubless.h
@@ -235,6 +235,8 @@ struct async_call_data
     unsigned short stack_size;
     /* number of parameters. optional for client to give it to us */
     unsigned int number_of_params;
+    /* location to put retval into */
+    LONG_PTR *retval_ptr;
     /* correlation cache */
     ULONG_PTR NdrCorrCache[256];
 };




More information about the wine-cvs mailing list