Commit 1b67da35 authored by Detlef Riekenberg's avatar Detlef Riekenberg Committed by Alexandre Julliard

shlwapi/tests: Add tests for SHCreateThreadRef.

parent bb1ca6e0
......@@ -29,6 +29,7 @@
#include "wine/test.h"
static HRESULT (WINAPI *pSHCreateThreadRef)(LONG*, IUnknown**);
static HRESULT (WINAPI *pSHGetThreadRef)(IUnknown**);
static HRESULT (WINAPI *pSHSetThreadRef)(IUnknown*);
......@@ -36,31 +37,37 @@ static DWORD AddRef_called;
typedef struct
{
void* lpVtbl;
const IUnknownVtbl* lpVtbl;
LONG *ref;
} threadref;
static HRESULT WINAPI threadref_QueryInterface(threadref *This, REFIID riid, LPVOID *ppvObj)
static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
{
threadref * This = (threadref *)iface;
trace("unexpected QueryInterface(%p, %p, %p) called\n", This, riid, ppvObj);
*ppvObj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI threadref_AddRef(threadref *This)
static ULONG WINAPI threadref_AddRef(IUnknown *iface)
{
threadref * This = (threadref *)iface;
AddRef_called++;
return InterlockedIncrement(This->ref);
}
static ULONG WINAPI threadref_Release(threadref *This)
static ULONG WINAPI threadref_Release(IUnknown *iface)
{
threadref * This = (threadref *)iface;
trace("unexpected Release(%p) called\n", This);
return InterlockedDecrement(This->ref);
}
/* VTable */
static void* threadref_vt[] =
static const IUnknownVtbl threadref_vt =
{
threadref_QueryInterface,
threadref_AddRef,
......@@ -69,12 +76,96 @@ static void* threadref_vt[] =
static void init_threadref(threadref* iface, LONG *refcount)
{
iface->lpVtbl = (void*)threadref_vt;
iface->lpVtbl = &threadref_vt;
iface->ref = refcount;
}
/* ##### */
static void test_SHCreateThreadRef(void)
{
IUnknown *pobj;
IUnknown *punk;
LONG refcount;
HRESULT hr;
/* Not present before IE 6_XP_sp2 */
if (!pSHCreateThreadRef) {
win_skip("SHCreateThreadRef not found\n");
return;
}
/* start with a clean state */
hr = pSHSetThreadRef(NULL);
ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
pobj = NULL;
refcount = 0xdeadbeef;
hr = pSHCreateThreadRef(&refcount, &pobj);
ok((hr == S_OK) && pobj && (refcount == 1),
"got 0x%x and %p with %d (expected S_OK and '!= NULL' with 1)\n",
hr, pobj, refcount);
/* the object is not automatic set as ThreadRef */
punk = NULL;
hr = pSHGetThreadRef(&punk);
ok( (hr == E_NOINTERFACE) && (punk == NULL),
"got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk);
/* set the object */
hr = pSHSetThreadRef(pobj);
ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
/* read back */
punk = NULL;
hr = pSHGetThreadRef(&punk);
ok( (hr == S_OK) && (punk == pobj) && (refcount == 2),
"got 0x%x and %p with %d (expected S_OK and %p with 2)\n",
hr, punk, refcount, pobj);
/* free the ref from SHGetThreadRef */
if (SUCCEEDED(hr)) {
hr = IUnknown_Release(pobj);
ok((hr == 1) && (hr == refcount),
"got %d with %d (expected 1 with 1)\n", hr, refcount);
}
/* free the object */
if (pobj) {
hr = IUnknown_Release(pobj);
ok((hr == 0) && (hr == refcount),
"got %d with %d (expected 0 with 0)\n", hr, refcount);
}
if (0) {
/* the ThreadRef has still the pointer,
but the object no longer exist after the *_Release */
punk = NULL;
hr = pSHGetThreadRef(&punk);
trace("got 0x%x and %p with %d\n", hr, punk, refcount);
}
/* remove the dead object pointer */
hr = pSHSetThreadRef(NULL);
ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
/* parameter check */
if (0) {
/* vista: E_INVALIDARG, XP: crash */
pobj = NULL;
hr = pSHCreateThreadRef(NULL, &pobj);
ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr);
refcount = 0xdeadbeef;
/* vista: E_INVALIDARG, XP: crash */
hr = pSHCreateThreadRef(&refcount, NULL);
ok( (hr == E_INVALIDARG) && (refcount == 0xdeadbeef),
"got 0x%x with 0x%x (expected E_INVALIDARG and oxdeadbeef)\n",
hr, refcount);
}
}
static void test_SHGetThreadRef(void)
{
IUnknown *punk;
......@@ -147,9 +238,11 @@ START_TEST(thread)
{
HMODULE hshlwapi = GetModuleHandleA("shlwapi.dll");
pSHCreateThreadRef = (void *) GetProcAddress(hshlwapi, "SHCreateThreadRef");
pSHGetThreadRef = (void *) GetProcAddress(hshlwapi, "SHGetThreadRef");
pSHSetThreadRef = (void *) GetProcAddress(hshlwapi, "SHSetThreadRef");
test_SHCreateThreadRef();
test_SHGetThreadRef();
test_SHSetThreadRef();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment