1 /* 2 * Schema test 3 * 4 * Copyright 2007 Huw Davies 5 * Copyright 2010 Adam Martinson for CodeWeavers 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdio.h> 23 #include <assert.h> 24 #define COBJMACROS 25 26 #include "initguid.h" 27 #include "windows.h" 28 #include "ole2.h" 29 #include "msxml2.h" 30 #undef CLSID_DOMDocument 31 #include "msxml2did.h" 32 #include "dispex.h" 33 34 #include "wine/test.h" 35 36 #ifdef __REACTOS__ 37 #include <cguid.h> 38 #endif 39 40 #define EXPECT_HR(hr,hr_exp) \ 41 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) 42 43 static const WCHAR xdr_schema_uri[] = {'x','-','s','c','h','e','m','a',':','t','e','s','t','.','x','m','l',0}; 44 45 static const WCHAR xdr_schema_xml[] = { 46 '<','S','c','h','e','m','a',' ','x','m','l','n','s','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','x','m','l','-','d','a','t','a','\"','\n', 47 'x','m','l','n','s',':','d','t','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','d','a','t','a','t','y','p','e','s','\"','>','\n', 48 '<','/','S','c','h','e','m','a','>','\n',0 49 }; 50 51 static const CHAR xdr_schema1_uri[] = "x-schema:test1.xdr"; 52 static const CHAR xdr_schema1_xml[] = 53 "<?xml version='1.0'?>" 54 "<Schema xmlns='urn:schemas-microsoft-com:xml-data'" 55 " xmlns:dt='urn:schemas-microsoft-com:datatypes'" 56 " name='test1.xdr'>" 57 " <ElementType name='x' dt:type='boolean'/>" 58 " <ElementType name='y'>" 59 " <datatype dt:type='int'/>" 60 " </ElementType>" 61 " <ElementType name='z'/>" 62 " <ElementType name='root' content='eltOnly' model='open' order='seq'>" 63 " <element type='x'/>" 64 " <element type='y'/>" 65 " <element type='z'/>" 66 " </ElementType>" 67 "</Schema>"; 68 69 static const CHAR xdr_schema2_uri[] = "x-schema:test2.xdr"; 70 static const CHAR xdr_schema2_xml[] = 71 "<?xml version='1.0'?>" 72 "<Schema xmlns='urn:schemas-microsoft-com:xml-data'" 73 " xmlns:dt='urn:schemas-microsoft-com:datatypes'" 74 " name='test2.xdr'>" 75 " <ElementType name='x' dt:type='bin.base64'/>" 76 " <ElementType name='y' dt:type='uuid'/>" 77 " <ElementType name='z'/>" 78 " <ElementType name='root' content='eltOnly' model='closed' order='one'>" 79 " <element type='x'/>" 80 " <element type='y'/>" 81 " <element type='z'/>" 82 " </ElementType>" 83 "</Schema>"; 84 85 static const CHAR xdr_schema3_uri[] = "x-schema:test3.xdr"; 86 static const CHAR xdr_schema3_xml[] = 87 "<?xml version='1.0'?>" 88 "<Schema xmlns='urn:schemas-microsoft-com:xml-data'" 89 " xmlns:dt='urn:schemas-microsoft-com:datatypes'" 90 " name='test3.xdr'>" 91 " <ElementType name='root' content='textOnly' model='open'>" 92 " <AttributeType name='x' dt:type='int'/>" 93 " <AttributeType name='y' dt:type='enumeration' dt:values='a b c'/>" 94 " <AttributeType name='z' dt:type='uuid'/>" 95 " <attribute type='x'/>" 96 " <attribute type='y'/>" 97 " <attribute type='z'/>" 98 " </ElementType>" 99 "</Schema>"; 100 101 static const CHAR xsd_schema1_uri[] = "x-schema:test1.xsd"; 102 static const CHAR xsd_schema1_xml[] = 103 "<?xml version='1.0'?>" 104 "<schema xmlns='http://www.w3.org/2001/XMLSchema'" 105 " targetNamespace='x-schema:test1.xsd'>" 106 " <element name='root'>" 107 " <complexType>" 108 " <sequence maxOccurs='unbounded'>" 109 " <any/>" 110 " </sequence>" 111 " </complexType>" 112 " </element>" 113 "</schema>"; 114 115 static const CHAR xsd_schema2_uri[] = "x-schema:test2.xsd"; 116 static const CHAR xsd_schema2_xml[] = 117 "<?xml version='1.0'?>" 118 "<schema xmlns='http://www.w3.org/2001/XMLSchema'" 119 " targetNamespace='x-schema:test2.xsd'>" 120 " <element name='root'>" 121 " <complexType>" 122 " <sequence maxOccurs='unbounded'>" 123 " <any/>" 124 " </sequence>" 125 " </complexType>" 126 " </element>" 127 "</schema>"; 128 129 static const CHAR xsd_schema3_uri[] = "x-schema:test3.xsd"; 130 static const CHAR xsd_schema3_xml[] = 131 "<?xml version='1.0'?>" 132 "<schema xmlns='http://www.w3.org/2001/XMLSchema'" 133 " targetNamespace='x-schema:test3.xsd'>" 134 " <element name='root'>" 135 " <complexType>" 136 " <sequence maxOccurs='unbounded'>" 137 " <any/>" 138 " </sequence>" 139 " </complexType>" 140 " </element>" 141 "</schema>"; 142 143 static const CHAR szDatatypeXDR[] = 144 "<Schema xmlns='urn:schemas-microsoft-com:xml-data'\n" 145 " xmlns:dt='urn:schemas-microsoft-com:datatypes'>\n" 146 " <ElementType name='base64Data' content='textOnly' dt:type='bin.base64'/>\n" 147 " <ElementType name='hexData' content='textOnly' dt:type='bin.hex'/>\n" 148 " <ElementType name='boolData' content='textOnly' dt:type='boolean'/>\n" 149 " <ElementType name='charData' content='textOnly' dt:type='char'/>\n" 150 " <ElementType name='dateData' content='textOnly' dt:type='date'/>\n" 151 " <ElementType name='dateTimeData' content='textOnly' dt:type='dateTime'/>\n" 152 " <ElementType name='dateTimeTzData' content='textOnly' dt:type='dateTime.tz'/>\n" 153 " <ElementType name='entityData' content='textOnly' dt:type='entity'/>\n" 154 " <ElementType name='entitiesData' content='textOnly' dt:type='entities'/>\n" 155 " <ElementType name='fixedData' content='textOnly' dt:type='fixed.14.4'/>\n" 156 " <ElementType name='floatData' content='textOnly' dt:type='float'/>\n" 157 " <ElementType name='i1Data' content='textOnly' dt:type='i1'/>\n" 158 " <ElementType name='i2Data' content='textOnly' dt:type='i2'/>\n" 159 " <ElementType name='i4Data' content='textOnly' dt:type='i4'/>\n" 160 " <ElementType name='i8Data' content='textOnly' dt:type='i8'/>\n" 161 " <ElementType name='intData' content='textOnly' dt:type='int'/>\n" 162 " <ElementType name='nmtokData' content='textOnly' dt:type='nmtoken'/>\n" 163 " <ElementType name='nmtoksData' content='textOnly' dt:type='nmtokens'/>\n" 164 " <ElementType name='numData' content='textOnly' dt:type='number'/>\n" 165 " <ElementType name='r4Data' content='textOnly' dt:type='r4'/>\n" 166 " <ElementType name='r8Data' content='textOnly' dt:type='r8'/>\n" 167 " <ElementType name='stringData' content='textOnly' dt:type='string'/>\n" 168 " <ElementType name='timeData' content='textOnly' dt:type='time'/>\n" 169 " <ElementType name='timeTzData' content='textOnly' dt:type='time.tz'/>\n" 170 " <ElementType name='u1Data' content='textOnly' dt:type='ui1'/>\n" 171 " <ElementType name='u2Data' content='textOnly' dt:type='ui2'/>\n" 172 " <ElementType name='u4Data' content='textOnly' dt:type='ui4'/>\n" 173 " <ElementType name='u8Data' content='textOnly' dt:type='ui8'/>\n" 174 " <ElementType name='uriData' content='textOnly' dt:type='uri'/>\n" 175 " <ElementType name='uuidData' content='textOnly' dt:type='uuid'/>\n" 176 "\n" 177 " <ElementType name='Name' content='textOnly' dt:type='nmtoken'/>\n" 178 " <ElementType name='Value' content='eltOnly' order='many'>\n" 179 " <element type='base64Data'/>\n" 180 " <element type='hexData'/>\n" 181 " <element type='boolData'/>\n" 182 " <element type='charData'/>\n" 183 " <element type='dateData'/>\n" 184 " <element type='dateTimeData'/>\n" 185 " <element type='dateTimeTzData'/>\n" 186 " <element type='entityData'/>\n" 187 " <element type='entitiesData'/>\n" 188 " <element type='fixedData'/>\n" 189 " <element type='floatData'/>\n" 190 " <element type='i1Data'/>\n" 191 " <element type='i2Data'/>\n" 192 " <element type='i4Data'/>\n" 193 " <element type='i8Data'/>\n" 194 " <element type='intData'/>\n" 195 " <element type='nmtokData'/>\n" 196 " <element type='nmtoksData'/>\n" 197 " <element type='numData'/>\n" 198 " <element type='r4Data'/>\n" 199 " <element type='r8Data'/>\n" 200 " <element type='stringData'/>\n" 201 " <element type='timeData'/>\n" 202 " <element type='timeTzData'/>\n" 203 " <element type='u1Data'/>\n" 204 " <element type='u2Data'/>\n" 205 " <element type='u4Data'/>\n" 206 " <element type='u8Data'/>\n" 207 " <element type='uriData'/>\n" 208 " <element type='uuidData'/>\n" 209 " </ElementType>\n" 210 " <ElementType name='Property' content='eltOnly' order='seq'>\n" 211 " <element type='Name'/>\n" 212 " <element type='Value'/>\n" 213 " </ElementType>\n" 214 " <ElementType name='Properties' content='eltOnly'>\n" 215 " <element type='Property' minOccurs='0' maxOccurs='*'/>\n" 216 " </ElementType>\n" 217 "</Schema>"; 218 219 static const CHAR szDatatypeXML[] = 220 "<?xml version='1.0'?>\n" 221 "<Properties xmlns='urn:x-schema:datatype-test-xdr'>\n" 222 " <Property>\n" 223 " <Name>testBase64</Name>\n" 224 " <Value>\n" 225 " <base64Data>+HugeNumber+</base64Data>\n" 226 " </Value>\n" 227 " </Property>\n" 228 " <Property>\n" 229 " <Name>testHex</Name>\n" 230 " <Value>\n" 231 " <hexData>deadbeef</hexData>\n" 232 " </Value>\n" 233 " </Property>\n" 234 " <Property>\n" 235 " <Name>testBool</Name>\n" 236 " <Value>\n" 237 " <boolData>1</boolData>\n" 238 " </Value>\n" 239 " </Property>\n" 240 " <Property>\n" 241 " <Name>testChar</Name>\n" 242 " <Value>\n" 243 " <charData>u</charData>\n" 244 " </Value>\n" 245 " </Property>\n" 246 " <Property>\n" 247 " <Name>testDate</Name>\n" 248 " <Value>\n" 249 " <dateData>1998-02-01</dateData>\n" 250 " </Value>\n" 251 " </Property>\n" 252 " <Property>\n" 253 " <Name>testDateTime</Name>\n" 254 " <Value>\n" 255 " <dateTimeData>1998-02-01T12:34:56</dateTimeData>\n" 256 " </Value>\n" 257 " </Property>\n" 258 " <Property>\n" 259 " <Name>testDateTimeTz</Name>\n" 260 " <Value>\n" 261 " <dateTimeTzData>1998-02-01T12:34:56-06:00</dateTimeTzData>\n" 262 " </Value>\n" 263 " </Property>\n" 264 " <Property>\n" 265 " <Name>testFixed</Name>\n" 266 " <Value>\n" 267 " <fixedData>3.1416</fixedData>\n" 268 " </Value>\n" 269 " </Property>\n" 270 " <Property>\n" 271 " <Name>testFloat</Name>\n" 272 " <Value>\n" 273 " <floatData>3.14159</floatData>\n" 274 " </Value>\n" 275 " </Property>\n" 276 " <Property>\n" 277 " <Name>testI1</Name>\n" 278 " <Value>\n" 279 " <i1Data>42</i1Data>\n" 280 " </Value>\n" 281 " </Property>\n" 282 " <Property>\n" 283 " <Name>testI2</Name>\n" 284 " <Value>\n" 285 " <i2Data>420</i2Data>\n" 286 " </Value>\n" 287 " </Property>\n" 288 " <Property>\n" 289 " <Name>testI4</Name>\n" 290 " <Value>\n" 291 " <i4Data>-420000000</i4Data>\n" 292 " </Value>\n" 293 " </Property>\n" 294 " <Property>\n" 295 " <Name>testI8</Name>\n" 296 " <Value>\n" 297 " <i8Data>-4200000000</i8Data>\n" 298 " </Value>\n" 299 " </Property>\n" 300 " <Property>\n" 301 " <Name>testInt</Name>\n" 302 " <Value>\n" 303 " <intData>42</intData>\n" 304 " </Value>\n" 305 " </Property>\n" 306 " <Property>\n" 307 " <Name>testNmtoken</Name>\n" 308 " <Value>\n" 309 " <nmtokData>tok1</nmtokData>\n" 310 " </Value>\n" 311 " </Property>\n" 312 " <Property>\n" 313 " <Name>testNmtokens</Name>\n" 314 " <Value>\n" 315 " <nmtoksData>tok1 tok2 tok3</nmtoksData>\n" 316 " </Value>\n" 317 " </Property>\n" 318 " <Property>\n" 319 " <Name>testNumber</Name>\n" 320 " <Value>\n" 321 " <numData>3.14159</numData>\n" 322 " </Value>\n" 323 " </Property>\n" 324 " <Property>\n" 325 " <Name>testR4</Name>\n" 326 " <Value>\n" 327 " <r4Data>3.14159265</r4Data>\n" 328 " </Value>\n" 329 " </Property>\n" 330 " <Property>\n" 331 " <Name>testR8</Name>\n" 332 " <Value>\n" 333 " <r8Data>3.14159265358979323846</r8Data>\n" 334 " </Value>\n" 335 " </Property>\n" 336 " <Property>\n" 337 " <Name>testString</Name>\n" 338 " <Value>\n" 339 " <stringData>foo bar</stringData>\n" 340 " </Value>\n" 341 " </Property>\n" 342 " <Property>\n" 343 " <Name>testTime</Name>\n" 344 " <Value>\n" 345 " <timeData>12:34:56</timeData>\n" 346 " </Value>\n" 347 " </Property>\n" 348 " <Property>\n" 349 " <Name>testTimeTz</Name>\n" 350 " <Value>\n" 351 " <timeTzData>12:34:56-06:00</timeTzData>\n" 352 " </Value>\n" 353 " </Property>\n" 354 " <Property>\n" 355 " <Name>testU1</Name>\n" 356 " <Value>\n" 357 " <u1Data>255</u1Data>\n" 358 " </Value>\n" 359 " </Property>\n" 360 " <Property>\n" 361 " <Name>testU2</Name>\n" 362 " <Value>\n" 363 " <u2Data>65535</u2Data>\n" 364 " </Value>\n" 365 " </Property>\n" 366 " <Property>\n" 367 " <Name>testU4</Name>\n" 368 " <Value>\n" 369 " <u4Data>4294967295</u4Data>\n" 370 " </Value>\n" 371 " </Property>\n" 372 " <Property>\n" 373 " <Name>testU8</Name>\n" 374 " <Value>\n" 375 " <u8Data>18446744073709551615</u8Data>\n" 376 " </Value>\n" 377 " </Property>\n" 378 " <Property>\n" 379 " <Name>testURI</Name>\n" 380 " <Value>\n" 381 " <uriData>urn:schemas-microsoft-com:datatypes</uriData>\n" 382 " </Value>\n" 383 " </Property>\n" 384 " <Property>\n" 385 " <Name>testUUID</Name>\n" 386 " <Value>\n" 387 " <uuidData>2933BF81-7B36-11D2-B20E-00C04F983E60</uuidData>\n" 388 " </Value>\n" 389 " </Property>\n" 390 "</Properties>"; 391 392 static const CHAR szOpenSeqXDR[] = 393 "<Schema xmlns='urn:schemas-microsoft-com:xml-data'>\n" 394 " <ElementType name='w' content='empty' model='closed'/>\n" 395 " <ElementType name='x' content='empty' model='closed'/>\n" 396 " <ElementType name='y' content='empty' model='closed'/>\n" 397 " <ElementType name='z' content='empty' model='closed'/>\n" 398 " <ElementType name='test' content='eltOnly' model='open' order='seq'>\n" 399 " <element type='x'/>\n" 400 " <group order='seq'>\n" 401 " <element type='x'/>\n" 402 " <element type='y'/>\n" 403 " <element type='z'/>\n" 404 " </group>\n" 405 " <element type='z'/>\n" 406 " </ElementType>\n" 407 "</Schema>"; 408 409 static const CHAR szOpenSeqXML1[] = "<test><x/><x/><y/><z/><z/></test>"; 410 static const CHAR szOpenSeqXML2[] = "<test><x/><x/><y/><z/><z/><w/></test>"; 411 static const CHAR szOpenSeqXML3[] = "<test><w/><x/><x/><y/><z/><z/></test>"; 412 static const CHAR szOpenSeqXML4[] = "<test><x/><x/><y/><z/><z/><v/></test>"; 413 414 #define check_ref_expr(expr, n) { \ 415 LONG ref = expr; \ 416 ok(ref == n, "expected %i refs, got %i\n", n, ref); \ 417 } 418 419 #define check_refs(iface, obj, n) { \ 420 LONG ref = iface ## _AddRef(obj); \ 421 ok(ref == n+1, "expected %i refs, got %i\n", n+1, ref); \ 422 ref = iface ## _Release(obj); \ 423 ok(ref == n, "expected %i refs, got %i\n", n, ref); \ 424 } 425 426 #define ole_check(expr) { \ 427 HRESULT r = expr; \ 428 ok(r == S_OK, #expr " returned %x\n", r); \ 429 } 430 431 #define ole_expect(expr, expect) { \ 432 HRESULT r = expr; \ 433 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \ 434 } 435 436 #define _expect64(expr, str, base, TYPE, CONV) { \ 437 TYPE v1 = expr; \ 438 TYPE v2 = CONV(str, NULL, base); \ 439 ok(v1 == v2, #expr "returned %s, expected %s\n", \ 440 wine_dbgstr_longlong(v1), wine_dbgstr_longlong(v2)); \ 441 } 442 443 #ifdef __REACTOS__ 444 #define expect_int64(expr, x, base) _expect64(expr, #x, base, LONG64, _strtoi64) 445 #define expect_uint64(expr, x, base) _expect64(expr, #x, base, ULONG64, _strtoui64) 446 #else 447 #define expect_int64(expr, x, base) _expect64(expr, #x, base, LONG64, strtoll) 448 #define expect_uint64(expr, x, base) _expect64(expr, #x, base, ULONG64, strtoull) 449 #endif 450 451 static BSTR alloced_bstrs[256]; 452 static int alloced_bstrs_count; 453 454 static BSTR alloc_str_from_narrow(const char *str) 455 { 456 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 457 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */ 458 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); 459 return ret; 460 } 461 462 static BSTR _bstr_(const char *str) 463 { 464 assert(alloced_bstrs_count < ARRAY_SIZE(alloced_bstrs)); 465 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str); 466 return alloced_bstrs[alloced_bstrs_count++]; 467 } 468 469 static void free_bstrs(void) 470 { 471 int i; 472 for (i = 0; i < alloced_bstrs_count; i++) 473 SysFreeString(alloced_bstrs[i]); 474 alloced_bstrs_count = 0; 475 } 476 477 static VARIANT _variantdoc_(void* doc) 478 { 479 VARIANT v; 480 V_VT(&v) = VT_DISPATCH; 481 V_DISPATCH(&v) = (IDispatch*)doc; 482 return v; 483 } 484 485 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line) 486 { 487 void *obj = NULL; 488 HRESULT hr; 489 490 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj); 491 if (hr != S_OK) 492 win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr); 493 494 return obj; 495 } 496 497 #define _create(cls) cls, #cls 498 499 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__) 500 501 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__) 502 503 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__) 504 505 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__) 506 507 static void test_schema_refs(void) 508 { 509 static const WCHAR emptyW[] = {0}; 510 IXMLDOMDocument2 *doc; 511 IXMLDOMNode *node; 512 IXMLDOMSchemaCollection *cache; 513 VARIANT v; 514 VARIANT_BOOL b; 515 BSTR str; 516 LONG len; 517 HRESULT hr; 518 519 doc = create_document(&IID_IXMLDOMDocument2); 520 if (!doc) 521 return; 522 523 cache = create_cache(&IID_IXMLDOMSchemaCollection); 524 if(!cache) 525 { 526 IXMLDOMDocument2_Release(doc); 527 return; 528 } 529 530 VariantInit(&v); 531 str = SysAllocString(xdr_schema_xml); 532 ole_check(IXMLDOMDocument2_loadXML(doc, str, &b)); 533 ok(b == VARIANT_TRUE, "b %04x\n", b); 534 SysFreeString(str); 535 536 node = (void*)0xdeadbeef; 537 ole_check(IXMLDOMSchemaCollection_get(cache, NULL, &node)); 538 ok(node == NULL, "%p\n", node); 539 540 /* NULL uri pointer, still adds a document */ 541 ole_check(IXMLDOMSchemaCollection_add(cache, NULL, _variantdoc_(doc))); 542 len = -1; 543 ole_check(IXMLDOMSchemaCollection_get_length(cache, &len)); 544 ok(len == 1, "got %d\n", len); 545 /* read back - empty valid BSTR */ 546 str = NULL; 547 ole_check(IXMLDOMSchemaCollection_get_namespaceURI(cache, 0, &str)); 548 ok(str && *str == 0, "got %p\n", str); 549 SysFreeString(str); 550 551 node = NULL; 552 ole_check(IXMLDOMSchemaCollection_get(cache, NULL, &node)); 553 ok(node != NULL, "%p\n", node); 554 IXMLDOMNode_Release(node); 555 556 node = NULL; 557 str = SysAllocString(emptyW); 558 ole_check(IXMLDOMSchemaCollection_get(cache, str, &node)); 559 ok(node != NULL, "%p\n", node); 560 IXMLDOMNode_Release(node); 561 SysFreeString(str); 562 563 /* remove with NULL uri */ 564 ole_check(IXMLDOMSchemaCollection_remove(cache, NULL)); 565 len = -1; 566 ole_check(IXMLDOMSchemaCollection_get_length(cache, &len)); 567 ok(len == 0, "got %d\n", len); 568 569 /* same, but with VT_UNKNOWN type */ 570 V_VT(&v) = VT_UNKNOWN; 571 V_UNKNOWN(&v) = (IUnknown*)doc; 572 hr = IXMLDOMSchemaCollection_add(cache, NULL, v); 573 ok(hr == S_OK, "got 0x%08x\n", hr); 574 575 len = -1; 576 hr = IXMLDOMSchemaCollection_get_length(cache, &len); 577 ok(hr == S_OK, "got 0x%08x\n", hr); 578 ok(len == 1, "got %d\n", len); 579 580 hr = IXMLDOMSchemaCollection_remove(cache, NULL); 581 ok(hr == S_OK, "got 0x%08x\n", hr); 582 len = -1; 583 hr = IXMLDOMSchemaCollection_get_length(cache, &len); 584 ok(hr == S_OK, "got 0x%08x\n", hr); 585 ok(len == 0, "got %d\n", len); 586 587 str = SysAllocString(xdr_schema_uri); 588 ole_check(IXMLDOMSchemaCollection_add(cache, str, _variantdoc_(doc))); 589 590 /* IXMLDOMSchemaCollection_add doesn't add a ref on doc */ 591 check_refs(IXMLDOMDocument2, doc, 1); 592 593 SysFreeString(str); 594 595 V_VT(&v) = VT_INT; 596 ole_expect(IXMLDOMDocument2_get_schemas(doc, &v), S_FALSE); 597 ok(V_VT(&v) == VT_NULL, "vt %x\n", V_VT(&v)); 598 599 check_ref_expr(IXMLDOMSchemaCollection_AddRef(cache), 2); 600 V_VT(&v) = VT_DISPATCH; 601 V_DISPATCH(&v) = (IDispatch*)cache; 602 603 /* check that putref_schemas takes a ref */ 604 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 605 check_refs(IXMLDOMSchemaCollection, cache, 3); 606 607 VariantClear(&v); /* refs now 2 */ 608 609 V_VT(&v) = VT_INT; 610 /* check that get_schemas adds a ref */ 611 ole_check(IXMLDOMDocument2_get_schemas(doc, &v)); 612 ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v)); 613 check_refs(IXMLDOMSchemaCollection, cache, 3); 614 615 /* get_schemas doesn't release a ref if passed VT_DISPATCH - ie it doesn't call VariantClear() */ 616 ole_check(IXMLDOMDocument2_get_schemas(doc, &v)); 617 ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v)); 618 check_refs(IXMLDOMSchemaCollection, cache, 4); 619 620 /* release the two refs returned by get_schemas */ 621 check_ref_expr(IXMLDOMSchemaCollection_Release(cache), 3); 622 check_ref_expr(IXMLDOMSchemaCollection_Release(cache), 2); 623 624 /* check that taking another ref on the document doesn't change the schema's ref count */ 625 check_ref_expr(IXMLDOMDocument2_AddRef(doc), 2); 626 check_refs(IXMLDOMSchemaCollection, cache, 2); 627 check_ref_expr(IXMLDOMDocument2_Release(doc), 1); 628 629 /* call putref_schema with some odd variants */ 630 V_VT(&v) = VT_INT; 631 ole_expect(IXMLDOMDocument2_putref_schemas(doc, v), E_FAIL); 632 check_refs(IXMLDOMSchemaCollection, cache, 2); 633 634 /* calling with VT_EMPTY releases the schema */ 635 V_VT(&v) = VT_EMPTY; 636 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 637 check_refs(IXMLDOMSchemaCollection, cache, 1); 638 639 /* try setting with VT_UNKNOWN */ 640 check_ref_expr(IXMLDOMSchemaCollection_AddRef(cache), 2); 641 V_VT(&v) = VT_UNKNOWN; 642 V_UNKNOWN(&v) = (IUnknown*)cache; 643 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 644 check_refs(IXMLDOMSchemaCollection, cache, 3); 645 646 VariantClear(&v); /* refs now 2 */ 647 648 /* calling with VT_NULL releases the schema */ 649 V_VT(&v) = VT_NULL; 650 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 651 check_refs(IXMLDOMSchemaCollection, cache, 1); 652 653 /* refs now 1 */ 654 /* set again */ 655 check_ref_expr(IXMLDOMSchemaCollection_AddRef(cache), 2); 656 V_VT(&v) = VT_UNKNOWN; 657 V_UNKNOWN(&v) = (IUnknown*)cache; 658 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 659 check_refs(IXMLDOMSchemaCollection, cache, 3); 660 661 VariantClear(&v); /* refs now 2 */ 662 663 /* release the final ref on the doc which should release its ref on the schema */ 664 check_ref_expr(IXMLDOMDocument2_Release(doc), 0); 665 666 check_refs(IXMLDOMSchemaCollection, cache, 1); 667 check_ref_expr(IXMLDOMSchemaCollection_Release(cache), 0); 668 } 669 670 static void test_collection_refs(void) 671 { 672 IXMLDOMDocument2 *schema1, *schema2, *schema3; 673 IXMLDOMSchemaCollection *cache1, *cache2, *cache3; 674 VARIANT_BOOL b; 675 LONG length; 676 677 schema1 = create_document(&IID_IXMLDOMDocument2); 678 ok(schema1 != NULL, "Failed to create a document.\n"); 679 680 cache1 = create_cache(&IID_IXMLDOMSchemaCollection); 681 ok(cache1 != NULL, "Failed to create schema collection.\n"); 682 683 if (!schema1 || !cache1) 684 { 685 if (schema1) 686 IXMLDOMDocument2_Release(schema1); 687 if (cache1) 688 IXMLDOMSchemaCollection_Release(cache1); 689 return; 690 } 691 692 schema2 = create_document(&IID_IXMLDOMDocument2); 693 schema3 = create_document(&IID_IXMLDOMDocument2); 694 695 cache2 = create_cache(&IID_IXMLDOMSchemaCollection); 696 cache3 = create_cache(&IID_IXMLDOMSchemaCollection); 697 698 ole_check(IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b)); 699 ok(b == VARIANT_TRUE, "failed to load XML\n"); 700 701 ole_check(IXMLDOMDocument2_loadXML(schema2, _bstr_(xdr_schema2_xml), &b)); 702 ok(b == VARIANT_TRUE, "failed to load XML\n"); 703 704 ole_check(IXMLDOMDocument2_loadXML(schema3, _bstr_(xdr_schema3_xml), &b)); 705 ok(b == VARIANT_TRUE, "failed to load XML\n"); 706 707 ole_check(IXMLDOMSchemaCollection_add(cache1, _bstr_(xdr_schema1_uri), _variantdoc_(schema1))); 708 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xdr_schema2_uri), _variantdoc_(schema2))); 709 ole_check(IXMLDOMSchemaCollection_add(cache3, _bstr_(xdr_schema3_uri), _variantdoc_(schema3))); 710 711 check_ref_expr(IXMLDOMDocument2_Release(schema1), 0); 712 check_ref_expr(IXMLDOMDocument2_Release(schema2), 0); 713 check_ref_expr(IXMLDOMDocument2_Release(schema3), 0); 714 schema1 = NULL; 715 schema2 = NULL; 716 schema3 = NULL; 717 718 /* releasing the original doc does not affect the schema cache */ 719 ole_check(IXMLDOMSchemaCollection_get(cache1, _bstr_(xdr_schema1_uri), (IXMLDOMNode**)&schema1)); 720 ole_check(IXMLDOMSchemaCollection_get(cache2, _bstr_(xdr_schema2_uri), (IXMLDOMNode**)&schema2)); 721 ole_check(IXMLDOMSchemaCollection_get(cache3, _bstr_(xdr_schema3_uri), (IXMLDOMNode**)&schema3)); 722 723 /* we get a read-only domdoc interface, created just for us */ 724 if (schema1) check_refs(IXMLDOMDocument2, schema1, 1); 725 if (schema2) check_refs(IXMLDOMDocument2, schema2, 1); 726 if (schema3) check_refs(IXMLDOMDocument2, schema3, 1); 727 728 ole_expect(IXMLDOMSchemaCollection_addCollection(cache1, NULL), E_POINTER); 729 ole_check(IXMLDOMSchemaCollection_addCollection(cache2, cache1)); 730 ole_check(IXMLDOMSchemaCollection_addCollection(cache3, cache2)); 731 732 length = -1; 733 ole_check(IXMLDOMSchemaCollection_get_length(cache1, &length)); 734 ok(length == 1, "expected length 1, got %i\n", length); 735 736 length = -1; 737 ole_check(IXMLDOMSchemaCollection_get_length(cache2, &length)); 738 ok(length == 2, "expected length 2, got %i\n", length); 739 740 length = -1; 741 ole_check(IXMLDOMSchemaCollection_get_length(cache3, &length)); 742 ok(length == 3, "expected length 3, got %i\n", length); 743 744 745 /* merging collections does not affect the ref count */ 746 check_refs(IXMLDOMSchemaCollection, cache1, 1); 747 check_refs(IXMLDOMSchemaCollection, cache2, 1); 748 check_refs(IXMLDOMSchemaCollection, cache3, 1); 749 750 /* nor does it affect the domdoc instances */ 751 if (schema1) check_refs(IXMLDOMDocument2, schema1, 1); 752 if (schema2) check_refs(IXMLDOMDocument2, schema2, 1); 753 if (schema3) check_refs(IXMLDOMDocument2, schema3, 1); 754 755 if (schema1) check_ref_expr(IXMLDOMDocument2_Release(schema1), 0); 756 if (schema2) check_ref_expr(IXMLDOMDocument2_Release(schema2), 0); 757 if (schema3) check_ref_expr(IXMLDOMDocument2_Release(schema3), 0); 758 schema1 = NULL; 759 schema2 = NULL; 760 schema3 = NULL; 761 762 /* releasing the domdoc instances doesn't change the cache */ 763 ole_check(IXMLDOMSchemaCollection_get(cache1, _bstr_(xdr_schema1_uri), (IXMLDOMNode**)&schema1)); 764 ole_check(IXMLDOMSchemaCollection_get(cache2, _bstr_(xdr_schema2_uri), (IXMLDOMNode**)&schema2)); 765 ole_check(IXMLDOMSchemaCollection_get(cache3, _bstr_(xdr_schema3_uri), (IXMLDOMNode**)&schema3)); 766 767 /* we can just get them again */ 768 if (schema1) check_refs(IXMLDOMDocument2, schema1, 1); 769 if (schema2) check_refs(IXMLDOMDocument2, schema2, 1); 770 if (schema3) check_refs(IXMLDOMDocument2, schema3, 1); 771 772 /* releasing the caches does not affect the domdoc instances */ 773 check_ref_expr(IXMLDOMSchemaCollection_Release(cache1), 0); 774 check_ref_expr(IXMLDOMSchemaCollection_Release(cache2), 0); 775 check_ref_expr(IXMLDOMSchemaCollection_Release(cache3), 0); 776 777 /* they're just for us */ 778 if (schema1) check_refs(IXMLDOMDocument2, schema1, 1); 779 if (schema2) check_refs(IXMLDOMDocument2, schema2, 1); 780 if (schema3) check_refs(IXMLDOMDocument2, schema3, 1); 781 782 if (schema1) check_ref_expr(IXMLDOMDocument2_Release(schema1), 0); 783 if (schema2) check_ref_expr(IXMLDOMDocument2_Release(schema2), 0); 784 if (schema3) check_ref_expr(IXMLDOMDocument2_Release(schema3), 0); 785 786 free_bstrs(); 787 } 788 789 static void test_length(void) 790 { 791 IXMLDOMDocument2 *schema1, *schema2, *schema3; 792 IXMLDOMSchemaCollection *cache; 793 VARIANT_BOOL b; 794 VARIANT v; 795 LONG length; 796 797 schema1 = create_document(&IID_IXMLDOMDocument2); 798 schema2 = create_document(&IID_IXMLDOMDocument2); 799 schema3 = create_document(&IID_IXMLDOMDocument2); 800 801 cache = create_cache(&IID_IXMLDOMSchemaCollection); 802 803 if (!schema1 || !schema2 || !schema3 || !cache) 804 { 805 if (schema1) IXMLDOMDocument2_Release(schema1); 806 if (schema2) IXMLDOMDocument2_Release(schema2); 807 if (schema3) IXMLDOMDocument2_Release(schema3); 808 809 if (cache) IXMLDOMSchemaCollection_Release(cache); 810 811 return; 812 } 813 814 VariantInit(&v); 815 816 ole_check(IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b)); 817 ok(b == VARIANT_TRUE, "failed to load XML\n"); 818 819 ole_check(IXMLDOMDocument2_loadXML(schema2, _bstr_(xdr_schema2_xml), &b)); 820 ok(b == VARIANT_TRUE, "failed to load XML\n"); 821 822 ole_check(IXMLDOMDocument2_loadXML(schema3, _bstr_(xdr_schema3_xml), &b)); 823 ok(b == VARIANT_TRUE, "failed to load XML\n"); 824 825 ole_expect(IXMLDOMSchemaCollection_get_length(cache, NULL), E_POINTER); 826 827 /* MSDN lies; removing a nonexistent entry produces no error */ 828 ole_check(IXMLDOMSchemaCollection_remove(cache, NULL)); 829 ole_check(IXMLDOMSchemaCollection_remove(cache, _bstr_(xdr_schema1_uri))); 830 831 length = -1; 832 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 833 ok(length == 0, "expected length 0, got %i\n", length); 834 835 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema1_uri), _variantdoc_(schema1))); 836 837 length = -1; 838 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 839 ok(length == 1, "expected length 1, got %i\n", length); 840 841 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema2_uri), _variantdoc_(schema2))); 842 843 length = -1; 844 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 845 ok(length == 2, "expected length 2, got %i\n", length); 846 847 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema3_uri), _variantdoc_(schema3))); 848 849 length = -1; 850 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 851 ok(length == 3, "expected length 3, got %i\n", length); 852 853 /* adding with VT_NULL is the same as removing */ 854 V_VT(&v) = VT_NULL; 855 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema1_uri), v)); 856 857 length = -1; 858 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 859 ok(length == 2, "expected length 2, got %i\n", length); 860 861 ole_check(IXMLDOMSchemaCollection_remove(cache, _bstr_(xdr_schema2_uri))); 862 863 length = -1; 864 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 865 ok(length == 1, "expected length 1, got %i\n", length); 866 867 ole_check(IXMLDOMSchemaCollection_remove(cache, _bstr_(xdr_schema3_uri))); 868 869 length = -1; 870 ole_check(IXMLDOMSchemaCollection_get_length(cache, &length)); 871 ok(length == 0, "expected length 0, got %i\n", length); 872 873 IXMLDOMDocument2_Release(schema1); 874 IXMLDOMDocument2_Release(schema2); 875 IXMLDOMDocument2_Release(schema3); 876 IXMLDOMSchemaCollection_Release(cache); 877 878 free_bstrs(); 879 } 880 881 static void test_collection_content(void) 882 { 883 IXMLDOMDocument2 *schema1, *schema2, *schema3, *schema4, *schema5; 884 BSTR content[5] = {NULL, NULL, NULL, NULL, NULL}; 885 IXMLDOMSchemaCollection *cache1, *cache2; 886 VARIANT_BOOL b; 887 LONG length; 888 HRESULT hr; 889 BSTR bstr; 890 int i, j; 891 892 schema1 = create_document_version(30, &IID_IXMLDOMDocument2); 893 schema2 = create_document_version(30, &IID_IXMLDOMDocument2); 894 schema3 = create_document_version(30, &IID_IXMLDOMDocument2); 895 896 cache1 = create_cache_version(30, &IID_IXMLDOMSchemaCollection); 897 cache2 = create_cache_version(40, &IID_IXMLDOMSchemaCollection); 898 899 if (!schema1 || !schema2 || !schema3 || !cache1) 900 { 901 if (schema1) IXMLDOMDocument2_Release(schema1); 902 if (schema2) IXMLDOMDocument2_Release(schema2); 903 if (schema3) IXMLDOMDocument2_Release(schema3); 904 905 if (cache1) IXMLDOMSchemaCollection_Release(cache1); 906 907 return; 908 } 909 910 ole_check(IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b)); 911 ok(b == VARIANT_TRUE, "failed to load XML\n"); 912 913 ole_check(IXMLDOMDocument2_loadXML(schema2, _bstr_(xdr_schema2_xml), &b)); 914 ok(b == VARIANT_TRUE, "failed to load XML\n"); 915 916 ole_check(IXMLDOMDocument2_loadXML(schema3, _bstr_(xdr_schema3_xml), &b)); 917 ok(b == VARIANT_TRUE, "failed to load XML\n"); 918 919 ole_check(IXMLDOMSchemaCollection_add(cache1, _bstr_(xdr_schema1_uri), _variantdoc_(schema1))); 920 ole_check(IXMLDOMSchemaCollection_add(cache1, _bstr_(xdr_schema2_uri), _variantdoc_(schema2))); 921 ole_check(IXMLDOMSchemaCollection_add(cache1, _bstr_(xdr_schema3_uri), _variantdoc_(schema3))); 922 923 length = -1; 924 ole_check(IXMLDOMSchemaCollection_get_length(cache1, &length)); 925 ok(length == 3, "expected length 3, got %i\n", length); 926 927 IXMLDOMDocument2_Release(schema1); 928 IXMLDOMDocument2_Release(schema2); 929 IXMLDOMDocument2_Release(schema3); 930 931 if (cache2) 932 { 933 schema1 = create_document_version(40, &IID_IXMLDOMDocument2); 934 schema2 = create_document_version(40, &IID_IXMLDOMDocument2); 935 schema3 = create_document_version(40, &IID_IXMLDOMDocument2); 936 schema4 = create_document_version(40, &IID_IXMLDOMDocument2); 937 schema5 = create_document_version(40, &IID_IXMLDOMDocument2); 938 ole_check(IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b)); 939 ok(b == VARIANT_TRUE, "failed to load XML\n"); 940 ole_check(IXMLDOMDocument2_loadXML(schema2, _bstr_(xdr_schema2_xml), &b)); 941 ok(b == VARIANT_TRUE, "failed to load XML\n"); 942 ole_check(IXMLDOMDocument2_loadXML(schema3, _bstr_(xsd_schema1_xml), &b)); 943 ok(b == VARIANT_TRUE, "failed to load XML\n"); 944 ole_check(IXMLDOMDocument2_loadXML(schema4, _bstr_(xsd_schema2_xml), &b)); 945 ok(b == VARIANT_TRUE, "failed to load XML\n"); 946 ole_check(IXMLDOMDocument2_loadXML(schema5, _bstr_(xsd_schema3_xml), &b)); 947 ok(b == VARIANT_TRUE, "failed to load XML\n"); 948 949 /* combining XDR and XSD schemas in the same cache is fine */ 950 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xdr_schema1_uri), _variantdoc_(schema1))); 951 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xdr_schema2_uri), _variantdoc_(schema2))); 952 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xsd_schema1_uri), _variantdoc_(schema3))); 953 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xsd_schema2_uri), _variantdoc_(schema4))); 954 ole_check(IXMLDOMSchemaCollection_add(cache2, _bstr_(xsd_schema3_uri), _variantdoc_(schema5))); 955 956 length = -1; 957 ole_check(IXMLDOMSchemaCollection_get_length(cache2, &length)); 958 ok(length == 5, "expected length 5, got %i\n", length); 959 960 IXMLDOMDocument2_Release(schema1); 961 IXMLDOMDocument2_Release(schema2); 962 IXMLDOMDocument2_Release(schema3); 963 IXMLDOMDocument2_Release(schema4); 964 IXMLDOMDocument2_Release(schema5); 965 } 966 967 bstr = (void*)0xdeadbeef; 968 /* error if index is out of range */ 969 hr = IXMLDOMSchemaCollection_get_namespaceURI(cache1, 3, &bstr); 970 EXPECT_HR(hr, E_FAIL); 971 ok(bstr == (void*)0xdeadbeef, "got %p\n", bstr); 972 /* error if return pointer is NULL */ 973 ole_expect(IXMLDOMSchemaCollection_get_namespaceURI(cache1, 0, NULL), E_POINTER); 974 /* pointer is checked first */ 975 ole_expect(IXMLDOMSchemaCollection_get_namespaceURI(cache1, 3, NULL), E_POINTER); 976 977 schema1 = NULL; 978 /* no error if ns uri does not exist */ 979 ole_check(IXMLDOMSchemaCollection_get(cache1, _bstr_(xsd_schema1_uri), (IXMLDOMNode**)&schema1)); 980 ok(!schema1, "expected NULL\n"); 981 /* a NULL bstr corresponds to no-uri ns */ 982 ole_check(IXMLDOMSchemaCollection_get(cache1, NULL, (IXMLDOMNode**)&schema1)); 983 ok(!schema1, "expected NULL\n"); 984 /* error if return pointer is NULL */ 985 ole_expect(IXMLDOMSchemaCollection_get(cache1, _bstr_(xdr_schema1_uri), NULL), E_POINTER); 986 987 for (i = 0; i < 3; ++i) 988 { 989 bstr = NULL; 990 ole_check(IXMLDOMSchemaCollection_get_namespaceURI(cache1, i, &bstr)); 991 ok(bstr != NULL && *bstr, "expected non-empty string\n"); 992 content[i] = bstr; 993 994 for (j = 0; j < i; ++j) 995 ok(winetest_strcmpW(content[j], bstr), "got duplicate entry\n"); 996 } 997 998 for (i = 0; i < 3; ++i) 999 { 1000 SysFreeString(content[i]); 1001 content[i] = NULL; 1002 } 1003 1004 if (cache2) 1005 { 1006 for (i = 0; i < 5; ++i) 1007 { 1008 bstr = NULL; 1009 ole_check(IXMLDOMSchemaCollection_get_namespaceURI(cache2, i, &bstr)); 1010 ok(bstr != NULL && *bstr, "expected non-empty string\n"); 1011 1012 for (j = 0; j < i; ++j) 1013 ok(winetest_strcmpW(content[j], bstr), "got duplicate entry\n"); 1014 content[i] = bstr; 1015 } 1016 1017 for (i = 0; i < 5; ++i) 1018 { 1019 SysFreeString(content[i]); 1020 content[i] = NULL; 1021 } 1022 } 1023 1024 IXMLDOMSchemaCollection_Release(cache1); 1025 if (cache2) IXMLDOMSchemaCollection_Release(cache2); 1026 1027 free_bstrs(); 1028 } 1029 1030 static void test_XDR_schemas(void) 1031 { 1032 IXMLDOMDocument2 *doc, *schema; 1033 IXMLDOMSchemaCollection* cache; 1034 IXMLDOMParseError* err; 1035 VARIANT_BOOL b; 1036 VARIANT v; 1037 BSTR bstr; 1038 1039 doc = create_document(&IID_IXMLDOMDocument2); 1040 schema = create_document(&IID_IXMLDOMDocument2); 1041 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1042 1043 if (!doc || !schema || !cache) 1044 { 1045 if (doc) IXMLDOMDocument2_Release(doc); 1046 if (schema) IXMLDOMDocument2_Release(schema); 1047 if (cache) IXMLDOMSchemaCollection_Release(cache); 1048 1049 return; 1050 } 1051 1052 VariantInit(&v); 1053 1054 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML1), &b)); 1055 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1056 1057 ole_check(IXMLDOMDocument2_loadXML(schema, _bstr_(szOpenSeqXDR), &b)); 1058 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1059 1060 /* load the schema */ 1061 V_VT(&v) = VT_DISPATCH; 1062 V_DISPATCH(&v) = NULL; 1063 ole_check(IXMLDOMDocument2_QueryInterface(schema, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1064 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1065 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(""), v)); 1066 VariantClear(&v); 1067 1068 /* associate the cache to the doc */ 1069 V_VT(&v) = VT_DISPATCH; 1070 V_DISPATCH(&v) = NULL; 1071 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1072 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1073 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1074 VariantClear(&v); 1075 1076 /* validate the doc 1077 * only declared elements in the declared order 1078 * this is fine */ 1079 err = NULL; 1080 bstr = NULL; 1081 ole_check(IXMLDOMDocument2_validate(doc, &err)); 1082 ok(err != NULL, "domdoc_validate() should always set err\n"); 1083 ole_expect(IXMLDOMParseError_get_reason(err, &bstr), S_FALSE); 1084 ok(IXMLDOMParseError_get_reason(err, &bstr) == S_FALSE, "got error: %s\n", wine_dbgstr_w(bstr)); 1085 SysFreeString(bstr); 1086 IXMLDOMParseError_Release(err); 1087 1088 /* load the next doc */ 1089 IXMLDOMDocument2_Release(doc); 1090 doc = create_document(&IID_IXMLDOMDocument2); 1091 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML2), &b)); 1092 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1093 1094 /* associate the cache to the doc */ 1095 V_VT(&v) = VT_DISPATCH; 1096 V_DISPATCH(&v) = NULL; 1097 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1098 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1099 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1100 VariantClear(&v); 1101 1102 /* validate the doc 1103 * declared elements in the declared order, with an extra declared element at the end 1104 * this is fine */ 1105 err = NULL; 1106 bstr = NULL; 1107 ole_check(IXMLDOMDocument2_validate(doc, &err)); 1108 ok(err != NULL, "domdoc_validate() should always set err\n"); 1109 ole_expect(IXMLDOMParseError_get_reason(err, &bstr), S_FALSE); 1110 ok(IXMLDOMParseError_get_reason(err, &bstr) == S_FALSE, "got error: %s\n", wine_dbgstr_w(bstr)); 1111 SysFreeString(bstr); 1112 IXMLDOMParseError_Release(err); 1113 1114 /* load the next doc */ 1115 IXMLDOMDocument2_Release(doc); 1116 doc = create_document(&IID_IXMLDOMDocument2); 1117 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML3), &b)); 1118 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1119 1120 /* associate the cache to the doc */ 1121 V_VT(&v) = VT_DISPATCH; 1122 V_DISPATCH(&v) = NULL; 1123 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1124 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1125 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1126 VariantClear(&v); 1127 1128 /* validate the doc 1129 * fails, extra elements are only allowed at the end */ 1130 err = NULL; 1131 bstr = NULL; 1132 ole_expect(IXMLDOMDocument2_validate(doc, &err), S_FALSE); 1133 ok(err != NULL, "domdoc_validate() should always set err\n"); 1134 todo_wine ok(IXMLDOMParseError_get_reason(err, &bstr) == S_OK, "got error: %s\n", wine_dbgstr_w(bstr)); 1135 SysFreeString(bstr); 1136 IXMLDOMParseError_Release(err); 1137 1138 /* load the next doc */ 1139 IXMLDOMDocument2_Release(doc); 1140 doc = create_document(&IID_IXMLDOMDocument2); 1141 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML4), &b)); 1142 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1143 1144 /* associate the cache to the doc */ 1145 V_VT(&v) = VT_DISPATCH; 1146 V_DISPATCH(&v) = NULL; 1147 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1148 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1149 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1150 VariantClear(&v); 1151 1152 /* validate the doc 1153 * fails, undeclared elements are not allowed */ 1154 err = NULL; 1155 bstr = NULL; 1156 ole_expect(IXMLDOMDocument2_validate(doc, &err), S_FALSE); 1157 ok(err != NULL, "domdoc_validate() should always set err\n"); 1158 todo_wine ok(IXMLDOMParseError_get_reason(err, &bstr) == S_OK, "got error: %s\n", wine_dbgstr_w(bstr)); 1159 SysFreeString(bstr); 1160 IXMLDOMParseError_Release(err); 1161 1162 IXMLDOMDocument2_Release(doc); 1163 IXMLDOMDocument2_Release(schema); 1164 IXMLDOMSchemaCollection_Release(cache); 1165 1166 free_bstrs(); 1167 } 1168 1169 typedef struct { 1170 const char *query; 1171 enum VARENUM type_schema; 1172 const char *typename; 1173 BOOL todo; 1174 } xdr_datatypes; 1175 1176 static const xdr_datatypes xdr_datatypes_data[] = { 1177 { "//Property[Name!text()='testBase64']/Value/base64Data", VT_ARRAY|VT_UI1, "bin.base64" }, 1178 { "//Property[Name!text()='testHex']/Value/hexData", VT_ARRAY|VT_UI1, "bin.hex" }, 1179 { "//Property[Name!text()='testBool']/Value/boolData", VT_BOOL, "boolean" }, 1180 { "//Property[Name!text()='testChar']/Value/charData", VT_I4, "char", TRUE }, 1181 { "//Property[Name!text()='testDate']/Value/dateData", VT_DATE, "date" }, 1182 { "//Property[Name!text()='testDateTime']/Value/dateTimeData", VT_DATE, "dateTime" }, 1183 { "//Property[Name!text()='testDateTimeTz']/Value/dateTimeTzData", VT_DATE, "dateTime.tz" }, 1184 { "//Property[Name!text()='testFixed']/Value/fixedData", VT_CY, "fixed.14.4" }, 1185 { "//Property[Name!text()='testFloat']/Value/floatData", VT_R8, "float" }, 1186 { "//Property[Name!text()='testI1']/Value/i1Data", VT_I1, "i1" }, 1187 { "//Property[Name!text()='testI2']/Value/i2Data", VT_I2, "i2" }, 1188 { "//Property[Name!text()='testI4']/Value/i4Data", VT_I4, "i4" }, 1189 { "//Property[Name!text()='testI8']/Value/i8Data", VT_NULL, "i8", TRUE }, 1190 { "//Property[Name!text()='testInt']/Value/intData", VT_I4, "int" }, 1191 { "//Property[Name!text()='testNmtoken']/Value/nmtokData", VT_BSTR, NULL }, 1192 { "//Property[Name!text()='testNmtokens']/Value/nmtoksData", VT_BSTR, NULL }, 1193 { "//Property[Name!text()='testNumber']/Value/numData", VT_BSTR, "number" }, 1194 { "//Property[Name!text()='testR4']/Value/r4Data", VT_R4, "r4" }, 1195 { "//Property[Name!text()='testR8']/Value/r8Data", VT_R8, "r8" }, 1196 { "//Property[Name!text()='testString']/Value/stringData", VT_BSTR, NULL }, 1197 { "//Property[Name!text()='testTime']/Value/timeData", VT_DATE, "time" }, 1198 { "//Property[Name!text()='testTimeTz']/Value/timeTzData", VT_DATE, "time.tz" }, 1199 { "//Property[Name!text()='testU1']/Value/u1Data", VT_UI1, "ui1" }, 1200 { "//Property[Name!text()='testU2']/Value/u2Data", VT_UI2, "ui2" }, 1201 { "//Property[Name!text()='testU4']/Value/u4Data", VT_UI4, "ui4" }, 1202 { "//Property[Name!text()='testU8']/Value/u8Data", VT_NULL, "ui8", TRUE }, 1203 { "//Property[Name!text()='testURI']/Value/uriData", VT_BSTR, "uri" }, 1204 { "//Property[Name!text()='testUUID']/Value/uuidData", VT_BSTR, "uuid" }, 1205 { NULL } 1206 }; 1207 1208 static void test_XDR_datatypes(void) 1209 { 1210 IXMLDOMDocument2 *doc, *schema, *doc2; 1211 IXMLDOMSchemaCollection* cache; 1212 const xdr_datatypes *ptr; 1213 IXMLDOMParseError* err; 1214 VARIANT_BOOL b; 1215 HRESULT hr; 1216 VARIANT v; 1217 BSTR bstr; 1218 LONG l; 1219 1220 VariantInit(&v); 1221 1222 doc = create_document(&IID_IXMLDOMDocument2); 1223 doc2 = create_document(&IID_IXMLDOMDocument2); 1224 schema = create_document(&IID_IXMLDOMDocument2); 1225 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1226 1227 if (!doc || !doc2 || !schema || !cache) 1228 { 1229 if (doc) IXMLDOMDocument2_Release(doc); 1230 if (doc2) IXMLDOMDocument2_Release(doc2); 1231 if (schema) IXMLDOMDocument2_Release(schema); 1232 if (cache) IXMLDOMSchemaCollection_Release(cache); 1233 return; 1234 } 1235 1236 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szDatatypeXML), &b); 1237 EXPECT_HR(hr, S_OK); 1238 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1239 1240 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(szDatatypeXML), &b); 1241 EXPECT_HR(hr, S_OK); 1242 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1243 1244 hr = IXMLDOMDocument2_loadXML(schema, _bstr_(szDatatypeXDR), &b); 1245 EXPECT_HR(hr, S_OK); 1246 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1247 1248 err = NULL; 1249 hr = IXMLDOMDocument2_validate(doc, &err); 1250 EXPECT_HR(hr, S_FALSE); 1251 ok(err != NULL, "domdoc_validate() should always set err\n"); 1252 hr = IXMLDOMParseError_get_errorCode(err, &l); 1253 EXPECT_HR(hr, S_OK); 1254 ok(l == E_XML_NODTD, "got %08x\n", l); 1255 IXMLDOMParseError_Release(err); 1256 1257 err = NULL; 1258 hr = IXMLDOMDocument2_validate(doc2, &err); 1259 EXPECT_HR(hr, S_FALSE); 1260 ok(err != NULL, "domdoc_validate() should always set err\n"); 1261 hr = IXMLDOMParseError_get_errorCode(err, &l); 1262 EXPECT_HR(hr, S_OK); 1263 ok(l == E_XML_NODTD, "got %08x\n", l); 1264 IXMLDOMParseError_Release(err); 1265 1266 /* now load the schema */ 1267 V_VT(&v) = VT_DISPATCH; 1268 V_DISPATCH(&v) = NULL; 1269 hr = IXMLDOMDocument2_QueryInterface(schema, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 1270 EXPECT_HR(hr, S_OK); 1271 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1272 hr = IXMLDOMSchemaCollection_add(cache, _bstr_("urn:x-schema:datatype-test-xdr"), v); 1273 EXPECT_HR(hr, S_OK); 1274 VariantClear(&v); 1275 1276 /* associate the cache to the doc */ 1277 V_VT(&v) = VT_DISPATCH; 1278 V_DISPATCH(&v) = NULL; 1279 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 1280 EXPECT_HR(hr, S_OK); 1281 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1282 hr = IXMLDOMDocument2_putref_schemas(doc2, v); 1283 EXPECT_HR(hr, S_OK); 1284 VariantClear(&v); 1285 1286 /* validate the doc */ 1287 err = NULL; 1288 l = 0; 1289 bstr = NULL; 1290 hr = IXMLDOMDocument2_validate(doc2, &err); 1291 EXPECT_HR(hr, S_OK); 1292 ok(err != NULL, "domdoc_validate() should always set err\n"); 1293 hr = IXMLDOMParseError_get_errorCode(err, &l); 1294 EXPECT_HR(hr, S_FALSE); 1295 hr = IXMLDOMParseError_get_reason(err, &bstr); 1296 EXPECT_HR(hr, S_FALSE); 1297 ok(l == 0, "got %08x : %s\n", l, wine_dbgstr_w(bstr)); 1298 SysFreeString(bstr); 1299 IXMLDOMParseError_Release(err); 1300 1301 ptr = xdr_datatypes_data; 1302 while (ptr->query) 1303 { 1304 IXMLDOMNode* node = NULL; 1305 VARIANT type; 1306 1307 /* check data types without the schema */ 1308 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_(ptr->query), &node); 1309 EXPECT_HR(hr, S_OK); 1310 ok(node != NULL, "expected node\n"); 1311 1312 V_VT(&type) = VT_EMPTY; 1313 V_BSTR(&type) = (void*)-1; 1314 hr = IXMLDOMNode_get_dataType(node, &type); 1315 EXPECT_HR(hr, S_FALSE); 1316 ok(V_VT(&type) == VT_NULL, "got type %i\n", V_VT(&type)); 1317 /* when returning VT_NULL, the pointer is set to NULL */ 1318 ok(V_BSTR(&type) == NULL, "got %p\n", V_BSTR(&type)); 1319 1320 VariantClear(&type); 1321 hr = IXMLDOMNode_get_nodeTypedValue(node, &type); 1322 EXPECT_HR(hr, S_OK); 1323 ok(V_VT(&type) == VT_BSTR, "got variant type %i\n", V_VT(&v)); 1324 VariantClear(&type); 1325 IXMLDOMNode_Release(node); 1326 1327 /* check the data with schema */ 1328 node = NULL; 1329 hr = IXMLDOMDocument2_selectSingleNode(doc2, _bstr_(ptr->query), &node); 1330 EXPECT_HR(hr, S_OK); 1331 ok(node != NULL, "expected node\n"); 1332 1333 V_VT(&type) = VT_EMPTY; 1334 hr = IXMLDOMNode_get_dataType(node, &type); 1335 if (ptr->typename) 1336 { 1337 EXPECT_HR(hr, S_OK); 1338 ok(V_VT(&type) == VT_BSTR, "got type %i\n", V_VT(&type)); 1339 ok(!lstrcmpW(V_BSTR(&type), _bstr_(ptr->typename)), "got %s\n", wine_dbgstr_w(V_BSTR(&type))); 1340 } 1341 else 1342 { 1343 EXPECT_HR(hr, S_FALSE); 1344 ok(V_VT(&type) == VT_NULL, "%s: got type %i\n", ptr->query, V_VT(&type)); 1345 } 1346 VariantClear(&type); 1347 1348 VariantClear(&v); 1349 hr = IXMLDOMNode_get_nodeTypedValue(node, &v); 1350 EXPECT_HR(hr, S_OK); 1351 1352 todo_wine_if(ptr->todo) 1353 ok(V_VT(&v) == ptr->type_schema, "%s: got variant type %i\n", ptr->query, V_VT(&v)); 1354 1355 switch (ptr->type_schema) 1356 { 1357 case VT_BOOL: 1358 ok(V_BOOL(&v) == VARIANT_TRUE, "got %x\n", V_BOOL(&v)); 1359 break; 1360 case VT_I1: 1361 ok(V_I1(&v) == 42, "got %i\n", V_I1(&v)); 1362 break; 1363 case VT_I2: 1364 ok(V_I2(&v) == 420, "got %i\n", V_I2(&v)); 1365 break; 1366 case VT_I4: 1367 if (!strcmp(ptr->typename, "int")) 1368 ok(V_I4(&v) == 42, "got %i\n", V_I4(&v)); 1369 else if (!strcmp(ptr->typename, "char")) 1370 todo_wine 1371 ok(V_I4(&v) == 'u', "got %x\n", V_I4(&v)); 1372 else 1373 ok(V_I4(&v) == -420000000, "got %i\n", V_I4(&v)); 1374 break; 1375 case VT_I8: 1376 expect_int64(V_I8(&v), -4200000000, 10); 1377 break; 1378 case VT_R4: 1379 ok(V_R4(&v) == (float)3.14159265, "got %f\n", V_R4(&v)); 1380 break; 1381 case VT_R8: 1382 if (!strcmp(ptr->typename, "float")) 1383 ok(V_R8(&v) == 3.14159, "got %f\n", V_R8(&v)); 1384 else 1385 todo_wine 1386 ok(V_R8(&v) == 3.14159265358979323846, "got %.20f\n", V_R8(&v)); 1387 break; 1388 case VT_UI1: 1389 ok(V_UI1(&v) == 0xFF, "got %02x\n", V_UI1(&v)); 1390 break; 1391 case VT_UI2: 1392 ok(V_UI2(&v) == 0xFFFF, "got %04x\n", V_UI2(&v)); 1393 break; 1394 case VT_UI4: 1395 ok(V_UI4(&v) == 0xFFFFFFFF, "got %08x\n", V_UI4(&v)); 1396 break; 1397 case VT_UI8: 1398 expect_uint64(V_UI8(&v), 0xFFFFFFFFFFFFFFFF, 16); 1399 break; 1400 default: 1401 ; 1402 } 1403 1404 VariantClear(&v); 1405 1406 IXMLDOMNode_Release(node); 1407 1408 ptr++; 1409 } 1410 1411 IXMLDOMDocument2_Release(schema); 1412 IXMLDOMDocument2_Release(doc); 1413 IXMLDOMDocument2_Release(doc2); 1414 IXMLDOMSchemaCollection_Release(cache); 1415 1416 free_bstrs(); 1417 } 1418 1419 static void test_validate_on_load(void) 1420 { 1421 IXMLDOMSchemaCollection2 *cache; 1422 VARIANT_BOOL b; 1423 HRESULT hr; 1424 1425 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1426 if (!cache) return; 1427 1428 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, NULL); 1429 EXPECT_HR(hr, E_POINTER); 1430 1431 b = VARIANT_FALSE; 1432 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, &b); 1433 EXPECT_HR(hr, S_OK); 1434 ok(b == VARIANT_TRUE, "got %d\n", b); 1435 1436 IXMLDOMSchemaCollection2_Release(cache); 1437 } 1438 1439 static void test_obj_dispex(IUnknown *obj) 1440 { 1441 static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0}; 1442 static const WCHAR starW[] = {'*',0}; 1443 DISPID dispid = DISPID_SAX_XMLREADER_GETFEATURE; 1444 IDispatchEx *dispex; 1445 IUnknown *unk; 1446 DWORD props; 1447 UINT ticnt; 1448 HRESULT hr; 1449 BSTR name; 1450 1451 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex); 1452 EXPECT_HR(hr, S_OK); 1453 if (FAILED(hr)) return; 1454 1455 ticnt = 0; 1456 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); 1457 EXPECT_HR(hr, S_OK); 1458 ok(ticnt == 1, "ticnt=%u\n", ticnt); 1459 1460 name = SysAllocString(starW); 1461 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive); 1462 EXPECT_HR(hr, E_NOTIMPL); 1463 SysFreeString(name); 1464 1465 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid); 1466 EXPECT_HR(hr, E_NOTIMPL); 1467 1468 props = 0; 1469 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props); 1470 EXPECT_HR(hr, E_NOTIMPL); 1471 ok(props == 0, "expected 0 got %d\n", props); 1472 1473 hr = IDispatchEx_GetMemberName(dispex, dispid, &name); 1474 EXPECT_HR(hr, E_NOTIMPL); 1475 if (SUCCEEDED(hr)) SysFreeString(name); 1476 1477 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_SCHEMACOLLECTION_ADD, &dispid); 1478 EXPECT_HR(hr, E_NOTIMPL); 1479 1480 unk = (IUnknown*)0xdeadbeef; 1481 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk); 1482 EXPECT_HR(hr, E_NOTIMPL); 1483 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk); 1484 1485 name = SysAllocString(testW); 1486 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid); 1487 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); 1488 SysFreeString(name); 1489 1490 IDispatchEx_Release(dispex); 1491 } 1492 1493 static void test_dispex(void) 1494 { 1495 IXMLDOMSchemaCollection *cache; 1496 IDispatchEx *dispex; 1497 IUnknown *unk; 1498 HRESULT hr; 1499 DISPPARAMS dispparams; 1500 VARIANT arg, ret; 1501 1502 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1503 if (!cache) return; 1504 1505 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IUnknown, (void**)&unk); 1506 EXPECT_HR(hr, S_OK); 1507 test_obj_dispex(unk); 1508 IUnknown_Release(unk); 1509 1510 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatchEx, (void**)&dispex); 1511 ok(hr == S_OK, "got 0x%08x\n", hr); 1512 1513 V_VT(&arg) = VT_I4; 1514 V_I4(&arg) = 0; 1515 dispparams.cArgs = 1; 1516 dispparams.cNamedArgs = 0; 1517 dispparams.rgdispidNamedArgs = NULL; 1518 dispparams.rgvarg = &arg; 1519 1520 V_VT(&ret) = VT_EMPTY; 1521 V_DISPATCH(&ret) = (void*)0x1; 1522 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 1523 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr); 1524 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 1525 ok(V_DISPATCH(&ret) == (void*)0x1, "got %p\n", V_DISPATCH(&ret)); 1526 1527 IDispatchEx_Release(dispex); 1528 IXMLDOMSchemaCollection_Release(cache); 1529 1530 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection); 1531 if (cache) 1532 { 1533 test_obj_dispex((IUnknown*)cache); 1534 IXMLDOMSchemaCollection_Release(cache); 1535 } 1536 } 1537 1538 static void test_get(void) 1539 { 1540 IXMLDOMSchemaCollection2 *cache; 1541 IXMLDOMNode *node; 1542 HRESULT hr; 1543 1544 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1545 if (!cache) return; 1546 1547 hr = IXMLDOMSchemaCollection2_get(cache, NULL, NULL); 1548 ok(hr == E_NOTIMPL || hr == E_POINTER /* win8 */, "got %08x\n", hr); 1549 1550 hr = IXMLDOMSchemaCollection2_get(cache, _bstr_("uri"), &node); 1551 EXPECT_HR(hr, E_NOTIMPL); 1552 1553 IXMLDOMSchemaCollection2_Release(cache); 1554 1555 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1556 if (!cache) return; 1557 1558 hr = IXMLDOMSchemaCollection2_get(cache, NULL, NULL); 1559 EXPECT_HR(hr, E_POINTER); 1560 1561 hr = IXMLDOMSchemaCollection2_get(cache, _bstr_("uri"), &node); 1562 EXPECT_HR(hr, S_OK); 1563 1564 IXMLDOMSchemaCollection2_Release(cache); 1565 free_bstrs(); 1566 } 1567 1568 static void test_remove(void) 1569 { 1570 IXMLDOMSchemaCollection2 *cache; 1571 IXMLDOMDocument *doc; 1572 VARIANT_BOOL b; 1573 HRESULT hr; 1574 VARIANT v; 1575 LONG len; 1576 1577 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1578 if (!cache) return; 1579 1580 doc = create_document_version(60, &IID_IXMLDOMDocument); 1581 ok(doc != NULL, "got %p\n", doc); 1582 1583 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsd_schema1_xml), &b); 1584 EXPECT_HR(hr, S_OK); 1585 1586 V_VT(&v) = VT_DISPATCH; 1587 V_DISPATCH(&v) = (IDispatch*)doc; 1588 hr = IXMLDOMSchemaCollection2_add(cache, _bstr_(xsd_schema1_uri), v); 1589 EXPECT_HR(hr, S_OK); 1590 1591 len = -1; 1592 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1593 EXPECT_HR(hr, S_OK); 1594 ok(len == 1, "got %d\n", len); 1595 1596 /* ::remove() is a stub for version 6 */ 1597 hr = IXMLDOMSchemaCollection2_remove(cache, NULL); 1598 EXPECT_HR(hr, E_NOTIMPL); 1599 1600 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_("invaliduri")); 1601 EXPECT_HR(hr, E_NOTIMPL); 1602 1603 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(xsd_schema1_uri)); 1604 EXPECT_HR(hr, E_NOTIMPL); 1605 1606 len = -1; 1607 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1608 EXPECT_HR(hr, S_OK); 1609 ok(len == 1, "got %d\n", len); 1610 1611 IXMLDOMDocument_Release(doc); 1612 IXMLDOMSchemaCollection2_Release(cache); 1613 free_bstrs(); 1614 1615 /* ::remove() works for version 4 */ 1616 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1617 if (!cache) return; 1618 1619 doc = create_document_version(40, &IID_IXMLDOMDocument); 1620 ok(doc != NULL, "got %p\n", doc); 1621 1622 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsd_schema1_xml), &b); 1623 EXPECT_HR(hr, S_OK); 1624 1625 V_VT(&v) = VT_DISPATCH; 1626 V_DISPATCH(&v) = (IDispatch*)doc; 1627 hr = IXMLDOMSchemaCollection2_add(cache, _bstr_(xsd_schema1_uri), v); 1628 EXPECT_HR(hr, S_OK); 1629 1630 len = -1; 1631 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1632 EXPECT_HR(hr, S_OK); 1633 ok(len == 1, "got %d\n", len); 1634 1635 hr = IXMLDOMSchemaCollection2_remove(cache, NULL); 1636 EXPECT_HR(hr, S_OK); 1637 1638 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_("invaliduri")); 1639 EXPECT_HR(hr, S_OK); 1640 1641 len = -1; 1642 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1643 EXPECT_HR(hr, S_OK); 1644 ok(len == 1, "got %d\n", len); 1645 1646 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(xsd_schema1_uri)); 1647 EXPECT_HR(hr, S_OK); 1648 1649 len = -1; 1650 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1651 EXPECT_HR(hr, S_OK); 1652 ok(len == 0, "got %d\n", len); 1653 1654 IXMLDOMDocument_Release(doc); 1655 IXMLDOMSchemaCollection2_Release(cache); 1656 1657 free_bstrs(); 1658 } 1659 1660 static void test_ifaces(void) 1661 { 1662 IXMLDOMSchemaCollection2 *cache; 1663 IUnknown *unk; 1664 HRESULT hr; 1665 1666 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1667 if (!cache) return; 1668 1669 /* CLSID_XMLSchemaCache60 is returned as an interface (the same as IXMLDOMSchemaCollection2). */ 1670 hr = IXMLDOMSchemaCollection2_QueryInterface(cache, &CLSID_XMLSchemaCache60, (void**)&unk); 1671 ok (hr == S_OK, "Could not get CLSID_XMLSchemaCache60 iface: %08x\n", hr); 1672 ok (unk == (IUnknown*)cache, "unk != cache\n"); 1673 1674 IUnknown_Release(unk); 1675 IXMLDOMSchemaCollection2_Release(cache); 1676 } 1677 1678 START_TEST(schema) 1679 { 1680 HRESULT r; 1681 1682 r = CoInitialize( NULL ); 1683 ok( r == S_OK, "failed to init com\n"); 1684 1685 test_schema_refs(); 1686 test_collection_refs(); 1687 test_length(); 1688 test_collection_content(); 1689 test_XDR_schemas(); 1690 test_XDR_datatypes(); 1691 test_validate_on_load(); 1692 test_dispex(); 1693 test_get(); 1694 test_remove(); 1695 test_ifaces(); 1696 1697 CoUninitialize(); 1698 } 1699