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