ReactOS  0.4.15-dev-3287-gfec35dc
dispatch.c
Go to the documentation of this file.
1 /*
2  * Dispatch test
3  *
4  * Copyright 2009 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 #define CONST_VTABLE
23 
24 #include <wine/test.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <oaidl.h>
28 
29 static const WCHAR szSunshine[] = {'S','u','n','s','h','i','n','e',0};
30 
31 /* Temporary storage for ok_bstr. */
33 
34 #define ok_bstr(bstr, expected, format) \
35  do { \
36  WideCharToMultiByte(CP_ACP, 0, bstr, -1, temp_str, MAX_PATH, NULL, NULL); \
37  if (lstrcmpA(temp_str, expected) != 0) \
38  ok(0, format, expected, temp_str); \
39  } while(0);
40 
41 #define INIT_DISPPARAMS(dp, args, named_args, num_args, num_named_args) \
42  dp.rgvarg = args; \
43  dp.rgdispidNamedArgs = named_args; \
44  dp.cArgs = num_args; \
45  dp.cNamedArgs = num_named_args; \
46 
47 /* Initializes vararg with three values:
48  * VT_I2 - 42
49  * VT_I4 - 1234567890
50  * VT_BSTR - "Sunshine"
51  */
52 #define INIT_VARARG(vararg) \
53  VariantInit(&vararg[0]); \
54  V_VT(&vararg[0]) = VT_I2; \
55  V_I2(&vararg[0]) = 42; \
56  VariantInit(&vararg[1]); \
57  V_VT(&vararg[1]) = VT_I4; \
58  V_I4(&vararg[1]) = 1234567890; \
59  VariantInit(&vararg[2]); \
60  V_VT(&vararg[2]) = VT_BSTR; \
61  V_BSTR(&vararg[2]) = SysAllocString(szSunshine);
62 
63 /* Clears the vararg. */
64 #define CLEAR_VARARG(vararg) \
65  VariantClear(&vararg[0]); \
66  VariantClear(&vararg[1]); \
67  VariantClear(&vararg[2]);
68 
69 static void test_DispGetParam(void)
70 {
71  HRESULT hr;
72  DISPPARAMS dispparams;
73  VARIANTARG vararg[3];
75  unsigned int err_index;
76 
78 
79  /* DispGetParam crashes on Windows if pdispparams is NULL. */
80 
81  /* pdispparams has zero parameters. */
82  INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0);
84  err_index = 0xdeadbeef;
85  hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index);
87  "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr);
88  ok(V_VT(&result) == VT_EMPTY,
89  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
90  ok(err_index == 0xdeadbeef,
91  "Expected err_index to be unchanged, got %d\n", err_index);
92 
93  /* pdispparams has zero parameters, position is invalid. */
94  INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0);
96  err_index = 0xdeadbeef;
97  hr = DispGetParam(&dispparams, 1, VT_I2, &result, &err_index);
99  "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr);
100  ok(V_VT(&result) == VT_EMPTY,
101  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
102  ok(err_index == 0xdeadbeef,
103  "Expected err_index to be unchanged, got %d\n", err_index);
104 
105  /* pdispparams has zero parameters, pvarResult is NULL. */
106  INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0);
107  err_index = 0xdeadbeef;
108  hr = DispGetParam(&dispparams, 0, VT_I2, NULL, &err_index);
110  "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr);
111  ok(err_index == 0xdeadbeef,
112  "Expected err_index to be unchanged, got %d\n", err_index);
113 
114  /* pdispparams has zero parameters, puArgErr is NULL. */
115  INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0);
117  hr = DispGetParam(&dispparams, 0, VT_I2, &result, NULL);
119  "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr);
120  ok(V_VT(&result) == VT_EMPTY,
121  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
122 
123  /* pdispparams.cArgs is 1, yet pdispparams.rgvarg is NULL. */
124  INIT_DISPPARAMS(dispparams, NULL, NULL, 1, 0);
126  err_index = 0xdeadbeef;
127  hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index);
128  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
129  ok(V_VT(&result) == VT_EMPTY,
130  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
131  ok(err_index == 0, "Expected 0, got %d\n", err_index);
132 
133  /* pdispparams.cNamedArgs is 1, yet pdispparams.rgdispidNamedArgs is NULL.
134  *
135  * This crashes on Windows.
136  */
137 
138  /* {42, 1234567890, "Sunshine"} */
139  INIT_VARARG(vararg);
140 
141  /* Get the first param. position is end-based, so 2 is the first parameter
142  * of 3 parameters.
143  */
144  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
146  err_index = 0xdeadbeef;
147  hr = DispGetParam(&dispparams, 2, VT_I2, &result, &err_index);
148  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
149  ok(V_VT(&result) == VT_I2, "Expected VT_I2, got %08x\n", V_VT(&result));
150  ok(V_I2(&result) == 42, "Expected 42, got %d\n", V_I2(&result));
151  ok(err_index == 0xdeadbeef,
152  "Expected err_index to be unchanged, got %d\n", err_index);
153 
154  /* Get the second param. */
155  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
157  err_index = 0xdeadbeef;
158  hr = DispGetParam(&dispparams, 1, VT_I4, &result, &err_index);
159  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
160  ok(V_VT(&result) == VT_I4, "Expected VT_I4, got %08x\n", V_VT(&result));
161  ok(V_I4(&result) == 1234567890,
162  "Expected 1234567890, got %d\n", V_I4(&result));
163  ok(err_index == 0xdeadbeef,
164  "Expected err_index to be unchanged, got %d\n", err_index);
165 
166  /* Get the third param. */
167  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
169  err_index = 0xdeadbeef;
170  hr = DispGetParam(&dispparams, 0, VT_BSTR, &result, &err_index);
171  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
172  ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result));
173  ok_bstr(V_BSTR(&result), "Sunshine", "Expected %s, got %s\n");
174  ok(err_index == 0xdeadbeef,
175  "Expected err_index to be unchanged, got %d\n", err_index);
177 
178  /* position is out of range. */
179  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
181  err_index = 0xdeadbeef;
182  hr = DispGetParam(&dispparams, 3, VT_I2, &result, &err_index);
184  "Expected DISP_E_PARAMNOTFOUND, got %08x\n", hr);
185  ok(V_VT(&result) == VT_EMPTY,
186  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
187  ok(err_index == 0xdeadbeef,
188  "Expected err_index to be unchanged, got %d\n", err_index);
189 
190  /* pvarResult is NULL. */
191  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
192  err_index = 0xdeadbeef;
193  hr = DispGetParam(&dispparams, 2, VT_I2, NULL, &err_index);
194  ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
195  ok(err_index == 0, "Expected 0, got %d\n", err_index);
196 
197  /* puArgErr is NULL. */
198  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
200  hr = DispGetParam(&dispparams, 2, VT_I2, &result, NULL);
201  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
202  ok(V_VT(&result) == VT_I2, "Expected VT_I2, got %08x\n", V_VT(&result));
203  ok(V_I2(&result) == 42, "Expected 42, got %d\n", V_I2(&result));
204 
205  /* Coerce the first param to VT_I4. */
206  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
208  err_index = 0xdeadbeef;
209  hr = DispGetParam(&dispparams, 2, VT_I4, &result, &err_index);
210  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
211  ok(V_VT(&result) == VT_I4, "Expected VT_I4, got %08x\n", V_VT(&result));
212  ok(V_I4(&result) == 42, "Expected 42, got %d\n", V_I4(&result));
213  ok(err_index == 0xdeadbeef,
214  "Expected err_index to be unchanged, got %d\n", err_index);
215 
216  /* Coerce the first param to VT_BSTR. */
217  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
219  err_index = 0xdeadbeef;
220  hr = DispGetParam(&dispparams, 2, VT_BSTR, &result, &err_index);
221  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
222  ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result));
223  ok_bstr(V_BSTR(&result), "42", "Expected %s, got %s\n");
224  ok(err_index == 0xdeadbeef,
225  "Expected err_index to be unchanged, got %d\n", err_index);
227 
228  /* Coerce the second (VT_I4) param to VT_I2. */
229  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
231  err_index = 0xdeadbeef;
232  hr = DispGetParam(&dispparams, 1, VT_I2, &result, &err_index);
233  ok(hr == DISP_E_OVERFLOW, "Expected DISP_E_OVERFLOW, got %08x\n", hr);
234  ok(V_VT(&result) == VT_EMPTY,
235  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
236  ok(err_index == 1, "Expected 1, got %d\n", err_index);
237 
238  /* Coerce the third (VT_BSTR) param to VT_I2. */
239  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
241  err_index = 0xdeadbeef;
242  hr = DispGetParam(&dispparams, 0, VT_I2, &result, &err_index);
244  "Expected DISP_E_TYPEMISMATCH, got %08x\n", hr);
245  ok(V_VT(&result) == VT_EMPTY,
246  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
247  ok(err_index == 2, "Expected 2, got %d\n", err_index);
248 
249  /* Coerce the first parameter to an invalid type. */
250  INIT_DISPPARAMS(dispparams, vararg, NULL, 3, 0);
252  err_index = 0xdeadbeef;
253  hr = DispGetParam(&dispparams, 2, VT_ILLEGAL, &result, &err_index);
254  ok(hr == DISP_E_BADVARTYPE, "Expected DISP_E_BADVARTYPE, got %08x\n", hr);
255  ok(V_VT(&result) == VT_EMPTY,
256  "Expected VT_EMPTY, got %08x\n", V_VT(&result));
257  ok(err_index == 0, "Expected 0, got %d\n", err_index);
258 
259  CLEAR_VARARG(vararg);
260 
261  /* Coerce the first parameter, which is of type VT_EMPTY, to VT_BSTR. */
262  VariantInit(&vararg[0]);
263  INIT_DISPPARAMS(dispparams, vararg, NULL, 1, 0);
265  err_index = 0xdeadbeef;
266  hr = DispGetParam(&dispparams, 0, VT_BSTR, &result, &err_index);
267  ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
268  ok(V_VT(&result) == VT_BSTR, "Expected VT_BSTR, got %08x\n", V_VT(&result));
269  ok(err_index == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", err_index);
271 }
272 
273 static HRESULT WINAPI unk_QI(IUnknown *iface, REFIID riid, void **obj)
274 {
276  {
277  *obj = iface;
278  return S_OK;
279  }
280  else
281  {
282  *obj = NULL;
283  return E_NOINTERFACE;
284  }
285 }
286 
288 {
289  return 2;
290 }
291 
293 {
294  return 1;
295 }
296 
297 static const IUnknownVtbl unkvtbl =
298 {
299  unk_QI,
300  unk_AddRef,
302 };
303 
304 static IUnknown test_unk = { &unkvtbl };
305 
306 static void test_CreateStdDispatch(void)
307 {
308  static const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
309  ITypeLib *tl;
310  ITypeInfo *ti;
311  IUnknown *unk;
312  HRESULT hr;
313 
315  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
316 
317  hr = CreateStdDispatch(NULL, NULL, NULL, &unk);
318  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
319 
320  hr = LoadTypeLib(stdole2W, &tl);
321  ok(hr == S_OK, "got %08x\n", hr);
322  hr = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IUnknown, &ti);
323  ok(hr == S_OK, "got %08x\n", hr);
324  ITypeLib_Release(tl);
325 
326  hr = CreateStdDispatch(NULL, &test_unk, NULL, &unk);
327  ok(hr == E_INVALIDARG, "got %08x\n", hr);
328 
329  hr = CreateStdDispatch(NULL, NULL, ti, &unk);
330  ok(hr == E_INVALIDARG, "got %08x\n", hr);
331 
332  hr = CreateStdDispatch(NULL, &test_unk, ti, &unk);
333  ok(hr == S_OK, "got %08x\n", hr);
334  IUnknown_Release(unk);
335 
336  ITypeInfo_Release(ti);
337 }
338 
340 {
343 }
#define INIT_VARARG(vararg)
Definition: dispatch.c:52
#define REFIID
Definition: guiddef.h:118
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:2157
HRESULT hr
Definition: shlfolder.c:183
GLuint64EXT * result
Definition: glext.h:11304
HRESULT WINAPI CreateStdDispatch(IUnknown *punkOuter, void *pvThis, ITypeInfo *ptinfo, IUnknown **stddisp)
Definition: dispatch.c:434
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI DispGetParam(DISPPARAMS *pdispparams, UINT position, VARTYPE vtTarg, VARIANT *pvarResult, UINT *puArgErr)
Definition: dispatch.c:116
char CHAR
Definition: xmlstorage.h:175
#define V_I2(A)
Definition: oleauto.h:245
static ULONG WINAPI unk_Release(IUnknown *iface)
Definition: dispatch.c:292
static IUnknown test_unk
Definition: dispatch.c:304
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:458
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
static HRESULT WINAPI unk_QI(IUnknown *iface, REFIID riid, void **obj)
Definition: dispatch.c:273
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
#define V_I4(A)
Definition: oleauto.h:247
#define ok_bstr(bstr, expected, format)
Definition: dispatch.c:34
static void test_CreateStdDispatch(void)
Definition: dispatch.c:306
#define E_INVALIDARG
Definition: ddrawi.h:101
static const IUnknownVtbl unkvtbl
Definition: dispatch.c:297
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
const GUID IID_IUnknown
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
#define DISP_E_BADVARTYPE
Definition: winerror.h:2517
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
#define V_VT(A)
Definition: oleauto.h:211
static ULONG WINAPI unk_AddRef(IUnknown *iface)
Definition: dispatch.c:287
static void test_DispGetParam(void)
Definition: dispatch.c:69
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
#define V_BSTR(A)
Definition: oleauto.h:226
START_TEST(dispatch)
Definition: dispatch.c:339
#define CLEAR_VARARG(vararg)
Definition: dispatch.c:64
#define S_OK
Definition: intsafe.h:52
#define ok(value,...)
Definition: atltest.h:57
#define INIT_DISPPARAMS(dp, args, named_args, num_args, num_named_args)
Definition: dispatch.c:41
#define NULL
Definition: types.h:112
static CHAR temp_str[MAX_PATH]
Definition: dispatch.c:32
static const WCHAR szSunshine[]
Definition: dispatch.c:29
struct stdole::DISPPARAMS DISPPARAMS
unsigned int ULONG
Definition: retypes.h:1
#define DISP_E_OVERFLOW
Definition: winerror.h:2519
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
Definition: compat.h:2156