combase: Move CoGetContextToken().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-08-20 10:34:41 +03:00 committed by Alexandre Julliard
parent e00ea31d09
commit 90c0e3a4dd
4 changed files with 315 additions and 338 deletions

View File

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

View File

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

View File

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

View File

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