Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.spec | 2 +- dlls/combase/marshal.c | 295 +++++++++++++++++++++++++++++++++++ dlls/ole32/ftmarshal.c | 312 -------------------------------------- dlls/ole32/ole32.spec | 2 +- 4 files changed, 297 insertions(+), 314 deletions(-)
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 5ee52d950ee..79410be8be0 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -77,7 +77,7 @@ @ stub CoCancelCall @ stdcall CoCopyProxy(ptr ptr) @ stdcall CoCreateErrorInfo(ptr) CreateErrorInfo -@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) ole32.CoCreateFreeThreadedMarshaler +@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) @ stdcall CoCreateGuid(ptr) @ stdcall CoCreateInstance(ptr ptr long ptr ptr) @ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx diff --git a/dlls/combase/marshal.c b/dlls/combase/marshal.c index fe4c2f3adf8..2b0c0058125 100644 --- a/dlls/combase/marshal.c +++ b/dlls/combase/marshal.c @@ -1,4 +1,5 @@ /* + * Copyright 2002 Juergen Schmied * Copyright 2002 Marcus Meissner * Copyright 2004 Mike Hearn, for CodeWeavers * Copyright 2004 Rob Shearman, for CodeWeavers @@ -22,9 +23,28 @@ #include "objbase.h"
#include "wine/debug.h" +#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
+struct ftmarshaler +{ + IUnknown IUnknown_inner; + IMarshal IMarshal_iface; + IUnknown *outer_unk; + LONG refcount; +}; + +static struct ftmarshaler *impl_ft_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct ftmarshaler, IUnknown_inner); +} + +static struct ftmarshaler *impl_ft_from_IMarshal(IMarshal *iface) +{ + return CONTAINING_RECORD(iface, struct ftmarshaler, IMarshal_iface); +} + /*********************************************************************** * CoMarshalHresult (combase.@) */ @@ -84,3 +104,278 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, IUnknown *unk,
return hr; } + +static HRESULT WINAPI ftmarshaler_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) +{ + struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface); + + TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj); + + *obj = NULL; + + if (IsEqualIID(&IID_IUnknown, riid)) + *obj = &marshaler->IUnknown_inner; + else if (IsEqualIID(&IID_IMarshal, riid)) + *obj = &marshaler->IMarshal_iface; + else + { + FIXME("No interface for %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*obj); + + return S_OK; +} + +static ULONG WINAPI ftmarshaler_inner_AddRef(IUnknown *iface) +{ + struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&marshaler->refcount); + + TRACE("%p, refcount %u\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI ftmarshaler_inner_Release(IUnknown *iface) +{ + struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&marshaler->refcount); + + TRACE("%p, refcount %u\n", iface, refcount); + + if (!refcount) + heap_free(marshaler); + + return refcount; +} + +static const IUnknownVtbl ftmarshaler_inner_vtbl = +{ + ftmarshaler_inner_QueryInterface, + ftmarshaler_inner_AddRef, + ftmarshaler_inner_Release +}; + +static HRESULT WINAPI ftmarshaler_QueryInterface(IMarshal *iface, REFIID riid, void **obj) +{ + struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface); + + TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj); + + return IUnknown_QueryInterface(marshaler->outer_unk, riid, obj); +} + +static ULONG WINAPI ftmarshaler_AddRef(IMarshal *iface) +{ + struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface); + + TRACE("%p\n", iface); + + return IUnknown_AddRef(marshaler->outer_unk); +} + +static ULONG WINAPI ftmarshaler_Release(IMarshal *iface) +{ + struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface); + + TRACE("%p\n", iface); + + return IUnknown_Release(marshaler->outer_unk); +} + +static HRESULT WINAPI ftmarshaler_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv, + DWORD dest_context, void *pvDestContext, DWORD mshlflags, CLSID *clsid) +{ + TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, clsid); + + if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX) + *clsid = CLSID_InProcFreeMarshaler; + else + *clsid = CLSID_StdMarshal; + + return S_OK; +} + +static HRESULT WINAPI ftmarshaler_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv, + DWORD dest_context, void *pvDestContext, DWORD mshlflags, DWORD *size) +{ + IMarshal *marshal = NULL; + HRESULT hr; + + TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, size); + + /* If the marshalling happens inside the same process the interface pointer is + copied between the apartments */ + if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX) + { + *size = sizeof(mshlflags) + sizeof(pv) + sizeof(DWORD) + sizeof(GUID); + return S_OK; + } + + /* Use the standard marshaller to handle all other cases */ + CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal); + hr = IMarshal_GetMarshalSizeMax(marshal, riid, pv, dest_context, pvDestContext, mshlflags, size); + IMarshal_Release(marshal); + return hr; +} + +static HRESULT WINAPI ftmarshaler_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, + void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags) +{ + IMarshal *marshal = NULL; + HRESULT hr; + + TRACE("%p, %s, %p, %#x, %p, %#x\n", stream, debugstr_guid(riid), pv, + dest_context, pvDestContext, mshlflags); + + /* If the marshalling happens inside the same process the interface pointer is + copied between the apartments */ + if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX) + { + void *object; + DWORD constant = 0; + GUID unknown_guid = { 0 }; + + hr = IUnknown_QueryInterface((IUnknown *)pv, riid, &object); + if (FAILED(hr)) + return hr; + + /* don't hold a reference to table-weak marshaled interfaces */ + if (mshlflags & MSHLFLAGS_TABLEWEAK) + IUnknown_Release((IUnknown *)object); + + hr = IStream_Write(stream, &mshlflags, sizeof(mshlflags), NULL); + if (hr != S_OK) return STG_E_MEDIUMFULL; + + hr = IStream_Write(stream, &object, sizeof(object), NULL); + if (hr != S_OK) return STG_E_MEDIUMFULL; + + if (sizeof(object) == sizeof(DWORD)) + { + hr = IStream_Write(stream, &constant, sizeof(constant), NULL); + if (hr != S_OK) return STG_E_MEDIUMFULL; + } + + hr = IStream_Write(stream, &unknown_guid, sizeof(unknown_guid), NULL); + if (hr != S_OK) return STG_E_MEDIUMFULL; + + return S_OK; + } + + /* Use the standard marshaler to handle all other cases */ + CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal); + hr = IMarshal_MarshalInterface(marshal, stream, riid, pv, dest_context, pvDestContext, mshlflags); + IMarshal_Release(marshal); + return hr; +} + +static HRESULT WINAPI ftmarshaler_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv) +{ + DWORD mshlflags; + IUnknown *object; + DWORD constant; + GUID unknown_guid; + HRESULT hr; + + TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), ppv); + + hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + hr = IStream_Read(stream, &object, sizeof(object), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + if (sizeof(object) == sizeof(DWORD)) + { + hr = IStream_Read(stream, &constant, sizeof(constant), NULL); + if (hr != S_OK) return STG_E_READFAULT; + if (constant != 0) + FIXME("constant is 0x%x instead of 0\n", constant); + } + + hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + hr = IUnknown_QueryInterface(object, riid, ppv); + if (!(mshlflags & (MSHLFLAGS_TABLEWEAK | MSHLFLAGS_TABLESTRONG))) + IUnknown_Release(object); + + return hr; +} + +static HRESULT WINAPI ftmarshaler_ReleaseMarshalData(IMarshal *iface, IStream *stream) +{ + DWORD mshlflags; + IUnknown *object; + DWORD constant; + GUID unknown_guid; + HRESULT hr; + + TRACE("%p\n", stream); + + hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + hr = IStream_Read(stream, &object, sizeof(object), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + if (sizeof(object) == sizeof(DWORD)) + { + hr = IStream_Read(stream, &constant, sizeof(constant), NULL); + if (hr != S_OK) return STG_E_READFAULT; + if (constant != 0) + FIXME("constant is 0x%x instead of 0\n", constant); + } + + hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL); + if (hr != S_OK) return STG_E_READFAULT; + + IUnknown_Release(object); + return S_OK; +} + +static HRESULT WINAPI ftmarshaler_DisconnectObject(IMarshal *iface, DWORD reserved) +{ + TRACE("\n"); + + /* nothing to do */ + return S_OK; +} + +static const IMarshalVtbl ftmarshaler_vtbl = +{ + ftmarshaler_QueryInterface, + ftmarshaler_AddRef, + ftmarshaler_Release, + ftmarshaler_GetUnmarshalClass, + ftmarshaler_GetMarshalSizeMax, + ftmarshaler_MarshalInterface, + ftmarshaler_UnmarshalInterface, + ftmarshaler_ReleaseMarshalData, + ftmarshaler_DisconnectObject +}; + +/*********************************************************************** + * CoCreateFreeThreadedMarshaler (combase.@) + */ +HRESULT WINAPI CoCreateFreeThreadedMarshaler(IUnknown *outer, IUnknown **marshaler) +{ + struct ftmarshaler *object; + + TRACE("%p, %p\n", outer, marshaler); + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IUnknown_inner.lpVtbl = &ftmarshaler_inner_vtbl; + object->IMarshal_iface.lpVtbl = &ftmarshaler_vtbl; + object->refcount = 1; + object->outer_unk = outer ? outer : &object->IUnknown_inner; + + *marshaler = &object->IUnknown_inner; + + return S_OK; +} diff --git a/dlls/ole32/ftmarshal.c b/dlls/ole32/ftmarshal.c index 851810df42a..8777b553618 100644 --- a/dlls/ole32/ftmarshal.c +++ b/dlls/ole32/ftmarshal.c @@ -36,318 +36,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-typedef struct _FTMarshalImpl { - IUnknown IUnknown_inner; - IMarshal IMarshal_iface; - IUnknown *outer_unk; - LONG ref; -} FTMarshalImpl; - -static inline FTMarshalImpl *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, FTMarshalImpl, IUnknown_inner); -} - -static inline FTMarshalImpl *impl_from_IMarshal( IMarshal *iface ) -{ - return CONTAINING_RECORD(iface, FTMarshalImpl, IMarshal_iface); -} - -/* inner IUnknown to handle aggregation */ -static HRESULT WINAPI -IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv) -{ - - FTMarshalImpl *This = impl_from_IUnknown(iface); - - TRACE ("\n"); - *ppv = NULL; - - if (IsEqualIID (&IID_IUnknown, riid)) - *ppv = &This->IUnknown_inner; - else if (IsEqualIID (&IID_IMarshal, riid)) - *ppv = &This->IMarshal_iface; - else { - FIXME ("No interface for %s.\n", debugstr_guid (riid)); - return E_NOINTERFACE; - } - IUnknown_AddRef ((IUnknown *) * ppv); - return S_OK; -} - -static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface) -{ - - FTMarshalImpl *This = impl_from_IUnknown(iface); - - TRACE ("\n"); - return InterlockedIncrement (&This->ref); -} - -static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface) -{ - - FTMarshalImpl *This = impl_from_IUnknown(iface); - - TRACE ("\n"); - if (InterlockedDecrement (&This->ref)) - return This->ref; - HeapFree (GetProcessHeap (), 0, This); - return 0; -} - -static const IUnknownVtbl iunkvt = -{ - IiFTMUnknown_fnQueryInterface, - IiFTMUnknown_fnAddRef, - IiFTMUnknown_fnRelease -}; - -static HRESULT WINAPI -FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv) -{ - - FTMarshalImpl *This = impl_from_IMarshal(iface); - - TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppv); - return IUnknown_QueryInterface(This->outer_unk, riid, ppv); -} - -static ULONG WINAPI -FTMarshalImpl_AddRef (LPMARSHAL iface) -{ - - FTMarshalImpl *This = impl_from_IMarshal(iface); - - TRACE ("\n"); - return IUnknown_AddRef(This->outer_unk); -} - -static ULONG WINAPI -FTMarshalImpl_Release (LPMARSHAL iface) -{ - - FTMarshalImpl *This = impl_from_IMarshal(iface); - - TRACE ("\n"); - return IUnknown_Release(This->outer_unk); -} - -static HRESULT WINAPI -FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, - void *pvDestContext, DWORD mshlflags, CLSID * pCid) -{ - TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv, - dwDestContext, pvDestContext, mshlflags, pCid); - if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) - *pCid = CLSID_InProcFreeMarshaler; - else - *pCid = CLSID_StdMarshal; - return S_OK; -} - -static HRESULT WINAPI -FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, - void *pvDestContext, DWORD mshlflags, DWORD * pSize) -{ - - IMarshal *pMarshal = NULL; - HRESULT hres; - - TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv, - dwDestContext, pvDestContext, mshlflags, pSize); - - /* if the marshalling happens inside the same process the interface pointer is - copied between the apartments */ - if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) { - *pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID); - return S_OK; - } - - /* use the standard marshaller to handle all other cases */ - CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal); - hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize); - IMarshal_Release (pMarshal); - return hres; -} - -static HRESULT WINAPI -FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv, - DWORD dwDestContext, void *pvDestContext, DWORD mshlflags) -{ - - IMarshal *pMarshal = NULL; - HRESULT hres; - - TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv, - dwDestContext, pvDestContext, mshlflags); - - /* if the marshalling happens inside the same process the interface pointer is - copied between the apartments */ - if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) { - void *object; - DWORD constant = 0; - GUID unknown_guid = { 0 }; - - hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object); - if (FAILED(hres)) - return hres; - - /* don't hold a reference to table-weak marshaled interfaces */ - if (mshlflags & MSHLFLAGS_TABLEWEAK) - IUnknown_Release((IUnknown *)object); - - hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL); - if (hres != S_OK) return STG_E_MEDIUMFULL; - - hres = IStream_Write (pStm, &object, sizeof (object), NULL); - if (hres != S_OK) return STG_E_MEDIUMFULL; - - if (sizeof(object) == sizeof(DWORD)) - { - hres = IStream_Write (pStm, &constant, sizeof (constant), NULL); - if (hres != S_OK) return STG_E_MEDIUMFULL; - } - - hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL); - if (hres != S_OK) return STG_E_MEDIUMFULL; - - return S_OK; - } - - /* use the standard marshaler to handle all other cases */ - CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal); - hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags); - IMarshal_Release (pMarshal); - return hres; -} - -static HRESULT WINAPI -FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv) -{ - DWORD mshlflags; - IUnknown *object; - DWORD constant; - GUID unknown_guid; - HRESULT hres; - - TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv); - - hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - hres = IStream_Read (pStm, &object, sizeof (object), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - if (sizeof(object) == sizeof(DWORD)) - { - hres = IStream_Read (pStm, &constant, sizeof (constant), NULL); - if (hres != S_OK) return STG_E_READFAULT; - if (constant != 0) - FIXME("constant is 0x%x instead of 0\n", constant); - } - - hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - hres = IUnknown_QueryInterface(object, riid, ppv); - if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG))) - IUnknown_Release(object); - return hres; -} - -static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm) -{ - DWORD mshlflags; - IUnknown *object; - DWORD constant; - GUID unknown_guid; - HRESULT hres; - - TRACE ("(%p)\n", pStm); - - hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - hres = IStream_Read (pStm, &object, sizeof (object), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - if (sizeof(object) == sizeof(DWORD)) - { - hres = IStream_Read (pStm, &constant, sizeof (constant), NULL); - if (hres != S_OK) return STG_E_READFAULT; - if (constant != 0) - FIXME("constant is 0x%x instead of 0\n", constant); - } - - hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL); - if (hres != S_OK) return STG_E_READFAULT; - - IUnknown_Release(object); - return S_OK; -} - -static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved) -{ - TRACE ("()\n"); - /* nothing to do */ - return S_OK; -} - -static const IMarshalVtbl ftmvtbl = -{ - FTMarshalImpl_QueryInterface, - FTMarshalImpl_AddRef, - FTMarshalImpl_Release, - FTMarshalImpl_GetUnmarshalClass, - FTMarshalImpl_GetMarshalSizeMax, - FTMarshalImpl_MarshalInterface, - FTMarshalImpl_UnmarshalInterface, - FTMarshalImpl_ReleaseMarshalData, - FTMarshalImpl_DisconnectObject -}; - -/*********************************************************************** - * CoCreateFreeThreadedMarshaler [OLE32.@] - * - * Creates a free-threaded marshaler. - * - * PARAMS - * punkOuter [I] Optional. Outer unknown. - * ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler. - * - * RETURNS - * Success: S_OK - * Failure: E_OUTOFMEMORY if no memory available to create object. - * - * NOTES - * Objects that ensure their state is maintained consistent when used by - * multiple threads and reference no single-threaded objects are known as - * free-threaded. The free-threaded marshaler enables these objects to be - * efficiently marshaled within the same process, by not creating proxies - * (as they aren't needed for the object to be safely used), whilst still - * allowing the object to be used in inter-process and inter-machine contexts. - */ -HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal) -{ - - FTMarshalImpl *ftm; - - TRACE ("(%p %p)\n", punkOuter, ppunkMarshal); - - ftm = HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl)); - if (!ftm) - return E_OUTOFMEMORY; - - ftm->IUnknown_inner.lpVtbl = &iunkvt; - ftm->IMarshal_iface.lpVtbl = &ftmvtbl; - ftm->ref = 1; - ftm->outer_unk = punkOuter ? punkOuter : &ftm->IUnknown_inner; - - *ppunkMarshal = &ftm->IUnknown_inner; - return S_OK; -} - static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppv) { diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 1587f926381..d1dedd39c3f 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -10,7 +10,7 @@ @ stdcall CoAllowSetForegroundWindow(ptr ptr) @ stdcall CoBuildVersion() @ stdcall CoCopyProxy(ptr ptr) combase.CoCopyProxy -@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) +@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) combase.CoCreateFreeThreadedMarshaler @ stdcall CoCreateGuid(ptr) combase.CoCreateGuid @ stdcall CoCreateInstance(ptr ptr long ptr ptr) combase.CoCreateInstance @ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr)