diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 53acd8e20514803518bf131584af366ad6ad28e4..91a96a9cb0c6ddd3e690a613ea15791fe922a1d6 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -419,7 +419,8 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
     switch (msg)
     {
     case DM_EXECUTERPC:
-        return RPC_ExecuteCall((struct dispatch_params *)lParam);
+        RPC_ExecuteCall((struct dispatch_params *)lParam);
+        return 0;
     default:
         return DefWindowProcW(hWnd, msg, wParam, lParam);
     }
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 97a3177896f10adc5c0c1523066babeed4202a67..6947ef485f585048279f71f971462e69473bac63 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -200,7 +200,7 @@ struct dispatch_params;
 
 void    RPC_StartRemoting(struct apartment *apt);
 HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
-HRESULT RPC_ExecuteCall(struct dispatch_params *params);
+void    RPC_ExecuteCall(struct dispatch_params *params);
 HRESULT RPC_RegisterInterface(REFIID riid);
 void    RPC_UnregisterInterface(REFIID riid);
 void    RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index 117abfd4bb9dbcd8bfa4741e5c7490fa32310128..c6cb8ba5830ddaa24e363e08def1fa42940ecea1 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -42,7 +42,9 @@
 #include "winerror.h"
 #include "winreg.h"
 #include "wtypes.h"
+#include "excpt.h"
 #include "wine/unicode.h"
+#include "wine/exception.h"
 
 #include "compobj_private.h"
 
@@ -105,8 +107,17 @@ struct dispatch_params
     IRpcChannelBuffer *chan; /* server channel buffer, if applicable */
     HANDLE             handle; /* handle that will become signaled when call finishes */
     RPC_STATUS         status; /* status (out) */
+    HRESULT            hr; /* hresult (out) */
 };
 
+static WINE_EXCEPTION_FILTER(ole_filter)
+{
+    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
+        GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
+        return EXCEPTION_CONTINUE_SEARCH;
+    return EXCEPTION_EXECUTE_HANDLER;
+}
+
 static HRESULT WINAPI RpcChannelBuffer_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv)
 {
     *ppv = NULL;
@@ -228,6 +239,7 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
     
     params->msg = olemsg;
     params->status = RPC_S_OK;
+    params->hr = S_OK;
 
     /* Note: this is an optimization in the Microsoft OLE runtime that we need
      * to copy, as shown by the test_no_couninitialize_client test. without
@@ -271,6 +283,8 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
         hr = CoWaitForMultipleHandles(0, INFINITE, 1, &params->handle, &index);
     CloseHandle(params->handle);
 
+    if (hr == S_OK) hr = params->hr;
+
     status = params->status;
     HeapFree(GetProcessHeap(), 0, params);
     params = NULL;
@@ -434,12 +448,19 @@ HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan)
 }
 
 
-HRESULT RPC_ExecuteCall(struct dispatch_params *params)
+void RPC_ExecuteCall(struct dispatch_params *params)
 {
-    HRESULT hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
+    __TRY
+    {
+        params->hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
+    }
+    __EXCEPT(ole_filter)
+    {
+        params->hr = GetExceptionCode();
+    }
+    __ENDTRY
     IRpcStubBuffer_Release(params->stub);
     if (params->handle) SetEvent(params->handle);
-    return hr;
 }
 
 static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)