shcore: Add ThreadRef functions.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2018-11-27 11:55:46 +03:00 committed by Alexandre Julliard
parent dd4bb94706
commit e74a36f5c8
2 changed files with 142 additions and 4 deletions

View File

@ -35,6 +35,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(shcore);
static DWORD shcore_tls;
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
TRACE("(%p, %u, %p)\n", instance, reason, reserved);
@ -45,6 +47,12 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(instance);
shcore_tls = TlsAlloc();
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
if (shcore_tls != TLS_OUT_OF_INDEXES)
TlsFree(shcore_tls);
break;
}
@ -1123,3 +1131,133 @@ HRESULT WINAPI SHCreateStreamOnFileA(const char *path, DWORD mode, IStream **str
return hr;
}
struct threadref
{
IUnknown IUnknown_iface;
LONG *refcount;
};
static inline struct threadref *threadref_impl_from_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, struct threadref, IUnknown_iface);
}
static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, void **out)
{
struct threadref *threadref = threadref_impl_from_IUnknown(iface);
TRACE("(%p, %s, %p)\n", threadref, debugstr_guid(riid), out);
if (out == NULL)
return E_POINTER;
if (IsEqualGUID(&IID_IUnknown, riid))
{
*out = iface;
IUnknown_AddRef(iface);
return S_OK;
}
*out = NULL;
WARN("Interface %s not supported.\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI threadref_AddRef(IUnknown *iface)
{
struct threadref *threadref = threadref_impl_from_IUnknown(iface);
LONG refcount = InterlockedIncrement(threadref->refcount);
TRACE("(%p, %d)\n", threadref, refcount);
return refcount;
}
static ULONG WINAPI threadref_Release(IUnknown *iface)
{
struct threadref *threadref = threadref_impl_from_IUnknown(iface);
LONG refcount = InterlockedDecrement(threadref->refcount);
TRACE("(%p, %d)\n", threadref, refcount);
if (!refcount)
heap_free(threadref);
return refcount;
}
static const IUnknownVtbl threadrefvtbl =
{
threadref_QueryInterface,
threadref_AddRef,
threadref_Release,
};
/*************************************************************************
* SHCreateThreadRef [SHCORE.@]
*/
HRESULT WINAPI SHCreateThreadRef(LONG *refcount, IUnknown **out)
{
struct threadref *threadref;
TRACE("(%p, %p)\n", refcount, out);
if (!refcount || !out)
return E_INVALIDARG;
*out = NULL;
threadref = heap_alloc(sizeof(*threadref));
if (!threadref)
return E_OUTOFMEMORY;
threadref->IUnknown_iface.lpVtbl = &threadrefvtbl;
threadref->refcount = refcount;
*refcount = 1;
*out = &threadref->IUnknown_iface;
TRACE("Created %p.\n", threadref);
return S_OK;
}
/*************************************************************************
* SHGetThreadRef [SHCORE.@]
*/
HRESULT WINAPI SHGetThreadRef(IUnknown **out)
{
TRACE("(%p)\n", out);
if (shcore_tls == TLS_OUT_OF_INDEXES)
return E_NOINTERFACE;
*out = TlsGetValue(shcore_tls);
if (!*out)
return E_NOINTERFACE;
IUnknown_AddRef(*out);
return S_OK;
}
/*************************************************************************
* SHSetThreadRef [SHCORE.@]
*/
HRESULT WINAPI SHSetThreadRef(IUnknown *obj)
{
TRACE("(%p)\n", obj);
if (shcore_tls == TLS_OUT_OF_INDEXES)
return E_NOINTERFACE;
TlsSetValue(shcore_tls, obj);
return S_OK;
}
/*************************************************************************
* SHReleaseThreadRef [SHCORE.@]
*/
HRESULT WINAPI SHReleaseThreadRef(void)
{
FIXME("() - stub!\n");
return S_OK;
}

View File

@ -38,7 +38,7 @@
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr)
@ stdcall SHCreateStreamOnFileW(wstr long ptr)
@ stdcall SHCreateThread(ptr ptr long ptr) shlwapi.SHCreateThread
@ stdcall SHCreateThreadRef(ptr ptr) shlwapi.SHCreateThreadRef
@ stdcall SHCreateThreadRef(ptr ptr)
@ stub SHCreateThreadWithHandle
@ stdcall SHDeleteEmptyKeyA(long ptr) shlwapi.SHDeleteEmptyKeyA
@ stdcall SHDeleteEmptyKeyW(long ptr) shlwapi.SHDeleteEmptyKeyW
@ -50,7 +50,7 @@
@ stdcall SHEnumKeyExW(long long wstr ptr) shlwapi.SHEnumKeyExW
@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr) shlwapi.SHEnumValueA
@ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr) shlwapi.SHEnumValueW
@ stdcall SHGetThreadRef(ptr) shlwapi.SHGetThreadRef
@ stdcall SHGetThreadRef(ptr)
@ stdcall SHGetValueA( long str str ptr ptr ptr ) shlwapi.SHGetValueA
@ stdcall SHGetValueW( long wstr wstr ptr ptr ptr ) shlwapi.SHGetValueW
@ stdcall SHOpenRegStream2A(long str str long) shlwapi.SHOpenRegStream2A
@ -69,8 +69,8 @@
@ stdcall SHRegGetValueW( long wstr wstr long ptr ptr ptr ) shlwapi.SHRegGetValueW
@ stdcall SHRegSetPathA(long str str str long) shlwapi.SHRegSetPathA
@ stdcall SHRegSetPathW(long wstr wstr wstr long) shlwapi.SHRegSetPathW
@ stdcall SHReleaseThreadRef() shlwapi.SHReleaseThreadRef
@ stdcall SHSetThreadRef(ptr) shlwapi.SHSetThreadRef
@ stdcall SHReleaseThreadRef()
@ stdcall SHSetThreadRef(ptr)
@ stdcall SHSetValueA(long str str long ptr long) shlwapi.SHSetValueA
@ stdcall SHSetValueW(long wstr wstr long ptr long) shlwapi.SHSetValueW
@ stdcall SHStrDupA(str ptr) shlwapi.SHStrDupA