Rob Shearman <robertshearman <at> gmail.com> writes:

Hi Rob, i think i got the test ready now, i'll send it when the defenitions are
in place in ctxtcall.idl. Now still strugling how to fix the bug.

 I fixed up the patch below, also by looking how things are done in similar
places in wine-code. With patch applied I can see that
ContextCallback_ContextCallback and ContextCallback_Release are called from the
application (tested with NASA WorldWind), and the simple stubs are enough to let
the app continue fine. But i'm not sure if everything is 100% ok. Is this what
you more or less meant in your first comment?

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 37907ec..a1f41fd 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -55,6 +55,7 @@
 #include "objbase.h"
 #include "ole2.h"
 #include "ole2ver.h"
+#include "ctxtcall.h"
 
 #include "compobj_private.h"
 
@@ -3615,25 +3616,39 @@ HRESULT WINAPI CoRegisterChannelHook(REFGUID guidExtension, IChannelHook *pChann
 typedef struct Context
 {
     const IComThreadingInfoVtbl *lpVtbl;
+    const IContextCallback *lpVtblIContextCallback;
     LONG refs;
     APTTYPE apttype;
 } Context;
 
+static inline Context *impl_from_Context(IComThreadingInfo *iface)
+{
+    return (Context *)((char*)iface - FIELD_OFFSET(Context, lpVtbl));
+}
+
 static HRESULT WINAPI Context_QueryInterface(IComThreadingInfo *iface, REFIID riid, LPVOID *ppv)
 {
+    Context* This=impl_from_Context((IComThreadingInfo*) iface);
     *ppv = NULL;
 
     if (IsEqualIID(riid, &IID_IComThreadingInfo) ||
         IsEqualIID(riid, &IID_IUnknown))
     {
         *ppv = iface;
-        IUnknown_AddRef(iface);
-        return S_OK;
     }
+    else if(IsEqualIID(riid, &IID_IContextCallback))
+        {
+        *ppv = &This->lpVtblIContextCallback;
+        }
+    else
+        {
+        FIXME("interface not implemented %s\n", debugstr_guid(riid));
+        return E_NOINTERFACE;
+        }
 
-    FIXME("interface not implemented %s\n", debugstr_guid(riid));
-    return E_NOINTERFACE;
-}
+    IUnknown_AddRef(iface);
+    return S_OK;
+}    
 
 static ULONG WINAPI Context_AddRef(IComThreadingInfo *iface)
 {
@@ -3691,6 +3706,31 @@ static HRESULT WINAPI Context_SetCurrentLogicalThreadId(IComThreadingInfo *iface
     return E_NOTIMPL;
 }
 
+
+static HRESULT WINAPI  ContextCallback_QueryInterface(IContextCallback *iface, REFIID riid, LPVOID *ppv)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static ULONG WINAPI  ContextCallback_AddRef(IContextCallback *iface)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static ULONG WINAPI ContextCallback_Release(IContextCallback *iface)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ContextCallback_ContextCallback(IContextCallback *iface, PFNCONTEXTCALL pfnCallback, ComCallData* pParam, REFIID riid, int iMethod, IUnknown* pUnk)
+{
+    FIXME("not implemented yet\n");
+    return E_NOTIMPL;
+}
+
 static const IComThreadingInfoVtbl Context_Threading_Vtbl =
 {
     Context_QueryInterface,
@@ -3702,6 +3742,14 @@ static const IComThreadingInfoVtbl Context_Threading_Vtbl =
     Context_SetCurrentLogicalThreadId
 };
 
+static const IContextCallbackVtbl Context_Callback_Vtbl =
+{
+    ContextCallback_QueryInterface,
+    ContextCallback_AddRef,
+    ContextCallback_Release,
+    ContextCallback_ContextCallback
+};
+
 /***********************************************************************
  *           CoGetObjectContext [OLE32.@]
  *
@@ -3735,6 +3783,7 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv)
         return E_OUTOFMEMORY;
 
     context->lpVtbl = &Context_Threading_Vtbl;
+    context->lpVtblIContextCallback=(IContextCallback*)&Context_Callback_Vtbl;
     context->refs = 1;
     if (apt->multi_threaded)
         context->apttype = APTTYPE_MTA;