4 * Copyright 2009 James Hawkins
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.
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.
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
24 #include <wine/test.h>
29 static const WCHAR szSunshine
[] = {'S','u','n','s','h','i','n','e',0};
31 /* Temporary storage for ok_bstr. */
32 static CHAR temp_str
[MAX_PATH
];
34 #define ok_bstr(bstr, expected, format) \
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); \
41 #define INIT_DISPPARAMS(dp, args, named_args, num_args, num_named_args) \
43 dp.rgdispidNamedArgs = named_args; \
44 dp.cArgs = num_args; \
45 dp.cNamedArgs = num_named_args; \
47 /* Initializes vararg with three values:
50 * VT_BSTR - "Sunshine"
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);
63 /* Clears the vararg. */
64 #define CLEAR_VARARG(vararg) \
65 VariantClear(&vararg[0]); \
66 VariantClear(&vararg[1]); \
67 VariantClear(&vararg[2]);
69 static void test_DispGetParam(void)
72 DISPPARAMS dispparams
;
75 unsigned int err_index
;
79 /* DispGetParam crashes on Windows if pdispparams is NULL. */
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
);
86 ok(hr
== DISP_E_PARAMNOTFOUND
,
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
);
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
);
98 ok(hr
== DISP_E_PARAMNOTFOUND
,
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
);
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
);
109 ok(hr
== DISP_E_PARAMNOTFOUND
,
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
);
114 /* pdispparams has zero parameters, puArgErr is NULL. */
115 INIT_DISPPARAMS(dispparams
, NULL
, NULL
, 0, 0);
116 VariantInit(&result
);
117 hr
= DispGetParam(&dispparams
, 0, VT_I2
, &result
, NULL
);
118 ok(hr
== DISP_E_PARAMNOTFOUND
,
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
));
123 /* pdispparams.cArgs is 1, yet pdispparams.rgvarg is NULL. */
124 INIT_DISPPARAMS(dispparams
, NULL
, NULL
, 1, 0);
125 VariantInit(&result
);
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
);
133 /* pdispparams.cNamedArgs is 1, yet pdispparams.rgdispidNamedArgs is NULL.
135 * This crashes on Windows.
138 /* {42, 1234567890, "Sunshine"} */
141 /* Get the first param. position is end-based, so 2 is the first parameter
144 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
145 VariantInit(&result
);
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
);
154 /* Get the second param. */
155 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
156 VariantInit(&result
);
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
);
166 /* Get the third param. */
167 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
168 VariantInit(&result
);
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
);
176 VariantClear(&result
);
178 /* position is out of range. */
179 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
180 VariantInit(&result
);
181 err_index
= 0xdeadbeef;
182 hr
= DispGetParam(&dispparams
, 3, VT_I2
, &result
, &err_index
);
183 ok(hr
== DISP_E_PARAMNOTFOUND
,
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
);
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
);
197 /* puArgErr is NULL. */
198 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
199 VariantInit(&result
);
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
));
205 /* Coerce the first param to VT_I4. */
206 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
207 VariantInit(&result
);
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
);
216 /* Coerce the first param to VT_BSTR. */
217 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
218 VariantInit(&result
);
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
);
226 VariantClear(&result
);
228 /* Coerce the second (VT_I4) param to VT_I2. */
229 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
230 VariantInit(&result
);
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
);
238 /* Coerce the third (VT_BSTR) param to VT_I2. */
239 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
240 VariantInit(&result
);
241 err_index
= 0xdeadbeef;
242 hr
= DispGetParam(&dispparams
, 0, VT_I2
, &result
, &err_index
);
243 ok(hr
== DISP_E_TYPEMISMATCH
,
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
);
249 /* Coerce the first parameter to an invalid type. */
250 INIT_DISPPARAMS(dispparams
, vararg
, NULL
, 3, 0);
251 VariantInit(&result
);
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
);
259 CLEAR_VARARG(vararg
);
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);
264 VariantInit(&result
);
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
);
270 VariantClear(&result
);
273 static HRESULT WINAPI
unk_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
275 if (IsEqualIID(riid
, &IID_IUnknown
))
283 return E_NOINTERFACE
;
287 static ULONG WINAPI
unk_AddRef(IUnknown
*iface
)
292 static ULONG WINAPI
unk_Release(IUnknown
*iface
)
297 static const IUnknownVtbl unkvtbl
=
304 static IUnknown test_unk
= { &unkvtbl
};
306 static void test_CreateStdDispatch(void)
308 static const WCHAR stdole2W
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
314 hr
= CreateStdDispatch(NULL
, NULL
, NULL
, NULL
);
315 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
317 hr
= CreateStdDispatch(NULL
, NULL
, NULL
, &unk
);
318 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
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
);
326 hr
= CreateStdDispatch(NULL
, &test_unk
, NULL
, &unk
);
327 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
329 hr
= CreateStdDispatch(NULL
, NULL
, ti
, &unk
);
330 ok(hr
== E_INVALIDARG
, "got %08x\n", hr
);
332 hr
= CreateStdDispatch(NULL
, &test_unk
, ti
, &unk
);
333 ok(hr
== S_OK
, "got %08x\n", hr
);
334 IUnknown_Release(unk
);
336 ITypeInfo_Release(ti
);
342 test_CreateStdDispatch();