[MSXML3_WINETEST] Sync with Wine Staging 1.7.47. CORE-9924
[reactos.git] / rostests / winetests / msxml3 / domdoc.c
1 /*
2 * XML test
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2007-2008 Alistair Leslie-Hughes
6 * Copyright 2010-2011 Adam Martinson for CodeWeavers
7 * Copyright 2010-2013 Nikolay Sivov for CodeWeavers
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25 #define WIN32_NO_STATUS
26 #define _INC_WINDOWS
27 #define COM_NO_WINDOWS_H
28
29 #define COBJMACROS
30 #define CONST_VTABLE
31
32 #include <stdio.h>
33 #include <assert.h>
34
35 //#include "windows.h"
36
37 #include <wine/test.h>
38
39 #include <winnls.h>
40 #include <ole2.h>
41 #include <msxml.h>
42 #include <msxml2.h>
43 #include <msxml2did.h>
44 #include <dispex.h>
45 #include <objsafe.h>
46 //#include "initguid.h"
47
48 /* undef the #define in msxml2 so that we can access all versions */
49 #undef CLSID_DOMDocument
50
51 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
52
53 static int g_unexpectedcall, g_expectedcall;
54
55 struct msxmlsupported_data_t
56 {
57 const GUID *clsid;
58 const char *name;
59 const IID *ifaces[3];
60 BOOL supported[3];
61 };
62
63 static struct msxmlsupported_data_t domdoc_support_data[] =
64 {
65 { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
66 { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
67 { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
68 { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
69 { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
70 { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
71 { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
72 { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} },
73 { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
74 { NULL }
75 };
76
77 static const char *debugstr_msxml_guid(REFIID riid)
78 {
79 if(!riid)
80 return "(null)";
81
82 if (IsEqualIID(&IID_IXMLDOMDocument, riid))
83 return "IXMLDOMDocument";
84 else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
85 return "IXMLDOMDocument2";
86 else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
87 return "IXMLDOMDocument3";
88 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
89 return "IXMLDOMSchemaCollection";
90 else if (IsEqualIID(&IID_IXSLTemplate, riid))
91 return "IXSLTemplate";
92 else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
93 return "IMXNamespaceManager";
94 else
95 return wine_dbgstr_guid(riid);
96 }
97
98 static void get_class_support_data(struct msxmlsupported_data_t *table)
99 {
100 while (table->clsid)
101 {
102 IUnknown *unk;
103 HRESULT hr;
104 int i;
105
106 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
107 {
108 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
109 if (hr == S_OK) IUnknown_Release(unk);
110
111 table->supported[i] = hr == S_OK;
112 if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
113 }
114
115 table++;
116 }
117 }
118
119 static BOOL is_clsid_supported(const GUID *clsid, REFIID riid)
120 {
121 const struct msxmlsupported_data_t *table = domdoc_support_data;
122 while (table->clsid)
123 {
124 if (table->clsid == clsid)
125 {
126 int i;
127
128 for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
129 if (table->ifaces[i] == riid) return table->supported[i];
130 }
131
132 table++;
133 }
134 return FALSE;
135 }
136
137 typedef struct
138 {
139 IDispatch IDispatch_iface;
140 LONG ref;
141 } dispevent;
142
143 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
144 {
145 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
146 }
147
148 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
149 {
150 *ppvObject = NULL;
151
152 if ( IsEqualGUID( riid, &IID_IDispatch) ||
153 IsEqualGUID( riid, &IID_IUnknown) )
154 {
155 *ppvObject = iface;
156 }
157 else
158 return E_NOINTERFACE;
159
160 IDispatch_AddRef( iface );
161
162 return S_OK;
163 }
164
165 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
166 {
167 dispevent *This = impl_from_IDispatch( iface );
168 return InterlockedIncrement( &This->ref );
169 }
170
171 static ULONG WINAPI dispevent_Release(IDispatch *iface)
172 {
173 dispevent *This = impl_from_IDispatch( iface );
174 ULONG ref = InterlockedDecrement( &This->ref );
175
176 if (ref == 0)
177 HeapFree(GetProcessHeap(), 0, This);
178
179 return ref;
180 }
181
182 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
183 {
184 g_unexpectedcall++;
185 *pctinfo = 0;
186 return S_OK;
187 }
188
189 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
190 LCID lcid, ITypeInfo **ppTInfo)
191 {
192 g_unexpectedcall++;
193 return S_OK;
194 }
195
196 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
197 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
198 {
199 g_unexpectedcall++;
200 return S_OK;
201 }
202
203 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
204 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
205 EXCEPINFO *excepInfo, UINT *argErr)
206 {
207 ok(member == 0, "expected 0 member, got %d\n", member);
208 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
209 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
210
211 ok(params->cArgs == 0, "got %d\n", params->cArgs);
212 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
213 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
214 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
215
216 ok(result == NULL, "got %p\n", result);
217 ok(excepInfo == NULL, "got %p\n", excepInfo);
218 ok(argErr == NULL, "got %p\n", argErr);
219
220 g_expectedcall++;
221 return E_FAIL;
222 }
223
224 static const IDispatchVtbl dispeventVtbl =
225 {
226 dispevent_QueryInterface,
227 dispevent_AddRef,
228 dispevent_Release,
229 dispevent_GetTypeInfoCount,
230 dispevent_GetTypeInfo,
231 dispevent_GetIDsOfNames,
232 dispevent_Invoke
233 };
234
235 static IDispatch* create_dispevent(void)
236 {
237 dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
238
239 event->IDispatch_iface.lpVtbl = &dispeventVtbl;
240 event->ref = 1;
241
242 return (IDispatch*)&event->IDispatch_iface;
243 }
244
245 /* IStream */
246 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
247 {
248 *ppvObject = NULL;
249
250 if (IsEqualGUID(riid, &IID_IStream) ||
251 IsEqualGUID(riid, &IID_IUnknown))
252 *ppvObject = iface;
253 else
254 return E_NOINTERFACE;
255
256 return S_OK;
257 }
258
259 static ULONG WINAPI istream_AddRef(IStream *iface)
260 {
261 return 2;
262 }
263
264 static ULONG WINAPI istream_Release(IStream *iface)
265 {
266 return 1;
267 }
268
269 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread)
270 {
271 ok(0, "unexpected call\n");
272 return E_NOTIMPL;
273 }
274
275 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written)
276 {
277 *written = len/2;
278 return S_OK;
279 }
280
281 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos)
282 {
283 ok(0, "unexpected call\n");
284 return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size)
288 {
289 ok(0, "unexpected call\n");
290 return E_NOTIMPL;
291 }
292
293 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len,
294 ULARGE_INTEGER *pread, ULARGE_INTEGER *written)
295 {
296 ok(0, "unexpected call\n");
297 return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags)
301 {
302 ok(0, "unexpected call\n");
303 return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI istream_Revert(IStream *iface)
307 {
308 ok(0, "unexpected call\n");
309 return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset,
313 ULARGE_INTEGER len, DWORD locktype)
314 {
315 ok(0, "unexpected call\n");
316 return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
320 ULARGE_INTEGER len, DWORD locktype)
321 {
322 ok(0, "unexpected call\n");
323 return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag)
327 {
328 ok(0, "unexpected call\n");
329 return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream)
333 {
334 ok(0, "unexpected call\n");
335 return E_NOTIMPL;
336 }
337
338 static const IStreamVtbl StreamVtbl = {
339 istream_QueryInterface,
340 istream_AddRef,
341 istream_Release,
342 istream_Read,
343 istream_Write,
344 istream_Seek,
345 istream_SetSize,
346 istream_CopyTo,
347 istream_Commit,
348 istream_Revert,
349 istream_LockRegion,
350 istream_UnlockRegion,
351 istream_Stat,
352 istream_Clone
353 };
354
355 static IStream savestream = { &StreamVtbl };
356
357 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
358 static void _expect_children(IXMLDOMNode *node, int line)
359 {
360 VARIANT_BOOL b;
361 HRESULT hr;
362
363 b = VARIANT_FALSE;
364 hr = IXMLDOMNode_hasChildNodes(node, &b);
365 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
366 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
367 }
368
369 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
370 static void _expect_no_children(IXMLDOMNode *node, int line)
371 {
372 VARIANT_BOOL b;
373 HRESULT hr;
374
375 b = VARIANT_TRUE;
376 hr = IXMLDOMNode_hasChildNodes(node, &b);
377 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
378 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
379 }
380
381 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
382 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
383 {
384 ULONG rc;
385 IUnknown_AddRef(obj);
386 rc = IUnknown_Release(obj);
387 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
388 }
389
390 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
391 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
392 {
393 LONG length;
394 HRESULT hr;
395
396 length = 0;
397 hr = IXMLDOMNodeList_get_length(list, &length);
398 ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
399 ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
400 }
401
402 #define EXPECT_HR(hr,hr_exp) \
403 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
404
405 #define EXPECT_NOT_HR(hr,hr_exp) \
406 ok(hr != hr_exp, "got 0x%08x, expected not 0x%08x\n", hr, hr_exp)
407
408 static const WCHAR szEmpty[] = { 0 };
409 static const WCHAR szIncomplete[] = {
410 '<','?','x','m','l',' ',
411 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
412 };
413 static const WCHAR szComplete1[] = {
414 '<','?','x','m','l',' ',
415 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
416 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
417 };
418 static const WCHAR szComplete2[] = {
419 '<','?','x','m','l',' ',
420 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
421 '<','a','>','<','/','a','>','\n',0
422 };
423 static const char complete4A[] =
424 "<?xml version=\'1.0\'?>\n"
425 "<lc dl=\'str1\'>\n"
426 "<bs vr=\'str2\' sz=\'1234\'>"
427 "fn1.txt\n"
428 "</bs>\n"
429 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
430 "fn2.txt\n"
431 "</pr>\n"
432 "<empty></empty>\n"
433 "<fo>\n"
434 "<ba>\n"
435 "f1\n"
436 "</ba>\n"
437 "</fo>\n"
438 "</lc>\n";
439
440 static const WCHAR szComplete5[] = {
441 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
442 'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
443 ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
444 '<','S',':','s','c','o','p','e','>',
445 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
446 '<','/','S',':','s','c','o','p','e','>',
447 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
448 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
449 'c','o','m','p','u','t','e','r',
450 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
451 '<','/','S',':','s','e','a','r','c','h','>',0
452 };
453
454 static const WCHAR szComplete6[] = {
455 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
456 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
457 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
458 };
459
460 static const char complete7[] = {
461 "<?xml version=\"1.0\"?>\n\t"
462 "<root>\n"
463 "\t<a/>\n"
464 "\t<b/>\n"
465 "\t<c/>\n"
466 "</root>"
467 };
468
469 #define DECL_WIN_1252 \
470 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
471
472 static const char win1252xml[] =
473 DECL_WIN_1252
474 "<open></open>";
475
476 static const char win1252decl[] =
477 DECL_WIN_1252
478 ;
479
480 static const char nocontent[] = "no xml content here";
481
482 static const char szExampleXML[] =
483 "<?xml version='1.0' encoding='utf-8'?>\n"
484 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
485 " <elem>\n"
486 " <a>A1 field</a>\n"
487 " <b>B1 field</b>\n"
488 " <c>C1 field</c>\n"
489 " <d>D1 field</d>\n"
490 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
491 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
492 " This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
493 " </html>\n"
494 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
495 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
496 " </html>\n"
497 " </description>\n"
498 " </elem>\n"
499 "\n"
500 " <elem a='a'>\n"
501 " <a>A2 field</a>\n"
502 " <b>B2 field</b>\n"
503 " <c type=\"old\">C2 field</c>\n"
504 " <d>D2 field</d>\n"
505 " </elem>\n"
506 "\n"
507 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
508 " <a>A3 field</a>\n"
509 " <b>B3 field</b>\n"
510 " <c>C3 field</c>\n"
511 " </elem>\n"
512 "\n"
513 " <elem>\n"
514 " <a>A4 field</a>\n"
515 " <b>B4 field</b>\n"
516 " <foo:c>C4 field</foo:c>\n"
517 " <d>D4 field</d>\n"
518 " </elem>\n"
519 "</root>\n";
520
521 static const char charrefsxml[] =
522 "<?xml version='1.0'?>"
523 "<a>"
524 "<b1> Text &#65; end </b1>"
525 "<b2>&#65;&#66; &#67; </b2>"
526 "</a>";
527
528 static const CHAR szNodeTypesXML[] =
529 "<?xml version='1.0'?>"
530 "<!-- comment node 0 -->"
531 "<root id='0' depth='0'>"
532 " <!-- comment node 1 -->"
533 " text node 0"
534 " <x id='1' depth='1'>"
535 " <?foo value='PI for x'?>"
536 " <!-- comment node 2 -->"
537 " text node 1"
538 " <a id='3' depth='2'/>"
539 " <b id='4' depth='2'/>"
540 " <c id='5' depth='2'/>"
541 " </x>"
542 " <y id='2' depth='1'>"
543 " <?bar value='PI for y'?>"
544 " <!-- comment node 3 -->"
545 " text node 2"
546 " <a id='6' depth='2'/>"
547 " <b id='7' depth='2'/>"
548 " <c id='8' depth='2'/>"
549 " </y>"
550 "</root>";
551
552 static const CHAR szTransformXML[] =
553 "<?xml version=\"1.0\"?>\n"
554 "<greeting>\n"
555 "Hello World\n"
556 "</greeting>";
557
558 static const CHAR szTransformSSXML[] =
559 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
560 " <xsl:output method=\"html\"/>\n"
561 " <xsl:template match=\"/\">\n"
562 " <xsl:apply-templates select=\"greeting\"/>\n"
563 " </xsl:template>\n"
564 " <xsl:template match=\"greeting\">\n"
565 " <html>\n"
566 " <body>\n"
567 " <h1>\n"
568 " <xsl:value-of select=\".\"/>\n"
569 " </h1>\n"
570 " </body>\n"
571 " </html>\n"
572 " </xsl:template>\n"
573 "</xsl:stylesheet>";
574
575 static const CHAR szTransformOutput[] =
576 "<html><body><h1>"
577 "Hello World"
578 "</h1></body></html>";
579
580 static const CHAR szTypeValueXML[] =
581 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
582 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
583 " <string>Wine</string>\n"
584 " <string2 dt:dt=\"string\">String</string2>\n"
585 " <number dt:dt=\"number\">12.44</number>\n"
586 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
587 " <int dt:dt=\"int\">-13</int>\n"
588 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
589 " <bool dt:dt=\"boolean\">1</bool>\n"
590 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
591 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
592 " <date dt:dt=\"date\">3721-11-01</date>\n"
593 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
594 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
595 " <i1 dt:dt=\"i1\">-13</i1>\n"
596 " <i2 dt:dt=\"i2\">31915</i2>\n"
597 " <i4 dt:dt=\"i4\">-312232</i4>\n"
598 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
599 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
600 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
601 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
602 " <r8 dt:dt=\"r8\">0.412</r8>\n"
603 " <float dt:dt=\"float\">41221.421</float>\n"
604 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
605 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
606 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
607 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
608 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
609 "</root>";
610
611 static const CHAR szBasicTransformSSXMLPart1[] =
612 "<?xml version=\"1.0\"?>"
613 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
614 "<xsl:output method=\"html\"/>\n"
615 "<xsl:template match=\"/\">"
616 "<HTML><BODY><TABLE>"
617 " <xsl:apply-templates select='document(\"";
618
619 static const CHAR szBasicTransformSSXMLPart2[] =
620 "\")/bottle/wine'>"
621 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
622 " </xsl:apply-templates>"
623 "</TABLE></BODY></HTML>"
624 "</xsl:template>"
625 "<xsl:template match=\"bottle\">"
626 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
627 "</xsl:template>"
628 "<xsl:template match=\"name\">"
629 " <TD><xsl:apply-templates /></TD>"
630 "</xsl:template>"
631 "<xsl:template match=\"cost\">"
632 " <TD><xsl:apply-templates /></TD>"
633 "</xsl:template>"
634 "</xsl:stylesheet>";
635
636 static const CHAR szBasicTransformXML[] =
637 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
638
639 static const CHAR szBasicTransformOutput[] =
640 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
641
642 #define SZ_EMAIL_DTD \
643 "<!DOCTYPE email ["\
644 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
645 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
646 " <!ATTLIST email sent (yes|no) \"no\">"\
647 " <!ELEMENT recipients (to+,cc*)>"\
648 " <!ELEMENT to (#PCDATA)>"\
649 " <!ATTLIST to name CDATA #IMPLIED>"\
650 " <!ELEMENT cc (#PCDATA)>"\
651 " <!ATTLIST cc name CDATA #IMPLIED>"\
652 " <!ELEMENT from (#PCDATA)>"\
653 " <!ATTLIST from name CDATA #IMPLIED>"\
654 " <!ELEMENT reply-to (#PCDATA)>"\
655 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
656 " <!ELEMENT subject ANY>"\
657 " <!ELEMENT body ANY>"\
658 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
659 " <!ELEMENT attachment (#PCDATA)>"\
660 " <!ATTLIST attachment id ID #REQUIRED>"\
661 "]>"
662
663 static const CHAR szEmailXML[] =
664 "<?xml version=\"1.0\"?>"
665 SZ_EMAIL_DTD
666 "<email attachments=\"patch1\">"
667 " <recipients>"
668 " <to>wine-patches@winehq.org</to>"
669 " </recipients>"
670 " <from name=\"Anonymous\">user@localhost</from>"
671 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
672 " <body>"
673 " It no longer causes spontaneous combustion..."
674 " </body>"
675 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
676 "</email>";
677
678 static const CHAR szEmailXML_0D[] =
679 "<?xml version=\"1.0\"?>"
680 SZ_EMAIL_DTD
681 "<email attachments=\"patch1\">"
682 " <recipients>"
683 " <to>wine-patches@winehq.org</to>"
684 " </recipients>"
685 " <from name=\"Anonymous\">user@localhost</from>"
686 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
687 " <body>"
688 " <undecl />"
689 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
690 " </body>"
691 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
692 "</email>";
693
694 static const CHAR szEmailXML_0E[] =
695 "<?xml version=\"1.0\"?>"
696 SZ_EMAIL_DTD
697 "<email attachments=\"patch1\">"
698 " <recipients>"
699 " <to>wine-patches@winehq.org</to>"
700 " </recipients>"
701 " <from name=\"Anonymous\">user@localhost</from>"
702 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
703 " <body>"
704 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
705 " </body>"
706 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
707 "</email>";
708
709 static const CHAR szEmailXML_11[] =
710 "<?xml version=\"1.0\"?>"
711 SZ_EMAIL_DTD
712 "<email attachments=\"patch1\">"
713 " <recipients>"
714 " </recipients>"
715 " <from name=\"Anonymous\">user@localhost</from>"
716 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
717 " <body>"
718 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
719 " </body>"
720 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
721 "</email>";
722
723 static const CHAR szEmailXML_13[] =
724 "<?xml version=\"1.0\"?>"
725 SZ_EMAIL_DTD
726 "<msg attachments=\"patch1\">"
727 " <recipients>"
728 " <to>wine-patches@winehq.org</to>"
729 " </recipients>"
730 " <from name=\"Anonymous\">user@localhost</from>"
731 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
732 " <body>"
733 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
734 " </body>"
735 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
736 "</msg>";
737
738 static const CHAR szEmailXML_14[] =
739 "<?xml version=\"1.0\"?>"
740 SZ_EMAIL_DTD
741 "<email attachments=\"patch1\">"
742 " <to>wine-patches@winehq.org</to>"
743 " <from name=\"Anonymous\">user@localhost</from>"
744 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
745 " <body>"
746 " XML_INVALID_CONTENT 0xC00CE014"
747 " </body>"
748 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
749 "</email>";
750
751 static const CHAR szEmailXML_15[] =
752 "<?xml version=\"1.0\"?>"
753 SZ_EMAIL_DTD
754 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
755 " <recipients>"
756 " <to>wine-patches@winehq.org</to>"
757 " </recipients>"
758 " <from name=\"Anonymous\">user@localhost</from>"
759 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
760 " <body>"
761 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
762 " </body>"
763 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
764 "</email>";
765
766 static const CHAR szEmailXML_16[] =
767 "<?xml version=\"1.0\"?>"
768 SZ_EMAIL_DTD
769 "<email attachments=\"patch1\">"
770 " <recipients>"
771 " <to>wine-patches@winehq.org</to>"
772 " </recipients>"
773 " <from name=\"Anonymous\">user@localhost</from>"
774 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
775 " <body enc=\"ASCII\">"
776 " XML_ATTRIBUTE_FIXED 0xC00CE016"
777 " </body>"
778 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
779 "</email>";
780
781 static const CHAR szEmailXML_17[] =
782 "<?xml version=\"1.0\"?>"
783 SZ_EMAIL_DTD
784 "<email attachments=\"patch1\" sent=\"true\">"
785 " <recipients>"
786 " <to>wine-patches@winehq.org</to>"
787 " </recipients>"
788 " <from name=\"Anonymous\">user@localhost</from>"
789 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
790 " <body>"
791 " XML_ATTRIBUTE_VALUE 0xC00CE017"
792 " </body>"
793 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
794 "</email>";
795
796 static const CHAR szEmailXML_18[] =
797 "<?xml version=\"1.0\"?>"
798 SZ_EMAIL_DTD
799 "<email attachments=\"patch1\">"
800 " oops"
801 " <recipients>"
802 " <to>wine-patches@winehq.org</to>"
803 " </recipients>"
804 " <from name=\"Anonymous\">user@localhost</from>"
805 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
806 " <body>"
807 " XML_ILLEGAL_TEXT 0xC00CE018"
808 " </body>"
809 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
810 "</email>";
811
812 static const CHAR szEmailXML_20[] =
813 "<?xml version=\"1.0\"?>"
814 SZ_EMAIL_DTD
815 "<email>"
816 " <recipients>"
817 " <to>wine-patches@winehq.org</to>"
818 " </recipients>"
819 " <from name=\"Anonymous\">user@localhost</from>"
820 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
821 " <body>"
822 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
823 " </body>"
824 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
825 "</email>";
826
827 static const char xpath_simple_list[] =
828 "<?xml version=\"1.0\"?>"
829 "<root>"
830 " <a attr1=\"1\" attr2=\"2\" />"
831 " <b/>"
832 " <c/>"
833 " <d/>"
834 "</root>";
835
836 static const char default_ns_doc[] = {
837 "<?xml version=\"1.0\"?>"
838 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
839 " d=\"d attr\" />"
840 };
841
842 static const char attributes_map[] = {
843 "<?xml version=\"1.0\"?>"
844 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
845 };
846
847 static const WCHAR nonexistent_fileW[] = {
848 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
849 };
850 static const WCHAR nonexistent_attrW[] = {
851 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
852 };
853 static const WCHAR szDocument[] = {
854 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
855 };
856
857 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
858 static const WCHAR szdl[] = { 'd','l',0 };
859 static const WCHAR szvr[] = { 'v','r',0 };
860 static const WCHAR szlc[] = { 'l','c',0 };
861 static const WCHAR szbs[] = { 'b','s',0 };
862 static const WCHAR szstr1[] = { 's','t','r','1',0 };
863 static const WCHAR szstr2[] = { 's','t','r','2',0 };
864 static const WCHAR szstar[] = { '*',0 };
865 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
866
867 static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
868 static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
869 static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
870
871 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
872 static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
873 static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
874 static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
875 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
876 static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
877 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
878
879 static const WCHAR szAttribute[] = {'A','t','t','r',0 };
880 static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
881
882 static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
883 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
884 static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
885 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
886 '!',']',']','>',0};
887 static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
888 static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
889
890 static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
891 static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
892 static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
893
894 #define expect_bstr_eq_and_free(bstr, expect) { \
895 BSTR bstrExp = alloc_str_from_narrow(expect); \
896 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
897 SysFreeString(bstr); \
898 SysFreeString(bstrExp); \
899 }
900
901 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
902
903 #define ole_check(expr) { \
904 HRESULT r = expr; \
905 ok(r == S_OK, #expr " returned %x\n", r); \
906 }
907
908 #define ole_expect(expr, expect) { \
909 HRESULT r = expr; \
910 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
911 }
912
913 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
914
915 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
916 {
917 void *obj = NULL;
918 HRESULT hr;
919
920 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
921 ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr);
922
923 return obj;
924 }
925
926 #define _create(cls) cls, #cls
927
928 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
929 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
930 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
931 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
932
933 static BSTR alloc_str_from_narrow(const char *str)
934 {
935 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
936 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
937 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
938 return ret;
939 }
940
941 static BSTR alloced_bstrs[256];
942 static int alloced_bstrs_count;
943
944 static BSTR _bstr_(const char *str)
945 {
946 assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
947 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
948 return alloced_bstrs[alloced_bstrs_count++];
949 }
950
951 static void free_bstrs(void)
952 {
953 int i;
954 for (i = 0; i < alloced_bstrs_count; i++)
955 SysFreeString(alloced_bstrs[i]);
956 alloced_bstrs_count = 0;
957 }
958
959 static VARIANT _variantbstr_(const char *str)
960 {
961 VARIANT v;
962 V_VT(&v) = VT_BSTR;
963 V_BSTR(&v) = _bstr_(str);
964 return v;
965 }
966
967 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
968 {
969 for (;;)
970 {
971 while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
972 while (*sRight == '\r' || *sRight == '\n') sRight++;
973 if (*sLeft != *sRight) return FALSE;
974 if (!*sLeft) return TRUE;
975 sLeft++;
976 sRight++;
977 }
978 }
979
980 static void get_str_for_type(DOMNodeType type, char *buf)
981 {
982 switch (type)
983 {
984 case NODE_ATTRIBUTE:
985 strcpy(buf, "A");
986 break;
987 case NODE_ELEMENT:
988 strcpy(buf, "E");
989 break;
990 case NODE_DOCUMENT:
991 strcpy(buf, "D");
992 break;
993 case NODE_TEXT:
994 strcpy(buf, "T");
995 break;
996 case NODE_COMMENT:
997 strcpy(buf, "C");
998 break;
999 case NODE_PROCESSING_INSTRUCTION:
1000 strcpy(buf, "P");
1001 break;
1002 default:
1003 wsprintfA(buf, "[%d]", type);
1004 }
1005 }
1006
1007 static int get_node_position(IXMLDOMNode *node)
1008 {
1009 HRESULT r;
1010 int pos = 0;
1011
1012 IXMLDOMNode_AddRef(node);
1013 do
1014 {
1015 IXMLDOMNode *new_node;
1016
1017 pos++;
1018 r = IXMLDOMNode_get_previousSibling(node, &new_node);
1019 ok(SUCCEEDED(r), "get_previousSibling failed\n");
1020 IXMLDOMNode_Release(node);
1021 node = new_node;
1022 } while (r == S_OK);
1023 return pos;
1024 }
1025
1026 static void node_to_string(IXMLDOMNode *node, char *buf)
1027 {
1028 HRESULT r = S_OK;
1029 DOMNodeType type;
1030
1031 if (node == NULL)
1032 {
1033 lstrcpyA(buf, "(null)");
1034 return;
1035 }
1036
1037 IXMLDOMNode_AddRef(node);
1038 while (r == S_OK)
1039 {
1040 IXMLDOMNode *new_node;
1041
1042 ole_check(IXMLDOMNode_get_nodeType(node, &type));
1043 get_str_for_type(type, buf);
1044 buf+=strlen(buf);
1045
1046 if (type == NODE_ATTRIBUTE)
1047 {
1048 BSTR bstr;
1049 ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
1050 *(buf++) = '\'';
1051 wsprintfA(buf, "%ws", bstr);
1052 buf += strlen(buf);
1053 *(buf++) = '\'';
1054 SysFreeString(bstr);
1055
1056 r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
1057 }
1058 else
1059 {
1060 r = IXMLDOMNode_get_parentNode(node, &new_node);
1061 sprintf(buf, "%d", get_node_position(node));
1062 buf += strlen(buf);
1063 }
1064
1065 ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
1066 IXMLDOMNode_Release(node);
1067 node = new_node;
1068 if (r == S_OK)
1069 *(buf++) = '.';
1070 }
1071
1072 *buf = 0;
1073 }
1074
1075 static char *list_to_string(IXMLDOMNodeList *list)
1076 {
1077 static char buf[4096];
1078 char *pos = buf;
1079 LONG len = 0;
1080 HRESULT hr;
1081 int i;
1082
1083 if (list == NULL)
1084 {
1085 strcpy(buf, "(null)");
1086 return buf;
1087 }
1088 hr = IXMLDOMNodeList_get_length(list, &len);
1089 ok(hr == S_OK, "got 0x%08x\n", hr);
1090 for (i = 0; i < len; i++)
1091 {
1092 IXMLDOMNode *node;
1093 if (i > 0)
1094 *(pos++) = ' ';
1095 ole_check(IXMLDOMNodeList_nextNode(list, &node));
1096 node_to_string(node, pos);
1097 pos += strlen(pos);
1098 IXMLDOMNode_Release(node);
1099 }
1100 *pos = 0;
1101 return buf;
1102 }
1103
1104 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
1105 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
1106
1107 struct docload_ret_t {
1108 VARIANT_BOOL b;
1109 HRESULT hr;
1110 };
1111
1112 struct leading_spaces_t {
1113 const CLSID *clsid;
1114 const char *name;
1115 struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */
1116 };
1117
1118 static const struct leading_spaces_t leading_spaces_classdata[] = {
1119 { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1120 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1121 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }},
1122 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1123 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1124 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }},
1125 { NULL }
1126 };
1127
1128 static const char* leading_spaces_xmldata[] = {
1129 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1130 " <?xml version=\"1.0\"?><root/>",
1131 "\n<?xml version=\"1.0\"?><root/>",
1132 "\t<?xml version=\"1.0\"?><root/>",
1133 "\r\n<?xml version=\"1.0\"?><root/>",
1134 "\r<?xml version=\"1.0\"?><root/>",
1135 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1136 0
1137 };
1138
1139 static void test_domdoc( void )
1140 {
1141 HRESULT r, hr;
1142 IXMLDOMDocument *doc;
1143 IXMLDOMParseError *error;
1144 IXMLDOMElement *element = NULL;
1145 IXMLDOMNode *node;
1146 IXMLDOMText *nodetext = NULL;
1147 IXMLDOMComment *node_comment = NULL;
1148 IXMLDOMAttribute *node_attr = NULL;
1149 IXMLDOMNode *nodeChild = NULL;
1150 IXMLDOMProcessingInstruction *nodePI = NULL;
1151 const struct leading_spaces_t *class_ptr;
1152 const char **data_ptr;
1153 VARIANT_BOOL b;
1154 VARIANT var;
1155 BSTR str;
1156 LONG code, ref;
1157 LONG nLength = 0;
1158 WCHAR buff[100];
1159 char path[MAX_PATH];
1160 int index;
1161
1162 GetTempPathA(MAX_PATH, path);
1163 strcat(path, "leading_spaces.xml");
1164
1165 /* Load document with leading spaces
1166 *
1167 * Test all CLSIDs with all test data XML strings
1168 */
1169 class_ptr = leading_spaces_classdata;
1170 index = 0;
1171 while (class_ptr->clsid)
1172 {
1173 HRESULT hr;
1174 int i;
1175
1176 if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
1177 {
1178 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
1179 }
1180 else
1181 {
1182 class_ptr++;
1183 index++;
1184 continue;
1185 }
1186
1187 data_ptr = leading_spaces_xmldata;
1188 i = 0;
1189 while (*data_ptr) {
1190 BSTR data = _bstr_(*data_ptr);
1191 DWORD written;
1192 HANDLE file;
1193
1194 file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1195 ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError());
1196
1197 WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL);
1198 CloseHandle(file);
1199
1200 b = 0xc;
1201 V_VT(&var) = VT_BSTR;
1202 V_BSTR(&var) = _bstr_(path);
1203 hr = IXMLDOMDocument_load(doc, var, &b);
1204 EXPECT_HR(hr, class_ptr->ret[0].hr);
1205 ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
1206
1207 DeleteFileA(path);
1208
1209 b = 0xc;
1210 hr = IXMLDOMDocument_loadXML(doc, data, &b);
1211 EXPECT_HR(hr, class_ptr->ret[1].hr);
1212 ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b);
1213
1214 data_ptr++;
1215 i++;
1216 }
1217
1218 class_ptr++;
1219 index++;
1220 free_bstrs();
1221 }
1222
1223 doc = create_document(&IID_IXMLDOMDocument);
1224 if (!doc) return;
1225
1226 if (0)
1227 {
1228 /* crashes on native */
1229 IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
1230 }
1231
1232 /* try some stupid things */
1233 hr = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1234 EXPECT_HR(hr, S_FALSE);
1235
1236 b = VARIANT_TRUE;
1237 hr = IXMLDOMDocument_loadXML( doc, NULL, &b );
1238 EXPECT_HR(hr, S_FALSE);
1239 ok( b == VARIANT_FALSE, "failed to load XML string\n");
1240
1241 /* try to load a document from a nonexistent file */
1242 b = VARIANT_TRUE;
1243 str = SysAllocString( nonexistent_fileW );
1244 VariantInit(&var);
1245 V_VT(&var) = VT_BSTR;
1246 V_BSTR(&var) = str;
1247
1248 r = IXMLDOMDocument_load( doc, var, &b);
1249 ok( r == S_FALSE, "loadXML succeeded\n");
1250 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1251 SysFreeString( str );
1252
1253 str = (BSTR)0x1;
1254 hr = IXMLDOMDocument_get_url(doc, &str);
1255 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1256 ok(str == NULL, "got %p\n", str);
1257
1258 /* try load an empty document */
1259 b = VARIANT_TRUE;
1260 str = SysAllocString( szEmpty );
1261 r = IXMLDOMDocument_loadXML( doc, str, &b );
1262 ok( r == S_FALSE, "loadXML succeeded\n");
1263 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1264 SysFreeString( str );
1265
1266 r = IXMLDOMDocument_get_async( doc, &b );
1267 ok( r == S_OK, "get_async failed (%08x)\n", r);
1268 ok( b == VARIANT_TRUE, "Wrong default value\n");
1269
1270 /* check that there's no document element */
1271 element = NULL;
1272 r = IXMLDOMDocument_get_documentElement( doc, &element );
1273 ok( r == S_FALSE, "should be no document element\n");
1274
1275 /* try finding a node */
1276 node = NULL;
1277 str = SysAllocString( szstr1 );
1278 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
1279 ok( r == S_FALSE, "ret %08x\n", r );
1280 SysFreeString( str );
1281
1282 b = VARIANT_TRUE;
1283 str = SysAllocString( szIncomplete );
1284 r = IXMLDOMDocument_loadXML( doc, str, &b );
1285 ok( r == S_FALSE, "loadXML succeeded\n");
1286 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1287 SysFreeString( str );
1288
1289 /* check that there's no document element */
1290 element = (IXMLDOMElement*)1;
1291 r = IXMLDOMDocument_get_documentElement( doc, &element );
1292 ok( r == S_FALSE, "should be no document element\n");
1293 ok( element == NULL, "Element should be NULL\n");
1294
1295 /* test for BSTR handling, pass broken BSTR */
1296 memcpy(&buff[2], szComplete1, sizeof(szComplete1));
1297 /* just a big length */
1298 *(DWORD*)buff = 0xf0f0;
1299 b = VARIANT_FALSE;
1300 r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1301 ok( r == S_OK, "loadXML failed\n");
1302 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1303
1304 /* loadXML ignores the encoding attribute and always expects Unicode */
1305 b = VARIANT_FALSE;
1306 str = SysAllocString( szComplete6 );
1307 r = IXMLDOMDocument_loadXML( doc, str, &b );
1308 ok( r == S_OK, "loadXML failed\n");
1309 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1310 SysFreeString( str );
1311
1312 /* try a BSTR containing a Windows-1252 document */
1313 b = VARIANT_TRUE;
1314 str = SysAllocStringByteLen( win1252xml, strlen(win1252xml) );
1315 r = IXMLDOMDocument_loadXML( doc, str, &b );
1316 ok( r == S_FALSE, "loadXML succeeded\n");
1317 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1318 SysFreeString( str );
1319
1320 /* try to load something valid */
1321 b = VARIANT_FALSE;
1322 str = SysAllocString( szComplete1 );
1323 r = IXMLDOMDocument_loadXML( doc, str, &b );
1324 ok( r == S_OK, "loadXML failed\n");
1325 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1326 SysFreeString( str );
1327
1328 /* check if nodename is correct */
1329 r = IXMLDOMDocument_get_nodeName( doc, NULL );
1330 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1331
1332 str = (BSTR)0xdeadbeef;
1333 r = IXMLDOMDocument_get_baseName( doc, &str );
1334 ok ( r == S_FALSE, "got 0x%08x\n", r);
1335 ok (str == NULL, "got %p\n", str);
1336
1337 /* content doesn't matter here */
1338 str = NULL;
1339 r = IXMLDOMDocument_get_nodeName( doc, &str );
1340 ok ( r == S_OK, "get_nodeName wrong code\n");
1341 ok ( str != NULL, "str is null\n");
1342 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1343 SysFreeString( str );
1344
1345 /* test put_text */
1346 r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
1347 ok( r == E_FAIL, "ret %08x\n", r );
1348
1349 /* check that there's a document element */
1350 element = NULL;
1351 r = IXMLDOMDocument_get_documentElement( doc, &element );
1352 ok( r == S_OK, "should be a document element\n");
1353 if( element )
1354 {
1355 IObjectIdentity *ident;
1356
1357 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1358 ok( r == E_NOINTERFACE, "ret %08x\n", r);
1359
1360 IXMLDOMElement_Release( element );
1361 element = NULL;
1362 }
1363
1364 /* as soon as we call loadXML again, the document element will disappear */
1365 b = 2;
1366 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1367 ok( r == S_FALSE, "loadXML failed\n");
1368 ok( b == 2, "variant modified\n");
1369 r = IXMLDOMDocument_get_documentElement( doc, &element );
1370 ok( r == S_FALSE, "should be no document element\n");
1371
1372 /* try to load something else simple and valid */
1373 b = VARIANT_FALSE;
1374 str = SysAllocString( szComplete2 );
1375 r = IXMLDOMDocument_loadXML( doc, str, &b );
1376 ok( r == S_OK, "loadXML failed\n");
1377 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1378 SysFreeString( str );
1379
1380 /* try something a little more complicated */
1381 b = FALSE;
1382 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1383 ok( r == S_OK, "loadXML failed\n");
1384 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1385
1386 r = IXMLDOMDocument_get_parseError( doc, &error );
1387 ok( r == S_OK, "returns %08x\n", r );
1388
1389 r = IXMLDOMParseError_get_errorCode( error, &code );
1390 ok( r == S_FALSE, "returns %08x\n", r );
1391 ok( code == 0, "code %d\n", code );
1392 IXMLDOMParseError_Release( error );
1393
1394 /* test createTextNode */
1395 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1396 ok( r == S_OK, "returns %08x\n", r );
1397 IXMLDOMText_Release(nodetext);
1398
1399 str = SysAllocString( szOpen );
1400 r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1401 ok( r == E_INVALIDARG, "returns %08x\n", r );
1402 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1403 ok( r == S_OK, "returns %08x\n", r );
1404 SysFreeString( str );
1405 if(nodetext)
1406 {
1407 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1408 ok(r == E_NOINTERFACE, "ret %08x\n", r );
1409
1410 /* Text Last Child Checks */
1411 r = IXMLDOMText_get_lastChild(nodetext, NULL);
1412 ok(r == E_INVALIDARG, "ret %08x\n", r );
1413
1414 nodeChild = (IXMLDOMNode*)0x1;
1415 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1416 ok(r == S_FALSE, "ret %08x\n", r );
1417 ok(nodeChild == NULL, "nodeChild not NULL\n");
1418
1419 /* test length property */
1420 r = IXMLDOMText_get_length(nodetext, NULL);
1421 ok(r == E_INVALIDARG, "ret %08x\n", r );
1422
1423 r = IXMLDOMText_get_length(nodetext, &nLength);
1424 ok(r == S_OK, "ret %08x\n", r );
1425 ok(nLength == 4, "expected 4 got %d\n", nLength);
1426
1427 /* put data Tests */
1428 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1429 ok(r == S_OK, "ret %08x\n", r );
1430
1431 /* get data Tests */
1432 r = IXMLDOMText_get_data(nodetext, &str);
1433 ok(r == S_OK, "ret %08x\n", r );
1434 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1435 SysFreeString(str);
1436
1437 /* Confirm XML text is good */
1438 r = IXMLDOMText_get_xml(nodetext, &str);
1439 ok(r == S_OK, "ret %08x\n", r );
1440 ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
1441 SysFreeString(str);
1442
1443 /* Confirm we get the put_data Text back */
1444 r = IXMLDOMText_get_text(nodetext, &str);
1445 ok(r == S_OK, "ret %08x\n", r );
1446 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1447 SysFreeString(str);
1448
1449 /* test substringData */
1450 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1451 ok(r == E_INVALIDARG, "ret %08x\n", r );
1452
1453 /* test substringData - Invalid offset */
1454 str = (BSTR)&szElement;
1455 r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1456 ok(r == E_INVALIDARG, "ret %08x\n", r );
1457 ok( str == NULL, "incorrect string\n");
1458
1459 /* test substringData - Invalid offset */
1460 str = (BSTR)&szElement;
1461 r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1462 ok(r == S_FALSE, "ret %08x\n", r );
1463 ok( str == NULL, "incorrect string\n");
1464
1465 /* test substringData - Invalid size */
1466 str = (BSTR)&szElement;
1467 r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1468 ok(r == E_INVALIDARG, "ret %08x\n", r );
1469 ok( str == NULL, "incorrect string\n");
1470
1471 /* test substringData - Invalid size */
1472 str = (BSTR)&szElement;
1473 r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1474 ok(r == S_FALSE, "ret %08x\n", r );
1475 ok( str == NULL, "incorrect string\n");
1476
1477 /* test substringData - Start of string */
1478 r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1479 ok(r == S_OK, "ret %08x\n", r );
1480 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1481 SysFreeString(str);
1482
1483 /* test substringData - Middle of string */
1484 r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1485 ok(r == S_OK, "ret %08x\n", r );
1486 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1487 SysFreeString(str);
1488
1489 /* test substringData - End of string */
1490 r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1491 ok(r == S_OK, "ret %08x\n", r );
1492 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1493 SysFreeString(str);
1494
1495 /* test appendData */
1496 r = IXMLDOMText_appendData(nodetext, NULL);
1497 ok(r == S_OK, "ret %08x\n", r );
1498
1499 r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1500 ok(r == S_OK, "ret %08x\n", r );
1501
1502 r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1503 ok(r == S_OK, "ret %08x\n", r );
1504
1505 r = IXMLDOMText_get_text(nodetext, &str);
1506 ok(r == S_OK, "ret %08x\n", r );
1507 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1508 SysFreeString(str);
1509
1510 /* test insertData */
1511 str = SysAllocStringLen(NULL, 0);
1512 r = IXMLDOMText_insertData(nodetext, -1, str);
1513 ok(r == S_OK, "ret %08x\n", r );
1514
1515 r = IXMLDOMText_insertData(nodetext, -1, NULL);
1516 ok(r == S_OK, "ret %08x\n", r );
1517
1518 r = IXMLDOMText_insertData(nodetext, 1000, str);
1519 ok(r == S_OK, "ret %08x\n", r );
1520
1521 r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1522 ok(r == S_OK, "ret %08x\n", r );
1523
1524 r = IXMLDOMText_insertData(nodetext, 0, NULL);
1525 ok(r == S_OK, "ret %08x\n", r );
1526
1527 r = IXMLDOMText_insertData(nodetext, 0, str);
1528 ok(r == S_OK, "ret %08x\n", r );
1529 SysFreeString(str);
1530
1531 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1532 ok(r == E_INVALIDARG, "ret %08x\n", r );
1533
1534 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1535 ok(r == E_INVALIDARG, "ret %08x\n", r );
1536
1537 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1538 ok(r == S_OK, "ret %08x\n", r );
1539
1540 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1541 ok(r == S_OK, "ret %08x\n", r );
1542
1543 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1544 ok(r == S_OK, "ret %08x\n", r );
1545
1546 r = IXMLDOMText_get_text(nodetext, &str);
1547 ok(r == S_OK, "ret %08x\n", r );
1548 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1549 SysFreeString(str);
1550
1551 /* delete data */
1552 /* invalid arguments */
1553 r = IXMLDOMText_deleteData(nodetext, -1, 1);
1554 ok(r == E_INVALIDARG, "ret %08x\n", r );
1555
1556 r = IXMLDOMText_deleteData(nodetext, 0, 0);
1557 ok(r == S_OK, "ret %08x\n", r );
1558
1559 r = IXMLDOMText_deleteData(nodetext, 0, -1);
1560 ok(r == E_INVALIDARG, "ret %08x\n", r );
1561
1562 r = IXMLDOMText_get_length(nodetext, &nLength);
1563 ok(r == S_OK, "ret %08x\n", r );
1564 ok(nLength == 43, "expected 43 got %d\n", nLength);
1565
1566 r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1567 ok(r == S_OK, "ret %08x\n", r );
1568
1569 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1570 ok(r == E_INVALIDARG, "ret %08x\n", r );
1571
1572 /* delete from start */
1573 r = IXMLDOMText_deleteData(nodetext, 0, 5);
1574 ok(r == S_OK, "ret %08x\n", r );
1575
1576 r = IXMLDOMText_get_length(nodetext, &nLength);
1577 ok(r == S_OK, "ret %08x\n", r );
1578 ok(nLength == 38, "expected 38 got %d\n", nLength);
1579
1580 r = IXMLDOMText_get_text(nodetext, &str);
1581 ok(r == S_OK, "ret %08x\n", r );
1582 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1583 SysFreeString(str);
1584
1585 /* delete from end */
1586 r = IXMLDOMText_deleteData(nodetext, 35, 3);
1587 ok(r == S_OK, "ret %08x\n", r );
1588
1589 r = IXMLDOMText_get_length(nodetext, &nLength);
1590 ok(r == S_OK, "ret %08x\n", r );
1591 ok(nLength == 35, "expected 35 got %d\n", nLength);
1592
1593 r = IXMLDOMText_get_text(nodetext, &str);
1594 ok(r == S_OK, "ret %08x\n", r );
1595 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1596 SysFreeString(str);
1597
1598 /* delete from inside */
1599 r = IXMLDOMText_deleteData(nodetext, 1, 33);
1600 ok(r == S_OK, "ret %08x\n", r );
1601
1602 r = IXMLDOMText_get_length(nodetext, &nLength);
1603 ok(r == S_OK, "ret %08x\n", r );
1604 ok(nLength == 2, "expected 2 got %d\n", nLength);
1605
1606 r = IXMLDOMText_get_text(nodetext, &str);
1607 ok(r == S_OK, "ret %08x\n", r );
1608 ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1609 SysFreeString(str);
1610
1611 /* delete whole data ... */
1612 r = IXMLDOMText_get_length(nodetext, &nLength);
1613 ok(r == S_OK, "ret %08x\n", r );
1614
1615 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1616 ok(r == S_OK, "ret %08x\n", r );
1617 /* ... and try again with empty string */
1618 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1619 ok(r == S_OK, "ret %08x\n", r );
1620
1621 /* test put_data */
1622 V_VT(&var) = VT_BSTR;
1623 V_BSTR(&var) = SysAllocString(szstr1);
1624 r = IXMLDOMText_put_nodeValue(nodetext, var);
1625 ok(r == S_OK, "ret %08x\n", r );
1626 VariantClear(&var);
1627
1628 r = IXMLDOMText_get_text(nodetext, &str);
1629 ok(r == S_OK, "ret %08x\n", r );
1630 ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1631 SysFreeString(str);
1632
1633 /* test put_data */
1634 V_VT(&var) = VT_I4;
1635 V_I4(&var) = 99;
1636 r = IXMLDOMText_put_nodeValue(nodetext, var);
1637 ok(r == S_OK, "ret %08x\n", r );
1638 VariantClear(&var);
1639
1640 r = IXMLDOMText_get_text(nodetext, &str);
1641 ok(r == S_OK, "ret %08x\n", r );
1642 ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1643 SysFreeString(str);
1644
1645 /* ::replaceData() */
1646 V_VT(&var) = VT_BSTR;
1647 V_BSTR(&var) = SysAllocString(szstr1);
1648 r = IXMLDOMText_put_nodeValue(nodetext, var);
1649 ok(r == S_OK, "ret %08x\n", r );
1650 VariantClear(&var);
1651
1652 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1653 ok(r == E_INVALIDARG, "ret %08x\n", r );
1654 r = IXMLDOMText_get_text(nodetext, &str);
1655 ok(r == S_OK, "ret %08x\n", r );
1656 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1657 SysFreeString(str);
1658
1659 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1660 ok(r == S_OK, "ret %08x\n", r );
1661 r = IXMLDOMText_get_text(nodetext, &str);
1662 ok(r == S_OK, "ret %08x\n", r );
1663 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1664 SysFreeString(str);
1665
1666 /* NULL pointer means delete */
1667 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1668 ok(r == S_OK, "ret %08x\n", r );
1669 r = IXMLDOMText_get_text(nodetext, &str);
1670 ok(r == S_OK, "ret %08x\n", r );
1671 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1672 SysFreeString(str);
1673
1674 /* empty string means delete */
1675 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1676 ok(r == S_OK, "ret %08x\n", r );
1677 r = IXMLDOMText_get_text(nodetext, &str);
1678 ok(r == S_OK, "ret %08x\n", r );
1679 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1680 SysFreeString(str);
1681
1682 /* zero count means insert */
1683 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1684 ok(r == S_OK, "ret %08x\n", r );
1685 r = IXMLDOMText_get_text(nodetext, &str);
1686 ok(r == S_OK, "ret %08x\n", r );
1687 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1688 SysFreeString(str);
1689
1690 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1691 ok(r == S_OK, "ret %08x\n", r );
1692
1693 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1694 ok(r == S_OK, "ret %08x\n", r );
1695 r = IXMLDOMText_get_text(nodetext, &str);
1696 ok(r == S_OK, "ret %08x\n", r );
1697 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1698 SysFreeString(str);
1699
1700 /* nonempty string, count greater than its length */
1701 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1702 ok(r == S_OK, "ret %08x\n", r );
1703 r = IXMLDOMText_get_text(nodetext, &str);
1704 ok(r == S_OK, "ret %08x\n", r );
1705 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1706 SysFreeString(str);
1707
1708 /* nonempty string, count less than its length */
1709 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
1710 ok(r == S_OK, "ret %08x\n", r );
1711 r = IXMLDOMText_get_text(nodetext, &str);
1712 ok(r == S_OK, "ret %08x\n", r );
1713 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1714 SysFreeString(str);
1715
1716 IXMLDOMText_Release( nodetext );
1717 }
1718
1719 /* test Create Comment */
1720 r = IXMLDOMDocument_createComment(doc, NULL, NULL);
1721 ok( r == E_INVALIDARG, "returns %08x\n", r );
1722 node_comment = (IXMLDOMComment*)0x1;
1723
1724 /* empty comment */
1725 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
1726 ok( r == S_OK, "returns %08x\n", r );
1727 str = (BSTR)0x1;
1728 r = IXMLDOMComment_get_data(node_comment, &str);
1729 ok( r == S_OK, "returns %08x\n", r );
1730 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
1731 IXMLDOMComment_Release(node_comment);
1732 SysFreeString(str);
1733
1734 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
1735 ok( r == S_OK, "returns %08x\n", r );
1736 str = (BSTR)0x1;
1737 r = IXMLDOMComment_get_data(node_comment, &str);
1738 ok( r == S_OK, "returns %08x\n", r );
1739 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
1740 IXMLDOMComment_Release(node_comment);
1741 SysFreeString(str);
1742
1743 str = SysAllocString(szComment);
1744 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
1745 SysFreeString(str);
1746 ok( r == S_OK, "returns %08x\n", r );
1747 if(node_comment)
1748 {
1749 /* Last Child Checks */
1750 r = IXMLDOMComment_get_lastChild(node_comment, NULL);
1751 ok(r == E_INVALIDARG, "ret %08x\n", r );
1752
1753 nodeChild = (IXMLDOMNode*)0x1;
1754 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
1755 ok(r == S_FALSE, "ret %08x\n", r );
1756 ok(nodeChild == NULL, "pLastChild not NULL\n");
1757
1758 /* baseName */
1759 str = (BSTR)0xdeadbeef;
1760 r = IXMLDOMComment_get_baseName(node_comment, &str);
1761 ok(r == S_FALSE, "ret %08x\n", r );
1762 ok(str == NULL, "Expected NULL\n");
1763
1764 IXMLDOMComment_Release( node_comment );
1765 }
1766
1767 /* test Create Attribute */
1768 str = SysAllocString(szAttribute);
1769 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
1770 ok( r == E_INVALIDARG, "returns %08x\n", r );
1771 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
1772 ok( r == S_OK, "returns %08x\n", r );
1773 IXMLDOMAttribute_Release( node_attr);
1774 SysFreeString(str);
1775
1776 /* test Processing Instruction */
1777 str = SysAllocStringLen(NULL, 0);
1778 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
1779 ok( r == E_INVALIDARG, "returns %08x\n", r );
1780 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
1781 ok( r == E_FAIL, "returns %08x\n", r );
1782 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
1783 ok( r == E_FAIL, "returns %08x\n", r );
1784 SysFreeString(str);
1785
1786 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
1787 ok( r == S_OK, "returns %08x\n", r );
1788 if(nodePI)
1789 {
1790 /* Last Child Checks */
1791 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
1792 ok(r == E_INVALIDARG, "ret %08x\n", r );
1793
1794 nodeChild = (IXMLDOMNode*)0x1;
1795 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
1796 ok(r == S_FALSE, "ret %08x\n", r );
1797 ok(nodeChild == NULL, "nodeChild not NULL\n");
1798
1799 /* test nodeName */
1800 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1801 ok(r == S_OK, "ret %08x\n", r );
1802 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1803 SysFreeString(str);
1804
1805 /* test baseName */
1806 str = (BSTR)0x1;
1807 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
1808 ok(r == S_OK, "ret %08x\n", r );
1809 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1810 SysFreeString(str);
1811
1812 /* test Target */
1813 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
1814 ok(r == S_OK, "ret %08x\n", r );
1815 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
1816 SysFreeString(str);
1817
1818 /* test get_data */
1819 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
1820 ok(r == S_OK, "ret %08x\n", r );
1821 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1822 SysFreeString(str);
1823
1824 /* test put_data */
1825 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
1826 ok(r == E_FAIL, "ret %08x\n", r );
1827
1828 /* test put_data */
1829 V_VT(&var) = VT_BSTR;
1830 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
1831 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
1832 ok(r == E_FAIL, "ret %08x\n", r );
1833 VariantClear(&var);
1834
1835 /* test get nodeName */
1836 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1837 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1838 ok(r == S_OK, "ret %08x\n", r );
1839 SysFreeString(str);
1840
1841 IXMLDOMProcessingInstruction_Release(nodePI);
1842 }
1843
1844 ref = IXMLDOMDocument_Release( doc );
1845 ok( ref == 0, "got %d\n", ref);
1846
1847 free_bstrs();
1848 }
1849
1850 static void test_persiststreaminit(void)
1851 {
1852 IXMLDOMDocument *doc;
1853 IPersistStreamInit *streaminit;
1854 ULARGE_INTEGER size;
1855 HRESULT hr;
1856
1857 doc = create_document(&IID_IXMLDOMDocument);
1858
1859 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
1860 ok(hr == S_OK, "got 0x%08x\n", hr);
1861
1862 hr = IPersistStreamInit_InitNew(streaminit);
1863 ok(hr == S_OK, "got 0x%08x\n", hr);
1864
1865 hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
1866 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
1867
1868 IXMLDOMDocument_Release(doc);
1869 }
1870
1871 static void test_domnode( void )
1872 {
1873 HRESULT r;
1874 IXMLDOMDocument *doc, *owner = NULL;
1875 IXMLDOMElement *element = NULL;
1876 IXMLDOMNamedNodeMap *map = NULL;
1877 IXMLDOMNode *node = NULL, *next = NULL;
1878 IXMLDOMNodeList *list = NULL;
1879 IXMLDOMAttribute *attr = NULL;
1880 DOMNodeType type = NODE_INVALID;
1881 VARIANT_BOOL b;
1882 BSTR str;
1883 VARIANT var;
1884 LONG count;
1885
1886 doc = create_document(&IID_IXMLDOMDocument);
1887
1888 b = FALSE;
1889 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
1890 ok( r == S_OK, "loadXML failed\n");
1891 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1892
1893 EXPECT_CHILDREN(doc);
1894
1895 r = IXMLDOMDocument_get_documentElement( doc, &element );
1896 ok( r == S_OK, "should be a document element\n");
1897 ok( element != NULL, "should be an element\n");
1898
1899 VariantInit(&var);
1900 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1901
1902 r = IXMLDOMDocument_get_nodeValue( doc, NULL );
1903 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
1904
1905 r = IXMLDOMDocument_get_nodeValue( doc, &var );
1906 ok( r == S_FALSE, "nextNode returned wrong code\n");
1907 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1908 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1909
1910 if (element)
1911 {
1912 owner = NULL;
1913 r = IXMLDOMElement_get_ownerDocument( element, &owner );
1914 ok( r == S_OK, "get_ownerDocument return code\n");
1915 ok( owner != doc, "get_ownerDocument return\n");
1916 IXMLDOMDocument_Release(owner);
1917
1918 type = NODE_INVALID;
1919 r = IXMLDOMElement_get_nodeType( element, &type);
1920 ok( r == S_OK, "got %08x\n", r);
1921 ok( type == NODE_ELEMENT, "node not an element\n");
1922
1923 str = NULL;
1924 r = IXMLDOMElement_get_baseName( element, &str );
1925 ok( r == S_OK, "get_baseName returned wrong code\n");
1926 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
1927 SysFreeString(str);
1928
1929 /* check if nodename is correct */
1930 r = IXMLDOMElement_get_nodeName( element, NULL );
1931 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1932
1933 /* content doesn't matter here */
1934 str = NULL;
1935 r = IXMLDOMElement_get_nodeName( element, &str );
1936 ok ( r == S_OK, "get_nodeName wrong code\n");
1937 ok ( str != NULL, "str is null\n");
1938 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
1939 SysFreeString( str );
1940
1941 str = SysAllocString( nonexistent_fileW );
1942 V_VT(&var) = VT_I4;
1943 V_I4(&var) = 0x1234;
1944 r = IXMLDOMElement_getAttribute( element, str, &var );
1945 ok( r == E_FAIL, "getAttribute ret %08x\n", r );
1946 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
1947 VariantClear(&var);
1948 SysFreeString(str);
1949
1950 str = SysAllocString( szdl );
1951 V_VT(&var) = VT_I4;
1952 V_I4(&var) = 0x1234;
1953 r = IXMLDOMElement_getAttribute( element, str, &var );
1954 ok( r == S_OK, "getAttribute ret %08x\n", r );
1955 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
1956 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
1957 VariantClear( &var );
1958
1959 r = IXMLDOMElement_getAttribute( element, NULL, &var );
1960 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1961
1962 r = IXMLDOMElement_getAttribute( element, str, NULL );
1963 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1964
1965 attr = NULL;
1966 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1967 ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
1968 ok( attr != NULL, "getAttributeNode returned NULL\n" );
1969 if (attr)
1970 {
1971 r = IXMLDOMAttribute_get_parentNode( attr, NULL );
1972 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
1973
1974 /* attribute doesn't have a parent in msxml interpretation */
1975 node = (IXMLDOMNode*)0xdeadbeef;
1976 r = IXMLDOMAttribute_get_parentNode( attr, &node );
1977 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
1978 ok( node == NULL, "Expected NULL, got %p\n", node );
1979
1980 IXMLDOMAttribute_Release(attr);
1981 }
1982
1983 SysFreeString( str );
1984
1985 r = IXMLDOMElement_get_attributes( element, &map );
1986 ok( r == S_OK, "get_attributes returned wrong code\n");
1987 ok( map != NULL, "should be attributes\n");
1988
1989 EXPECT_CHILDREN(element);
1990 }
1991 else
1992 ok( FALSE, "no element\n");
1993
1994 if (map)
1995 {
1996 str = SysAllocString( szdl );
1997 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1998 ok( r == S_OK, "getNamedItem returned wrong code\n");
1999 ok( node != NULL, "should be attributes\n");
2000 IXMLDOMNode_Release(node);
2001 SysFreeString( str );
2002
2003 str = SysAllocString( szdl );
2004 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
2005 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
2006 SysFreeString( str );
2007
2008 /* something that isn't in complete4A */
2009 str = SysAllocString( szOpen );
2010 node = (IXMLDOMNode *) 1;
2011 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
2012 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
2013 ok( node == NULL, "getNamedItem should have returned NULL\n");
2014 SysFreeString( str );
2015
2016 /* test indexed access of attributes */
2017 r = IXMLDOMNamedNodeMap_get_length( map, NULL );
2018 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
2019
2020 r = IXMLDOMNamedNodeMap_get_length( map, &count );
2021 ok ( r == S_OK, "get_length wrong code\n");
2022 ok ( count == 1, "get_length != 1\n");
2023
2024 node = NULL;
2025 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
2026 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
2027 ok ( node == NULL, "there is no node\n");
2028
2029 node = NULL;
2030 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
2031 ok ( r == S_FALSE, "get_item (1) wrong code\n");
2032 ok ( node == NULL, "there is no attribute\n");
2033
2034 node = NULL;
2035 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
2036 ok ( r == S_OK, "get_item (0) wrong code\n");
2037 ok ( node != NULL, "should be attribute\n");
2038
2039 r = IXMLDOMNode_get_nodeName( node, NULL );
2040 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
2041
2042 /* content doesn't matter here */
2043 str = NULL;
2044 r = IXMLDOMNode_get_nodeName( node, &str );
2045 ok ( r == S_OK, "get_nodeName wrong code\n");
2046 ok ( str != NULL, "str is null\n");
2047 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
2048 SysFreeString( str );
2049 IXMLDOMNode_Release( node );
2050
2051 /* test sequential access of attributes */
2052 node = NULL;
2053 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2054 ok ( r == S_OK, "nextNode (first time) wrong code\n");
2055 ok ( node != NULL, "nextNode, should be attribute\n");
2056 IXMLDOMNode_Release( node );
2057
2058 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2059 ok ( r != S_OK, "nextNode (second time) wrong code\n");
2060 ok ( node == NULL, "nextNode, there is no attribute\n");
2061
2062 r = IXMLDOMNamedNodeMap_reset( map );
2063 ok ( r == S_OK, "reset should return S_OK\n");
2064
2065 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
2066 ok ( r == S_OK, "nextNode (third time) wrong code\n");
2067 ok ( node != NULL, "nextNode, should be attribute\n");
2068 }
2069 else
2070 ok( FALSE, "no map\n");
2071
2072 if (node)
2073 {
2074 type = NODE_INVALID;
2075 r = IXMLDOMNode_get_nodeType( node, &type);
2076 ok( r == S_OK, "getNamedItem returned wrong code\n");
2077 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
2078
2079 str = NULL;
2080 r = IXMLDOMNode_get_baseName( node, NULL );
2081 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
2082
2083 str = NULL;
2084 r = IXMLDOMNode_get_baseName( node, &str );
2085 ok( r == S_OK, "get_baseName returned wrong code\n");
2086 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
2087 SysFreeString( str );
2088
2089 r = IXMLDOMNode_get_childNodes( node, NULL );
2090 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
2091
2092 r = IXMLDOMNode_get_childNodes( node, &list );
2093 ok( r == S_OK, "get_childNodes returned wrong code\n");
2094
2095 if (list)
2096 {
2097 r = IXMLDOMNodeList_nextNode( list, &next );
2098 ok( r == S_OK, "nextNode returned wrong code\n");
2099 }
2100 else
2101 ok( FALSE, "no childlist\n");
2102
2103 if (next)
2104 {
2105 EXPECT_NO_CHILDREN(next);
2106
2107 type = NODE_INVALID;
2108 r = IXMLDOMNode_get_nodeType( next, &type);
2109 ok( r == S_OK, "getNamedItem returned wrong code\n");
2110 ok( type == NODE_TEXT, "node not text\n");
2111
2112 str = (BSTR) 1;
2113 r = IXMLDOMNode_get_baseName( next, &str );
2114 ok( r == S_FALSE, "get_baseName returned wrong code\n");
2115 ok( str == NULL, "basename was wrong\n");
2116 SysFreeString(str);
2117 }
2118 else
2119 ok( FALSE, "no next\n");
2120
2121 if (next)
2122 IXMLDOMNode_Release( next );
2123 next = NULL;
2124 if (list)
2125 IXMLDOMNodeList_Release( list );
2126 list = NULL;
2127 if (node)
2128 IXMLDOMNode_Release( node );
2129 }
2130 else
2131 ok( FALSE, "no node\n");
2132 node = NULL;
2133
2134 if (map)
2135 IXMLDOMNamedNodeMap_Release( map );
2136
2137 /* now traverse the tree from the root element */
2138 if (element)
2139 {
2140 r = IXMLDOMElement_get_childNodes( element, &list );
2141 ok( r == S_OK, "get_childNodes returned wrong code\n");
2142
2143 /* using get_item for child list doesn't advance the position */
2144 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2145 expect_node(node, "E2.E2.D1");
2146 IXMLDOMNode_Release(node);
2147 ole_check(IXMLDOMNodeList_nextNode(list, &node));
2148 expect_node(node, "E1.E2.D1");
2149 IXMLDOMNode_Release(node);
2150 ole_check(IXMLDOMNodeList_reset(list));
2151
2152 IXMLDOMNodeList_AddRef(list);
2153 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2154 ole_check(IXMLDOMNodeList_reset(list));
2155
2156 node = (void*)0xdeadbeef;
2157 str = SysAllocString(szdl);
2158 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2159 SysFreeString(str);
2160 ok( r == S_FALSE, "ret %08x\n", r );
2161 ok( node == NULL, "node %p\n", node );
2162
2163 str = SysAllocString(szbs);
2164 r = IXMLDOMElement_selectSingleNode( element, str, &node );
2165 SysFreeString(str);
2166 ok( r == S_OK, "ret %08x\n", r );
2167 r = IXMLDOMNode_Release( node );
2168 ok( r == 0, "ret %08x\n", r );
2169 }
2170 else
2171 ok( FALSE, "no element\n");
2172
2173 if (list)
2174 {
2175 r = IXMLDOMNodeList_get_item(list, 0, NULL);
2176 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2177
2178 r = IXMLDOMNodeList_get_length(list, NULL);
2179 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2180
2181 r = IXMLDOMNodeList_get_length( list, &count );
2182 ok( r == S_OK, "get_length returns %08x\n", r );
2183 ok( count == 4, "get_length got %d\n", count );
2184
2185 r = IXMLDOMNodeList_nextNode(list, NULL);
2186 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r);
2187
2188 r = IXMLDOMNodeList_nextNode( list, &node );
2189 ok( r == S_OK, "nextNode returned wrong code\n");
2190 }
2191 else
2192 ok( FALSE, "no list\n");
2193
2194 if (node)
2195 {
2196 type = NODE_INVALID;
2197 r = IXMLDOMNode_get_nodeType( node, &type);
2198 ok( r == S_OK, "getNamedItem returned wrong code\n");
2199 ok( type == NODE_ELEMENT, "node not text\n");
2200
2201 r = IXMLDOMNode_hasChildNodes( node, NULL );
2202 ok( r == E_INVALIDARG, "hasChildNodes bad return\n");
2203
2204 EXPECT_CHILDREN(node);
2205
2206 str = NULL;
2207 r = IXMLDOMNode_get_baseName( node, &str );
2208 ok( r == S_OK, "get_baseName returned wrong code\n");
2209 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
2210 SysFreeString(str);
2211 }
2212 else
2213 ok( FALSE, "no node\n");
2214
2215 if (node)
2216 IXMLDOMNode_Release( node );
2217 if (list)
2218 IXMLDOMNodeList_Release( list );
2219 if (element)
2220 IXMLDOMElement_Release( element );
2221
2222 b = FALSE;
2223 str = SysAllocString( szComplete5 );
2224 r = IXMLDOMDocument_loadXML( doc, str, &b );
2225 ok( r == S_OK, "loadXML failed\n");
2226 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2227 SysFreeString( str );
2228
2229 EXPECT_CHILDREN(doc);
2230
2231 r = IXMLDOMDocument_get_documentElement( doc, &element );
2232 ok( r == S_OK, "should be a document element\n");
2233 ok( element != NULL, "should be an element\n");
2234
2235 if (element)
2236 {
2237 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
2238 BSTR tag = NULL;
2239
2240 /* check if the tag is correct */
2241 r = IXMLDOMElement_get_tagName( element, &tag );
2242 ok( r == S_OK, "couldn't get tag name\n");
2243 ok( tag != NULL, "tag was null\n");
2244 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
2245 SysFreeString( tag );
2246
2247 IXMLDOMElement_Release( element );
2248 }
2249 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2250
2251 free_bstrs();
2252 }
2253
2254 typedef struct {
2255 DOMNodeType type;
2256 REFIID iid;
2257 } refcount_test_t;
2258
2259 static const refcount_test_t refcount_test[] = {
2260 { NODE_ELEMENT, &IID_IXMLDOMElement },
2261 { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute },
2262 { NODE_TEXT, &IID_IXMLDOMText },
2263 { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection },
2264 { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference },
2265 { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction },
2266 { NODE_COMMENT, &IID_IXMLDOMComment },
2267 { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment },
2268 { NODE_INVALID, &IID_NULL }
2269 };
2270
2271 static void test_refs(void)
2272 {
2273 IXMLDOMImplementation *impl, *impl2;
2274 IXMLDOMElement *element, *elem2;
2275 IXMLDOMNodeList *node_list = NULL;
2276 IXMLDOMNode *node, *node2, *node3;
2277 const refcount_test_t *ptr;
2278 IXMLDOMDocument *doc;
2279 IUnknown *unk, *unk2;
2280 VARIANT_BOOL b;
2281 HRESULT hr;
2282 LONG ref;
2283
2284 doc = create_document(&IID_IXMLDOMDocument);
2285
2286 ptr = refcount_test;
2287 while (ptr->type != NODE_INVALID)
2288 {
2289 IUnknown *node_typed, *node_typed2;
2290 IDispatchEx *dispex, *dispex2;
2291 IDispatch *disp, *disp2;
2292 VARIANT type;
2293
2294 V_VT(&type) = VT_I1;
2295 V_I1(&type) = ptr->type;
2296
2297 EXPECT_REF(doc, 1);
2298 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node);
2299 EXPECT_HR(hr, S_OK);
2300 EXPECT_REF(doc, 1);
2301 EXPECT_REF(node, 1);
2302
2303 /* try IDispatch and IUnknown from IXMLDOMNode */
2304 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
2305 EXPECT_HR(hr, S_OK);
2306 EXPECT_REF(unk, 2);
2307 todo_wine {
2308 EXPECT_REF(node, 1);
2309 ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node);
2310 }
2311 EXPECT_REF(unk, 2);
2312 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2313 EXPECT_HR(hr, S_OK);
2314 todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp);
2315 EXPECT_REF(unk, 3);
2316 todo_wine EXPECT_REF(disp, 1);
2317
2318 EXPECT_REF(unk, 3);
2319 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2);
2320 EXPECT_HR(hr, S_OK);
2321 todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2);
2322 EXPECT_REF(unk, 4);
2323 todo_wine EXPECT_REF(disp2, 1);
2324
2325 IDispatch_Release(disp);
2326 IDispatch_Release(disp2);
2327
2328 /* get IXMLDOMNode from this IUnknown */
2329 EXPECT_REF(unk, 2);
2330 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2);
2331 EXPECT_HR(hr, S_OK);
2332 todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2);
2333 EXPECT_REF(unk, 3);
2334 todo_wine EXPECT_REF(node2, 1);
2335
2336 EXPECT_REF(unk, 3);
2337 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3);
2338 EXPECT_HR(hr, S_OK);
2339 todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3);
2340 EXPECT_REF(unk, 4);
2341 todo_wine EXPECT_REF(node3, 1);
2342
2343 IXMLDOMNode_Release(node2);
2344 IXMLDOMNode_Release(node3);
2345
2346 /* try IDispatchEx from IUnknown */
2347 EXPECT_REF(unk, 2);
2348 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
2349 EXPECT_HR(hr, S_OK);
2350 ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex);
2351 EXPECT_REF(unk, 3);
2352 todo_wine EXPECT_REF(dispex, 1);
2353
2354 EXPECT_REF(unk, 3);
2355 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2);
2356 EXPECT_HR(hr, S_OK);
2357 todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2);
2358 EXPECT_REF(unk, 4);
2359 todo_wine EXPECT_REF(dispex2, 1);
2360
2361 IDispatchEx_Release(dispex);
2362 IDispatchEx_Release(dispex2);
2363
2364 /* try corresponding IXMLDOM* */
2365 EXPECT_REF(unk, 2);
2366 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed);
2367 EXPECT_HR(hr, S_OK);
2368 EXPECT_REF(unk, 3);
2369 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2);
2370 EXPECT_HR(hr, S_OK);
2371 EXPECT_REF(unk, 4);
2372 todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2);
2373 IUnknown_Release(node_typed);
2374 IUnknown_Release(node_typed2);
2375
2376 /* try invalid IXMLDOM* */
2377 hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed);
2378 EXPECT_HR(hr, E_NOINTERFACE);
2379
2380 IUnknown_Release(unk);
2381
2382 EXPECT_REF(node, 1);
2383 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2);
2384 EXPECT_HR(hr, S_OK);
2385 EXPECT_REF(node, 2);
2386 ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2);
2387
2388 EXPECT_REF(node, 2);
2389 hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed);
2390 EXPECT_HR(hr, S_OK);
2391 EXPECT_REF(node, 3);
2392 todo_wine {
2393 EXPECT_REF(node_typed, 2);
2394 ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed);
2395 }
2396 IUnknown_Release(node_typed);
2397
2398 IXMLDOMNode_Release(node2);
2399 IXMLDOMNode_Release(node);
2400
2401 ptr++;
2402 }
2403
2404 EXPECT_REF(doc, 1);
2405 ref = IXMLDOMDocument_Release(doc);
2406 ok( ref == 0, "ref %d\n", ref);
2407
2408 /* check IUnknown after releasing DOM iface */
2409 doc = create_document(&IID_IXMLDOMDocument);
2410 EXPECT_REF(doc, 1);
2411 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2412 EXPECT_HR(hr, S_OK);
2413 todo_wine {
2414 EXPECT_REF(unk, 3);
2415 EXPECT_REF(doc, 1);
2416 }
2417 IXMLDOMDocument_Release(doc);
2418 EXPECT_REF(unk, 1);
2419 IUnknown_Release(unk);
2420
2421 doc = create_document(&IID_IXMLDOMDocument);
2422
2423 EXPECT_REF(doc, 1);
2424 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2425 EXPECT_HR(hr, S_OK);
2426 todo_wine {
2427 EXPECT_REF(unk, 3);
2428 EXPECT_REF(doc, 1);
2429 }
2430 IUnknown_Release(unk);
2431
2432 /* IXMLDOMImplementation */
2433 EXPECT_REF(doc, 1);
2434 hr = IXMLDOMDocument_get_implementation(doc, &impl);
2435 EXPECT_HR(hr, S_OK);
2436 EXPECT_REF(doc, 1);
2437 EXPECT_REF(impl, 1);
2438 hr = IXMLDOMDocument_get_implementation(doc, &impl2);
2439 EXPECT_HR(hr, S_OK);
2440 EXPECT_REF(doc, 1);
2441 EXPECT_REF(impl2, 1);
2442 ok(impl != impl2, "got %p, %p\n", impl, impl2);
2443 IXMLDOMImplementation_Release(impl);
2444 IXMLDOMImplementation_Release(impl2);
2445
2446 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
2447 EXPECT_HR(hr, S_OK);
2448 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2449
2450 EXPECT_REF(doc, 1);
2451 IXMLDOMDocument_AddRef( doc );
2452 EXPECT_REF(doc, 2);
2453 IXMLDOMDocument_AddRef( doc );
2454 EXPECT_REF(doc, 3);
2455
2456 IXMLDOMDocument_Release( doc );
2457 IXMLDOMDocument_Release( doc );
2458
2459 EXPECT_REF(doc, 1);
2460 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
2461 EXPECT_HR(hr, S_OK);
2462 todo_wine {
2463 EXPECT_REF(unk, 3);
2464 EXPECT_REF(doc, 1);
2465 }
2466 hr = IXMLDOMDocument_get_documentElement(doc, &element);
2467 EXPECT_HR(hr, S_OK);
2468 todo_wine {
2469 EXPECT_REF(doc, 1);
2470 EXPECT_REF(element, 2);
2471 }
2472 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
2473 EXPECT_HR(hr, S_OK);
2474
2475 todo_wine {
2476 EXPECT_REF(doc, 1);
2477 EXPECT_REF(element, 2);
2478 EXPECT_REF(elem2, 2);
2479 }
2480 IXMLDOMElement_AddRef(element);
2481 todo_wine EXPECT_REF(element, 3);
2482 IXMLDOMElement_Release(element);
2483
2484 /* get IUnknown from a node doesn't touch node instance refcount */
2485 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2486 EXPECT_HR(hr, S_OK);
2487 EXPECT_REF(element, 2);
2488 todo_wine {
2489 EXPECT_REF(unk, 4);
2490 EXPECT_REF(elem2, 2);
2491 }
2492 hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2);
2493 EXPECT_HR(hr, S_OK);
2494 todo_wine {
2495 EXPECT_REF(unk, 5);
2496 EXPECT_REF(unk2, 5);
2497 }
2498 EXPECT_REF(element, 2);
2499 EXPECT_REF(elem2, 2);
2500
2501 todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
2502 IUnknown_Release(unk);
2503
2504 /* IUnknown refcount is not affected by node refcount */
2505 todo_wine EXPECT_REF(unk2, 4);
2506 IXMLDOMElement_AddRef(elem2);
2507 todo_wine EXPECT_REF(unk2, 4);
2508 IXMLDOMElement_Release(elem2);
2509
2510 IXMLDOMElement_Release(elem2);
2511 todo_wine EXPECT_REF(unk2, 3);
2512
2513 IUnknown_Release(unk2);
2514
2515 hr = IXMLDOMElement_get_childNodes( element, &node_list );
2516 EXPECT_HR(hr, S_OK);
2517
2518 todo_wine EXPECT_REF(element, 2);
2519 EXPECT_REF(node_list, 1);
2520
2521 hr = IXMLDOMNodeList_get_item( node_list, 0, &node );
2522 EXPECT_HR(hr, S_OK);
2523 EXPECT_REF(node_list, 1);
2524 EXPECT_REF(node, 1);
2525
2526 hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2527 EXPECT_HR(hr, S_OK);
2528 EXPECT_REF(node_list, 1);
2529 EXPECT_REF(node2, 1);
2530
2531 ref = IXMLDOMNode_Release( node );
2532 ok( ref == 0, "ref %d\n", ref );
2533 ref = IXMLDOMNode_Release( node2 );
2534 ok( ref == 0, "ref %d\n", ref );
2535
2536 ref = IXMLDOMNodeList_Release( node_list );
2537 ok( ref == 0, "ref %d\n", ref );
2538
2539 ok( node != node2, "node %p node2 %p\n", node, node2 );
2540
2541 ref = IXMLDOMDocument_Release( doc );
2542 todo_wine ok( ref == 0, "ref %d\n", ref );
2543
2544 todo_wine EXPECT_REF(element, 2);
2545
2546 /* IUnknown must be unique however we obtain it */
2547 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk);
2548 EXPECT_HR(hr, S_OK);
2549 EXPECT_REF(element, 2);
2550 hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node);
2551 EXPECT_HR(hr, S_OK);
2552 todo_wine EXPECT_REF(element, 2);
2553 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2);
2554 EXPECT_HR(hr, S_OK);
2555 todo_wine EXPECT_REF(element, 2);
2556 ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2);
2557 todo_wine ok(element != (void*)node, "node %p element %p\n", node, element);
2558
2559 IUnknown_Release( unk2 );
2560 IUnknown_Release( unk );
2561 IXMLDOMNode_Release( node );
2562 todo_wine EXPECT_REF(element, 2);
2563
2564 IXMLDOMElement_Release( element );
2565
2566 free_bstrs();
2567 }
2568
2569 static void test_create(void)
2570 {
2571 static const WCHAR szOne[] = {'1',0};
2572 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2573 HRESULT r;
2574 VARIANT var;
2575 BSTR str, name;
2576 IXMLDOMDocument *doc;
2577 IXMLDOMElement *element;
2578 IXMLDOMComment *comment;
2579 IXMLDOMText *text;
2580 IXMLDOMCDATASection *cdata;
2581 IXMLDOMNode *root, *node, *child;
2582 IXMLDOMNamedNodeMap *attr_map;
2583 IUnknown *unk;
2584 LONG ref;
2585 LONG num;
2586
2587 doc = create_document(&IID_IXMLDOMDocument);
2588
2589 EXPECT_REF(doc, 1);
2590
2591 /* types not supported for creation */
2592 V_VT(&var) = VT_I1;
2593 V_I1(&var) = NODE_DOCUMENT;
2594 node = (IXMLDOMNode*)0x1;
2595 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2596 ok( r == E_INVALIDARG, "returns %08x\n", r );
2597 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2598
2599 V_VT(&var) = VT_I1;
2600 V_I1(&var) = NODE_DOCUMENT_TYPE;
2601 node = (IXMLDOMNode*)0x1;
2602 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2603 ok( r == E_INVALIDARG, "returns %08x\n", r );
2604 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2605
2606 V_VT(&var) = VT_I1;
2607 V_I1(&var) = NODE_ENTITY;
2608 node = (IXMLDOMNode*)0x1;
2609 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2610 ok( r == E_INVALIDARG, "returns %08x\n", r );
2611 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2612
2613 V_VT(&var) = VT_I1;
2614 V_I1(&var) = NODE_NOTATION;
2615 node = (IXMLDOMNode*)0x1;
2616 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2617 ok( r == E_INVALIDARG, "returns %08x\n", r );
2618 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2619
2620 /* NODE_COMMENT */
2621 V_VT(&var) = VT_I1;
2622 V_I1(&var) = NODE_COMMENT;
2623 node = NULL;
2624 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2625 ok( r == S_OK, "returns %08x\n", r );
2626 ok( node != NULL, "\n");
2627
2628 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2629 ok( r == S_OK, "returns %08x\n", r );
2630 IXMLDOMNode_Release(node);
2631
2632 str = NULL;
2633 r = IXMLDOMComment_get_data(comment, &str);
2634 ok( r == S_OK, "returns %08x\n", r );
2635 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2636 IXMLDOMComment_Release(comment);
2637 SysFreeString(str);
2638
2639 node = (IXMLDOMNode*)0x1;
2640 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2641 ok( r == S_OK, "returns %08x\n", r );
2642
2643 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2644 ok( r == S_OK, "returns %08x\n", r );
2645 IXMLDOMNode_Release(node);
2646
2647 str = NULL;
2648 r = IXMLDOMComment_get_data(comment, &str);
2649 ok( r == S_OK, "returns %08x\n", r );
2650 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2651 IXMLDOMComment_Release(comment);
2652 SysFreeString(str);
2653
2654 node = (IXMLDOMNode*)0x1;
2655 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2656 ok( r == S_OK, "returns %08x\n", r );
2657
2658 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2659 ok( r == S_OK, "returns %08x\n", r );
2660 IXMLDOMNode_Release(node);
2661
2662 str = NULL;
2663 r = IXMLDOMComment_get_data(comment, &str);
2664 ok( r == S_OK, "returns %08x\n", r );
2665 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2666 IXMLDOMComment_Release(comment);
2667 SysFreeString(str);
2668
2669 /* NODE_TEXT */
2670 V_VT(&var) = VT_I1;
2671 V_I1(&var) = NODE_TEXT;
2672 node = NULL;
2673 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2674 ok( r == S_OK, "returns %08x\n", r );
2675 ok( node != NULL, "\n");
2676
2677 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2678 ok( r == S_OK, "returns %08x\n", r );
2679 IXMLDOMNode_Release(node);
2680
2681 str = NULL;
2682 r = IXMLDOMText_get_data(text, &str);
2683 ok( r == S_OK, "returns %08x\n", r );
2684 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2685 IXMLDOMText_Release(text);
2686 SysFreeString(str);
2687
2688 node = (IXMLDOMNode*)0x1;
2689 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2690 ok( r == S_OK, "returns %08x\n", r );
2691
2692 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2693 ok( r == S_OK, "returns %08x\n", r );
2694 IXMLDOMNode_Release(node);
2695
2696 str = NULL;
2697 r = IXMLDOMText_get_data(text, &str);
2698 ok( r == S_OK, "returns %08x\n", r );
2699 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2700 IXMLDOMText_Release(text);
2701 SysFreeString(str);
2702
2703 node = (IXMLDOMNode*)0x1;
2704 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2705 ok( r == S_OK, "returns %08x\n", r );
2706
2707 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2708 ok( r == S_OK, "returns %08x\n", r );
2709 IXMLDOMNode_Release(node);
2710
2711 str = NULL;
2712 r = IXMLDOMText_get_data(text, &str);
2713 ok( r == S_OK, "returns %08x\n", r );
2714 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2715 IXMLDOMText_Release(text);
2716 SysFreeString(str);
2717
2718 /* NODE_CDATA_SECTION */
2719 V_VT(&var) = VT_I1;
2720 V_I1(&var) = NODE_CDATA_SECTION;
2721 node = NULL;
2722 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );