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. */ 32 static CHAR temp_str[MAX_PATH]; 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]; 74 VARIANT result; 75 unsigned int err_index; 76 77 VariantInit(&result); 78 79 /* DispGetParam crashes on Windows if pdispparams is NULL. */ 80 81 /* pdispparams has zero parameters. */ 82 INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); 83 VariantInit(&result); 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); 92 93 /* pdispparams has zero parameters, position is invalid. */ 94 INIT_DISPPARAMS(dispparams, NULL, NULL, 0, 0); 95 VariantInit(&result); 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); 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); 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); 113 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)); 122 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); 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); 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); 153 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); 165 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); 177 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); 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); 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)); 204 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); 215 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); 227 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); 237 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); 248 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); 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); 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); 271 } 272 273 static HRESULT WINAPI unk_QI(IUnknown *iface, REFIID riid, void **obj) 274 { 275 if (IsEqualIID(riid, &IID_IUnknown)) 276 { 277 *obj = iface; 278 return S_OK; 279 } 280 else 281 { 282 *obj = NULL; 283 return E_NOINTERFACE; 284 } 285 } 286 287 static ULONG WINAPI unk_AddRef(IUnknown *iface) 288 { 289 return 2; 290 } 291 292 static ULONG WINAPI unk_Release(IUnknown *iface) 293 { 294 return 1; 295 } 296 297 static const IUnknownVtbl unkvtbl = 298 { 299 unk_QI, 300 unk_AddRef, 301 unk_Release 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 314 hr = CreateStdDispatch(NULL, NULL, NULL, NULL); 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 339 START_TEST(dispatch) 340 { 341 test_DispGetParam(); 342 test_CreateStdDispatch(); 343 } 344