diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index 516e8c9fd40..a2e5ac93a53 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -24,6 +24,7 @@ #define WIN32_NO_STATUS #define USE_COM_CONTEXT_DEF #include "objbase.h" +#include "ctxtcall.h" #include "oleauto.h" #include "dde.h" #include "winternl.h" @@ -1898,3 +1899,315 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid) return S_OK; } + +struct thread_context +{ + IComThreadingInfo IComThreadingInfo_iface; + IContextCallback IContextCallback_iface; + IObjContext IObjContext_iface; + LONG refcount; +}; + +static inline struct thread_context *impl_from_IComThreadingInfo(IComThreadingInfo *iface) +{ + return CONTAINING_RECORD(iface, struct thread_context, IComThreadingInfo_iface); +} + +static inline struct thread_context *impl_from_IContextCallback(IContextCallback *iface) +{ + return CONTAINING_RECORD(iface, struct thread_context, IContextCallback_iface); +} + +static inline struct thread_context *impl_from_IObjContext(IObjContext *iface) +{ + return CONTAINING_RECORD(iface, struct thread_context, IObjContext_iface); +} + +static HRESULT WINAPI thread_context_info_QueryInterface(IComThreadingInfo *iface, REFIID riid, void **obj) +{ + struct thread_context *context = impl_from_IComThreadingInfo(iface); + + *obj = NULL; + + if (IsEqualIID(riid, &IID_IComThreadingInfo) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = &context->IComThreadingInfo_iface; + } + else if (IsEqualIID(riid, &IID_IContextCallback)) + { + *obj = &context->IContextCallback_iface; + } + else if (IsEqualIID(riid, &IID_IObjContext)) + { + *obj = &context->IObjContext_iface; + } + + if (*obj) + { + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; + } + + FIXME("interface not implemented %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI thread_context_info_AddRef(IComThreadingInfo *iface) +{ + struct thread_context *context = impl_from_IComThreadingInfo(iface); + return InterlockedIncrement(&context->refcount); +} + +static ULONG WINAPI thread_context_info_Release(IComThreadingInfo *iface) +{ + struct thread_context *context = impl_from_IComThreadingInfo(iface); + + /* Context instance is initially created with CoGetContextToken() with refcount set to 0, + releasing context while refcount is at 0 destroys it. */ + if (!context->refcount) + { + heap_free(context); + return 0; + } + + return InterlockedDecrement(&context->refcount); +} + +static HRESULT WINAPI thread_context_info_GetCurrentApartmentType(IComThreadingInfo *iface, APTTYPE *apttype) +{ + APTTYPEQUALIFIER qualifier; + + TRACE("%p\n", apttype); + + return CoGetApartmentType(apttype, &qualifier); +} + +static HRESULT WINAPI thread_context_info_GetCurrentThreadType(IComThreadingInfo *iface, THDTYPE *thdtype) +{ + APTTYPEQUALIFIER qualifier; + APTTYPE apttype; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &qualifier); + if (FAILED(hr)) + return hr; + + TRACE("%p\n", thdtype); + + switch (apttype) + { + case APTTYPE_STA: + case APTTYPE_MAINSTA: + *thdtype = THDTYPE_PROCESSMESSAGES; + break; + default: + *thdtype = THDTYPE_BLOCKMESSAGES; + break; + } + return S_OK; +} + +static HRESULT WINAPI thread_context_info_GetCurrentLogicalThreadId(IComThreadingInfo *iface, GUID *logical_thread_id) +{ + TRACE("%p\n", logical_thread_id); + + return CoGetCurrentLogicalThreadId(logical_thread_id); +} + +static HRESULT WINAPI thread_context_info_SetCurrentLogicalThreadId(IComThreadingInfo *iface, REFGUID logical_thread_id) +{ + FIXME("%s stub\n", debugstr_guid(logical_thread_id)); + + return E_NOTIMPL; +} + +static const IComThreadingInfoVtbl thread_context_info_vtbl = +{ + thread_context_info_QueryInterface, + thread_context_info_AddRef, + thread_context_info_Release, + thread_context_info_GetCurrentApartmentType, + thread_context_info_GetCurrentThreadType, + thread_context_info_GetCurrentLogicalThreadId, + thread_context_info_SetCurrentLogicalThreadId +}; + +static HRESULT WINAPI thread_context_callback_QueryInterface(IContextCallback *iface, REFIID riid, void **obj) +{ + struct thread_context *context = impl_from_IContextCallback(iface); + return IComThreadingInfo_QueryInterface(&context->IComThreadingInfo_iface, riid, obj); +} + +static ULONG WINAPI thread_context_callback_AddRef(IContextCallback *iface) +{ + struct thread_context *context = impl_from_IContextCallback(iface); + return IComThreadingInfo_AddRef(&context->IComThreadingInfo_iface); +} + +static ULONG WINAPI thread_context_callback_Release(IContextCallback *iface) +{ + struct thread_context *context = impl_from_IContextCallback(iface); + return IComThreadingInfo_Release(&context->IComThreadingInfo_iface); +} + +static HRESULT WINAPI thread_context_callback_ContextCallback(IContextCallback *iface, + PFNCONTEXTCALL callback, ComCallData *param, REFIID riid, int method, IUnknown *punk) +{ + FIXME("%p, %p, %p, %s, %d, %p\n", iface, callback, param, debugstr_guid(riid), method, punk); + + return E_NOTIMPL; +} + +static const IContextCallbackVtbl thread_context_callback_vtbl = +{ + thread_context_callback_QueryInterface, + thread_context_callback_AddRef, + thread_context_callback_Release, + thread_context_callback_ContextCallback +}; + +static HRESULT WINAPI thread_object_context_QueryInterface(IObjContext *iface, REFIID riid, void **obj) +{ + struct thread_context *context = impl_from_IObjContext(iface); + return IComThreadingInfo_QueryInterface(&context->IComThreadingInfo_iface, riid, obj); +} + +static ULONG WINAPI thread_object_context_AddRef(IObjContext *iface) +{ + struct thread_context *context = impl_from_IObjContext(iface); + return IComThreadingInfo_AddRef(&context->IComThreadingInfo_iface); +} + +static ULONG WINAPI thread_object_context_Release(IObjContext *iface) +{ + struct thread_context *context = impl_from_IObjContext(iface); + return IComThreadingInfo_Release(&context->IComThreadingInfo_iface); +} + +static HRESULT WINAPI thread_object_context_SetProperty(IObjContext *iface, REFGUID propid, CPFLAGS flags, IUnknown *punk) +{ + FIXME("%p, %s, %x, %p\n", iface, debugstr_guid(propid), flags, punk); + + return E_NOTIMPL; +} + +static HRESULT WINAPI thread_object_context_RemoveProperty(IObjContext *iface, REFGUID propid) +{ + FIXME("%p, %s\n", iface, debugstr_guid(propid)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI thread_object_context_GetProperty(IObjContext *iface, REFGUID propid, CPFLAGS *flags, IUnknown **punk) +{ + FIXME("%p, %s, %p, %p\n", iface, debugstr_guid(propid), flags, punk); + + return E_NOTIMPL; +} + +static HRESULT WINAPI thread_object_context_EnumContextProps(IObjContext *iface, IEnumContextProps **props) +{ + FIXME("%p, %p\n", iface, props); + + return E_NOTIMPL; +} + +static void WINAPI thread_object_context_Reserved1(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved2(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved3(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved4(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved5(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved6(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static void WINAPI thread_object_context_Reserved7(IObjContext *iface) +{ + FIXME("%p\n", iface); +} + +static const IObjContextVtbl thread_object_context_vtbl = +{ + thread_object_context_QueryInterface, + thread_object_context_AddRef, + thread_object_context_Release, + thread_object_context_SetProperty, + thread_object_context_RemoveProperty, + thread_object_context_GetProperty, + thread_object_context_EnumContextProps, + thread_object_context_Reserved1, + thread_object_context_Reserved2, + thread_object_context_Reserved3, + thread_object_context_Reserved4, + thread_object_context_Reserved5, + thread_object_context_Reserved6, + thread_object_context_Reserved7 +}; + +/*********************************************************************** + * CoGetContextToken (combase.@) + */ +HRESULT WINAPI CoGetContextToken(ULONG_PTR *token) +{ + struct tlsdata *tlsdata; + HRESULT hr; + + TRACE("%p\n", token); + + if (!InternalIsInitialized()) + { + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; + } + + if (FAILED(hr = com_get_tlsdata(&tlsdata))) + return hr; + + if (!token) + return E_POINTER; + + if (!tlsdata->context_token) + { + struct thread_context *context; + + context = heap_alloc_zero(sizeof(*context)); + if (!context) + return E_OUTOFMEMORY; + + context->IComThreadingInfo_iface.lpVtbl = &thread_context_info_vtbl; + context->IContextCallback_iface.lpVtbl = &thread_context_callback_vtbl; + context->IObjContext_iface.lpVtbl = &thread_object_context_vtbl; + /* Context token does not take a reference, it's always zero until the + interface is explicitly requested with CoGetObjectContext(). */ + context->refcount = 0; + + tlsdata->context_token = &context->IObjContext_iface; + } + + *token = (ULONG_PTR)tlsdata->context_token; + TRACE("context_token %p\n", tlsdata->context_token); + + return S_OK; +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 02004852aa8..806ee015371 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -103,7 +103,7 @@ @ stub CoGetCancelObject @ stdcall CoGetClassObject(ptr long ptr ptr ptr) ole32.CoGetClassObject @ stub CoGetClassVersion -@ stdcall CoGetContextToken(ptr) ole32.CoGetContextToken +@ stdcall CoGetContextToken(ptr) @ stdcall CoGetCurrentLogicalThreadId(ptr) ole32.CoGetCurrentLogicalThreadId @ stdcall CoGetCurrentProcess() ole32.CoGetCurrentProcess @ stdcall CoGetDefaultContext(long ptr ptr) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index e8cc75c7de4..83644782589 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -3142,342 +3142,6 @@ HRESULT WINAPI CoRegisterChannelHook(REFGUID guidExtension, IChannelHook *pChann return RPC_RegisterChannelHook(guidExtension, pChannelHook); } -typedef struct Context -{ - IComThreadingInfo IComThreadingInfo_iface; - IContextCallback IContextCallback_iface; - IObjContext IObjContext_iface; - LONG refs; -} Context; - -static inline Context *impl_from_IComThreadingInfo( IComThreadingInfo *iface ) -{ - return CONTAINING_RECORD(iface, Context, IComThreadingInfo_iface); -} - -static inline Context *impl_from_IContextCallback( IContextCallback *iface ) -{ - return CONTAINING_RECORD(iface, Context, IContextCallback_iface); -} - -static inline Context *impl_from_IObjContext( IObjContext *iface ) -{ - return CONTAINING_RECORD(iface, Context, IObjContext_iface); -} - -static HRESULT Context_QueryInterface(Context *iface, REFIID riid, LPVOID *ppv) -{ - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IComThreadingInfo) || - IsEqualIID(riid, &IID_IUnknown)) - { - *ppv = &iface->IComThreadingInfo_iface; - } - else if (IsEqualIID(riid, &IID_IContextCallback)) - { - *ppv = &iface->IContextCallback_iface; - } - else if (IsEqualIID(riid, &IID_IObjContext)) - { - *ppv = &iface->IObjContext_iface; - } - - if (*ppv) - { - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; - } - - FIXME("interface not implemented %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG Context_AddRef(Context *This) -{ - return InterlockedIncrement(&This->refs); -} - -static ULONG Context_Release(Context *This) -{ - /* Context instance is initially created with CoGetContextToken() with refcount set to 0, - releasing context while refcount is at 0 destroys it. */ - if (!This->refs) - { - HeapFree(GetProcessHeap(), 0, This); - return 0; - } - - return InterlockedDecrement(&This->refs); -} - -static HRESULT WINAPI Context_CTI_QueryInterface(IComThreadingInfo *iface, REFIID riid, LPVOID *ppv) -{ - Context *This = impl_from_IComThreadingInfo(iface); - return Context_QueryInterface(This, riid, ppv); -} - -static ULONG WINAPI Context_CTI_AddRef(IComThreadingInfo *iface) -{ - Context *This = impl_from_IComThreadingInfo(iface); - return Context_AddRef(This); -} - -static ULONG WINAPI Context_CTI_Release(IComThreadingInfo *iface) -{ - Context *This = impl_from_IComThreadingInfo(iface); - return Context_Release(This); -} - -static HRESULT WINAPI Context_CTI_GetCurrentApartmentType(IComThreadingInfo *iface, APTTYPE *apttype) -{ - APTTYPEQUALIFIER qualifier; - - TRACE("(%p)\n", apttype); - - return CoGetApartmentType(apttype, &qualifier); -} - -static HRESULT WINAPI Context_CTI_GetCurrentThreadType(IComThreadingInfo *iface, THDTYPE *thdtype) -{ - APTTYPEQUALIFIER qualifier; - APTTYPE apttype; - HRESULT hr; - - hr = CoGetApartmentType(&apttype, &qualifier); - if (FAILED(hr)) - return hr; - - TRACE("(%p)\n", thdtype); - - switch (apttype) - { - case APTTYPE_STA: - case APTTYPE_MAINSTA: - *thdtype = THDTYPE_PROCESSMESSAGES; - break; - default: - *thdtype = THDTYPE_BLOCKMESSAGES; - break; - } - return S_OK; -} - -static HRESULT WINAPI Context_CTI_GetCurrentLogicalThreadId(IComThreadingInfo *iface, GUID *logical_thread_id) -{ - TRACE("(%p)\n", logical_thread_id); - return CoGetCurrentLogicalThreadId(logical_thread_id); -} - -static HRESULT WINAPI Context_CTI_SetCurrentLogicalThreadId(IComThreadingInfo *iface, REFGUID logical_thread_id) -{ - FIXME("(%s): stub\n", debugstr_guid(logical_thread_id)); - return E_NOTIMPL; -} - -static const IComThreadingInfoVtbl Context_Threading_Vtbl = -{ - Context_CTI_QueryInterface, - Context_CTI_AddRef, - Context_CTI_Release, - Context_CTI_GetCurrentApartmentType, - Context_CTI_GetCurrentThreadType, - Context_CTI_GetCurrentLogicalThreadId, - Context_CTI_SetCurrentLogicalThreadId -}; - -static HRESULT WINAPI Context_CC_QueryInterface(IContextCallback *iface, REFIID riid, LPVOID *ppv) -{ - Context *This = impl_from_IContextCallback(iface); - return Context_QueryInterface(This, riid, ppv); -} - -static ULONG WINAPI Context_CC_AddRef(IContextCallback *iface) -{ - Context *This = impl_from_IContextCallback(iface); - return Context_AddRef(This); -} - -static ULONG WINAPI Context_CC_Release(IContextCallback *iface) -{ - Context *This = impl_from_IContextCallback(iface); - return Context_Release(This); -} - -static HRESULT WINAPI Context_CC_ContextCallback(IContextCallback *iface, PFNCONTEXTCALL pCallback, - ComCallData *param, REFIID riid, int method, IUnknown *punk) -{ - Context *This = impl_from_IContextCallback(iface); - - FIXME("(%p/%p)->(%p, %p, %s, %d, %p)\n", This, iface, pCallback, param, debugstr_guid(riid), method, punk); - return E_NOTIMPL; -} - -static const IContextCallbackVtbl Context_Callback_Vtbl = -{ - Context_CC_QueryInterface, - Context_CC_AddRef, - Context_CC_Release, - Context_CC_ContextCallback -}; - -static HRESULT WINAPI Context_OC_QueryInterface(IObjContext *iface, REFIID riid, LPVOID *ppv) -{ - Context *This = impl_from_IObjContext(iface); - return Context_QueryInterface(This, riid, ppv); -} - -static ULONG WINAPI Context_OC_AddRef(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - return Context_AddRef(This); -} - -static ULONG WINAPI Context_OC_Release(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - return Context_Release(This); -} - -static HRESULT WINAPI Context_OC_SetProperty(IObjContext *iface, REFGUID propid, CPFLAGS flags, IUnknown *punk) -{ - Context *This = impl_from_IObjContext(iface); - - FIXME("(%p/%p)->(%s, %x, %p)\n", This, iface, debugstr_guid(propid), flags, punk); - return E_NOTIMPL; -} - -static HRESULT WINAPI Context_OC_RemoveProperty(IObjContext *iface, REFGUID propid) -{ - Context *This = impl_from_IObjContext(iface); - - FIXME("(%p/%p)->(%s)\n", This, iface, debugstr_guid(propid)); - return E_NOTIMPL; -} - -static HRESULT WINAPI Context_OC_GetProperty(IObjContext *iface, REFGUID propid, CPFLAGS *flags, IUnknown **punk) -{ - Context *This = impl_from_IObjContext(iface); - - FIXME("(%p/%p)->(%s, %p, %p)\n", This, iface, debugstr_guid(propid), flags, punk); - return E_NOTIMPL; -} - -static HRESULT WINAPI Context_OC_EnumContextProps(IObjContext *iface, IEnumContextProps **props) -{ - Context *This = impl_from_IObjContext(iface); - - FIXME("(%p/%p)->(%p)\n", This, iface, props); - return E_NOTIMPL; -} - -static void WINAPI Context_OC_Reserved1(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved2(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved3(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved4(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved5(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved6(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static void WINAPI Context_OC_Reserved7(IObjContext *iface) -{ - Context *This = impl_from_IObjContext(iface); - FIXME("(%p/%p)\n", This, iface); -} - -static const IObjContextVtbl Context_Object_Vtbl = -{ - Context_OC_QueryInterface, - Context_OC_AddRef, - Context_OC_Release, - Context_OC_SetProperty, - Context_OC_RemoveProperty, - Context_OC_GetProperty, - Context_OC_EnumContextProps, - Context_OC_Reserved1, - Context_OC_Reserved2, - Context_OC_Reserved3, - Context_OC_Reserved4, - Context_OC_Reserved5, - Context_OC_Reserved6, - Context_OC_Reserved7 -}; - -/*********************************************************************** - * CoGetContextToken [OLE32.@] - */ -HRESULT WINAPI CoGetContextToken( ULONG_PTR *token ) -{ - struct oletls *info = COM_CurrentInfo(); - APARTMENT *apt; - - TRACE("(%p)\n", token); - - if (!info) - return E_OUTOFMEMORY; - - if (!(apt = apartment_get_current_or_mta())) - { - ERR("apartment not initialised\n"); - return CO_E_NOTINITIALIZED; - } - apartment_release(apt); - - if (!token) - return E_POINTER; - - if (!info->context_token) - { - Context *context; - - context = HeapAlloc(GetProcessHeap(), 0, sizeof(*context)); - if (!context) - return E_OUTOFMEMORY; - - context->IComThreadingInfo_iface.lpVtbl = &Context_Threading_Vtbl; - context->IContextCallback_iface.lpVtbl = &Context_Callback_Vtbl; - context->IObjContext_iface.lpVtbl = &Context_Object_Vtbl; - /* Context token does not take a reference, it's always zero until the - interface is explicitly requested with CoGetObjectContext(). */ - context->refs = 0; - - info->context_token = &context->IObjContext_iface; - } - - *token = (ULONG_PTR)info->context_token; - TRACE("context_token=%p\n", info->context_token); - - return S_OK; -} - HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { static const WCHAR wszInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0}; diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 02a8434d264..9c663692484 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -31,7 +31,7 @@ @ stdcall CoGetCallState(long ptr) combase.CoGetCallState @ stdcall CoGetCallerTID(ptr) @ stdcall CoGetClassObject(ptr long ptr ptr ptr) -@ stdcall CoGetContextToken(ptr) +@ stdcall CoGetContextToken(ptr) combase.CoGetContextToken @ stdcall CoGetCurrentLogicalThreadId(ptr) @ stdcall CoGetCurrentProcess() @ stdcall CoGetDefaultContext(long ptr ptr) combase.CoGetDefaultContext