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, ¶ms->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)