Module: wine Branch: master Commit: bb1ca6e08d9f798502d2f20eb4bdcfac5e7d89d3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bb1ca6e08d9f798502d2f20eb4...
Author: Detlef Riekenberg wine.dev@web.de Date: Mon Apr 19 23:26:48 2010 +0200
shlwapi: Implement SHCreateThreadRef.
---
dlls/shlwapi/shlwapi.spec | 1 + dlls/shlwapi/thread.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ include/shlwapi.h | 1 + 3 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 367046b..268a2e2 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -683,6 +683,7 @@ @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) @ stdcall SHCreateStreamOnFileW(wstr long ptr) @ stdcall SHCreateStreamWrapper(ptr ptr long ptr) +@ stdcall SHCreateThreadRef(ptr ptr) @ stdcall SHDeleteEmptyKeyA(long ptr) @ stdcall SHDeleteEmptyKeyW(long ptr) @ stdcall SHDeleteKeyA(long str) diff --git a/dlls/shlwapi/thread.c b/dlls/shlwapi/thread.c index fd9e4ba..00d26f7 100644 --- a/dlls/shlwapi/thread.c +++ b/dlls/shlwapi/thread.c @@ -120,6 +120,93 @@ typedef struct tagSHLWAPI_THREAD_INFO IUnknown *refIE; /* Reference to the IE process */ } SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO;
+typedef struct +{ + const IUnknownVtbl* lpVtbl; + LONG *ref; +} threadref; + +static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObj); + + if (ppvObj == NULL) + return E_POINTER; + + if (IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj); + *ppvObj = This; + IUnknown_AddRef((IUnknown*)*ppvObj); + return S_OK; + } + + *ppvObj = NULL; + FIXME("(%p, %s, %p) interface not supported\n", This, debugstr_guid(riid), ppvObj); + return E_NOINTERFACE; +} + +static ULONG WINAPI threadref_AddRef(IUnknown *iface) +{ + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + return InterlockedIncrement(This->ref); +} + +static ULONG WINAPI threadref_Release(IUnknown *iface) +{ + LONG refcount; + threadref * This = (threadref *)iface; + + TRACE("(%p)\n", This); + + refcount = InterlockedDecrement(This->ref); + if (!refcount) + HeapFree(GetProcessHeap(), 0, This); + + return refcount; +} + +/* VTable */ +static const IUnknownVtbl threadref_vt = +{ + threadref_QueryInterface, + threadref_AddRef, + threadref_Release, +}; + +/************************************************************************* + * SHCreateThreadRef [SHLWAPI.@] + * + * Create a per-thread IUnknown object + * + * PARAMS + * lprefcount [I] Pointer to a LONG to be used as refcount + * lppUnknown [O] Destination to receive the created object reference + * + * RETURNS + * Success: S_OK. lppUnknown is set to the object reference. + * Failure: E_INVALIDARG, if a parameter is NULL + */ +HRESULT WINAPI SHCreateThreadRef(LONG *lprefcount, IUnknown **lppUnknown) +{ + threadref * This; + TRACE("(%p, %p)\n", lprefcount, lppUnknown); + + if (!lprefcount || !lppUnknown) + return E_INVALIDARG; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(threadref)); + This->lpVtbl = &threadref_vt; + This->ref = lprefcount; + + *lprefcount = 1; + *lppUnknown = (IUnknown *) This; + TRACE("=> returning S_OK with %p\n", This); + return S_OK; +}
/************************************************************************* * SHGetThreadRef [SHLWAPI.@] diff --git a/include/shlwapi.h b/include/shlwapi.h index 223bcdd..d4362ac 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -974,6 +974,7 @@ HRESULT WINAPI SHCreateStreamWrapper(LPBYTE,DWORD,DWORD,struct IStream**); HRESULT WINAPI SHAutoComplete(HWND,DWORD);
/* Threads */ +HRESULT WINAPI SHCreateThreadRef(LONG*, IUnknown**); HRESULT WINAPI SHGetThreadRef(IUnknown**); HRESULT WINAPI SHSetThreadRef(IUnknown*); HRESULT WINAPI SHReleaseThreadRef(void);