shlwapi: Implement SHCreateThreadRef.
This commit is contained in:
parent
f84f939411
commit
bb1ca6e08d
|
@ -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)
|
||||
|
|
|
@ -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.@]
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue