ole32: Send a causality ID in the ORPCTHIS header for a call.

Use the causality ID to determine whether this is a top-level or a 
nested (called-back) call for the purposes of IMessageFilter::HandleInComingCall.
This commit is contained in:
Rob Shearman 2006-12-19 19:37:34 +00:00 committed by Alexandre Julliard
parent 4fa03831a5
commit e236edb91e
2 changed files with 25 additions and 2 deletions

View File

@ -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 */

View File

@ -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;