From 1b7d346d1f46aa28b77524a9f752bd038b27a231 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Fri, 20 Jan 2006 16:16:08 +0100 Subject: [PATCH] ole: Verify that the proxy is being used in the correct thread. --- dlls/ole32/rpc.c | 39 ++++++++++++++++++++++++++++++++++----- dlls/ole32/tests/marshal.c | 4 +--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 06c24d3f054..c45df68b3b3 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -98,6 +98,7 @@ typedef struct RpcChannelBuffer super; /* superclass */ RPC_BINDING_HANDLE bind; /* handle to the remote server */ + OXID oxid; /* apartment in which the channel is valid */ } ClientRpcChannelBuffer; struct dispatch_params @@ -206,6 +207,12 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, return HRESULT_FROM_WIN32(status); } +static HRESULT WINAPI ServerRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + /* this thread runs an outgoing RPC */ static DWORD WINAPI rpc_sendreceive_thread(LPVOID param) { @@ -219,9 +226,22 @@ static DWORD WINAPI rpc_sendreceive_thread(LPVOID param) return 0; } -static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus) +static inline HRESULT ClientRpcChannelBuffer_IsCorrectApartment(ClientRpcChannelBuffer *This, APARTMENT *apt) { - HRESULT hr = S_OK; + OXID oxid; + if (!apt) + return S_FALSE; + if (apartment_getoxid(apt, &oxid) != S_OK) + return S_FALSE; + if (This->oxid != oxid) + return S_FALSE; + return S_OK; +} + +static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus) +{ + ClientRpcChannelBuffer *This = (ClientRpcChannelBuffer *)iface; + HRESULT hr; RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg; RPC_STATUS status; DWORD index; @@ -232,9 +252,17 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC TRACE("(%p) iMethod=%ld\n", olemsg, olemsg->iMethod); + hr = ClientRpcChannelBuffer_IsCorrectApartment(This, COM_CurrentApt()); + if (hr != S_OK) + { + ERR("called from wrong apartment, should have been 0x%s\n", + wine_dbgstr_longlong(This->oxid)); + return RPC_E_WRONG_THREAD; + } + params = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*params)); if (!params) return E_OUTOFMEMORY; - + params->msg = olemsg; params->status = RPC_S_OK; params->hr = S_OK; @@ -369,7 +397,7 @@ static const IRpcChannelBufferVtbl ClientRpcChannelBufferVtbl = RpcChannelBuffer_AddRef, ClientRpcChannelBuffer_Release, ClientRpcChannelBuffer_GetBuffer, - RpcChannelBuffer_SendReceive, + ClientRpcChannelBuffer_SendReceive, ClientRpcChannelBuffer_FreeBuffer, RpcChannelBuffer_GetDestCtx, RpcChannelBuffer_IsConnected @@ -381,7 +409,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl = RpcChannelBuffer_AddRef, ServerRpcChannelBuffer_Release, ServerRpcChannelBuffer_GetBuffer, - RpcChannelBuffer_SendReceive, + ServerRpcChannelBuffer_SendReceive, ServerRpcChannelBuffer_FreeBuffer, RpcChannelBuffer_GetDestCtx, RpcChannelBuffer_IsConnected @@ -440,6 +468,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelB This->super.lpVtbl = &ClientRpcChannelBufferVtbl; This->super.refs = 1; This->bind = bind; + apartment_getoxid(COM_CurrentApt(), &This->oxid); *chan = (IRpcChannelBuffer*)This; diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c index dc445e5a104..10c690c6fea 100644 --- a/dlls/ole32/tests/marshal.c +++ b/dlls/ole32/tests/marshal.c @@ -1021,14 +1021,12 @@ static DWORD CALLBACK bad_thread_proc(LPVOID p) IUnknown * proxy = NULL; pCoInitializeEx(NULL, COINIT_MULTITHREADED); - + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy); if (proxy) IUnknown_Release(proxy); - todo_wine { ok(hr == RPC_E_WRONG_THREAD, "COM should have failed with RPC_E_WRONG_THREAD on using proxy from wrong apartment, but instead returned 0x%08lx\n", hr); - } CoUninitialize(); -- 2.11.4.GIT