diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index aee19f28bcd..f9d1c76c249 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -168,6 +168,7 @@ struct oletls IErrorInfo *errorinfo; /* see errorinfo.c */ IUnknown *state; /* see CoSetState */ DWORD inits; /* number of times CoInitializeEx called */ + GUID causality_id; /* unique identifier for each COM call */ }; @@ -273,6 +274,16 @@ static inline APARTMENT* COM_CurrentApt(void) return COM_CurrentInfo()->apt; } +static inline GUID COM_CurrentCausalityId(void) +{ + struct oletls *info = COM_CurrentInfo(); + if (!info) + return GUID_NULL; + if (IsEqualGUID(&info->causality_id, &GUID_NULL)) + CoCreateGuid(&info->causality_id); + return info->causality_id; +} + #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) /* helpers for debugging */ diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 586562ec3a6..49f58428fac 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -418,7 +418,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, message_state->channel_hook_info.iid = *riid; message_state->channel_hook_info.cbSize = sizeof(message_state->channel_hook_info); - message_state->channel_hook_info.uCausality = GUID_NULL; /* FIXME */ + message_state->channel_hook_info.uCausality = COM_CurrentCausalityId(); message_state->channel_hook_info.dwServerPid = 0; /* FIXME */ message_state->channel_hook_info.iMethod = msg->ProcNum; message_state->channel_hook_info.pObject = NULL; /* only present on server-side */ @@ -940,6 +940,7 @@ void RPC_ExecuteCall(struct dispatch_params *params) ORPCTHIS orpcthis; ORPC_EXTENT_ARRAY orpc_ext_array; WIRE_ORPC_EXTENT *first_wire_orpc_extent; + GUID old_causality_id; /* handle ORPCTHIS and server extensions */ @@ -977,12 +978,17 @@ void RPC_ExecuteCall(struct dispatch_params *params) { DWORD handlecall; INTERFACEINFO interface_info; + CALLTYPE calltype; interface_info.pUnk = params->iface; interface_info.iid = params->iid; interface_info.wMethod = msg->ProcNum; + if (IsEqualGUID(&orpcthis.cid, &COM_CurrentInfo()->causality_id)) + calltype = CALLTYPE_NESTED; + else /* FIXME: also detect CALLTYPE_TOPLEVEL_CALLPENDING */ + calltype = CALLTYPE_TOPLEVEL; handlecall = IMessageFilter_HandleInComingCall(COM_CurrentApt()->filter, - CALLTYPE_TOPLEVEL /* FIXME */, + calltype, (HTASK)GetCurrentProcessId(), 0 /* FIXME */, &interface_info); @@ -1008,7 +1014,13 @@ void RPC_ExecuteCall(struct dispatch_params *params) /* invoke the method */ + /* save the old causality ID - note: any calls executed while processing + * messages received during the SendReceive will appear to originate from + * this call - this should be checked with what Windows does */ + old_causality_id = COM_CurrentInfo()->causality_id; + COM_CurrentInfo()->causality_id = orpcthis.cid; params->hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan); + COM_CurrentInfo()->causality_id = old_causality_id; message_state = (struct message_state *)msg->Handle; msg->Handle = message_state->binding_handle;