Rob Shearman : ole32: Send a causality ID in the ORPCTHIS header for
a call .
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Dec 20 08:54:59 CST 2006
Module: wine
Branch: master
Commit: e236edb91ed9fff5de8c792fcf3abe427e9e0872
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e236edb91ed9fff5de8c792fcf3abe427e9e0872
Author: Rob Shearman <rob at codeweavers.com>
Date: Tue Dec 19 19:37:34 2006 +0000
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.
---
dlls/ole32/compobj_private.h | 11 +++++++++++
dlls/ole32/rpc.c | 16 ++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index aee19f2..f9d1c76 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(
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 586562e..49f5842 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -418,7 +418,7 @@ static HRESULT WINAPI ClientRpcChannelBu
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_par
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_par
{
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_par
/* 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;
More information about the wine-cvs
mailing list