X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fwin32%2Fole32%2Frpc.c;h=bd4611d7d5f8a579ad52d1ec8563a9656f3f4090;hp=eaf67f74a8b2b78af0bb4442b9c1b89535af3583;hb=aeea29430187779d759395c7ace9e03b2e4ccb38;hpb=538011301663df17c3b12b5c57e75ca80ffebb3d diff --git a/dll/win32/ole32/rpc.c b/dll/win32/ole32/rpc.c index eaf67f74a8b..bd4611d7d5f 100644 --- a/dll/win32/ole32/rpc.c +++ b/dll/win32/ole32/rpc.c @@ -20,9 +20,30 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "config.h" +#include "wine/port.h" -#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winsvc.h" +#include "objbase.h" +#include "ole2.h" +#include "rpc.h" +#include "winerror.h" +#include "winreg.h" +#include "servprov.h" +#include "wine/unicode.h" + +#include "compobj_private.h" + +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -88,6 +109,7 @@ typedef struct OXID oxid; /* apartment in which the channel is valid */ DWORD server_pid; /* id of server process */ HANDLE event; /* cached event handle */ + IID iid; /* IID of the proxy this belongs to */ } ClientRpcChannelBuffer; struct dispatch_params @@ -629,7 +651,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, cif->Length = sizeof(RPC_CLIENT_INTERFACE); /* RPC interface ID = COM interface ID */ - cif->InterfaceId.SyntaxGUID = *riid; + cif->InterfaceId.SyntaxGUID = This->iid; /* COM objects always have a version of 0.0 */ cif->InterfaceId.SyntaxVersion.MajorVersion = 0; cif->InterfaceId.SyntaxVersion.MinorVersion = 0; @@ -643,7 +665,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, message_state->channel_hook_info.cbSize = sizeof(message_state->channel_hook_info); message_state->channel_hook_info.uCausality = COM_CurrentCausalityId(); message_state->channel_hook_info.dwServerPid = This->server_pid; - message_state->channel_hook_info.iMethod = msg->ProcNum; + message_state->channel_hook_info.iMethod = msg->ProcNum & ~RPC_FLAGS_VALID_BIT; message_state->channel_hook_info.pObject = NULL; /* only present on server-side */ message_state->target_hwnd = NULL; message_state->target_tid = 0; @@ -661,7 +683,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, } RpcBindingInqObject(message_state->binding_handle, &ipid); - hr = ipid_get_dispatch_params(&ipid, &apt, &message_state->params.stub, + hr = ipid_get_dispatch_params(&ipid, &apt, NULL, &message_state->params.stub, &message_state->params.chan, &message_state->params.iid, &message_state->params.iface); @@ -809,14 +831,16 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac ORPC_EXTENT_ARRAY orpc_ext_array; WIRE_ORPC_EXTENT *first_wire_orpc_extent = NULL; HRESULT hrFault = S_OK; + APARTMENT *apt = apartment_get_current_or_mta(); TRACE("(%p) iMethod=%d\n", olemsg, olemsg->iMethod); - hr = ClientRpcChannelBuffer_IsCorrectApartment(This, COM_CurrentApt()); + hr = ClientRpcChannelBuffer_IsCorrectApartment(This, apt); if (hr != S_OK) { ERR("called from wrong apartment, should have been 0x%s\n", wine_dbgstr_longlong(This->oxid)); + if (apt) apartment_release(apt); return RPC_E_WRONG_THREAD; } /* This situation should be impossible in multi-threaded apartments, @@ -824,11 +848,12 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac * Note: doing a COM call during the processing of a sent message is * only disallowed if a client call is already being waited for * completion */ - if (!COM_CurrentApt()->multi_threaded && + if (!apt->multi_threaded && COM_CurrentInfo()->pending_call_count_client && InSendMessage()) { ERR("can't make an outgoing COM call in response to a sent message\n"); + apartment_release(apt); return RPC_E_CANTCALLOUT_ININPUTSYNCCALL; } @@ -946,6 +971,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac TRACE("-- 0x%08x\n", hr); + apartment_release(apt); return hr; } @@ -1071,9 +1097,9 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl = /* returns a channel buffer for proxies */ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, - const OXID_INFO *oxid_info, + const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, - IRpcChannelBuffer **chan) + IRpcChannelBuffer **chan, APARTMENT *apt) { ClientRpcChannelBuffer *This; WCHAR endpoint[200]; @@ -1127,9 +1153,10 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, This->super.dest_context = dest_context; This->super.dest_context_data = dest_context_data; This->bind = bind; - apartment_getoxid(COM_CurrentApt(), &This->oxid); + apartment_getoxid(apt, &This->oxid); This->server_pid = oxid_info->dwPid; This->event = NULL; + This->iid = *iid; *chan = &This->super.IRpcChannelBuffer_iface; @@ -1420,6 +1447,7 @@ exit: static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) { struct dispatch_params *params; + struct stub_manager *stub_manager; APARTMENT *apt; IPID ipid; HRESULT hr; @@ -1435,7 +1463,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) return; } - hr = ipid_get_dispatch_params(&ipid, &apt, ¶ms->stub, ¶ms->chan, + hr = ipid_get_dispatch_params(&ipid, &apt, &stub_manager, ¶ms->stub, ¶ms->chan, ¶ms->iid, ¶ms->iface); if (hr != S_OK) { @@ -1473,16 +1501,17 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) else { BOOL joined = FALSE; - if (!COM_CurrentInfo()->apt) + struct oletls *info = COM_CurrentInfo(); + + if (!info->apt) { - apartment_joinmta(); + enter_apartment(info, COINIT_MULTITHREADED); joined = TRUE; } RPC_ExecuteCall(params); if (joined) { - apartment_release(COM_CurrentInfo()->apt); - COM_CurrentInfo()->apt = NULL; + leave_apartment(info); } } @@ -1493,6 +1522,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) IRpcStubBuffer_Release(params->stub); HeapFree(GetProcessHeap(), 0, params); + stub_manager_int_release(stub_manager); apartment_release(apt); /* if IRpcStubBuffer_Invoke fails, we should raise an exception to tell @@ -1558,7 +1588,7 @@ HRESULT RPC_RegisterInterface(REFIID riid) } /* stub unregistration */ -void RPC_UnregisterInterface(REFIID riid) +void RPC_UnregisterInterface(REFIID riid, BOOL wait) { struct registered_if *rif; EnterCriticalSection(&csRegIf); @@ -1568,7 +1598,7 @@ void RPC_UnregisterInterface(REFIID riid) { if (!--rif->refs) { - RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, TRUE); + RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, wait); list_remove(&rif->entry); HeapFree(GetProcessHeap(), 0, rif); } @@ -1620,7 +1650,7 @@ void RPC_StartRemoting(struct apartment *apt) /* FIXME: move remote unknown exporting into this function */ } - start_apartment_remote_unknown(); + start_apartment_remote_unknown(apt); } @@ -1630,7 +1660,7 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 }; HKEY key; HRESULT hres; - WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)]; + WCHAR command[MAX_PATH+ARRAY_SIZE(embedding)]; DWORD size = (MAX_PATH+1) * sizeof(WCHAR); STARTUPINFOW sinfo; PROCESS_INFORMATION pinfo; @@ -1771,7 +1801,7 @@ static void get_localserver_pipe_name(WCHAR *pipefn, REFCLSID rclsid) { static const WCHAR wszPipeRef[] = {'\\','\\','.','\\','p','i','p','e','\\',0}; strcpyW(pipefn, wszPipeRef); - StringFromGUID2(rclsid, pipefn + sizeof(wszPipeRef)/sizeof(wszPipeRef[0]) - 1, CHARS_IN_GUID); + StringFromGUID2(rclsid, pipefn + ARRAY_SIZE(wszPipeRef) - 1, CHARS_IN_GUID); } /* FIXME: should call to rpcss instead */ @@ -1828,6 +1858,7 @@ HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) bufferlen = 0; if (!ReadFile(hPipe,marshalbuffer,sizeof(marshalbuffer),&bufferlen,NULL)) { FIXME("Failed to read marshal id from classfactory of %s.\n",debugstr_guid(rclsid)); + CloseHandle(hPipe); Sleep(1000); continue; }