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