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 BOOL todo; 1136 }; 1137 1138 struct regex_test tests[] = { 1139 { L"\\!", L"!", TRUE }, 1140 { L"\\\"", L"\"", TRUE }, 1141 { L"\\#", L"#", TRUE }, 1142 { L"\\$", L"$", TRUE }, 1143 { L"\\%", L"%", TRUE }, 1144 { L"\\,", L",", TRUE }, 1145 { L"\\/", L"/", TRUE }, 1146 { L"\\:", L":", TRUE }, 1147 { L"\\;", L";", TRUE }, 1148 { L"\\=", L"=", TRUE }, 1149 { L"\\>", L">", TRUE }, 1150 { L"\\@", L"@", TRUE }, 1151 { L"\\`", L"`", TRUE }, 1152 { L"\\~", L"~", TRUE }, 1153 { L"\\uCAFE", L"\xCAFE", TRUE }, 1154 /* non-BMP character in surrogate pairs: */ 1155 { L"\\uD83D\\uDE00", L"\xD83D\xDE00", TRUE } 1156 }; 1157 1158 int i; 1159 1160 for (i = 0; i < ARRAY_SIZE(tests); i++) 1161 { 1162 IXMLDOMDocument2 *doc40, *doc60; 1163 IXMLDOMDocument2 *schema40, *schema60; 1164 IXMLDOMSchemaCollection *cache40, *cache60; 1165 1166 doc40 = create_document_version(40, &IID_IXMLDOMDocument2); 1167 doc60 = create_document_version(60, &IID_IXMLDOMDocument2); 1168 schema40 = create_document_version(40, &IID_IXMLDOMDocument2); 1169 schema60 = create_document_version(60, &IID_IXMLDOMDocument2); 1170 cache40 = create_cache_version(40, &IID_IXMLDOMSchemaCollection); 1171 cache60 = create_cache_version(60, &IID_IXMLDOMSchemaCollection); 1172 1173 if (doc60 && schema60 && cache60) 1174 { 1175 HRESULT hr = validate_regex_document(doc60, schema60, cache60, tests[i].regex, tests[i].input); 1176 todo_wine_if(tests[i].todo) 1177 ok(hr == S_OK, "got 0x%08x 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 todo_wine_if(tests[i].todo) 1183 ok(hr == S_OK, "got 0x%08x for version 40 regex %s input %s\n", 1184 hr, wine_dbgstr_w(tests[i].regex), wine_dbgstr_w(tests[i].input)); 1185 } 1186 } 1187 else 1188 ok(0, "out of memory\n"); 1189 1190 if (doc40) 1191 IXMLDOMDocument2_Release(doc40); 1192 if (doc60) 1193 IXMLDOMDocument2_Release(doc60); 1194 if (schema40) 1195 IXMLDOMDocument2_Release(schema40); 1196 if (schema60) 1197 IXMLDOMDocument2_Release(schema60); 1198 if (cache40) 1199 IXMLDOMSchemaCollection_Release(cache40); 1200 if (cache60) 1201 IXMLDOMSchemaCollection_Release(cache60); 1202 } 1203 } 1204 1205 static void test_XDR_schemas(void) 1206 { 1207 IXMLDOMDocument2 *doc, *schema; 1208 IXMLDOMSchemaCollection* cache; 1209 IXMLDOMParseError* err; 1210 VARIANT_BOOL b; 1211 VARIANT v; 1212 BSTR bstr; 1213 1214 doc = create_document(&IID_IXMLDOMDocument2); 1215 schema = create_document(&IID_IXMLDOMDocument2); 1216 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1217 1218 if (!doc || !schema || !cache) 1219 { 1220 if (doc) IXMLDOMDocument2_Release(doc); 1221 if (schema) IXMLDOMDocument2_Release(schema); 1222 if (cache) IXMLDOMSchemaCollection_Release(cache); 1223 1224 return; 1225 } 1226 1227 VariantInit(&v); 1228 1229 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML1), &b)); 1230 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1231 1232 ole_check(IXMLDOMDocument2_loadXML(schema, _bstr_(szOpenSeqXDR), &b)); 1233 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1234 1235 /* load the schema */ 1236 V_VT(&v) = VT_DISPATCH; 1237 V_DISPATCH(&v) = NULL; 1238 ole_check(IXMLDOMDocument2_QueryInterface(schema, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1239 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1240 ole_check(IXMLDOMSchemaCollection_add(cache, _bstr_(""), v)); 1241 VariantClear(&v); 1242 1243 /* associate the cache to the doc */ 1244 V_VT(&v) = VT_DISPATCH; 1245 V_DISPATCH(&v) = NULL; 1246 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1247 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1248 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1249 VariantClear(&v); 1250 1251 /* validate the doc 1252 * only declared elements in the declared order 1253 * this is fine */ 1254 err = NULL; 1255 bstr = NULL; 1256 ole_check(IXMLDOMDocument2_validate(doc, &err)); 1257 ok(err != NULL, "domdoc_validate() should always set err\n"); 1258 ole_expect(IXMLDOMParseError_get_reason(err, &bstr), S_FALSE); 1259 ok(IXMLDOMParseError_get_reason(err, &bstr) == S_FALSE, "got error: %s\n", wine_dbgstr_w(bstr)); 1260 SysFreeString(bstr); 1261 IXMLDOMParseError_Release(err); 1262 1263 /* load the next doc */ 1264 IXMLDOMDocument2_Release(doc); 1265 doc = create_document(&IID_IXMLDOMDocument2); 1266 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML2), &b)); 1267 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1268 1269 /* associate the cache to the doc */ 1270 V_VT(&v) = VT_DISPATCH; 1271 V_DISPATCH(&v) = NULL; 1272 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1273 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1274 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1275 VariantClear(&v); 1276 1277 /* validate the doc 1278 * declared elements in the declared order, with an extra declared element at the end 1279 * this is fine */ 1280 err = NULL; 1281 bstr = NULL; 1282 ole_check(IXMLDOMDocument2_validate(doc, &err)); 1283 ok(err != NULL, "domdoc_validate() should always set err\n"); 1284 ole_expect(IXMLDOMParseError_get_reason(err, &bstr), S_FALSE); 1285 ok(IXMLDOMParseError_get_reason(err, &bstr) == S_FALSE, "got error: %s\n", wine_dbgstr_w(bstr)); 1286 SysFreeString(bstr); 1287 IXMLDOMParseError_Release(err); 1288 1289 /* load the next doc */ 1290 IXMLDOMDocument2_Release(doc); 1291 doc = create_document(&IID_IXMLDOMDocument2); 1292 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML3), &b)); 1293 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1294 1295 /* associate the cache to the doc */ 1296 V_VT(&v) = VT_DISPATCH; 1297 V_DISPATCH(&v) = NULL; 1298 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1299 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1300 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1301 VariantClear(&v); 1302 1303 /* validate the doc 1304 * fails, extra elements are only allowed at the end */ 1305 err = NULL; 1306 bstr = NULL; 1307 ole_expect(IXMLDOMDocument2_validate(doc, &err), S_FALSE); 1308 ok(err != NULL, "domdoc_validate() should always set err\n"); 1309 todo_wine ok(IXMLDOMParseError_get_reason(err, &bstr) == S_OK, "got error: %s\n", wine_dbgstr_w(bstr)); 1310 SysFreeString(bstr); 1311 IXMLDOMParseError_Release(err); 1312 1313 /* load the next doc */ 1314 IXMLDOMDocument2_Release(doc); 1315 doc = create_document(&IID_IXMLDOMDocument2); 1316 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szOpenSeqXML4), &b)); 1317 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1318 1319 /* associate the cache to the doc */ 1320 V_VT(&v) = VT_DISPATCH; 1321 V_DISPATCH(&v) = NULL; 1322 ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v))); 1323 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1324 ole_check(IXMLDOMDocument2_putref_schemas(doc, v)); 1325 VariantClear(&v); 1326 1327 /* validate the doc 1328 * fails, undeclared elements are not allowed */ 1329 err = NULL; 1330 bstr = NULL; 1331 ole_expect(IXMLDOMDocument2_validate(doc, &err), S_FALSE); 1332 ok(err != NULL, "domdoc_validate() should always set err\n"); 1333 todo_wine ok(IXMLDOMParseError_get_reason(err, &bstr) == S_OK, "got error: %s\n", wine_dbgstr_w(bstr)); 1334 SysFreeString(bstr); 1335 IXMLDOMParseError_Release(err); 1336 1337 IXMLDOMDocument2_Release(doc); 1338 IXMLDOMDocument2_Release(schema); 1339 IXMLDOMSchemaCollection_Release(cache); 1340 1341 free_bstrs(); 1342 } 1343 1344 typedef struct { 1345 const char *query; 1346 enum VARENUM type_schema; 1347 const char *typename; 1348 BOOL todo; 1349 } xdr_datatypes; 1350 1351 static const xdr_datatypes xdr_datatypes_data[] = { 1352 { "//Property[Name!text()='testBase64']/Value/base64Data", VT_ARRAY|VT_UI1, "bin.base64" }, 1353 { "//Property[Name!text()='testHex']/Value/hexData", VT_ARRAY|VT_UI1, "bin.hex" }, 1354 { "//Property[Name!text()='testBool']/Value/boolData", VT_BOOL, "boolean" }, 1355 { "//Property[Name!text()='testChar']/Value/charData", VT_I4, "char", TRUE }, 1356 { "//Property[Name!text()='testDate']/Value/dateData", VT_DATE, "date" }, 1357 { "//Property[Name!text()='testDateTime']/Value/dateTimeData", VT_DATE, "dateTime" }, 1358 { "//Property[Name!text()='testDateTimeTz']/Value/dateTimeTzData", VT_DATE, "dateTime.tz" }, 1359 { "//Property[Name!text()='testFixed']/Value/fixedData", VT_CY, "fixed.14.4" }, 1360 { "//Property[Name!text()='testFloat']/Value/floatData", VT_R8, "float" }, 1361 { "//Property[Name!text()='testI1']/Value/i1Data", VT_I1, "i1" }, 1362 { "//Property[Name!text()='testI2']/Value/i2Data", VT_I2, "i2" }, 1363 { "//Property[Name!text()='testI4']/Value/i4Data", VT_I4, "i4" }, 1364 { "//Property[Name!text()='testI8']/Value/i8Data", VT_NULL, "i8", TRUE }, 1365 { "//Property[Name!text()='testInt']/Value/intData", VT_I4, "int" }, 1366 { "//Property[Name!text()='testNmtoken']/Value/nmtokData", VT_BSTR, NULL }, 1367 { "//Property[Name!text()='testNmtokens']/Value/nmtoksData", VT_BSTR, NULL }, 1368 { "//Property[Name!text()='testNumber']/Value/numData", VT_BSTR, "number" }, 1369 { "//Property[Name!text()='testR4']/Value/r4Data", VT_R4, "r4" }, 1370 { "//Property[Name!text()='testR8']/Value/r8Data", VT_R8, "r8" }, 1371 { "//Property[Name!text()='testString']/Value/stringData", VT_BSTR, NULL }, 1372 { "//Property[Name!text()='testTime']/Value/timeData", VT_DATE, "time" }, 1373 { "//Property[Name!text()='testTimeTz']/Value/timeTzData", VT_DATE, "time.tz" }, 1374 { "//Property[Name!text()='testU1']/Value/u1Data", VT_UI1, "ui1" }, 1375 { "//Property[Name!text()='testU2']/Value/u2Data", VT_UI2, "ui2" }, 1376 { "//Property[Name!text()='testU4']/Value/u4Data", VT_UI4, "ui4" }, 1377 { "//Property[Name!text()='testU8']/Value/u8Data", VT_NULL, "ui8", TRUE }, 1378 { "//Property[Name!text()='testURI']/Value/uriData", VT_BSTR, "uri" }, 1379 { "//Property[Name!text()='testUUID']/Value/uuidData", VT_BSTR, "uuid" }, 1380 { NULL } 1381 }; 1382 1383 static void test_XDR_datatypes(void) 1384 { 1385 IXMLDOMDocument2 *doc, *schema, *doc2; 1386 IXMLDOMSchemaCollection* cache; 1387 const xdr_datatypes *ptr; 1388 IXMLDOMParseError* err; 1389 VARIANT_BOOL b; 1390 HRESULT hr; 1391 VARIANT v; 1392 BSTR bstr; 1393 LONG l; 1394 1395 VariantInit(&v); 1396 1397 doc = create_document(&IID_IXMLDOMDocument2); 1398 doc2 = create_document(&IID_IXMLDOMDocument2); 1399 schema = create_document(&IID_IXMLDOMDocument2); 1400 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1401 1402 if (!doc || !doc2 || !schema || !cache) 1403 { 1404 if (doc) IXMLDOMDocument2_Release(doc); 1405 if (doc2) IXMLDOMDocument2_Release(doc2); 1406 if (schema) IXMLDOMDocument2_Release(schema); 1407 if (cache) IXMLDOMSchemaCollection_Release(cache); 1408 return; 1409 } 1410 1411 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szDatatypeXML), &b); 1412 EXPECT_HR(hr, S_OK); 1413 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1414 1415 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(szDatatypeXML), &b); 1416 EXPECT_HR(hr, S_OK); 1417 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1418 1419 hr = IXMLDOMDocument2_loadXML(schema, _bstr_(szDatatypeXDR), &b); 1420 EXPECT_HR(hr, S_OK); 1421 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 1422 1423 err = NULL; 1424 hr = IXMLDOMDocument2_validate(doc, &err); 1425 EXPECT_HR(hr, S_FALSE); 1426 ok(err != NULL, "domdoc_validate() should always set err\n"); 1427 hr = IXMLDOMParseError_get_errorCode(err, &l); 1428 EXPECT_HR(hr, S_OK); 1429 ok(l == E_XML_NODTD, "got %08x\n", l); 1430 IXMLDOMParseError_Release(err); 1431 1432 err = NULL; 1433 hr = IXMLDOMDocument2_validate(doc2, &err); 1434 EXPECT_HR(hr, S_FALSE); 1435 ok(err != NULL, "domdoc_validate() should always set err\n"); 1436 hr = IXMLDOMParseError_get_errorCode(err, &l); 1437 EXPECT_HR(hr, S_OK); 1438 ok(l == E_XML_NODTD, "got %08x\n", l); 1439 IXMLDOMParseError_Release(err); 1440 1441 /* now load the schema */ 1442 V_VT(&v) = VT_DISPATCH; 1443 V_DISPATCH(&v) = NULL; 1444 hr = IXMLDOMDocument2_QueryInterface(schema, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 1445 EXPECT_HR(hr, S_OK); 1446 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1447 hr = IXMLDOMSchemaCollection_add(cache, _bstr_("urn:x-schema:datatype-test-xdr"), v); 1448 EXPECT_HR(hr, S_OK); 1449 VariantClear(&v); 1450 1451 /* associate the cache to the doc */ 1452 V_VT(&v) = VT_DISPATCH; 1453 V_DISPATCH(&v) = NULL; 1454 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 1455 EXPECT_HR(hr, S_OK); 1456 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 1457 hr = IXMLDOMDocument2_putref_schemas(doc2, v); 1458 EXPECT_HR(hr, S_OK); 1459 VariantClear(&v); 1460 1461 /* validate the doc */ 1462 err = NULL; 1463 l = 0; 1464 bstr = NULL; 1465 hr = IXMLDOMDocument2_validate(doc2, &err); 1466 EXPECT_HR(hr, S_OK); 1467 ok(err != NULL, "domdoc_validate() should always set err\n"); 1468 hr = IXMLDOMParseError_get_errorCode(err, &l); 1469 EXPECT_HR(hr, S_FALSE); 1470 hr = IXMLDOMParseError_get_reason(err, &bstr); 1471 EXPECT_HR(hr, S_FALSE); 1472 ok(l == 0, "got %08x : %s\n", l, wine_dbgstr_w(bstr)); 1473 SysFreeString(bstr); 1474 IXMLDOMParseError_Release(err); 1475 1476 ptr = xdr_datatypes_data; 1477 while (ptr->query) 1478 { 1479 IXMLDOMNode* node = NULL; 1480 VARIANT type; 1481 1482 /* check data types without the schema */ 1483 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_(ptr->query), &node); 1484 EXPECT_HR(hr, S_OK); 1485 ok(node != NULL, "expected node\n"); 1486 1487 V_VT(&type) = VT_EMPTY; 1488 V_BSTR(&type) = (void*)-1; 1489 hr = IXMLDOMNode_get_dataType(node, &type); 1490 EXPECT_HR(hr, S_FALSE); 1491 ok(V_VT(&type) == VT_NULL, "got type %i\n", V_VT(&type)); 1492 /* when returning VT_NULL, the pointer is set to NULL */ 1493 ok(V_BSTR(&type) == NULL, "got %p\n", V_BSTR(&type)); 1494 1495 VariantClear(&type); 1496 hr = IXMLDOMNode_get_nodeTypedValue(node, &type); 1497 EXPECT_HR(hr, S_OK); 1498 ok(V_VT(&type) == VT_BSTR, "got variant type %i\n", V_VT(&v)); 1499 VariantClear(&type); 1500 IXMLDOMNode_Release(node); 1501 1502 /* check the data with schema */ 1503 node = NULL; 1504 hr = IXMLDOMDocument2_selectSingleNode(doc2, _bstr_(ptr->query), &node); 1505 EXPECT_HR(hr, S_OK); 1506 ok(node != NULL, "expected node\n"); 1507 1508 V_VT(&type) = VT_EMPTY; 1509 hr = IXMLDOMNode_get_dataType(node, &type); 1510 if (ptr->typename) 1511 { 1512 EXPECT_HR(hr, S_OK); 1513 ok(V_VT(&type) == VT_BSTR, "got type %i\n", V_VT(&type)); 1514 ok(!lstrcmpW(V_BSTR(&type), _bstr_(ptr->typename)), "got %s\n", wine_dbgstr_w(V_BSTR(&type))); 1515 } 1516 else 1517 { 1518 EXPECT_HR(hr, S_FALSE); 1519 ok(V_VT(&type) == VT_NULL, "%s: got type %i\n", ptr->query, V_VT(&type)); 1520 } 1521 VariantClear(&type); 1522 1523 VariantClear(&v); 1524 hr = IXMLDOMNode_get_nodeTypedValue(node, &v); 1525 EXPECT_HR(hr, S_OK); 1526 1527 todo_wine_if(ptr->todo) 1528 ok(V_VT(&v) == ptr->type_schema, "%s: got variant type %i\n", ptr->query, V_VT(&v)); 1529 1530 switch (ptr->type_schema) 1531 { 1532 case VT_BOOL: 1533 ok(V_BOOL(&v) == VARIANT_TRUE, "got %x\n", V_BOOL(&v)); 1534 break; 1535 case VT_I1: 1536 ok(V_I1(&v) == 42, "got %i\n", V_I1(&v)); 1537 break; 1538 case VT_I2: 1539 ok(V_I2(&v) == 420, "got %i\n", V_I2(&v)); 1540 break; 1541 case VT_I4: 1542 if (!strcmp(ptr->typename, "int")) 1543 ok(V_I4(&v) == 42, "got %i\n", V_I4(&v)); 1544 else if (!strcmp(ptr->typename, "char")) 1545 todo_wine 1546 ok(V_I4(&v) == 'u', "got %x\n", V_I4(&v)); 1547 else 1548 ok(V_I4(&v) == -420000000, "got %i\n", V_I4(&v)); 1549 break; 1550 case VT_I8: 1551 expect_int64(V_I8(&v), -4200000000, 10); 1552 break; 1553 case VT_R4: 1554 ok(V_R4(&v) == (float)3.14159265, "got %f\n", V_R4(&v)); 1555 break; 1556 case VT_R8: 1557 if (!strcmp(ptr->typename, "float")) 1558 ok(V_R8(&v) == 3.14159, "got %f\n", V_R8(&v)); 1559 else 1560 todo_wine 1561 ok(V_R8(&v) == 3.14159265358979323846, "got %.20f\n", V_R8(&v)); 1562 break; 1563 case VT_UI1: 1564 ok(V_UI1(&v) == 0xFF, "got %02x\n", V_UI1(&v)); 1565 break; 1566 case VT_UI2: 1567 ok(V_UI2(&v) == 0xFFFF, "got %04x\n", V_UI2(&v)); 1568 break; 1569 case VT_UI4: 1570 ok(V_UI4(&v) == 0xFFFFFFFF, "got %08x\n", V_UI4(&v)); 1571 break; 1572 case VT_UI8: 1573 expect_uint64(V_UI8(&v), 0xFFFFFFFFFFFFFFFF, 16); 1574 break; 1575 default: 1576 ; 1577 } 1578 1579 VariantClear(&v); 1580 1581 IXMLDOMNode_Release(node); 1582 1583 ptr++; 1584 } 1585 1586 IXMLDOMDocument2_Release(schema); 1587 IXMLDOMDocument2_Release(doc); 1588 IXMLDOMDocument2_Release(doc2); 1589 IXMLDOMSchemaCollection_Release(cache); 1590 1591 free_bstrs(); 1592 } 1593 1594 static void test_validate_on_load(void) 1595 { 1596 IXMLDOMSchemaCollection2 *cache; 1597 VARIANT_BOOL b; 1598 HRESULT hr; 1599 1600 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1601 if (!cache) return; 1602 1603 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, NULL); 1604 EXPECT_HR(hr, E_POINTER); 1605 1606 b = VARIANT_FALSE; 1607 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, &b); 1608 EXPECT_HR(hr, S_OK); 1609 ok(b == VARIANT_TRUE, "got %d\n", b); 1610 1611 IXMLDOMSchemaCollection2_Release(cache); 1612 } 1613 1614 static void test_obj_dispex(IUnknown *obj) 1615 { 1616 DISPID dispid = DISPID_SAX_XMLREADER_GETFEATURE; 1617 IDispatchEx *dispex; 1618 IUnknown *unk; 1619 DWORD props; 1620 UINT ticnt; 1621 HRESULT hr; 1622 BSTR name; 1623 1624 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex); 1625 EXPECT_HR(hr, S_OK); 1626 if (FAILED(hr)) return; 1627 1628 ticnt = 0; 1629 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); 1630 EXPECT_HR(hr, S_OK); 1631 ok(ticnt == 1, "ticnt=%u\n", ticnt); 1632 1633 name = SysAllocString(L"*"); 1634 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive); 1635 EXPECT_HR(hr, E_NOTIMPL); 1636 SysFreeString(name); 1637 1638 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid); 1639 EXPECT_HR(hr, E_NOTIMPL); 1640 1641 props = 0; 1642 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props); 1643 EXPECT_HR(hr, E_NOTIMPL); 1644 ok(props == 0, "expected 0 got %d\n", props); 1645 1646 hr = IDispatchEx_GetMemberName(dispex, dispid, &name); 1647 EXPECT_HR(hr, E_NOTIMPL); 1648 if (SUCCEEDED(hr)) SysFreeString(name); 1649 1650 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_SCHEMACOLLECTION_ADD, &dispid); 1651 EXPECT_HR(hr, E_NOTIMPL); 1652 1653 unk = (IUnknown*)0xdeadbeef; 1654 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk); 1655 EXPECT_HR(hr, E_NOTIMPL); 1656 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk); 1657 1658 name = SysAllocString(L"testprop"); 1659 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid); 1660 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); 1661 SysFreeString(name); 1662 1663 IDispatchEx_Release(dispex); 1664 } 1665 1666 static void test_dispex(void) 1667 { 1668 IXMLDOMSchemaCollection *cache; 1669 IDispatchEx *dispex; 1670 IUnknown *unk; 1671 HRESULT hr; 1672 DISPPARAMS dispparams; 1673 VARIANT arg, ret; 1674 1675 cache = create_cache(&IID_IXMLDOMSchemaCollection); 1676 if (!cache) return; 1677 1678 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IUnknown, (void**)&unk); 1679 EXPECT_HR(hr, S_OK); 1680 test_obj_dispex(unk); 1681 IUnknown_Release(unk); 1682 1683 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatchEx, (void**)&dispex); 1684 ok(hr == S_OK, "got 0x%08x\n", hr); 1685 1686 V_VT(&arg) = VT_I4; 1687 V_I4(&arg) = 0; 1688 dispparams.cArgs = 1; 1689 dispparams.cNamedArgs = 0; 1690 dispparams.rgdispidNamedArgs = NULL; 1691 dispparams.rgvarg = &arg; 1692 1693 V_VT(&ret) = VT_EMPTY; 1694 V_DISPATCH(&ret) = (void*)0x1; 1695 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 1696 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr); 1697 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 1698 ok(V_DISPATCH(&ret) == (void*)0x1, "got %p\n", V_DISPATCH(&ret)); 1699 1700 IDispatchEx_Release(dispex); 1701 IXMLDOMSchemaCollection_Release(cache); 1702 1703 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection); 1704 if (cache) 1705 { 1706 test_obj_dispex((IUnknown*)cache); 1707 IXMLDOMSchemaCollection_Release(cache); 1708 } 1709 } 1710 1711 static void test_get(void) 1712 { 1713 IXMLDOMSchemaCollection2 *cache; 1714 IXMLDOMNode *node; 1715 HRESULT hr; 1716 1717 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1718 if (!cache) return; 1719 1720 hr = IXMLDOMSchemaCollection2_get(cache, NULL, NULL); 1721 ok(hr == E_NOTIMPL || hr == E_POINTER /* win8 */, "got %08x\n", hr); 1722 1723 hr = IXMLDOMSchemaCollection2_get(cache, _bstr_("uri"), &node); 1724 EXPECT_HR(hr, E_NOTIMPL); 1725 1726 IXMLDOMSchemaCollection2_Release(cache); 1727 1728 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1729 if (!cache) return; 1730 1731 hr = IXMLDOMSchemaCollection2_get(cache, NULL, NULL); 1732 EXPECT_HR(hr, E_POINTER); 1733 1734 hr = IXMLDOMSchemaCollection2_get(cache, _bstr_("uri"), &node); 1735 EXPECT_HR(hr, S_OK); 1736 1737 IXMLDOMSchemaCollection2_Release(cache); 1738 free_bstrs(); 1739 } 1740 1741 static void test_remove(void) 1742 { 1743 IXMLDOMSchemaCollection2 *cache; 1744 IXMLDOMDocument *doc; 1745 VARIANT_BOOL b; 1746 HRESULT hr; 1747 VARIANT v; 1748 LONG len; 1749 1750 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1751 if (!cache) return; 1752 1753 doc = create_document_version(60, &IID_IXMLDOMDocument); 1754 ok(doc != NULL, "got %p\n", doc); 1755 1756 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsd_schema1_xml), &b); 1757 EXPECT_HR(hr, S_OK); 1758 1759 V_VT(&v) = VT_DISPATCH; 1760 V_DISPATCH(&v) = (IDispatch*)doc; 1761 hr = IXMLDOMSchemaCollection2_add(cache, _bstr_(xsd_schema1_uri), v); 1762 EXPECT_HR(hr, S_OK); 1763 1764 len = -1; 1765 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1766 EXPECT_HR(hr, S_OK); 1767 ok(len == 1, "got %d\n", len); 1768 1769 /* ::remove() is a stub for version 6 */ 1770 hr = IXMLDOMSchemaCollection2_remove(cache, NULL); 1771 EXPECT_HR(hr, E_NOTIMPL); 1772 1773 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_("invaliduri")); 1774 EXPECT_HR(hr, E_NOTIMPL); 1775 1776 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(xsd_schema1_uri)); 1777 EXPECT_HR(hr, E_NOTIMPL); 1778 1779 len = -1; 1780 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1781 EXPECT_HR(hr, S_OK); 1782 ok(len == 1, "got %d\n", len); 1783 1784 IXMLDOMDocument_Release(doc); 1785 IXMLDOMSchemaCollection2_Release(cache); 1786 free_bstrs(); 1787 1788 /* ::remove() works for version 4 */ 1789 cache = create_cache_version(40, &IID_IXMLDOMSchemaCollection2); 1790 if (!cache) return; 1791 1792 doc = create_document_version(40, &IID_IXMLDOMDocument); 1793 ok(doc != NULL, "got %p\n", doc); 1794 1795 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsd_schema1_xml), &b); 1796 EXPECT_HR(hr, S_OK); 1797 1798 V_VT(&v) = VT_DISPATCH; 1799 V_DISPATCH(&v) = (IDispatch*)doc; 1800 hr = IXMLDOMSchemaCollection2_add(cache, _bstr_(xsd_schema1_uri), v); 1801 EXPECT_HR(hr, S_OK); 1802 1803 len = -1; 1804 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1805 EXPECT_HR(hr, S_OK); 1806 ok(len == 1, "got %d\n", len); 1807 1808 hr = IXMLDOMSchemaCollection2_remove(cache, NULL); 1809 EXPECT_HR(hr, S_OK); 1810 1811 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_("invaliduri")); 1812 EXPECT_HR(hr, S_OK); 1813 1814 len = -1; 1815 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1816 EXPECT_HR(hr, S_OK); 1817 ok(len == 1, "got %d\n", len); 1818 1819 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(xsd_schema1_uri)); 1820 EXPECT_HR(hr, S_OK); 1821 1822 len = -1; 1823 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 1824 EXPECT_HR(hr, S_OK); 1825 ok(len == 0, "got %d\n", len); 1826 1827 IXMLDOMDocument_Release(doc); 1828 IXMLDOMSchemaCollection2_Release(cache); 1829 1830 free_bstrs(); 1831 } 1832 1833 static void test_ifaces(void) 1834 { 1835 IXMLDOMSchemaCollection2 *cache; 1836 IUnknown *unk; 1837 HRESULT hr; 1838 1839 cache = create_cache_version(60, &IID_IXMLDOMSchemaCollection2); 1840 if (!cache) return; 1841 1842 /* CLSID_XMLSchemaCache60 is returned as an interface (the same as IXMLDOMSchemaCollection2). */ 1843 hr = IXMLDOMSchemaCollection2_QueryInterface(cache, &CLSID_XMLSchemaCache60, (void**)&unk); 1844 ok (hr == S_OK, "Could not get CLSID_XMLSchemaCache60 iface: %08x\n", hr); 1845 ok (unk == (IUnknown*)cache, "unk != cache\n"); 1846 1847 IUnknown_Release(unk); 1848 IXMLDOMSchemaCollection2_Release(cache); 1849 } 1850 1851 START_TEST(schema) 1852 { 1853 HRESULT r; 1854 1855 r = CoInitialize( NULL ); 1856 ok( r == S_OK, "failed to init com\n"); 1857 1858 test_schema_refs(); 1859 test_collection_refs(); 1860 test_length(); 1861 test_collection_content(); 1862 test_regex(); 1863 test_XDR_schemas(); 1864 test_XDR_datatypes(); 1865 test_validate_on_load(); 1866 test_dispex(); 1867 test_get(); 1868 test_remove(); 1869 test_ifaces(); 1870 1871 CoUninitialize(); 1872 } 1873