Nikolay Sivov : shcore: Add ThreadRef functions.
Alexandre Julliard
julliard at winehq.org
Tue Nov 27 14:26:11 CST 2018
Module: wine
Branch: master
Commit: e74a36f5c89294c194fd8b58b93fba0dad296b2b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e74a36f5c89294c194fd8b58b93fba0dad296b2b
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue Nov 27 11:55:46 2018 +0300
shcore: Add ThreadRef functions.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/shcore/main.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++
dlls/shcore/shcore.spec | 8 +--
2 files changed, 142 insertions(+), 4 deletions(-)
diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c
index f99479d..7f423c1 100644
--- a/dlls/shcore/main.c
+++ b/dlls/shcore/main.c
@@ -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;
+}
diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec
index c3bb8d2..568cb20 100644
--- a/dlls/shcore/shcore.spec
+++ b/dlls/shcore/shcore.spec
@@ -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
More information about the wine-cvs
mailing list