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