shlwapi: Fix broken NULL checks (with tests).
[wine/multimedia.git] / dlls / shlwapi / tests / thread.c
blobea894240d351101e2af7f7da60c91083752f0d70
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
20 #include <stdio.h>
21 #include <stdarg.h>
23 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "ole2.h"
28 #include "shlwapi.h"
30 #include "wine/test.h"
32 static HRESULT (WINAPI *pSHGetThreadRef)(IUnknown**);
33 static HRESULT (WINAPI *pSHSetThreadRef)(IUnknown*);
35 static DWORD AddRef_called;
37 typedef struct
39 void* lpVtbl;
40 LONG *ref;
41 } threadref;
43 static HRESULT WINAPI threadref_QueryInterface(threadref *This, REFIID riid, LPVOID *ppvObj)
45 trace("unexpected QueryInterface(%p, %p, %p) called\n", This, riid, ppvObj);
46 *ppvObj = NULL;
47 return E_NOINTERFACE;
50 static ULONG WINAPI threadref_AddRef(threadref *This)
52 AddRef_called++;
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);
62 /* VTable */
63 static void* threadref_vt[] =
65 threadref_QueryInterface,
66 threadref_AddRef,
67 threadref_Release
70 static void init_threadref(threadref* iface, LONG *refcount)
72 iface->lpVtbl = (void*)threadref_vt;
73 iface->ref = refcount;
76 /* ##### */
78 static void test_SHGetThreadRef(void)
80 IUnknown *punk;
81 HRESULT hr;
83 /* Not present before IE 5 */
84 if (!pSHGetThreadRef) {
85 win_skip("SHGetThreadRef not found\n");
86 return;
89 punk = NULL;
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);
94 if (0) {
95 /* this crash on Windows */
96 hr = pSHGetThreadRef(NULL);
100 static void test_SHSetThreadRef(void)
102 threadref ref;
103 IUnknown *punk;
104 HRESULT hr;
105 LONG refcount;
107 /* Not present before IE 5 */
108 if (!pSHSetThreadRef) {
109 win_skip("SHSetThreadRef not found\n");
110 return;
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);
119 AddRef_called = 0;
120 refcount = 1;
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 */
127 AddRef_called = 0;
128 refcount = 1;
129 punk = NULL;
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);
146 START_TEST(thread)
148 HMODULE hshlwapi = GetModuleHandleA("shlwapi.dll");
150 pSHGetThreadRef = (void *) GetProcAddress(hshlwapi, "SHGetThreadRef");
151 pSHSetThreadRef = (void *) GetProcAddress(hshlwapi, "SHSetThreadRef");
153 test_SHGetThreadRef();
154 test_SHSetThreadRef();