1 /* Tests for Thread and SHGlobalCounter functions
3 * Copyright 2010 Detlef Riekenberg
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/test.h"
32 static HRESULT (WINAPI *pSHGetThreadRef)(IUnknown**);
33 static HRESULT (WINAPI *pSHSetThreadRef)(IUnknown*);
35 static DWORD AddRef_called;
43 static HRESULT WINAPI threadref_QueryInterface(threadref *This, REFIID riid, LPVOID *ppvObj)
45 trace("unexpected QueryInterface(%p, %p, %p) called\n", This, riid, ppvObj);
50 static ULONG WINAPI threadref_AddRef(threadref *This)
53 return InterlockedIncrement(This->ref);
56 static ULONG WINAPI threadref_Release(threadref *This)
58 trace("unexpected Release(%p) called\n", This);
59 return InterlockedDecrement(This->ref);
63 static void* threadref_vt[] =
65 threadref_QueryInterface,
70 static void init_threadref(threadref* iface, LONG *refcount)
72 iface->lpVtbl = (void*)threadref_vt;
73 iface->ref = refcount;
78 static void test_SHGetThreadRef(void)
83 /* Not present before IE 5 */
84 if (!pSHGetThreadRef) {
85 win_skip("SHGetThreadRef not found\n");
90 hr = pSHGetThreadRef(&punk);
91 ok( (hr == E_NOINTERFACE) && (punk == NULL),
92 "got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk);
95 /* this crash on Windows */
96 hr = pSHGetThreadRef(NULL);
100 static void test_SHSetThreadRef(void)
107 /* Not present before IE 5 */
108 if (!pSHSetThreadRef) {
109 win_skip("SHSetThreadRef not found\n");
113 /* start with a clean state */
114 hr = pSHSetThreadRef(NULL);
115 ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
117 /* build and set out object */
118 init_threadref(&ref, &refcount);
121 hr = pSHSetThreadRef( (IUnknown *)&ref);
122 ok( (hr == S_OK) && (refcount == 1) && (!AddRef_called),
123 "got 0x%x with %d, %d (expected S_OK with 1, 0)\n",
124 hr, refcount, AddRef_called);
126 /* read back our object */
130 hr = pSHGetThreadRef(&punk);
131 ok( (hr == S_OK) && (punk == (IUnknown *)&ref) && (refcount == 2) && (AddRef_called == 1),
132 "got 0x%x and %p with %d, %d (expected S_OK and %p with 2, 1)\n",
133 hr, punk, refcount, AddRef_called, &ref);
135 /* clear the onject pointer */
136 hr = pSHSetThreadRef(NULL);
137 ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
139 /* verify, that our object is no longer known as ThreadRef */
140 hr = pSHGetThreadRef(&punk);
141 ok( (hr == E_NOINTERFACE) && (punk == NULL),
142 "got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk);
148 HMODULE hshlwapi = GetModuleHandleA("shlwapi.dll");
150 pSHGetThreadRef = (void *) GetProcAddress(hshlwapi, "SHGetThreadRef");
151 pSHSetThreadRef = (void *) GetProcAddress(hshlwapi, "SHSetThreadRef");
153 test_SHGetThreadRef();
154 test_SHSetThreadRef();