[PATCH] rpcrt4: Add an exception handler to NdrAsyncClientCall.

Dmitry Timoshkov dmitry at baikal.ru
Wed Aug 28 04:51:48 CDT 2019


NdrClientCall already uses TRY/EXCEPT block if the procedure has
Oi_HAS_COMM_OR_FAULT in its Oi_flags, I've added similar block
to NdrAsyncClientCall but without mapping the fault code using
CommFaultOffsets because NdrAsyncClientCall doesn't have this
implemented.

An installer that I have here calls NdrAsyncClientCall in order
to query status of a not yet installed service, and that leads
to a crash due to RaiseException from inside of NdrAsyncClientCall.
With this patch it no longer crashes on an unhandled exception,
and then installs the service.

Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/rpcrt4/ndr_stubless.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c
index b47ffa97b8..de58a9f22b 100644
--- a/dlls/rpcrt4/ndr_stubless.c
+++ b/dlls/rpcrt4/ndr_stubless.c
@@ -1574,8 +1574,9 @@ struct async_call_data
     ULONG_PTR NdrCorrCache[256];
 };
 
-LONG_PTR CDECL DECLSPEC_HIDDEN ndr_async_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
-                                                      void **stack_top )
+/* Helper for ndr_async_client_call, to factor out the part that may or may not be
+ * guarded by a try/except block. */
+static void do_ndr_async_client_call( const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormat, void **stack_top )
 {
     /* pointer to start of stack where arguments start */
     PRPC_MESSAGE pRpcMsg;
@@ -1592,8 +1593,6 @@ LONG_PTR CDECL DECLSPEC_HIDDEN ndr_async_client_call( PMIDL_STUB_DESC pStubDesc,
     const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
     RPC_STATUS status;
 
-    TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
-
     /* Later NDR language versions probably won't be backwards compatible */
     if (pStubDesc->Version > 0x50002)
     {
@@ -1650,7 +1649,7 @@ LONG_PTR CDECL DECLSPEC_HIDDEN ndr_async_client_call( PMIDL_STUB_DESC pStubDesc,
 
     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) goto done;
+    if (!async_call_data->hBinding) return;
 
     if (is_oicf_stubdesc(pStubDesc))
     {
@@ -1769,8 +1768,30 @@ LONG_PTR CDECL DECLSPEC_HIDDEN ndr_async_client_call( PMIDL_STUB_DESC pStubDesc,
                 RpcRaiseException(status);
         }
     }
+}
+
+LONG_PTR CDECL DECLSPEC_HIDDEN ndr_async_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
+                                                      void **stack_top )
+{
+    const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
+
+    TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
+
+    if (pProcHeader->Oi_flags & Oi_HAS_COMM_OR_FAULT)
+    {
+        __TRY
+        {
+            do_ndr_async_client_call( pStubDesc, pFormat, stack_top );
+        }
+        __EXCEPT_ALL
+        {
+            FIXME("exception %x during ndr_async_client_call()\n", GetExceptionCode());
+        }
+        __ENDTRY
+    }
+    else
+        do_ndr_async_client_call( pStubDesc, pFormat, stack_top);
 
-done:
     TRACE("returning 0\n");
     return 0;
 }
-- 
2.20.1




More information about the wine-devel mailing list