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