wined3d: Get rid of wined3d_buffer_get_desc().
[wine] / dlls / msxml3 / tests / domdoc.c
1 /*
2  * XML test
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2007-2008 Alistair Leslie-Hughes
6  * Copyright 2010 Adam Martinson for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23
24 #define COBJMACROS
25
26 #include "windows.h"
27 #include "ole2.h"
28 #include "objsafe.h"
29 #include "msxml2.h"
30 #include "msxml2did.h"
31 #include "dispex.h"
32 #include <stdio.h>
33 #include <assert.h>
34
35 #include "wine/test.h"
36
37 #include "initguid.h"
38
39 DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f,0x20, 0x00,0x80,0x5f,0x2c,0xd0,0x64);
40
41 static int g_unexpectedcall, g_expectedcall;
42
43 typedef struct
44 {
45     const struct IDispatchVtbl *lpVtbl;
46     LONG ref;
47 } dispevent;
48
49 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
50 {
51     return (dispevent *)((char*)iface - FIELD_OFFSET(dispevent, lpVtbl));
52 }
53
54 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
55 {
56     *ppvObject = NULL;
57
58     if ( IsEqualGUID( riid, &IID_IDispatch) ||
59          IsEqualGUID( riid, &IID_IUnknown) )
60     {
61         *ppvObject = iface;
62     }
63     else
64         return E_NOINTERFACE;
65
66     IDispatch_AddRef( iface );
67
68     return S_OK;
69 }
70
71 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
72 {
73     dispevent *This = impl_from_IDispatch( iface );
74     return InterlockedIncrement( &This->ref );
75 }
76
77 static ULONG WINAPI dispevent_Release(IDispatch *iface)
78 {
79     dispevent *This = impl_from_IDispatch( iface );
80     ULONG ref = InterlockedDecrement( &This->ref );
81
82     if (ref == 0)
83         HeapFree(GetProcessHeap(), 0, This);
84
85     return ref;
86 }
87
88 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
89 {
90     g_unexpectedcall++;
91     *pctinfo = 0;
92     return S_OK;
93 }
94
95 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
96         LCID lcid, ITypeInfo **ppTInfo)
97 {
98     g_unexpectedcall++;
99     return S_OK;
100 }
101
102 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
103         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
104 {
105     g_unexpectedcall++;
106     return S_OK;
107 }
108
109 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
110         LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
111         EXCEPINFO *excepInfo, UINT *argErr)
112 {
113     ok(member == 0, "expected 0 member, got %d\n", member);
114     ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
115     ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
116
117     ok(params->cArgs == 0, "got %d\n", params->cArgs);
118     ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
119     ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
120     ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
121
122     ok(result == NULL, "got %p\n", result);
123     ok(excepInfo == NULL, "got %p\n", excepInfo);
124     ok(argErr == NULL, "got %p\n", argErr);
125
126     g_expectedcall++;
127     return E_FAIL;
128 }
129
130 static const IDispatchVtbl dispeventVtbl =
131 {
132     dispevent_QueryInterface,
133     dispevent_AddRef,
134     dispevent_Release,
135     dispevent_GetTypeInfoCount,
136     dispevent_GetTypeInfo,
137     dispevent_GetIDsOfNames,
138     dispevent_Invoke
139 };
140
141 static IDispatch* create_dispevent(void)
142 {
143     dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
144
145     event->lpVtbl = &dispeventVtbl;
146     event->ref = 1;
147
148     return (IDispatch*)&event->lpVtbl;
149 }
150
151 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
152 static void _expect_children(IXMLDOMNode *node, int line)
153 {
154     VARIANT_BOOL b;
155     HRESULT hr;
156
157     b = VARIANT_FALSE;
158     hr = IXMLDOMNode_hasChildNodes(node, &b);
159     ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
160     ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
161 }
162
163 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
164 static void _expect_no_children(IXMLDOMNode *node, int line)
165 {
166     VARIANT_BOOL b;
167     HRESULT hr;
168
169     b = VARIANT_TRUE;
170     hr = IXMLDOMNode_hasChildNodes(node, &b);
171     ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
172     ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
173 }
174
175 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
176 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
177 {
178     ULONG rc = IUnknown_AddRef(obj);
179     IUnknown_Release(obj);
180     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
181 }
182
183 static const WCHAR szEmpty[] = { 0 };
184 static const WCHAR szIncomplete[] = {
185     '<','?','x','m','l',' ',
186     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
187 };
188 static const WCHAR szComplete1[] = {
189     '<','?','x','m','l',' ',
190     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
191     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
192 };
193 static const WCHAR szComplete2[] = {
194     '<','?','x','m','l',' ',
195     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
196     '<','o','>','<','/','o','>','\n',0
197 };
198 static const WCHAR szComplete3[] = {
199     '<','?','x','m','l',' ',
200     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
201     '<','a','>','<','/','a','>','\n',0
202 };
203 static const WCHAR szComplete4[] = {
204     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
205     '<','l','c',' ','d','l','=','\'','s','t','r','1','\'','>','\n',
206         '<','b','s',' ','v','r','=','\'','s','t','r','2','\'',' ','s','z','=','\'','1','2','3','4','\'','>',
207             'f','n','1','.','t','x','t','\n',
208         '<','/','b','s','>','\n',
209         '<','p','r',' ','i','d','=','\'','s','t','r','3','\'',' ','v','r','=','\'','1','.','2','.','3','\'',' ',
210                     'p','n','=','\'','w','i','n','e',' ','2','0','0','5','0','8','0','4','\'','>','\n',
211             'f','n','2','.','t','x','t','\n',
212         '<','/','p','r','>','\n',
213         '<','e','m','p','t','y','>','<','/','e','m','p','t','y','>','\n',
214         '<','f','o','>','\n',
215             '<','b','a','>','\n',
216                 'f','1','\n',
217             '<','/','b','a','>','\n',
218         '<','/','f','o','>','\n',
219     '<','/','l','c','>','\n',0
220 };
221 static const WCHAR szComplete5[] = {
222     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
223     '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','"',
224     ' ','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','"','>',
225         '<','S',':','s','c','o','p','e','>',
226             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
227         '<','/','S',':','s','c','o','p','e','>',
228         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
229             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
230             'c','o','m','p','u','t','e','r',
231         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
232     '<','/','S',':','s','e','a','r','c','h','>',0
233 };
234
235 static const WCHAR szComplete6[] = {
236     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
237     'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
238     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
239 };
240
241 static const CHAR szNonUnicodeXML[] =
242 "<?xml version='1.0' encoding='Windows-1252'?>\n"
243 "<open></open>\n";
244
245 static const CHAR szExampleXML[] =
246 "<?xml version='1.0' encoding='utf-8'?>\n"
247 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
248 "    <elem>\n"
249 "        <a>A1 field</a>\n"
250 "        <b>B1 field</b>\n"
251 "        <c>C1 field</c>\n"
252 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
253 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
254 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
255 "            </html>\n"
256 "            <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
257 "                This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
258 "            </html>\n"
259 "        </description>\n"
260 "    </elem>\n"
261 "\n"
262 "    <elem>\n"
263 "        <a>A2 field</a>\n"
264 "        <b>B2 field</b>\n"
265 "        <c type=\"old\">C2 field</c>\n"
266 "    </elem>\n"
267 "\n"
268 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
269 "        <a>A3 field</a>\n"
270 "        <b>B3 field</b>\n"
271 "        <c>C3 field</c>\n"
272 "    </elem>\n"
273 "\n"
274 "    <elem>\n"
275 "        <a>A4 field</a>\n"
276 "        <b>B4 field</b>\n"
277 "        <foo:c>C4 field</foo:c>\n"
278 "    </elem>\n"
279 "</root>\n";
280
281 static const CHAR szNodeTypesXML[] =
282 "<?xml version='1.0'?>"
283 "<!-- comment node 0 -->"
284 "<root id='0' depth='0'>"
285 "   <!-- comment node 1 -->"
286 "   text node 0"
287 "   <x id='1' depth='1'>"
288 "       <?foo value='PI for x'?>"
289 "       <!-- comment node 2 -->"
290 "       text node 1"
291 "       <a id='3' depth='2'/>"
292 "       <b id='4' depth='2'/>"
293 "       <c id='5' depth='2'/>"
294 "   </x>"
295 "   <y id='2' depth='1'>"
296 "       <?bar value='PI for y'?>"
297 "       <!-- comment node 3 -->"
298 "       text node 2"
299 "       <a id='6' depth='2'/>"
300 "       <b id='7' depth='2'/>"
301 "       <c id='8' depth='2'/>"
302 "   </y>"
303 "</root>";
304
305 static const CHAR szTransformXML[] =
306 "<?xml version=\"1.0\"?>\n"
307 "<greeting>\n"
308 "Hello World\n"
309 "</greeting>";
310
311 static  const CHAR szTransformSSXML[] =
312 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
313 "   <xsl:output method=\"html\"/>\n"
314 "   <xsl:template match=\"/\">\n"
315 "       <xsl:apply-templates select=\"greeting\"/>\n"
316 "   </xsl:template>\n"
317 "   <xsl:template match=\"greeting\">\n"
318 "       <html>\n"
319 "           <body>\n"
320 "               <h1>\n"
321 "                   <xsl:value-of select=\".\"/>\n"
322 "               </h1>\n"
323 "           </body>\n"
324 "       </html>\n"
325 "   </xsl:template>\n"
326 "</xsl:stylesheet>";
327
328 static  const CHAR szTransformOutput[] =
329 "<html><body><h1>"
330 "Hello World"
331 "</h1></body></html>";
332
333 static const CHAR szTypeValueXML[] =
334 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
335 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
336 "   <string>Wine</string>\n"
337 "   <string2 dt:dt=\"string\">String</string2>\n"
338 "   <number dt:dt=\"number\">12.44</number>\n"
339 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
340 "   <int dt:dt=\"int\">-13</int>\n"
341 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
342 "   <bool dt:dt=\"boolean\">1</bool>\n"
343 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
344 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
345 "   <date dt:dt=\"date\">3721-11-01</date>\n"
346 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
347 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
348 "   <i1 dt:dt=\"i1\">-13</i1>\n"
349 "   <i2 dt:dt=\"i2\">31915</i2>\n"
350 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
351 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
352 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
353 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
354 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
355 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
356 "   <float dt:dt=\"float\">41221.421</float>\n"
357 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
358 "   <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
359 "   <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
360 "</root>";
361
362 static const CHAR szBasicTransformSSXMLPart1[] =
363 "<?xml version=\"1.0\"?>"
364 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
365 "<xsl:output method=\"html\"/>\n"
366 "<xsl:template match=\"/\">"
367 "<HTML><BODY><TABLE>"
368 "        <xsl:apply-templates select='document(\"";
369
370 static const CHAR szBasicTransformSSXMLPart2[] =
371 "\")/bottle/wine'>"
372 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
373 "        </xsl:apply-templates>"
374 "</TABLE></BODY></HTML>"
375 "</xsl:template>"
376 "<xsl:template match=\"bottle\">"
377 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
378 "</xsl:template>"
379 "<xsl:template match=\"name\">"
380 "   <TD><xsl:apply-templates /></TD>"
381 "</xsl:template>"
382 "<xsl:template match=\"cost\">"
383 "   <TD><xsl:apply-templates /></TD>"
384 "</xsl:template>"
385 "</xsl:stylesheet>";
386
387 static const CHAR szBasicTransformXML[] =
388 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
389
390 static const CHAR szBasicTransformOutput[] =
391 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
392
393 #define SZ_EMAIL_DTD \
394 "<!DOCTYPE email ["\
395 "   <!ELEMENT email         (recipients,from,reply-to?,subject,body,attachment*)>"\
396 "       <!ATTLIST email attachments IDREFS #REQUIRED>"\
397 "       <!ATTLIST email sent (yes|no) \"no\">"\
398 "   <!ELEMENT recipients    (to+,cc*)>"\
399 "   <!ELEMENT to            (#PCDATA)>"\
400 "       <!ATTLIST to name CDATA #IMPLIED>"\
401 "   <!ELEMENT cc            (#PCDATA)>"\
402 "       <!ATTLIST cc name CDATA #IMPLIED>"\
403 "   <!ELEMENT from          (#PCDATA)>"\
404 "       <!ATTLIST from name CDATA #IMPLIED>"\
405 "   <!ELEMENT reply-to      (#PCDATA)>"\
406 "       <!ATTLIST reply-to name CDATA #IMPLIED>"\
407 "   <!ELEMENT subject       ANY>"\
408 "   <!ELEMENT body          ANY>"\
409 "       <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
410 "   <!ELEMENT attachment    (#PCDATA)>"\
411 "       <!ATTLIST attachment id ID #REQUIRED>"\
412 "]>"
413
414 static const CHAR szEmailXML[] =
415 "<?xml version=\"1.0\"?>"
416 SZ_EMAIL_DTD
417 "<email attachments=\"patch1\">"
418 "   <recipients>"
419 "       <to>wine-patches@winehq.org</to>"
420 "   </recipients>"
421 "   <from name=\"Anonymous\">user@localhost</from>"
422 "   <subject>msxml3/tests: DTD validation (try 87)</subject>"
423 "   <body>"
424 "       It no longer causes spontaneous combustion..."
425 "   </body>"
426 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
427 "</email>";
428
429 static const CHAR szEmailXML_0D[] =
430 "<?xml version=\"1.0\"?>"
431 SZ_EMAIL_DTD
432 "<email attachments=\"patch1\">"
433 "   <recipients>"
434 "       <to>wine-patches@winehq.org</to>"
435 "   </recipients>"
436 "   <from name=\"Anonymous\">user@localhost</from>"
437 "   <subject>msxml3/tests: DTD validation (try 88)</subject>"
438 "   <body>"
439 "       <undecl />"
440 "       XML_ELEMENT_UNDECLARED 0xC00CE00D"
441 "   </body>"
442 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
443 "</email>";
444
445 static const CHAR szEmailXML_0E[] =
446 "<?xml version=\"1.0\"?>"
447 SZ_EMAIL_DTD
448 "<email attachments=\"patch1\">"
449 "   <recipients>"
450 "       <to>wine-patches@winehq.org</to>"
451 "   </recipients>"
452 "   <from name=\"Anonymous\">user@localhost</from>"
453 "   <subject>msxml3/tests: DTD validation (try 89)</subject>"
454 "   <body>"
455 "       XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
456 "   </body>"
457 "   <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
458 "</email>";
459
460 static const CHAR szEmailXML_11[] =
461 "<?xml version=\"1.0\"?>"
462 SZ_EMAIL_DTD
463 "<email attachments=\"patch1\">"
464 "   <recipients>"
465 "   </recipients>"
466 "   <from name=\"Anonymous\">user@localhost</from>"
467 "   <subject>msxml3/tests: DTD validation (try 90)</subject>"
468 "   <body>"
469 "       XML_EMPTY_NOT_ALLOWED 0xC00CE011"
470 "   </body>"
471 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
472 "</email>";
473
474 static const CHAR szEmailXML_13[] =
475 "<?xml version=\"1.0\"?>"
476 SZ_EMAIL_DTD
477 "<msg attachments=\"patch1\">"
478 "   <recipients>"
479 "       <to>wine-patches@winehq.org</to>"
480 "   </recipients>"
481 "   <from name=\"Anonymous\">user@localhost</from>"
482 "   <subject>msxml3/tests: DTD validation (try 91)</subject>"
483 "   <body>"
484 "       XML_ROOT_NAME_MISMATCH 0xC00CE013"
485 "   </body>"
486 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
487 "</msg>";
488
489 static const CHAR szEmailXML_14[] =
490 "<?xml version=\"1.0\"?>"
491 SZ_EMAIL_DTD
492 "<email attachments=\"patch1\">"
493 "   <to>wine-patches@winehq.org</to>"
494 "   <from name=\"Anonymous\">user@localhost</from>"
495 "   <subject>msxml3/tests: DTD validation (try 92)</subject>"
496 "   <body>"
497 "       XML_INVALID_CONTENT 0xC00CE014"
498 "   </body>"
499 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
500 "</email>";
501
502 static const CHAR szEmailXML_15[] =
503 "<?xml version=\"1.0\"?>"
504 SZ_EMAIL_DTD
505 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
506 "   <recipients>"
507 "       <to>wine-patches@winehq.org</to>"
508 "   </recipients>"
509 "   <from name=\"Anonymous\">user@localhost</from>"
510 "   <subject>msxml3/tests: DTD validation (try 93)</subject>"
511 "   <body>"
512 "       XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
513 "   </body>"
514 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
515 "</email>";
516
517 static const CHAR szEmailXML_16[] =
518 "<?xml version=\"1.0\"?>"
519 SZ_EMAIL_DTD
520 "<email attachments=\"patch1\">"
521 "   <recipients>"
522 "       <to>wine-patches@winehq.org</to>"
523 "   </recipients>"
524 "   <from name=\"Anonymous\">user@localhost</from>"
525 "   <subject>msxml3/tests: DTD validation (try 94)</subject>"
526 "   <body enc=\"ASCII\">"
527 "       XML_ATTRIBUTE_FIXED 0xC00CE016"
528 "   </body>"
529 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
530 "</email>";
531
532 static const CHAR szEmailXML_17[] =
533 "<?xml version=\"1.0\"?>"
534 SZ_EMAIL_DTD
535 "<email attachments=\"patch1\" sent=\"true\">"
536 "   <recipients>"
537 "       <to>wine-patches@winehq.org</to>"
538 "   </recipients>"
539 "   <from name=\"Anonymous\">user@localhost</from>"
540 "   <subject>msxml3/tests: DTD validation (try 95)</subject>"
541 "   <body>"
542 "       XML_ATTRIBUTE_VALUE 0xC00CE017"
543 "   </body>"
544 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
545 "</email>";
546
547 static const CHAR szEmailXML_18[] =
548 "<?xml version=\"1.0\"?>"
549 SZ_EMAIL_DTD
550 "<email attachments=\"patch1\">"
551 "   oops"
552 "   <recipients>"
553 "       <to>wine-patches@winehq.org</to>"
554 "   </recipients>"
555 "   <from name=\"Anonymous\">user@localhost</from>"
556 "   <subject>msxml3/tests: DTD validation (try 96)</subject>"
557 "   <body>"
558 "       XML_ILLEGAL_TEXT 0xC00CE018"
559 "   </body>"
560 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
561 "</email>";
562
563 static const CHAR szEmailXML_20[] =
564 "<?xml version=\"1.0\"?>"
565 SZ_EMAIL_DTD
566 "<email>"
567 "   <recipients>"
568 "       <to>wine-patches@winehq.org</to>"
569 "   </recipients>"
570 "   <from name=\"Anonymous\">user@localhost</from>"
571 "   <subject>msxml3/tests: DTD validation (try 97)</subject>"
572 "   <body>"
573 "       XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
574 "   </body>"
575 "   <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
576 "</email>";
577
578 static const WCHAR szNonExistentFile[] = {
579     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
580 };
581 static const WCHAR szNonExistentAttribute[] = {
582     'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
583 };
584 static const WCHAR szDocument[] = {
585     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
586 };
587
588 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
589 static WCHAR szdl[] = { 'd','l',0 };
590 static const WCHAR szvr[] = { 'v','r',0 };
591 static const WCHAR szlc[] = { 'l','c',0 };
592 static WCHAR szbs[] = { 'b','s',0 };
593 static const WCHAR szstr1[] = { 's','t','r','1',0 };
594 static const WCHAR szstr2[] = { 's','t','r','2',0 };
595 static const WCHAR szstar[] = { '*',0 };
596 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
597
598 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
599 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
600 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
601
602 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
603 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
604 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
605 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
606                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
607 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
608                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
609
610 static WCHAR szAttribute[] = {'A','t','t','r',0 };
611 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
612
613 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
614                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
615 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
616                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
617                              '!',']',']','>',0};
618 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
619 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
620
621 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
622 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
623 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
624
625 #define expect_bstr_eq_and_free(bstr, expect) { \
626     BSTR bstrExp = alloc_str_from_narrow(expect); \
627     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
628     SysFreeString(bstr); \
629     SysFreeString(bstrExp); \
630 }
631
632 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
633
634 #define ole_check(expr) { \
635     HRESULT r = expr; \
636     ok(r == S_OK, #expr " returned %x\n", r); \
637 }
638
639 #define ole_expect(expr, expect) { \
640     HRESULT r = expr; \
641     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
642 }
643
644 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
645
646 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
647 {
648     void *obj = NULL;
649     HRESULT hr;
650
651     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
652     if (hr != S_OK)
653         win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
654
655     return obj;
656 }
657
658 #define _create(cls) cls, #cls
659
660 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
661 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
662 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
663 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
664 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
665
666 static BSTR alloc_str_from_narrow(const char *str)
667 {
668     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
669     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
670     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
671     return ret;
672 }
673
674 static BSTR alloced_bstrs[256];
675 static int alloced_bstrs_count;
676
677 static BSTR _bstr_(const char *str)
678 {
679     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
680     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
681     return alloced_bstrs[alloced_bstrs_count++];
682 }
683
684 static void free_bstrs(void)
685 {
686     int i;
687     for (i = 0; i < alloced_bstrs_count; i++)
688         SysFreeString(alloced_bstrs[i]);
689     alloced_bstrs_count = 0;
690 }
691
692 static VARIANT _variantbstr_(const char *str)
693 {
694     VARIANT v;
695     V_VT(&v) = VT_BSTR;
696     V_BSTR(&v) = _bstr_(str);
697     return v;
698 }
699
700 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
701 {
702     for (;;)
703     {
704         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
705         while (*sRight == '\r' || *sRight == '\n') sRight++;
706         if (*sLeft != *sRight) return FALSE;
707         if (!*sLeft) return TRUE;
708         sLeft++;
709         sRight++;
710     }
711 }
712
713 static void get_str_for_type(DOMNodeType type, char *buf)
714 {
715     switch (type)
716     {
717         case NODE_ATTRIBUTE:
718             strcpy(buf, "A");
719             break;
720         case NODE_ELEMENT:
721             strcpy(buf, "E");
722             break;
723         case NODE_DOCUMENT:
724             strcpy(buf, "D");
725             break;
726         case NODE_TEXT:
727             strcpy(buf, "T");
728             break;
729         case NODE_COMMENT:
730             strcpy(buf, "C");
731             break;
732         case NODE_PROCESSING_INSTRUCTION:
733             strcpy(buf, "P");
734             break;
735         default:
736             wsprintfA(buf, "[%d]", type);
737     }
738 }
739
740 #define test_disp(u) _test_disp(__LINE__,u)
741 static void _test_disp(unsigned line, IUnknown *unk)
742 {
743     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
744     IDispatchEx *dispex;
745     DWORD dwProps = 0;
746     BSTR sName;
747     UINT ticnt;
748     IUnknown *pUnk;
749     HRESULT hres;
750
751     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
752     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
753     if(FAILED(hres))
754         return;
755
756     ticnt = 0xdeadbeef;
757     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
758     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
759     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
760
761     sName = SysAllocString( szstar );
762     hres = IDispatchEx_DeleteMemberByName(dispex, sName, fdexNameCaseSensitive);
763     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
764     SysFreeString( sName );
765
766     hres = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
767     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
768
769     hres = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &dwProps);
770     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
771     ok(dwProps == 0, "expected 0 got %d\n", dwProps);
772
773     hres = IDispatchEx_GetMemberName(dispex, dispid, &sName);
774     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
775     if(SUCCEEDED(hres))
776         SysFreeString(sName);
777
778     hres = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
779     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
780
781     hres = IDispatchEx_GetNameSpaceParent(dispex, &pUnk);
782     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
783     if(hres == S_OK && pUnk)
784         IUnknown_Release(pUnk);
785
786     IDispatchEx_Release(dispex);
787 }
788
789 static int get_node_position(IXMLDOMNode *node)
790 {
791     HRESULT r;
792     int pos = 0;
793
794     IXMLDOMNode_AddRef(node);
795     do
796     {
797         IXMLDOMNode *new_node;
798
799         pos++;
800         r = IXMLDOMNode_get_previousSibling(node, &new_node);
801         ok(SUCCEEDED(r), "get_previousSibling failed\n");
802         IXMLDOMNode_Release(node);
803         node = new_node;
804     } while (r == S_OK);
805     return pos;
806 }
807
808 static void node_to_string(IXMLDOMNode *node, char *buf)
809 {
810     HRESULT r = S_OK;
811     DOMNodeType type;
812
813     if (node == NULL)
814     {
815         lstrcpyA(buf, "(null)");
816         return;
817     }
818
819     IXMLDOMNode_AddRef(node);
820     while (r == S_OK)
821     {
822         IXMLDOMNode *new_node;
823
824         ole_check(IXMLDOMNode_get_nodeType(node, &type));
825         get_str_for_type(type, buf);
826         buf+=strlen(buf);
827
828         if (type == NODE_ATTRIBUTE)
829         {
830             BSTR bstr;
831             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
832             *(buf++) = '\'';
833             wsprintfA(buf, "%ws", bstr);
834             buf += strlen(buf);
835             *(buf++) = '\'';
836             SysFreeString(bstr);
837
838             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
839         }
840         else
841         {
842             r = IXMLDOMNode_get_parentNode(node, &new_node);
843             wsprintf(buf, "%d", get_node_position(node));
844             buf += strlen(buf);
845         }
846
847         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
848         IXMLDOMNode_Release(node);
849         node = new_node;
850         if (r == S_OK)
851             *(buf++) = '.';
852     }
853
854     *buf = 0;
855 }
856
857 static char *list_to_string(IXMLDOMNodeList *list)
858 {
859     static char buf[4096];
860     char *pos = buf;
861     LONG len = 0;
862     int i;
863
864     if (list == NULL)
865     {
866         lstrcpyA(buf, "(null)");
867         return buf;
868     }
869     ole_check(IXMLDOMNodeList_get_length(list, &len));
870     for (i = 0; i < len; i++)
871     {
872         IXMLDOMNode *node;
873         if (i > 0)
874             *(pos++) = ' ';
875         ole_check(IXMLDOMNodeList_nextNode(list, &node));
876         node_to_string(node, pos);
877         pos += strlen(pos);
878         IXMLDOMNode_Release(node);
879     }
880     *pos = 0;
881     return buf;
882 }
883
884 #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); }
885 #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); }
886
887 static void test_domdoc( void )
888 {
889     HRESULT r;
890     IXMLDOMDocument *doc;
891     IXMLDOMParseError *error;
892     IXMLDOMElement *element = NULL;
893     IXMLDOMNode *node;
894     IXMLDOMText *nodetext = NULL;
895     IXMLDOMComment *node_comment = NULL;
896     IXMLDOMAttribute *node_attr = NULL;
897     IXMLDOMNode *nodeChild = NULL;
898     IXMLDOMProcessingInstruction *nodePI = NULL;
899     ISupportErrorInfo *support_error = NULL;
900     VARIANT_BOOL b;
901     VARIANT var;
902     BSTR str;
903     LONG code;
904     LONG nLength = 0;
905     WCHAR buff[100];
906
907     doc = create_document(&IID_IXMLDOMDocument);
908     if (!doc) return;
909
910     test_disp((IUnknown*)doc);
911
912 if (0)
913 {
914     /* crashes on native */
915     IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
916 }
917
918     /* try some stupid things */
919     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
920     ok( r == S_FALSE, "loadXML succeeded\n");
921
922     b = VARIANT_TRUE;
923     r = IXMLDOMDocument_loadXML( doc, NULL, &b );
924     ok( r == S_FALSE, "loadXML succeeded\n");
925     ok( b == VARIANT_FALSE, "failed to load XML string\n");
926
927     /* try to load a document from a nonexistent file */
928     b = VARIANT_TRUE;
929     str = SysAllocString( szNonExistentFile );
930     VariantInit(&var);
931     V_VT(&var) = VT_BSTR;
932     V_BSTR(&var) = str;
933
934     r = IXMLDOMDocument_load( doc, var, &b);
935     ok( r == S_FALSE, "loadXML succeeded\n");
936     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
937     SysFreeString( str );
938
939     /* try load an empty document */
940     b = VARIANT_TRUE;
941     str = SysAllocString( szEmpty );
942     r = IXMLDOMDocument_loadXML( doc, str, &b );
943     ok( r == S_FALSE, "loadXML succeeded\n");
944     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
945     SysFreeString( str );
946
947     r = IXMLDOMDocument_get_async( doc, &b );
948     ok( r == S_OK, "get_async failed (%08x)\n", r);
949     ok( b == VARIANT_TRUE, "Wrong default value\n");
950
951     /* check that there's no document element */
952     element = NULL;
953     r = IXMLDOMDocument_get_documentElement( doc, &element );
954     ok( r == S_FALSE, "should be no document element\n");
955
956     /* try finding a node */
957     node = NULL;
958     str = SysAllocString( szstr1 );
959     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
960     ok( r == S_FALSE, "ret %08x\n", r );
961     SysFreeString( str );
962
963     b = VARIANT_TRUE;
964     str = SysAllocString( szIncomplete );
965     r = IXMLDOMDocument_loadXML( doc, str, &b );
966     ok( r == S_FALSE, "loadXML succeeded\n");
967     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
968     SysFreeString( str );
969
970     /* check that there's no document element */
971     element = (IXMLDOMElement*)1;
972     r = IXMLDOMDocument_get_documentElement( doc, &element );
973     ok( r == S_FALSE, "should be no document element\n");
974     ok( element == NULL, "Element should be NULL\n");
975
976     /* test for BSTR handling, pass broken BSTR */
977     memcpy(&buff[2], szComplete1, sizeof(szComplete1));
978     /* just a big length */
979     *(DWORD*)buff = 0xf0f0;
980     b = VARIANT_FALSE;
981     r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
982     ok( r == S_OK, "loadXML failed\n");
983     ok( b == VARIANT_TRUE, "failed to load XML string\n");
984
985     /* loadXML ignores the encoding attribute and always expects Unicode */
986     b = VARIANT_FALSE;
987     str = SysAllocString( szComplete6 );
988     r = IXMLDOMDocument_loadXML( doc, str, &b );
989     ok( r == S_OK, "loadXML failed\n");
990     ok( b == VARIANT_TRUE, "failed to load XML string\n");
991     SysFreeString( str );
992
993     /* try a BSTR containing a Windows-1252 document */
994     b = VARIANT_TRUE;
995     str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
996     r = IXMLDOMDocument_loadXML( doc, str, &b );
997     ok( r == S_FALSE, "loadXML succeeded\n");
998     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
999     SysFreeString( str );
1000
1001     /* try to load something valid */
1002     b = VARIANT_FALSE;
1003     str = SysAllocString( szComplete1 );
1004     r = IXMLDOMDocument_loadXML( doc, str, &b );
1005     ok( r == S_OK, "loadXML failed\n");
1006     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1007     SysFreeString( str );
1008
1009     /* check if nodename is correct */
1010     r = IXMLDOMDocument_get_nodeName( doc, NULL );
1011     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1012
1013     str = (BSTR)0xdeadbeef;
1014     r = IXMLDOMDocument_get_baseName( doc, &str );
1015     ok ( r == S_FALSE, "got 0x%08x\n", r);
1016     ok (str == NULL, "got %p\n", str);
1017
1018     /* content doesn't matter here */
1019     str = NULL;
1020     r = IXMLDOMDocument_get_nodeName( doc, &str );
1021     ok ( r == S_OK, "get_nodeName wrong code\n");
1022     ok ( str != NULL, "str is null\n");
1023     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1024     SysFreeString( str );
1025
1026     /* test put_text */
1027     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
1028     ok( r == E_FAIL, "ret %08x\n", r );
1029
1030     /* check that there's a document element */
1031     element = NULL;
1032     r = IXMLDOMDocument_get_documentElement( doc, &element );
1033     ok( r == S_OK, "should be a document element\n");
1034     if( element )
1035     {
1036         IObjectIdentity *ident;
1037
1038         test_disp((IUnknown*)element);
1039
1040         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1041         ok( r == E_NOINTERFACE, "ret %08x\n", r);
1042
1043         IXMLDOMElement_Release( element );
1044         element = NULL;
1045     }
1046
1047     /* as soon as we call loadXML again, the document element will disappear */
1048     b = 2;
1049     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1050     ok( r == S_FALSE, "loadXML failed\n");
1051     ok( b == 2, "variant modified\n");
1052     r = IXMLDOMDocument_get_documentElement( doc, &element );
1053     ok( r == S_FALSE, "should be no document element\n");
1054
1055     /* try to load something else simple and valid */
1056     b = VARIANT_FALSE;
1057     str = SysAllocString( szComplete3 );
1058     r = IXMLDOMDocument_loadXML( doc, str, &b );
1059     ok( r == S_OK, "loadXML failed\n");
1060     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1061     SysFreeString( str );
1062
1063     /* try something a little more complicated */
1064     b = FALSE;
1065     str = SysAllocString( szComplete4 );
1066     r = IXMLDOMDocument_loadXML( doc, str, &b );
1067     ok( r == S_OK, "loadXML failed\n");
1068     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1069     SysFreeString( str );
1070
1071     r = IXMLDOMDocument_get_parseError( doc, &error );
1072     ok( r == S_OK, "returns %08x\n", r );
1073
1074     r = IXMLDOMParseError_get_errorCode( error, &code );
1075     ok( r == S_FALSE, "returns %08x\n", r );
1076     ok( code == 0, "code %d\n", code );
1077     IXMLDOMParseError_Release( error );
1078
1079     /* test createTextNode */
1080     r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1081     ok( r == S_OK, "returns %08x\n", r );
1082     IXMLDOMText_Release(nodetext);
1083
1084     str = SysAllocString( szOpen );
1085     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1086     ok( r == E_INVALIDARG, "returns %08x\n", r );
1087     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1088     ok( r == S_OK, "returns %08x\n", r );
1089     SysFreeString( str );
1090     if(nodetext)
1091     {
1092         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1093         ok(r == E_NOINTERFACE, "ret %08x\n", r );
1094
1095         /* Text Last Child Checks */
1096         r = IXMLDOMText_get_lastChild(nodetext, NULL);
1097         ok(r == E_INVALIDARG, "ret %08x\n", r );
1098
1099         nodeChild = (IXMLDOMNode*)0x1;
1100         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1101         ok(r == S_FALSE, "ret %08x\n", r );
1102         ok(nodeChild == NULL, "nodeChild not NULL\n");
1103
1104         /* test length property */
1105         r = IXMLDOMText_get_length(nodetext, NULL);
1106         ok(r == E_INVALIDARG, "ret %08x\n", r );
1107
1108         r = IXMLDOMText_get_length(nodetext, &nLength);
1109         ok(r == S_OK, "ret %08x\n", r );
1110         ok(nLength == 4, "expected 4 got %d\n", nLength);
1111
1112         /* put data Tests */
1113         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1114         ok(r == S_OK, "ret %08x\n", r );
1115
1116         /* get data Tests */
1117         r = IXMLDOMText_get_data(nodetext, &str);
1118         ok(r == S_OK, "ret %08x\n", r );
1119         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1120         SysFreeString(str);
1121
1122         /* Confirm XML text is good */
1123         r = IXMLDOMText_get_xml(nodetext, &str);
1124         ok(r == S_OK, "ret %08x\n", r );
1125         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
1126         SysFreeString(str);
1127
1128         /* Confirm we get the put_data Text back */
1129         r = IXMLDOMText_get_text(nodetext, &str);
1130         ok(r == S_OK, "ret %08x\n", r );
1131         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1132         SysFreeString(str);
1133
1134         /* test substringData */
1135         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1136         ok(r == E_INVALIDARG, "ret %08x\n", r );
1137
1138         /* test substringData - Invalid offset */
1139         str = (BSTR)&szElement;
1140         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1141         ok(r == E_INVALIDARG, "ret %08x\n", r );
1142         ok( str == NULL, "incorrect string\n");
1143
1144         /* test substringData - Invalid offset */
1145         str = (BSTR)&szElement;
1146         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1147         ok(r == S_FALSE, "ret %08x\n", r );
1148         ok( str == NULL, "incorrect string\n");
1149
1150         /* test substringData - Invalid size */
1151         str = (BSTR)&szElement;
1152         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1153         ok(r == E_INVALIDARG, "ret %08x\n", r );
1154         ok( str == NULL, "incorrect string\n");
1155
1156         /* test substringData - Invalid size */
1157         str = (BSTR)&szElement;
1158         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1159         ok(r == S_FALSE, "ret %08x\n", r );
1160         ok( str == NULL, "incorrect string\n");
1161
1162         /* test substringData - Start of string */
1163         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1164         ok(r == S_OK, "ret %08x\n", r );
1165         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1166         SysFreeString(str);
1167
1168         /* test substringData - Middle of string */
1169         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1170         ok(r == S_OK, "ret %08x\n", r );
1171         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1172         SysFreeString(str);
1173
1174         /* test substringData - End of string */
1175         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1176         ok(r == S_OK, "ret %08x\n", r );
1177         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1178         SysFreeString(str);
1179
1180         /* test appendData */
1181         r = IXMLDOMText_appendData(nodetext, NULL);
1182         ok(r == S_OK, "ret %08x\n", r );
1183
1184         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1185         ok(r == S_OK, "ret %08x\n", r );
1186
1187         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1188         ok(r == S_OK, "ret %08x\n", r );
1189
1190         r = IXMLDOMText_get_text(nodetext, &str);
1191         ok(r == S_OK, "ret %08x\n", r );
1192         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1193         SysFreeString(str);
1194
1195         /* test insertData */
1196         str = SysAllocStringLen(NULL, 0);
1197         r = IXMLDOMText_insertData(nodetext, -1, str);
1198         ok(r == S_OK, "ret %08x\n", r );
1199
1200         r = IXMLDOMText_insertData(nodetext, -1, NULL);
1201         ok(r == S_OK, "ret %08x\n", r );
1202
1203         r = IXMLDOMText_insertData(nodetext, 1000, str);
1204         ok(r == S_OK, "ret %08x\n", r );
1205
1206         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1207         ok(r == S_OK, "ret %08x\n", r );
1208
1209         r = IXMLDOMText_insertData(nodetext, 0, NULL);
1210         ok(r == S_OK, "ret %08x\n", r );
1211
1212         r = IXMLDOMText_insertData(nodetext, 0, str);
1213         ok(r == S_OK, "ret %08x\n", r );
1214         SysFreeString(str);
1215
1216         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1217         ok(r == E_INVALIDARG, "ret %08x\n", r );
1218
1219         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1220         ok(r == E_INVALIDARG, "ret %08x\n", r );
1221
1222         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1223         ok(r == S_OK, "ret %08x\n", r );
1224
1225         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1226         ok(r == S_OK, "ret %08x\n", r );
1227
1228         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1229         ok(r == S_OK, "ret %08x\n", r );
1230
1231         r = IXMLDOMText_get_text(nodetext, &str);
1232         ok(r == S_OK, "ret %08x\n", r );
1233         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1234         SysFreeString(str);
1235
1236         /* delete data */
1237         /* invalid arguments */
1238         r = IXMLDOMText_deleteData(nodetext, -1, 1);
1239         ok(r == E_INVALIDARG, "ret %08x\n", r );
1240
1241         r = IXMLDOMText_deleteData(nodetext, 0, 0);
1242         ok(r == S_OK, "ret %08x\n", r );
1243
1244         r = IXMLDOMText_deleteData(nodetext, 0, -1);
1245         ok(r == E_INVALIDARG, "ret %08x\n", r );
1246
1247         r = IXMLDOMText_get_length(nodetext, &nLength);
1248         ok(r == S_OK, "ret %08x\n", r );
1249         ok(nLength == 43, "expected 43 got %d\n", nLength);
1250
1251         r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1252         ok(r == S_OK, "ret %08x\n", r );
1253
1254         r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1255         ok(r == E_INVALIDARG, "ret %08x\n", r );
1256
1257         /* delete from start */
1258         r = IXMLDOMText_deleteData(nodetext, 0, 5);
1259         ok(r == S_OK, "ret %08x\n", r );
1260
1261         r = IXMLDOMText_get_length(nodetext, &nLength);
1262         ok(r == S_OK, "ret %08x\n", r );
1263         ok(nLength == 38, "expected 38 got %d\n", nLength);
1264
1265         r = IXMLDOMText_get_text(nodetext, &str);
1266         ok(r == S_OK, "ret %08x\n", r );
1267         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1268         SysFreeString(str);
1269
1270         /* delete from end */
1271         r = IXMLDOMText_deleteData(nodetext, 35, 3);
1272         ok(r == S_OK, "ret %08x\n", r );
1273
1274         r = IXMLDOMText_get_length(nodetext, &nLength);
1275         ok(r == S_OK, "ret %08x\n", r );
1276         ok(nLength == 35, "expected 35 got %d\n", nLength);
1277
1278         r = IXMLDOMText_get_text(nodetext, &str);
1279         ok(r == S_OK, "ret %08x\n", r );
1280         ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1281         SysFreeString(str);
1282
1283         /* delete from inside */
1284         r = IXMLDOMText_deleteData(nodetext, 1, 33);
1285         ok(r == S_OK, "ret %08x\n", r );
1286
1287         r = IXMLDOMText_get_length(nodetext, &nLength);
1288         ok(r == S_OK, "ret %08x\n", r );
1289         ok(nLength == 2, "expected 2 got %d\n", nLength);
1290
1291         r = IXMLDOMText_get_text(nodetext, &str);
1292         ok(r == S_OK, "ret %08x\n", r );
1293         ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1294         SysFreeString(str);
1295
1296         /* delete whole data ... */
1297         r = IXMLDOMText_get_length(nodetext, &nLength);
1298         ok(r == S_OK, "ret %08x\n", r );
1299
1300         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1301         ok(r == S_OK, "ret %08x\n", r );
1302         /* ... and try again with empty string */
1303         r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1304         ok(r == S_OK, "ret %08x\n", r );
1305
1306         /* test put_data */
1307         V_VT(&var) = VT_BSTR;
1308         V_BSTR(&var) = SysAllocString(szstr1);
1309         r = IXMLDOMText_put_nodeValue(nodetext, var);
1310         ok(r == S_OK, "ret %08x\n", r );
1311         VariantClear(&var);
1312
1313         r = IXMLDOMText_get_text(nodetext, &str);
1314         ok(r == S_OK, "ret %08x\n", r );
1315         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1316         SysFreeString(str);
1317
1318         /* test put_data */
1319         V_VT(&var) = VT_I4;
1320         V_I4(&var) = 99;
1321         r = IXMLDOMText_put_nodeValue(nodetext, var);
1322         ok(r == S_OK, "ret %08x\n", r );
1323         VariantClear(&var);
1324
1325         r = IXMLDOMText_get_text(nodetext, &str);
1326         ok(r == S_OK, "ret %08x\n", r );
1327         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1328         SysFreeString(str);
1329
1330         /* ::replaceData() */
1331         V_VT(&var) = VT_BSTR;
1332         V_BSTR(&var) = SysAllocString(szstr1);
1333         r = IXMLDOMText_put_nodeValue(nodetext, var);
1334         ok(r == S_OK, "ret %08x\n", r );
1335         VariantClear(&var);
1336
1337         r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1338         ok(r == E_INVALIDARG, "ret %08x\n", r );
1339         r = IXMLDOMText_get_text(nodetext, &str);
1340         ok(r == S_OK, "ret %08x\n", r );
1341         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1342         SysFreeString(str);
1343
1344         r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1345         ok(r == S_OK, "ret %08x\n", r );
1346         r = IXMLDOMText_get_text(nodetext, &str);
1347         ok(r == S_OK, "ret %08x\n", r );
1348         ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1349         SysFreeString(str);
1350
1351         /* NULL pointer means delete */
1352         r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1353         ok(r == S_OK, "ret %08x\n", r );
1354         r = IXMLDOMText_get_text(nodetext, &str);
1355         ok(r == S_OK, "ret %08x\n", r );
1356         ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1357         SysFreeString(str);
1358
1359         /* empty string means delete */
1360         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1361         ok(r == S_OK, "ret %08x\n", r );
1362         r = IXMLDOMText_get_text(nodetext, &str);
1363         ok(r == S_OK, "ret %08x\n", r );
1364         ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1365         SysFreeString(str);
1366
1367         /* zero count means insert */
1368         r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1369         ok(r == S_OK, "ret %08x\n", r );
1370         r = IXMLDOMText_get_text(nodetext, &str);
1371         ok(r == S_OK, "ret %08x\n", r );
1372         ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1373         SysFreeString(str);
1374
1375         r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1376         ok(r == S_OK, "ret %08x\n", r );
1377
1378         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1379         ok(r == S_OK, "ret %08x\n", r );
1380         r = IXMLDOMText_get_text(nodetext, &str);
1381         ok(r == S_OK, "ret %08x\n", r );
1382         ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1383         SysFreeString(str);
1384
1385         /* nonempty string, count greater than its length */
1386         r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1387         ok(r == S_OK, "ret %08x\n", r );
1388         r = IXMLDOMText_get_text(nodetext, &str);
1389         ok(r == S_OK, "ret %08x\n", r );
1390         ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1391         SysFreeString(str);
1392
1393         /* nonempty string, count less than its length */
1394         r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
1395         ok(r == S_OK, "ret %08x\n", r );
1396         r = IXMLDOMText_get_text(nodetext, &str);
1397         ok(r == S_OK, "ret %08x\n", r );
1398         ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1399         SysFreeString(str);
1400
1401         IXMLDOMText_Release( nodetext );
1402     }
1403
1404     /* test Create Comment */
1405     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
1406     ok( r == E_INVALIDARG, "returns %08x\n", r );
1407     node_comment = (IXMLDOMComment*)0x1;
1408
1409     /* empty comment */
1410     r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
1411     ok( r == S_OK, "returns %08x\n", r );
1412     str = (BSTR)0x1;
1413     r = IXMLDOMComment_get_data(node_comment, &str);
1414     ok( r == S_OK, "returns %08x\n", r );
1415     ok( str && SysStringLen(str) == 0, "expected empty string data\n");
1416     IXMLDOMComment_Release(node_comment);
1417     SysFreeString(str);
1418
1419     r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
1420     ok( r == S_OK, "returns %08x\n", r );
1421     str = (BSTR)0x1;
1422     r = IXMLDOMComment_get_data(node_comment, &str);
1423     ok( r == S_OK, "returns %08x\n", r );
1424     ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
1425     IXMLDOMComment_Release(node_comment);
1426     SysFreeString(str);
1427
1428     str = SysAllocString(szComment);
1429     r = IXMLDOMDocument_createComment(doc, str, &node_comment);
1430     SysFreeString(str);
1431     ok( r == S_OK, "returns %08x\n", r );
1432     if(node_comment)
1433     {
1434         /* Last Child Checks */
1435         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
1436         ok(r == E_INVALIDARG, "ret %08x\n", r );
1437
1438         nodeChild = (IXMLDOMNode*)0x1;
1439         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
1440         ok(r == S_FALSE, "ret %08x\n", r );
1441         ok(nodeChild == NULL, "pLastChild not NULL\n");
1442
1443         /* baseName */
1444         str = (BSTR)0xdeadbeef;
1445         IXMLDOMComment_get_baseName(node_comment, &str);
1446         ok(r == S_FALSE, "ret %08x\n", r );
1447         ok(str == NULL, "Expected NULL\n");
1448
1449         IXMLDOMComment_Release( node_comment );
1450     }
1451
1452     /* test Create Attribute */
1453     str = SysAllocString(szAttribute);
1454     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
1455     ok( r == E_INVALIDARG, "returns %08x\n", r );
1456     r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
1457     ok( r == S_OK, "returns %08x\n", r );
1458     IXMLDOMText_Release( node_attr);
1459     SysFreeString(str);
1460
1461     /* test Processing Instruction */
1462     str = SysAllocStringLen(NULL, 0);
1463     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
1464     ok( r == E_INVALIDARG, "returns %08x\n", r );
1465     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
1466     ok( r == E_FAIL, "returns %08x\n", r );
1467     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
1468     ok( r == E_FAIL, "returns %08x\n", r );
1469     SysFreeString(str);
1470
1471     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
1472     ok( r == S_OK, "returns %08x\n", r );
1473     if(nodePI)
1474     {
1475         /* Last Child Checks */
1476         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
1477         ok(r == E_INVALIDARG, "ret %08x\n", r );
1478
1479         nodeChild = (IXMLDOMNode*)0x1;
1480         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
1481         ok(r == S_FALSE, "ret %08x\n", r );
1482         ok(nodeChild == NULL, "nodeChild not NULL\n");
1483
1484         /* test nodeName */
1485         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1486         ok(r == S_OK, "ret %08x\n", r );
1487         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1488         SysFreeString(str);
1489
1490         /* test baseName */
1491         str = (BSTR)0x1;
1492         r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
1493         ok(r == S_OK, "ret %08x\n", r );
1494         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1495         SysFreeString(str);
1496
1497         /* test Target */
1498         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
1499         ok(r == S_OK, "ret %08x\n", r );
1500         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
1501         SysFreeString(str);
1502
1503         /* test get_nodeValue */
1504         r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
1505         ok(r == S_OK, "ret %08x\n", r );
1506         ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1507         VariantClear(&var);
1508
1509         /* test get_data */
1510         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
1511         ok(r == S_OK, "ret %08x\n", r );
1512         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1513         SysFreeString(str);
1514
1515         /* test put_data */
1516         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
1517         ok(r == E_FAIL, "ret %08x\n", r );
1518
1519         /* test put_data */
1520         V_VT(&var) = VT_BSTR;
1521         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
1522         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
1523         ok(r == E_FAIL, "ret %08x\n", r );
1524         VariantClear(&var);
1525
1526         /* test get nodeName */
1527         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1528         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1529         ok(r == S_OK, "ret %08x\n", r );
1530         SysFreeString(str);
1531
1532         IXMLDOMProcessingInstruction_Release(nodePI);
1533     }
1534
1535     r = IXMLDOMDocument_QueryInterface( doc, &IID_ISupportErrorInfo, (void**)&support_error );
1536     ok( r == S_OK, "ret %08x\n", r );
1537     if(r == S_OK)
1538     {
1539         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMDocument );
1540         todo_wine ok( r == S_OK, "ret %08x\n", r );
1541         ISupportErrorInfo_Release( support_error );
1542     }
1543
1544     r = IXMLDOMDocument_Release( doc );
1545     ok( r == 0, "document ref count incorrect\n");
1546
1547     free_bstrs();
1548 }
1549
1550 static void test_persiststreaminit(void)
1551 {
1552     IXMLDOMDocument *doc;
1553     IPersistStreamInit *streaminit;
1554     HRESULT hr;
1555
1556     doc = create_document(&IID_IXMLDOMDocument);
1557     if (!doc) return;
1558
1559     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
1560     ok( hr == S_OK, "failed with 0x%08x\n", hr );
1561
1562     hr = IPersistStreamInit_InitNew(streaminit);
1563     ok( hr == S_OK, "failed with 0x%08x\n", hr );
1564
1565     IXMLDOMDocument_Release(doc);
1566 }
1567
1568 static void test_domnode( void )
1569 {
1570     HRESULT r;
1571     IXMLDOMDocument *doc, *owner = NULL;
1572     IXMLDOMElement *element = NULL;
1573     IXMLDOMNamedNodeMap *map = NULL;
1574     IXMLDOMNode *node = NULL, *next = NULL;
1575     IXMLDOMNodeList *list = NULL;
1576     IXMLDOMAttribute *attr = NULL;
1577     DOMNodeType type = NODE_INVALID;
1578     VARIANT_BOOL b;
1579     BSTR str;
1580     VARIANT var;
1581     LONG count;
1582
1583     doc = create_document(&IID_IXMLDOMDocument);
1584     if (!doc) return;
1585
1586     b = FALSE;
1587     str = SysAllocString( szComplete4 );
1588     r = IXMLDOMDocument_loadXML( doc, str, &b );
1589     ok( r == S_OK, "loadXML failed\n");
1590     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1591     SysFreeString( str );
1592
1593     EXPECT_CHILDREN(doc);
1594
1595     r = IXMLDOMDocument_get_documentElement( doc, &element );
1596     ok( r == S_OK, "should be a document element\n");
1597     ok( element != NULL, "should be an element\n");
1598
1599     VariantInit(&var);
1600     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1601
1602     r = IXMLDOMNode_get_nodeValue( doc, NULL );
1603     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
1604
1605     r = IXMLDOMNode_get_nodeValue( doc, &var );
1606     ok( r == S_FALSE, "nextNode returned wrong code\n");
1607     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1608     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1609
1610     if (element)
1611     {
1612         owner = NULL;
1613         r = IXMLDOMNode_get_ownerDocument( element, &owner );
1614         ok( r == S_OK, "get_ownerDocument return code\n");
1615         ok( owner != doc, "get_ownerDocument return\n");
1616         IXMLDOMDocument_Release(owner);
1617
1618         type = NODE_INVALID;
1619         r = IXMLDOMNode_get_nodeType( element, &type);
1620         ok( r == S_OK, "got %08x\n", r);
1621         ok( type == NODE_ELEMENT, "node not an element\n");
1622
1623         str = NULL;
1624         r = IXMLDOMNode_get_baseName( element, &str );
1625         ok( r == S_OK, "get_baseName returned wrong code\n");
1626         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
1627         SysFreeString(str);
1628
1629         /* check if nodename is correct */
1630         r = IXMLDOMElement_get_nodeName( element, NULL );
1631         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1632
1633         /* content doesn't matter here */
1634         str = NULL;
1635         r = IXMLDOMElement_get_nodeName( element, &str );
1636         ok ( r == S_OK, "get_nodeName wrong code\n");
1637         ok ( str != NULL, "str is null\n");
1638         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
1639         SysFreeString( str );
1640
1641         str = SysAllocString( szNonExistentFile );      
1642         V_VT(&var) = VT_I4;
1643         V_I4(&var) = 0x1234;
1644         r = IXMLDOMElement_getAttribute( element, str, &var );
1645         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
1646         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
1647         VariantClear(&var);
1648
1649         r = IXMLDOMElement_getAttributeNode( element, str, NULL);
1650         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1651
1652         attr = (IXMLDOMAttribute*)0xdeadbeef;
1653         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1654         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1655         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1656         SysFreeString( str );
1657
1658         attr = (IXMLDOMAttribute*)0xdeadbeef;
1659         str = SysAllocString( szNonExistentAttribute );
1660         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1661         ok( r == S_FALSE, "getAttributeNode ret %08x\n", r );
1662         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1663         SysFreeString( str );
1664
1665         str = SysAllocString( szdl );   
1666         V_VT(&var) = VT_I4;
1667         V_I4(&var) = 0x1234;
1668         r = IXMLDOMElement_getAttribute( element, str, &var );
1669         ok( r == S_OK, "getAttribute ret %08x\n", r );
1670         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
1671         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
1672         VariantClear( &var );
1673
1674         r = IXMLDOMElement_getAttribute( element, NULL, &var );
1675         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1676
1677         r = IXMLDOMElement_getAttribute( element, str, NULL );
1678         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1679
1680         attr = NULL;
1681         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1682         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
1683         ok( attr != NULL, "getAttributeNode returned NULL\n" );
1684         if (attr)
1685         {
1686             r = IXMLDOMAttribute_get_parentNode( attr, NULL );
1687             ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
1688
1689             /* attribute doesn't have a parent in msxml interpretation */
1690             node = (IXMLDOMNode*)0xdeadbeef;
1691             r = IXMLDOMAttribute_get_parentNode( attr, &node );
1692             ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
1693             ok( node == NULL, "Expected NULL, got %p\n", node );
1694
1695             IXMLDOMAttribute_Release(attr);
1696         }
1697
1698         SysFreeString( str );
1699
1700         r = IXMLDOMElement_get_attributes( element, &map );
1701         ok( r == S_OK, "get_attributes returned wrong code\n");
1702         ok( map != NULL, "should be attributes\n");
1703
1704         EXPECT_CHILDREN(element);
1705     }
1706     else
1707         ok( FALSE, "no element\n");
1708
1709     if (map)
1710     {
1711         ISupportErrorInfo *support_error;
1712         r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (void**)&support_error );
1713         ok( r == S_OK, "ret %08x\n", r );
1714
1715         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
1716 todo_wine
1717 {
1718         ok( r == S_OK, "ret %08x\n", r );
1719 }
1720         ISupportErrorInfo_Release( support_error );
1721
1722         str = SysAllocString( szdl );
1723         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1724         ok( r == S_OK, "getNamedItem returned wrong code\n");
1725         ok( node != NULL, "should be attributes\n");
1726         IXMLDOMNode_Release(node);
1727         SysFreeString( str );
1728
1729         str = SysAllocString( szdl );
1730         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
1731         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
1732         SysFreeString( str );
1733
1734         /* something that isn't in szComplete4 */
1735         str = SysAllocString( szOpen );
1736         node = (IXMLDOMNode *) 1;
1737         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1738         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
1739         ok( node == NULL, "getNamedItem should have returned NULL\n");
1740         SysFreeString( str );
1741
1742         /* test indexed access of attributes */
1743         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
1744         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
1745
1746         r = IXMLDOMNamedNodeMap_get_length( map, &count );
1747         ok ( r == S_OK, "get_length wrong code\n");
1748         ok ( count == 1, "get_length != 1\n");
1749
1750         node = NULL;
1751         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
1752         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
1753         ok ( node == NULL, "there is no node\n");
1754
1755         node = NULL;
1756         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
1757         ok ( r == S_FALSE, "get_item (1) wrong code\n");
1758         ok ( node == NULL, "there is no attribute\n");
1759
1760         node = NULL;
1761         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
1762         ok ( r == S_OK, "get_item (0) wrong code\n");
1763         ok ( node != NULL, "should be attribute\n");
1764
1765         r = IXMLDOMNode_get_nodeName( node, NULL );
1766         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1767
1768         /* content doesn't matter here */
1769         str = NULL;
1770         r = IXMLDOMNode_get_nodeName( node, &str );
1771         ok ( r == S_OK, "get_nodeName wrong code\n");
1772         ok ( str != NULL, "str is null\n");
1773         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
1774         SysFreeString( str );
1775         IXMLDOMNode_Release( node );
1776
1777         /* test sequential access of attributes */
1778         node = NULL;
1779         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1780         ok ( r == S_OK, "nextNode (first time) wrong code\n");
1781         ok ( node != NULL, "nextNode, should be attribute\n");
1782         IXMLDOMNode_Release( node );
1783
1784         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1785         ok ( r != S_OK, "nextNode (second time) wrong code\n");
1786         ok ( node == NULL, "nextNode, there is no attribute\n");
1787
1788         r = IXMLDOMNamedNodeMap_reset( map );
1789         ok ( r == S_OK, "reset should return S_OK\n");
1790
1791         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1792         ok ( r == S_OK, "nextNode (third time) wrong code\n");
1793         ok ( node != NULL, "nextNode, should be attribute\n");
1794     }
1795     else
1796         ok( FALSE, "no map\n");
1797
1798     if (node)
1799     {
1800         type = NODE_INVALID;
1801         r = IXMLDOMNode_get_nodeType( node, &type);
1802         ok( r == S_OK, "getNamedItem returned wrong code\n");
1803         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
1804
1805         str = NULL;
1806         r = IXMLDOMNode_get_baseName( node, NULL );
1807         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
1808
1809         str = NULL;
1810         r = IXMLDOMNode_get_baseName( node, &str );
1811         ok( r == S_OK, "get_baseName returned wrong code\n");
1812         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
1813         SysFreeString( str );
1814
1815         r = IXMLDOMNode_get_nodeValue( node, &var );
1816         ok( r == S_OK, "returns %08x\n", r );
1817         ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
1818         ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
1819         VariantClear(&var);
1820
1821         r = IXMLDOMNode_get_childNodes( node, NULL );
1822         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
1823
1824         r = IXMLDOMNode_get_childNodes( node, &list );
1825         ok( r == S_OK, "get_childNodes returned wrong code\n");
1826
1827         if (list)
1828         {
1829             r = IXMLDOMNodeList_nextNode( list, &next );
1830             ok( r == S_OK, "nextNode returned wrong code\n");
1831         }
1832         else
1833             ok( FALSE, "no childlist\n");
1834
1835         if (next)
1836         {
1837             EXPECT_NO_CHILDREN(next);
1838
1839             type = NODE_INVALID;
1840             r = IXMLDOMNode_get_nodeType( next, &type);
1841             ok( r == S_OK, "getNamedItem returned wrong code\n");
1842             ok( type == NODE_TEXT, "node not text\n");
1843
1844             str = (BSTR) 1;
1845             r = IXMLDOMNode_get_baseName( next, &str );
1846             ok( r == S_FALSE, "get_baseName returned wrong code\n");
1847             ok( str == NULL, "basename was wrong\n");
1848             SysFreeString(str);
1849         }
1850         else
1851             ok( FALSE, "no next\n");
1852
1853         if (next)
1854             IXMLDOMNode_Release( next );
1855         next = NULL;
1856         if (list)
1857             IXMLDOMNodeList_Release( list );
1858         list = NULL;
1859         if (node)
1860             IXMLDOMNode_Release( node );
1861     }
1862     else
1863         ok( FALSE, "no node\n");
1864     node = NULL;
1865
1866     if (map)
1867         IXMLDOMNamedNodeMap_Release( map );
1868
1869     /* now traverse the tree from the root element */
1870     if (element)
1871     {
1872         r = IXMLDOMNode_get_childNodes( element, &list );
1873         ok( r == S_OK, "get_childNodes returned wrong code\n");
1874
1875         /* using get_item for child list doesn't advance the position */
1876         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
1877         expect_node(node, "E2.E2.D1");
1878         IXMLDOMNode_Release(node);
1879         ole_check(IXMLDOMNodeList_nextNode(list, &node));
1880         expect_node(node, "E1.E2.D1");
1881         IXMLDOMNode_Release(node);
1882         ole_check(IXMLDOMNodeList_reset(list));
1883
1884         IXMLDOMNodeList_AddRef(list);
1885         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
1886         ole_check(IXMLDOMNodeList_reset(list));
1887
1888         node = (void*)0xdeadbeef;
1889         str = SysAllocString(szdl);
1890         r = IXMLDOMNode_selectSingleNode( element, str, &node );
1891         SysFreeString(str);
1892         ok( r == S_FALSE, "ret %08x\n", r );
1893         ok( node == NULL, "node %p\n", node );
1894
1895         str = SysAllocString(szbs);
1896         r = IXMLDOMNode_selectSingleNode( element, str, &node );
1897         SysFreeString(str);
1898         ok( r == S_OK, "ret %08x\n", r );
1899         r = IXMLDOMNode_Release( node );
1900         ok( r == 0, "ret %08x\n", r );
1901     }
1902     else
1903         ok( FALSE, "no element\n");
1904
1905     if (list)
1906     {
1907         r = IXMLDOMNodeList_get_item(list, 0, NULL);
1908         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1909
1910         r = IXMLDOMNodeList_get_length(list, NULL);
1911         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1912
1913         r = IXMLDOMNodeList_get_length( list, &count );
1914         ok( r == S_OK, "get_length returns %08x\n", r );
1915         ok( count == 4, "get_length got %d\n", count );
1916
1917         r = IXMLDOMNodeList_nextNode(list, NULL);
1918         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1919
1920         r = IXMLDOMNodeList_nextNode( list, &node );
1921         ok( r == S_OK, "nextNode returned wrong code\n");
1922     }
1923     else
1924         ok( FALSE, "no list\n");
1925
1926     if (node)
1927     {
1928         type = NODE_INVALID;
1929         r = IXMLDOMNode_get_nodeType( node, &type);
1930         ok( r == S_OK, "getNamedItem returned wrong code\n");
1931         ok( type == NODE_ELEMENT, "node not text\n");
1932
1933         VariantInit(&var);
1934         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1935         r = IXMLDOMNode_get_nodeValue( node, &var );
1936         ok( r == S_FALSE, "nextNode returned wrong code\n");
1937         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1938         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1939
1940         r = IXMLDOMNode_hasChildNodes( node, NULL );
1941         ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
1942
1943         EXPECT_CHILDREN(node);
1944
1945         str = NULL;
1946         r = IXMLDOMNode_get_baseName( node, &str );
1947         ok( r == S_OK, "get_baseName returned wrong code\n");
1948         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
1949         SysFreeString(str);
1950     }
1951     else
1952         ok( FALSE, "no node\n");
1953
1954     if (node)
1955         IXMLDOMNode_Release( node );
1956     if (list)
1957         IXMLDOMNodeList_Release( list );
1958     if (element)
1959         IXMLDOMElement_Release( element );
1960
1961     b = FALSE;
1962     str = SysAllocString( szComplete5 );
1963     r = IXMLDOMDocument_loadXML( doc, str, &b );
1964     ok( r == S_OK, "loadXML failed\n");
1965     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1966     SysFreeString( str );
1967
1968     EXPECT_CHILDREN(doc);
1969
1970     r = IXMLDOMDocument_get_documentElement( doc, &element );
1971     ok( r == S_OK, "should be a document element\n");
1972     ok( element != NULL, "should be an element\n");
1973
1974     if (element)
1975     {
1976         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
1977         BSTR tag = NULL;
1978
1979         /* check if the tag is correct */
1980         r = IXMLDOMElement_get_tagName( element, &tag );
1981         ok( r == S_OK, "couldn't get tag name\n");
1982         ok( tag != NULL, "tag was null\n");
1983         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
1984         SysFreeString( tag );
1985     }
1986
1987     if (element)
1988         IXMLDOMElement_Release( element );
1989     ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
1990 }
1991
1992 static void test_refs(void)
1993 {
1994     HRESULT r;
1995     BSTR str;
1996     VARIANT_BOOL b;
1997     IXMLDOMDocument *doc;
1998     IXMLDOMElement *element = NULL;
1999     IXMLDOMNode *node = NULL, *node2;
2000     IXMLDOMNodeList *node_list = NULL;
2001     LONG ref;
2002     IUnknown *unk, *unk2;
2003
2004     doc = create_document(&IID_IXMLDOMDocument);
2005     if (!doc) return;
2006
2007     EXPECT_REF(doc, 1);
2008     ref = IXMLDOMDocument_Release(doc);
2009     ok( ref == 0, "ref %d\n", ref);
2010
2011     doc = create_document(&IID_IXMLDOMDocument);
2012     if (!doc) return;
2013
2014     str = SysAllocString( szComplete4 );
2015     r = IXMLDOMDocument_loadXML( doc, str, &b );
2016     ok( r == S_OK, "loadXML failed\n");
2017     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2018     SysFreeString( str );
2019
2020     EXPECT_REF(doc, 1);
2021     IXMLDOMDocument_AddRef( doc );
2022     EXPECT_REF(doc, 2);
2023     IXMLDOMDocument_AddRef( doc );
2024     EXPECT_REF(doc, 3);
2025
2026     IXMLDOMDocument_Release( doc );
2027     IXMLDOMDocument_Release( doc );
2028
2029     r = IXMLDOMDocument_get_documentElement( doc, &element );
2030     ok( r == S_OK, "should be a document element\n");
2031     ok( element != NULL, "should be an element\n");
2032
2033     EXPECT_REF(doc, 1);
2034     todo_wine EXPECT_REF(element, 2);
2035
2036     IXMLDOMElement_AddRef(element);
2037     todo_wine EXPECT_REF(element, 3);
2038     IXMLDOMElement_Release(element);
2039
2040     r = IXMLDOMElement_get_childNodes( element, &node_list );
2041     ok( r == S_OK, "rets %08x\n", r);
2042
2043     todo_wine EXPECT_REF(element, 2);
2044     EXPECT_REF(node_list, 1);
2045
2046     IXMLDOMNodeList_get_item( node_list, 0, &node );
2047     ok( r == S_OK, "rets %08x\n", r);
2048     EXPECT_REF(node_list, 1);
2049     EXPECT_REF(node, 1);
2050
2051     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2052     ok( r == S_OK, "rets %08x\n", r);
2053     EXPECT_REF(node_list, 1);
2054     EXPECT_REF(node2, 1);
2055
2056     ref = IXMLDOMNode_Release( node );
2057     ok( ref == 0, "ref %d\n", ref );
2058     ref = IXMLDOMNode_Release( node2 );
2059     ok( ref == 0, "ref %d\n", ref );
2060
2061     ref = IXMLDOMNodeList_Release( node_list );
2062     ok( ref == 0, "ref %d\n", ref );
2063
2064     ok( node != node2, "node %p node2 %p\n", node, node2 );
2065
2066     ref = IXMLDOMDocument_Release( doc );
2067     ok( ref == 0, "ref %d\n", ref );
2068
2069     todo_wine EXPECT_REF(element, 2);
2070
2071     /* IUnknown must be unique however we obtain it */
2072     r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (void**)&unk );
2073     ok( r == S_OK, "rets %08x\n", r );
2074     EXPECT_REF(element, 2);
2075     r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (void**)&node );
2076     ok( r == S_OK, "rets %08x\n", r );
2077     todo_wine EXPECT_REF(element, 2);
2078     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk2 );
2079     ok( r == S_OK, "rets %08x\n", r );
2080     todo_wine EXPECT_REF(element, 2);
2081     ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
2082     todo_wine ok( element != (void*)node, "node %p element %p\n", node, element );
2083
2084     IUnknown_Release( unk2 );
2085     IUnknown_Release( unk );
2086     IXMLDOMNode_Release( node );
2087     todo_wine EXPECT_REF(element, 2);
2088
2089     IXMLDOMElement_Release( element );
2090 }
2091
2092 static void test_create(void)
2093 {
2094     static const WCHAR szOne[] = {'1',0};
2095     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2096     HRESULT r;
2097     VARIANT var;
2098     BSTR str, name;
2099     IXMLDOMDocument *doc;
2100     IXMLDOMElement *element;
2101     IXMLDOMComment *comment;
2102     IXMLDOMText *text;
2103     IXMLDOMCDATASection *cdata;
2104     IXMLDOMNode *root, *node, *child;
2105     IXMLDOMNamedNodeMap *attr_map;
2106     IUnknown *unk;
2107     LONG ref;
2108     LONG num;
2109
2110     doc = create_document(&IID_IXMLDOMDocument);
2111     if (!doc) return;
2112
2113     EXPECT_REF(doc, 1);
2114
2115     /* types not supported for creation */
2116     V_VT(&var) = VT_I1;
2117     V_I1(&var) = NODE_DOCUMENT;
2118     node = (IXMLDOMNode*)0x1;
2119     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2120     ok( r == E_INVALIDARG, "returns %08x\n", r );
2121     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2122
2123     V_VT(&var) = VT_I1;
2124     V_I1(&var) = NODE_DOCUMENT_TYPE;
2125     node = (IXMLDOMNode*)0x1;
2126     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2127     ok( r == E_INVALIDARG, "returns %08x\n", r );
2128     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2129
2130     V_VT(&var) = VT_I1;
2131     V_I1(&var) = NODE_ENTITY;
2132     node = (IXMLDOMNode*)0x1;
2133     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2134     ok( r == E_INVALIDARG, "returns %08x\n", r );
2135     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2136
2137     V_VT(&var) = VT_I1;
2138     V_I1(&var) = NODE_NOTATION;
2139     node = (IXMLDOMNode*)0x1;
2140     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2141     ok( r == E_INVALIDARG, "returns %08x\n", r );
2142     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2143
2144     /* NODE_COMMENT */
2145     V_VT(&var) = VT_I1;
2146     V_I1(&var) = NODE_COMMENT;
2147     node = NULL;
2148     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2149     ok( r == S_OK, "returns %08x\n", r );
2150     ok( node != NULL, "\n");
2151
2152     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2153     ok( r == S_OK, "returns %08x\n", r );
2154     IXMLDOMNode_Release(node);
2155
2156     str = NULL;
2157     r = IXMLDOMComment_get_data(comment, &str);
2158     ok( r == S_OK, "returns %08x\n", r );
2159     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2160     IXMLDOMComment_Release(comment);
2161     SysFreeString(str);
2162
2163     node = (IXMLDOMNode*)0x1;
2164     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2165     ok( r == S_OK, "returns %08x\n", r );
2166
2167     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2168     ok( r == S_OK, "returns %08x\n", r );
2169     IXMLDOMNode_Release(node);
2170
2171     str = NULL;
2172     r = IXMLDOMComment_get_data(comment, &str);
2173     ok( r == S_OK, "returns %08x\n", r );
2174     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2175     IXMLDOMComment_Release(comment);
2176     SysFreeString(str);
2177
2178     node = (IXMLDOMNode*)0x1;
2179     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2180     ok( r == S_OK, "returns %08x\n", r );
2181
2182     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2183     ok( r == S_OK, "returns %08x\n", r );
2184     IXMLDOMNode_Release(node);
2185
2186     str = NULL;
2187     r = IXMLDOMComment_get_data(comment, &str);
2188     ok( r == S_OK, "returns %08x\n", r );
2189     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2190     IXMLDOMComment_Release(comment);
2191     SysFreeString(str);
2192
2193     /* NODE_TEXT */
2194     V_VT(&var) = VT_I1;
2195     V_I1(&var) = NODE_TEXT;
2196     node = NULL;
2197     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2198     ok( r == S_OK, "returns %08x\n", r );
2199     ok( node != NULL, "\n");
2200
2201     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2202     ok( r == S_OK, "returns %08x\n", r );
2203     IXMLDOMNode_Release(node);
2204
2205     str = NULL;
2206     r = IXMLDOMText_get_data(text, &str);
2207     ok( r == S_OK, "returns %08x\n", r );
2208     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2209     IXMLDOMText_Release(text);
2210     SysFreeString(str);
2211
2212     node = (IXMLDOMNode*)0x1;
2213     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2214     ok( r == S_OK, "returns %08x\n", r );
2215
2216     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2217     ok( r == S_OK, "returns %08x\n", r );
2218     IXMLDOMNode_Release(node);
2219
2220     str = NULL;
2221     r = IXMLDOMText_get_data(text, &str);
2222     ok( r == S_OK, "returns %08x\n", r );
2223     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2224     IXMLDOMText_Release(text);
2225     SysFreeString(str);
2226
2227     node = (IXMLDOMNode*)0x1;
2228     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2229     ok( r == S_OK, "returns %08x\n", r );
2230
2231     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2232     ok( r == S_OK, "returns %08x\n", r );
2233     IXMLDOMNode_Release(node);
2234
2235     str = NULL;
2236     r = IXMLDOMText_get_data(text, &str);
2237     ok( r == S_OK, "returns %08x\n", r );
2238     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2239     IXMLDOMText_Release(text);
2240     SysFreeString(str);
2241
2242     /* NODE_CDATA_SECTION */
2243     V_VT(&var) = VT_I1;
2244     V_I1(&var) = NODE_CDATA_SECTION;
2245     node = NULL;
2246     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2247     ok( r == S_OK, "returns %08x\n", r );
2248     ok( node != NULL, "\n");
2249
2250     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2251     ok( r == S_OK, "returns %08x\n", r );
2252     IXMLDOMNode_Release(node);
2253
2254     str = NULL;
2255     r = IXMLDOMCDATASection_get_data(cdata, &str);
2256     ok( r == S_OK, "returns %08x\n", r );
2257     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2258     IXMLDOMCDATASection_Release(cdata);
2259     SysFreeString(str);
2260
2261     node = (IXMLDOMNode*)0x1;
2262     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2263     ok( r == S_OK, "returns %08x\n", r );
2264
2265     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2266     ok( r == S_OK, "returns %08x\n", r );
2267     IXMLDOMNode_Release(node);
2268
2269     str = NULL;
2270     r = IXMLDOMCDATASection_get_data(cdata, &str);
2271     ok( r == S_OK, "returns %08x\n", r );
2272     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2273     IXMLDOMCDATASection_Release(cdata);
2274     SysFreeString(str);
2275
2276     node = (IXMLDOMNode*)0x1;
2277     r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2278     ok( r == S_OK, "returns %08x\n", r );
2279
2280     r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2281     ok( r == S_OK, "returns %08x\n", r );
2282     IXMLDOMNode_Release(node);
2283
2284     str = NULL;
2285     r = IXMLDOMCDATASection_get_data(cdata, &str);
2286     ok( r == S_OK, "returns %08x\n", r );
2287     ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2288     IXMLDOMCDATASection_Release(cdata);
2289     SysFreeString(str);
2290
2291     /* NODE_ATTRIBUTE */
2292     V_VT(&var) = VT_I1;
2293     V_I1(&var) = NODE_ATTRIBUTE;
2294     node = (IXMLDOMNode*)0x1;
2295     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2296     ok( r == E_FAIL, "returns %08x\n", r );
2297     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2298
2299     V_VT(&var) = VT_I1;
2300     V_I1(&var) = NODE_ATTRIBUTE;
2301     node = (IXMLDOMNode*)0x1;
2302     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2303     ok( r == E_FAIL, "returns %08x\n", r );
2304     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2305
2306     V_VT(&var) = VT_I1;
2307     V_I1(&var) = NODE_ATTRIBUTE;
2308     str = SysAllocString( szlc );
2309     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2310     ok( r == S_OK, "returns %08x\n", r );
2311     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2312     SysFreeString(str);
2313
2314     /* a name is required for attribute, try a BSTR with first null wchar */
2315     V_VT(&var) = VT_I1;
2316     V_I1(&var) = NODE_ATTRIBUTE;
2317     str = SysAllocString( szstr1 );
2318     str[0] = 0;
2319     node = (IXMLDOMNode*)0x1;
2320     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2321     ok( r == E_FAIL, "returns %08x\n", r );
2322     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2323     SysFreeString(str);
2324
2325     /* NODE_PROCESSING_INSTRUCTION */
2326     V_VT(&var) = VT_I1;
2327     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2328     node = (IXMLDOMNode*)0x1;
2329     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2330     ok( r == E_FAIL, "returns %08x\n", r );
2331     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2332
2333     V_VT(&var) = VT_I1;
2334     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2335     node = (IXMLDOMNode*)0x1;
2336     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2337     ok( r == E_FAIL, "returns %08x\n", r );
2338     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2339
2340     V_VT(&var) = VT_I1;
2341     V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2342     r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
2343     ok( r == E_INVALIDARG, "returns %08x\n", r );
2344
2345     /* NODE_ENTITY_REFERENCE */
2346     V_VT(&var) = VT_I1;
2347     V_I1(&var) = NODE_ENTITY_REFERENCE;
2348     node = (IXMLDOMNode*)0x1;
2349     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2350     ok( r == E_FAIL, "returns %08x\n", r );
2351     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2352
2353     V_VT(&var) = VT_I1;
2354     V_I1(&var) = NODE_ENTITY_REFERENCE;
2355     node = (IXMLDOMNode*)0x1;
2356     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2357     ok( r == E_FAIL, "returns %08x\n", r );
2358     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2359
2360     /* NODE_ELEMENT */
2361     V_VT(&var) = VT_I1;
2362     V_I1(&var) = NODE_ELEMENT;
2363     node = (IXMLDOMNode*)0x1;
2364     r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2365     ok( r == E_FAIL, "returns %08x\n", r );
2366     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2367
2368     V_VT(&var) = VT_I1;
2369     V_I1(&var) = NODE_ELEMENT;
2370     node = (IXMLDOMNode*)0x1;
2371     r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2372     ok( r == E_FAIL, "returns %08x\n", r );
2373     ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2374
2375     V_VT(&var) = VT_I1;
2376     V_I1(&var) = NODE_ELEMENT;
2377     str = SysAllocString( szlc );
2378     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2379     ok( r == S_OK, "returns %08x\n", r );
2380     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2381
2382     V_VT(&var) = VT_I1;
2383     V_I1(&var) = NODE_ELEMENT;
2384     r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
2385     ok( r == E_INVALIDARG, "returns %08x\n", r );
2386
2387     V_VT(&var) = VT_R4;
2388     V_R4(&var) = NODE_ELEMENT;
2389     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2390     ok( r == S_OK, "returns %08x\n", r );
2391     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2392
2393     V_VT(&var) = VT_BSTR;
2394     V_BSTR(&var) = SysAllocString( szOne );
2395     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2396     ok( r == S_OK, "returns %08x\n", r );
2397     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2398     VariantClear(&var);
2399
2400     V_VT(&var) = VT_BSTR;
2401     V_BSTR(&var) = SysAllocString( szOneGarbage );
2402     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2403     ok( r == E_INVALIDARG, "returns %08x\n", r );
2404     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2405     VariantClear(&var);
2406
2407     V_VT(&var) = VT_I4;
2408     V_I4(&var) = NODE_ELEMENT;
2409     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2410     ok( r == S_OK, "returns %08x\n", r );
2411
2412     EXPECT_REF(doc, 1);
2413     r = IXMLDOMDocument_appendChild( doc, node, &root );
2414     ok( r == S_OK, "returns %08x\n", r );
2415     ok( node == root, "%p %p\n", node, root );
2416     EXPECT_REF(doc, 1);
2417
2418     EXPECT_REF(node, 2);
2419
2420     ref = IXMLDOMNode_Release( node );
2421     ok(ref == 1, "ref %d\n", ref);
2422     SysFreeString( str );
2423
2424     V_VT(&var) = VT_I4;
2425     V_I4(&var) = NODE_ELEMENT;
2426     str = SysAllocString( szbs );
2427     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2428     ok( r == S_OK, "returns %08x\n", r );
2429     SysFreeString( str );
2430
2431     EXPECT_REF(node, 1);
2432
2433     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
2434     ok( r == S_OK, "returns %08x\n", r );
2435
2436     EXPECT_REF(unk, 2);
2437
2438     V_VT(&var) = VT_EMPTY;
2439     child = NULL;
2440     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
2441     ok( r == S_OK, "returns %08x\n", r );
2442     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
2443
2444     todo_wine EXPECT_REF(unk, 4);
2445
2446     IXMLDOMNode_Release( child );
2447     IUnknown_Release( unk );
2448
2449     V_VT(&var) = VT_NULL;
2450     V_DISPATCH(&var) = (IDispatch*)node;
2451     r = IXMLDOMNode_insertBefore( root, node, var, &child );
2452     ok( r == S_OK, "returns %08x\n", r );
2453     ok( node == child, "%p %p\n", node, child );
2454     IXMLDOMNode_Release( child );
2455
2456     V_VT(&var) = VT_NULL;
2457     V_DISPATCH(&var) = (IDispatch*)node;
2458     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
2459     ok( r == S_OK, "returns %08x\n", r );
2460     IXMLDOMNode_Release( node );
2461
2462     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
2463     ok( r == S_OK, "returns %08x\n", r );
2464
2465     r = IXMLDOMElement_get_attributes( element, &attr_map );
2466     ok( r == S_OK, "returns %08x\n", r );
2467     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2468     ok( r == S_OK, "returns %08x\n", r );
2469     ok( num == 0, "num %d\n", num );
2470     IXMLDOMNamedNodeMap_Release( attr_map );
2471
2472     V_VT(&var) = VT_BSTR;
2473     V_BSTR(&var) = SysAllocString( szstr1 );
2474     name = SysAllocString( szdl );
2475     r = IXMLDOMElement_setAttribute( element, name, var );
2476     ok( r == S_OK, "returns %08x\n", r );
2477     r = IXMLDOMElement_get_attributes( element, &attr_map );
2478     ok( r == S_OK, "returns %08x\n", r );
2479     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2480     ok( r == S_OK, "returns %08x\n", r );
2481     ok( num == 1, "num %d\n", num );
2482     IXMLDOMNamedNodeMap_Release( attr_map );
2483     VariantClear(&var);
2484
2485     V_VT(&var) = VT_BSTR;
2486     V_BSTR(&var) = SysAllocString( szstr2 );
2487     r = IXMLDOMElement_setAttribute( element, name, var );
2488     ok( r == S_OK, "returns %08x\n", r );
2489     r = IXMLDOMElement_get_attributes( element, &attr_map );
2490     ok( r == S_OK, "returns %08x\n", r );
2491     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2492     ok( r == S_OK, "returns %08x\n", r );
2493     ok( num == 1, "num %d\n", num );
2494     IXMLDOMNamedNodeMap_Release( attr_map );
2495     VariantClear(&var);
2496     r = IXMLDOMElement_getAttribute( element, name, &var );
2497     ok( r == S_OK, "returns %08x\n", r );
2498     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
2499     VariantClear(&var);
2500     SysFreeString(name);
2501
2502     V_VT(&var) = VT_BSTR;
2503     V_BSTR(&var) = SysAllocString( szstr1 );
2504     name = SysAllocString( szlc );
2505     r = IXMLDOMElement_setAttribute( element, name, var );
2506     ok( r == S_OK, "returns %08x\n", r );
2507     r = IXMLDOMElement_get_attributes( element, &attr_map );
2508     ok( r == S_OK, "returns %08x\n", r );
2509     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2510     ok( r == S_OK, "returns %08x\n", r );
2511     ok( num == 2, "num %d\n", num );
2512     IXMLDOMNamedNodeMap_Release( attr_map );
2513     VariantClear(&var);
2514     SysFreeString(name);
2515
2516     V_VT(&var) = VT_I4;
2517     V_I4(&var) = 10;
2518     name = SysAllocString( szbs );
2519     r = IXMLDOMElement_setAttribute( element, name, var );
2520     ok( r == S_OK, "returns %08x\n", r );
2521     VariantClear(&var);
2522     r = IXMLDOMElement_getAttribute( element, name, &var );
2523     ok( r == S_OK, "returns %08x\n", r );
2524     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
2525     VariantClear(&var);
2526     SysFreeString(name);
2527
2528     /* Create an Attribute */
2529     V_VT(&var) = VT_I4;
2530     V_I4(&var) = NODE_ATTRIBUTE;
2531     str = SysAllocString( szAttribute );
2532     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2533     ok( r == S_OK, "returns %08x\n", r );
2534     ok( node != NULL, "node was null\n");
2535     SysFreeString(str);
2536
2537     IXMLDOMElement_Release( element );
2538     IXMLDOMNode_Release( root );
2539     IXMLDOMDocument_Release( doc );
2540 }
2541
2542 static void test_getElementsByTagName(void)
2543 {
2544     IXMLDOMNodeList *node_list;
2545     IXMLDOMDocument *doc;
2546     IXMLDOMElement *elem;
2547     WCHAR buff[100];
2548     VARIANT_BOOL b;
2549     HRESULT r;
2550     LONG len;
2551     BSTR str;
2552
2553     doc = create_document(&IID_IXMLDOMDocument);
2554     if (!doc) return;
2555
2556     str = SysAllocString( szComplete4 );
2557     r = IXMLDOMDocument_loadXML( doc, str, &b );
2558     ok( r == S_OK, "loadXML failed\n");
2559     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2560     SysFreeString( str );
2561
2562     str = SysAllocString( szstar );
2563
2564     /* null arguments cases */
2565     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
2566     ok( r == E_INVALIDARG, "ret %08x\n", r );
2567     r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
2568     ok( r == E_INVALIDARG, "ret %08x\n", r );
2569
2570     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2571     ok( r == S_OK, "ret %08x\n", r );
2572     r = IXMLDOMNodeList_get_length( node_list, &len );
2573     ok( r == S_OK, "ret %08x\n", r );
2574     ok( len == 6, "len %d\n", len );
2575
2576     test_disp((IUnknown*)node_list);
2577
2578     IXMLDOMNodeList_Release( node_list );
2579     SysFreeString( str );
2580
2581     /* broken query BSTR */
2582     memcpy(&buff[2], szstar, sizeof(szstar));
2583     /* just a big length */
2584     *(DWORD*)buff = 0xf0f0;
2585     r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
2586     ok( r == S_OK, "ret %08x\n", r );
2587     r = IXMLDOMNodeList_get_length( node_list, &len );
2588     ok( r == S_OK, "ret %08x\n", r );
2589     ok( len == 6, "len %d\n", len );
2590     IXMLDOMNodeList_Release( node_list );
2591
2592     str = SysAllocString( szbs );
2593     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2594     ok( r == S_OK, "ret %08x\n", r );
2595     r = IXMLDOMNodeList_get_length( node_list, &len );
2596     ok( r == S_OK, "ret %08x\n", r );
2597     ok( len == 1, "len %d\n", len );
2598     IXMLDOMNodeList_Release( node_list );
2599     SysFreeString( str );
2600
2601     str = SysAllocString( szdl );
2602     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2603     ok( r == S_OK, "ret %08x\n", r );
2604     r = IXMLDOMNodeList_get_length( node_list, &len );
2605     ok( r == S_OK, "ret %08x\n", r );
2606     ok( len == 0, "len %d\n", len );
2607     IXMLDOMNodeList_Release( node_list );
2608     SysFreeString( str );
2609
2610     str = SysAllocString( szstr1 );
2611     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2612     ok( r == S_OK, "ret %08x\n", r );
2613     r = IXMLDOMNodeList_get_length( node_list, &len );
2614     ok( r == S_OK, "ret %08x\n", r );
2615     ok( len == 0, "len %d\n", len );
2616     IXMLDOMNodeList_Release( node_list );
2617     SysFreeString( str );
2618
2619     /* test for element */
2620     r = IXMLDOMDocument_get_documentElement(doc, &elem);
2621     ok( r == S_OK, "ret %08x\n", r );
2622
2623     str = SysAllocString( szstar );
2624
2625     /* null arguments cases */
2626     r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
2627     ok( r == E_INVALIDARG, "ret %08x\n", r );
2628     r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
2629     ok( r == E_INVALIDARG, "ret %08x\n", r );
2630
2631     r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
2632     ok( r == S_OK, "ret %08x\n", r );
2633     r = IXMLDOMNodeList_get_length( node_list, &len );
2634     ok( r == S_OK, "ret %08x\n", r );
2635     ok( len == 5, "len %d\n", len );
2636     expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
2637     SysFreeString( str );
2638
2639     /* broken query BSTR */
2640     memcpy(&buff[2], szstar, sizeof(szstar));
2641     /* just a big length */
2642     *(DWORD*)buff = 0xf0f0;
2643     r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
2644     ok( r == S_OK, "ret %08x\n", r );
2645     r = IXMLDOMNodeList_get_length( node_list, &len );
2646     ok( r == S_OK, "ret %08x\n", r );
2647     ok( len == 5, "len %d\n", len );
2648     IXMLDOMNodeList_Release( node_list );
2649
2650     IXMLDOMElement_Release(elem);
2651
2652     IXMLDOMDocument_Release( doc );
2653 }
2654
2655 static void test_get_text(void)
2656 {
2657     HRESULT r;
2658     BSTR str;
2659     VARIANT_BOOL b;
2660     IXMLDOMDocument *doc;
2661     IXMLDOMNode *node, *node2, *node3;
2662     IXMLDOMNode *nodeRoot;
2663     IXMLDOMNodeList *node_list;
2664     IXMLDOMNamedNodeMap *node_map;
2665     LONG len;
2666
2667     doc = create_document(&IID_IXMLDOMDocument);
2668     if (!doc) return;
2669
2670     str = SysAllocString( szComplete4 );
2671     r = IXMLDOMDocument_loadXML( doc, str, &b );
2672     ok( r == S_OK, "loadXML failed\n");
2673     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2674     SysFreeString( str );
2675
2676     str = SysAllocString( szbs );
2677     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
2678     ok( r == S_OK, "ret %08x\n", r );
2679     SysFreeString(str);
2680
2681     /* Test to get all child node text. */
2682     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
2683     ok( r == S_OK, "ret %08x\n", r );
2684     if(r == S_OK)
2685     {
2686         r = IXMLDOMNode_get_text( nodeRoot, &str );
2687         ok( r == S_OK, "ret %08x\n", r );
2688         ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
2689         SysFreeString(str);
2690
2691         IXMLDOMNode_Release(nodeRoot);
2692     }
2693
2694     r = IXMLDOMNodeList_get_length( node_list, NULL );
2695     ok( r == E_INVALIDARG, "ret %08x\n", r );
2696
2697     r = IXMLDOMNodeList_get_length( node_list, &len );
2698     ok( r == S_OK, "ret %08x\n", r );
2699     ok( len == 1, "expect 1 got %d\n", len );
2700
2701     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
2702     ok( r == E_INVALIDARG, "ret %08x\n", r );
2703
2704     r = IXMLDOMNodeList_nextNode( node_list, NULL );
2705     ok( r == E_INVALIDARG, "ret %08x\n", r );
2706
2707     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
2708     ok( r == S_OK, "ret %08x\n", r );
2709     IXMLDOMNodeList_Release( node_list );
2710
2711     /* Invalid output parameter*/
2712     r = IXMLDOMNode_get_text( node, NULL );
2713     ok( r == E_INVALIDARG, "ret %08x\n", r );
2714
2715     r = IXMLDOMNode_get_text( node, &str );
2716     ok( r == S_OK, "ret %08x\n", r );
2717     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
2718     SysFreeString(str);
2719
2720     r = IXMLDOMNode_get_attributes( node, &node_map );
2721     ok( r == S_OK, "ret %08x\n", r );
2722
2723     str = SysAllocString( szvr );
2724     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
2725     ok( r == S_OK, "ret %08x\n", r );
2726     SysFreeString(str);
2727
2728     r = IXMLDOMNode_get_text( node2, &str );
2729     ok( r == S_OK, "ret %08x\n", r );
2730     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2731     SysFreeString(str);
2732
2733     r = IXMLDOMNode_get_firstChild( node2, &node3 );
2734     ok( r == S_OK, "ret %08x\n", r );
2735
2736     r = IXMLDOMNode_get_text( node3, &str );
2737     ok( r == S_OK, "ret %08x\n", r );
2738     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2739     SysFreeString(str);
2740
2741
2742     IXMLDOMNode_Release( node3 );
2743     IXMLDOMNode_Release( node2 );
2744     IXMLDOMNamedNodeMap_Release( node_map );
2745     IXMLDOMNode_Release( node );
2746     IXMLDOMDocument_Release( doc );
2747 }
2748
2749 static void test_get_childNodes(void)
2750 {
2751     HRESULT r;
2752     BSTR str;
2753     VARIANT_BOOL b;
2754     IXMLDOMDocument *doc;
2755     IXMLDOMElement *element;
2756     IXMLDOMNode *node, *node2;
2757     IXMLDOMNodeList *node_list, *node_list2;
2758     LONG len;
2759
2760     doc = create_document(&IID_IXMLDOMDocument);
2761     if (!doc) return;
2762
2763     str = SysAllocString( szComplete4 );
2764     r = IXMLDOMDocument_loadXML( doc, str, &b );
2765     ok( r == S_OK, "loadXML failed\n");
2766     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2767     SysFreeString( str );
2768
2769     r = IXMLDOMDocument_get_documentElement( doc, &element );
2770     ok( r == S_OK, "ret %08x\n", r);
2771
2772     r = IXMLDOMElement_get_childNodes( element, &node_list );
2773     ok( r == S_OK, "ret %08x\n", r);
2774
2775     r = IXMLDOMNodeList_get_length( node_list, &len );
2776     ok( r == S_OK, "ret %08x\n", r);
2777     ok( len == 4, "len %d\n", len);
2778
2779     r = IXMLDOMNodeList_get_item( node_list, 2, &node );
2780     ok( r == S_OK, "ret %08x\n", r);
2781
2782     r = IXMLDOMNode_get_childNodes( node, &node_list2 );
2783     ok( r == S_OK, "ret %08x\n", r);
2784
2785     r = IXMLDOMNodeList_get_length( node_list2, &len );
2786     ok( r == S_OK, "ret %08x\n", r);
2787     ok( len == 0, "len %d\n", len);
2788
2789     r = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
2790     ok( r == S_FALSE, "ret %08x\n", r);
2791
2792     IXMLDOMNodeList_Release( node_list2 );
2793     IXMLDOMNode_Release( node );
2794     IXMLDOMNodeList_Release( node_list );
2795     IXMLDOMElement_Release( element );
2796     IXMLDOMDocument_Release( doc );
2797 }
2798
2799 static void test_get_firstChild(void)
2800 {
2801     static WCHAR xmlW[] = {'x','m','l',0};
2802     IXMLDOMDocument *doc;
2803     IXMLDOMNode *node;
2804     VARIANT_BOOL b;
2805     HRESULT r;
2806     BSTR str;
2807
2808     doc = create_document(&IID_IXMLDOMDocument);
2809     if (!doc) return;
2810
2811     str = SysAllocString( szComplete4 );
2812     r = IXMLDOMDocument_loadXML( doc, str, &b );
2813     ok( r == S_OK, "loadXML failed\n");
2814     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2815     SysFreeString( str );
2816
2817     r = IXMLDOMDocument_get_firstChild( doc, &node );
2818     ok( r == S_OK, "ret %08x\n", r);
2819
2820     r = IXMLDOMNode_get_nodeName( node, &str );
2821     ok( r == S_OK, "ret %08x\n", r);
2822
2823     ok(memcmp(str, xmlW, sizeof(xmlW)) == 0, "expected \"xml\" node name\n");
2824
2825     SysFreeString(str);
2826     IXMLDOMNode_Release( node );
2827     IXMLDOMDocument_Release( doc );
2828 }
2829
2830 static void test_get_lastChild(void)
2831 {
2832     static WCHAR lcW[] = {'l','c',0};
2833     static WCHAR foW[] = {'f','o',0};
2834     IXMLDOMDocument *doc;
2835     IXMLDOMNode *node, *child;
2836     VARIANT_BOOL b;
2837     HRESULT r;
2838     BSTR str;
2839
2840     doc = create_document(&IID_IXMLDOMDocument);
2841     if (!doc) return;
2842
2843     str = SysAllocString( szComplete4 );
2844     r = IXMLDOMDocument_loadXML( doc, str, &b );
2845     ok( r == S_OK, "loadXML failed\n");
2846     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2847     SysFreeString( str );
2848
2849     r = IXMLDOMDocument_get_lastChild( doc, &node );
2850     ok( r == S_OK, "ret %08x\n", r);
2851
2852     r = IXMLDOMNode_get_nodeName( node, &str );
2853     ok( r == S_OK, "ret %08x\n", r);
2854
2855     ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
2856     SysFreeString(str);
2857
2858     r = IXMLDOMNode_get_lastChild( node, &child );
2859     ok( r == S_OK, "ret %08x\n", r);
2860
2861     r = IXMLDOMNode_get_nodeName( child, &str );
2862     ok( r == S_OK, "ret %08x\n", r);
2863
2864     ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
2865     SysFreeString(str);
2866
2867     IXMLDOMNode_Release( child );
2868     IXMLDOMNode_Release( node );
2869     IXMLDOMDocument_Release( doc );
2870 }
2871
2872 static void test_removeChild(void)
2873 {
2874     HRESULT r;
2875     BSTR str;
2876     VARIANT_BOOL b;
2877     IXMLDOMDocument *doc;
2878     IXMLDOMElement *element, *lc_element;
2879     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
2880     IXMLDOMNodeList *root_list, *fo_list;
2881
2882     doc = create_document(&IID_IXMLDOMDocument);
2883     if (!doc) return;
2884
2885     str = SysAllocString( szComplete4 );
2886     r = IXMLDOMDocument_loadXML( doc, str, &b );
2887     ok( r == S_OK, "loadXML failed\n");
2888     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2889     SysFreeString( str );
2890
2891     r = IXMLDOMDocument_get_documentElement( doc, &element );
2892     ok( r == S_OK, "ret %08x\n", r);
2893     todo_wine EXPECT_REF(element, 2);
2894
2895     r = IXMLDOMElement_get_childNodes( element, &root_list );
2896     ok( r == S_OK, "ret %08x\n", r);
2897     EXPECT_REF(root_list, 1);
2898
2899     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
2900     ok( r == S_OK, "ret %08x\n", r);
2901     EXPECT_REF(fo_node, 1);
2902
2903     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2904     ok( r == S_OK, "ret %08x\n", r);
2905     EXPECT_REF(fo_list, 1);
2906
2907     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
2908     ok( r == S_OK, "ret %08x\n", r);
2909     EXPECT_REF(ba_node, 1);
2910
2911     /* invalid parameter: NULL ptr */
2912     removed_node = (void*)0xdeadbeef;
2913     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
2914     ok( r == E_INVALIDARG, "ret %08x\n", r );
2915     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2916
2917     /* ba_node is a descendant of element, but not a direct child. */
2918     removed_node = (void*)0xdeadbeef;
2919     EXPECT_REF(ba_node, 1);
2920     EXPECT_CHILDREN(fo_node);
2921     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
2922     ok( r == E_INVALIDARG, "ret %08x\n", r );
2923     ok( removed_node == NULL, "%p\n", removed_node );
2924     EXPECT_REF(ba_node, 1);
2925     EXPECT_CHILDREN(fo_node);
2926
2927     EXPECT_REF(ba_node, 1);
2928     EXPECT_REF(fo_node, 1);
2929     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
2930     ok( r == S_OK, "ret %08x\n", r);
2931     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
2932     EXPECT_REF(fo_node, 2);
2933     EXPECT_REF(ba_node, 1);
2934
2935     /* try removing already removed child */
2936     temp_node = (void*)0xdeadbeef;
2937     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
2938     ok( r == E_INVALIDARG, "ret %08x\n", r);
2939     ok( temp_node == NULL, "%p\n", temp_node );
2940     IXMLDOMNode_Release( fo_node );
2941
2942     /* the removed node has no parent anymore */
2943     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
2944     ok( r == S_FALSE, "ret %08x\n", r);
2945     ok( temp_node == NULL, "%p\n", temp_node );
2946
2947     IXMLDOMNode_Release( removed_node );
2948     IXMLDOMNode_Release( ba_node );
2949     IXMLDOMNodeList_Release( fo_list );
2950
2951     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2952     ok( r == S_OK, "ret %08x\n", r);
2953
2954     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
2955     ok( r == S_OK, "ret %08x\n", r);
2956
2957     /* MS quirk: passing wrong interface pointer works, too */
2958     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
2959     ok( r == S_OK, "ret %08x\n", r);
2960     IXMLDOMElement_Release( lc_element );
2961
2962     temp_node = (void*)0xdeadbeef;
2963     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
2964     ok( r == S_FALSE, "ret %08x\n", r);
2965     ok( temp_node == NULL, "%p\n", temp_node );
2966
2967     IXMLDOMNode_Release( lc_node );
2968     IXMLDOMNodeList_Release( root_list );
2969     IXMLDOMElement_Release( element );
2970     IXMLDOMDocument_Release( doc );
2971 }
2972
2973 static void test_replaceChild(void)
2974 {
2975     HRESULT r;
2976     BSTR str;
2977     VARIANT_BOOL b;
2978     IXMLDOMDocument *doc;
2979     IXMLDOMElement *element, *ba_element;
2980     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
2981     IXMLDOMNodeList *root_list, *fo_list;
2982     IUnknown * unk1, *unk2;
2983     LONG len;
2984
2985     doc = create_document(&IID_IXMLDOMDocument);
2986     if (!doc) return;
2987
2988     str = SysAllocString( szComplete4 );
2989     r = IXMLDOMDocument_loadXML( doc, str, &b );
2990     ok( r == S_OK, "loadXML failed\n");
2991     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2992     SysFreeString( str );
2993
2994     r = IXMLDOMDocument_get_documentElement( doc, &element );
2995     ok( r == S_OK, "ret %08x\n", r);
2996
2997     r = IXMLDOMElement_get_childNodes( element, &root_list );
2998     ok( r == S_OK, "ret %08x\n", r);
2999
3000     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3001     ok( r == S_OK, "ret %08x\n", r);
3002
3003     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3004     ok( r == S_OK, "ret %08x\n", r);
3005
3006     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3007     ok( r == S_OK, "ret %08x\n", r);
3008
3009     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3010     ok( r == S_OK, "ret %08x\n", r);
3011
3012     IXMLDOMNodeList_Release( fo_list );
3013
3014     /* invalid parameter: NULL ptr for element to remove */
3015     removed_node = (void*)0xdeadbeef;
3016     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3017     ok( r == E_INVALIDARG, "ret %08x\n", r );
3018     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3019
3020     /* invalid parameter: NULL for replacement element. (Sic!) */
3021     removed_node = (void*)0xdeadbeef;
3022     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3023     ok( r == E_INVALIDARG, "ret %08x\n", r );
3024     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3025
3026     /* invalid parameter: OldNode is not a child */
3027     removed_node = (void*)0xdeadbeef;
3028     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3029     ok( r == E_INVALIDARG, "ret %08x\n", r );
3030     ok( removed_node == NULL, "%p\n", removed_node );
3031     IXMLDOMNode_Release( lc_node );
3032
3033     /* invalid parameter: would create loop */
3034     removed_node = (void*)0xdeadbeef;
3035     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3036     ok( r == E_FAIL, "ret %08x\n", r );
3037     ok( removed_node == NULL, "%p\n", removed_node );
3038
3039     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
3040     ok( r == S_OK, "ret %08x\n", r );
3041
3042     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
3043     ok( r == S_OK, "ret %08x\n", r );
3044
3045     /* ba_node and temp_node refer to the same node, yet they
3046        are different interface pointers */
3047     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
3048     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
3049     ok( r == S_OK, "ret %08x\n", r );
3050     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
3051     ok( r == S_OK, "ret %08x\n", r );
3052     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
3053
3054     IUnknown_Release( unk1 );
3055     IUnknown_Release( unk2 );
3056
3057     /* ba_node should have been removed from below fo_node */
3058     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3059     ok( r == S_OK, "ret %08x\n", r );
3060
3061     /* MS quirk: replaceChild also accepts elements instead of nodes */
3062     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
3063     ok( r == S_OK, "ret %08x\n", r );
3064     EXPECT_REF(ba_element, 2);
3065
3066     removed_node = NULL;
3067     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
3068     ok( r == S_OK, "ret %08x\n", r );
3069     ok( removed_node != NULL, "got %p\n", removed_node);
3070     EXPECT_REF(ba_element, 3);
3071     IXMLDOMElement_Release( ba_element );
3072
3073     r = IXMLDOMNodeList_get_length( fo_list, &len);
3074     ok( r == S_OK, "ret %08x\n", r );
3075     ok( len == 0, "len %d\n", len);
3076
3077     IXMLDOMNodeList_Release( fo_list );
3078
3079     IXMLDOMNode_Release(ba_node);
3080     IXMLDOMNode_Release(fo_node);
3081     IXMLDOMNode_Release(temp_node);
3082     IXMLDOMNodeList_Release( root_list );
3083     IXMLDOMElement_Release( element );
3084     IXMLDOMDocument_Release( doc );
3085 }
3086
3087 static void test_removeNamedItem(void)
3088 {
3089     IXMLDOMDocument *doc;
3090     IXMLDOMElement *element;
3091     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
3092     IXMLDOMNodeList *root_list;
3093     IXMLDOMNamedNodeMap * pr_attrs;
3094     VARIANT_BOOL b;
3095     BSTR str;
3096     LONG len;
3097     HRESULT r;
3098
3099     doc = create_document(&IID_IXMLDOMDocument);
3100     if (!doc) return;
3101
3102     str = SysAllocString( szComplete4 );
3103     r = IXMLDOMDocument_loadXML( doc, str, &b );
3104     ok( r == S_OK, "loadXML failed\n");
3105     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3106     SysFreeString( str );
3107
3108     r = IXMLDOMDocument_get_documentElement( doc, &element );
3109     ok( r == S_OK, "ret %08x\n", r);
3110
3111     r = IXMLDOMElement_get_childNodes( element, &root_list );
3112     ok( r == S_OK, "ret %08x\n", r);
3113
3114     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
3115     ok( r == S_OK, "ret %08x\n", r);
3116
3117     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
3118     ok( r == S_OK, "ret %08x\n", r);
3119
3120     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3121     ok( r == S_OK, "ret %08x\n", r);
3122     ok( len == 3, "length %d\n", len);
3123
3124     removed_node = (void*)0xdeadbeef;
3125     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
3126     ok ( r == E_INVALIDARG, "ret %08x\n", r);
3127     ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
3128
3129     removed_node = (void*)0xdeadbeef;
3130     str = SysAllocString(szvr);
3131     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
3132     ok ( r == S_OK, "ret %08x\n", r);
3133
3134     removed_node2 = (void*)0xdeadbeef;
3135     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
3136     ok ( r == S_FALSE, "ret %08x\n", r);
3137     ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
3138
3139     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3140     ok( r == S_OK, "ret %08x\n", r);
3141     ok( len == 2, "length %d\n", len);
3142
3143     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
3144     ok ( r == S_OK, "ret %08x\n", r);
3145     IXMLDOMNode_Release(removed_node);
3146
3147     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3148     ok( r == S_OK, "ret %08x\n", r);
3149     ok( len == 3, "length %d\n", len);
3150
3151     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
3152     ok ( r == S_OK, "ret %08x\n", r);
3153
3154     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3155     ok( r == S_OK, "ret %08x\n", r);
3156     ok( len == 2, "length %d\n", len);
3157
3158     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
3159     ok ( r == S_FALSE, "ret %08x\n", r);
3160
3161     SysFreeString(str);
3162
3163     IXMLDOMNamedNodeMap_Release( pr_attrs );
3164     IXMLDOMNode_Release( pr_node );
3165     IXMLDOMNodeList_Release( root_list );
3166     IXMLDOMElement_Release( element );
3167     IXMLDOMDocument_Release( doc );
3168 }
3169
3170 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
3171 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
3172                                     HRESULT result2, DWORD set, DWORD mask, DWORD expected,
3173                                     DWORD expected2)
3174 {
3175     DWORD enabled, supported;
3176     HRESULT hr;
3177
3178     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
3179     if (result == result2)
3180         ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
3181     else
3182         ok_(__FILE__,line)(broken(hr == result) || hr == result2,
3183            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
3184
3185     supported = enabled = 0xCAFECAFE;
3186     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3187     ok(hr == S_OK, "ret %08x\n", hr );
3188     if (expected == expected2)
3189         ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
3190     else
3191         ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
3192            "Expected %08x, got %08x\n", expected2, enabled);
3193
3194     /* reset the safety options */
3195
3196     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3197             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
3198             0);
3199     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3200
3201     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3202     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3203     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
3204 }
3205
3206 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
3207 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
3208 {
3209     DWORD enabled = 0, supported = 0;
3210     HRESULT hr;
3211
3212     /* get */
3213     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
3214     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
3215     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
3216     ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
3217
3218     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3219     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3220     ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
3221        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
3222         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
3223              "got %08x\n", supported);
3224     ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
3225
3226     /* set -- individual flags */
3227
3228     test_IObjectSafety_set(safety, S_OK, S_OK,
3229         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3230         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3231
3232     test_IObjectSafety_set(safety, S_OK, S_OK,
3233         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
3234         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
3235
3236     test_IObjectSafety_set(safety, S_OK, S_OK,
3237         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
3238         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
3239
3240     /* set INTERFACE_USES_DISPEX  */
3241
3242     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
3243         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
3244         0, 0);
3245
3246     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
3247         INTERFACE_USES_DISPEX, 0,
3248         0, 0);
3249
3250     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
3251         0, INTERFACE_USES_DISPEX,
3252         0, 0);
3253
3254     /* set option masking */
3255
3256     test_IObjectSafety_set(safety, S_OK, S_OK,
3257         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3258         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3259         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3260         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3261
3262     test_IObjectSafety_set(safety, S_OK, S_OK,
3263         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3264         INTERFACESAFE_FOR_UNTRUSTED_DATA,
3265         INTERFACESAFE_FOR_UNTRUSTED_DATA,
3266         INTERFACESAFE_FOR_UNTRUSTED_DATA);
3267
3268     test_IObjectSafety_set(safety, S_OK, S_OK,
3269         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3270         INTERFACE_USES_SECURITY_MANAGER,
3271         0,
3272         0);
3273
3274     /* set -- inheriting previous settings */
3275
3276     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3277                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3278                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3279     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3280     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3281     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3282     todo_wine
3283     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER) ||
3284        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
3285          "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER), "
3286          "got %08x\n", enabled);
3287
3288     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3289                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
3290                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
3291     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3292     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3293     ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3294     todo_wine
3295     ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
3296        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) /* msxml3 SP8+ */,
3297         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA), "
3298         "got %08x\n", enabled);
3299 }
3300
3301 static void test_XMLHTTP(void)
3302 {
3303     static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
3304     static const WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
3305         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
3306         'p','o','s','t','t','e','s','t','.','p','h','p',0};
3307     static const WCHAR xmltestW[] = {'h','t','t','p',':','/','/',
3308         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
3309         'x','m','l','t','e','s','t','.','x','m','l',0};
3310     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
3311     static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
3312
3313     IXMLHttpRequest *pXMLHttpRequest;
3314     IObjectSafety *safety;
3315     IObjectWithSite *pSite;
3316     BSTR bstrResponse, url;
3317     VARIANT dummy;
3318     VARIANT async;
3319     VARIANT varbody;
3320     LONG state, status, bound;
3321     void *ptr;
3322     IDispatch *event;
3323     HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
3324                                   CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest,
3325                                   (void **)&pXMLHttpRequest);
3326     if (FAILED(hr))
3327     {
3328         win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
3329         return;
3330     }
3331
3332     hr = IXMLHttpRequest_QueryInterface(pXMLHttpRequest, &IID_IObjectWithSite, (void**)&pSite);
3333     ok(hr == S_OK, "got 0x%08x\n", hr);
3334     if(hr == S_OK) IObjectWithSite_Release(pSite);
3335
3336     VariantInit(&dummy);
3337     V_VT(&dummy) = VT_ERROR;
3338     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
3339     VariantInit(&async);
3340     V_VT(&async) = VT_BOOL;
3341     V_BOOL(&async) = VARIANT_FALSE;
3342     V_VT(&varbody) = VT_BSTR;
3343     V_BSTR(&varbody) = SysAllocString(wszBody);
3344
3345     url = SysAllocString(wszUrl);
3346
3347     hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, NULL);
3348     ok(hr == S_OK, "got 0x%08x\n", hr);
3349
3350     hr = IXMLHttpRequest_abort(pXMLHttpRequest);
3351     ok(hr == S_OK, "got 0x%08x\n", hr);
3352
3353     /* send before open */
3354     hr = IXMLHttpRequest_send(pXMLHttpRequest, dummy);
3355     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3356
3357     /* initial status code */
3358     hr = IXMLHttpRequest_get_status(pXMLHttpRequest, NULL);
3359     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3360
3361     status = 0xdeadbeef;
3362     hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3363     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3364     ok(status == 0xdeadbeef, "got %d\n", status);
3365
3366     /* invalid parameters */
3367     hr = IXMLHttpRequest_open(pXMLHttpRequest, NULL, NULL, async, dummy, dummy);
3368     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3369
3370     hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), NULL, async, dummy, dummy);
3371     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3372
3373     hr = IXMLHttpRequest_open(pXMLHttpRequest, NULL, url, async, dummy, dummy);
3374     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3375
3376     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, NULL);
3377     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3378
3379     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), NULL);
3380     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3381
3382     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
3383     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3384
3385     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
3386     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3387
3388     hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, NULL);
3389     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3390
3391     state = -1;
3392     hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3393     ok(hr == S_OK, "got 0x%08x\n", hr);
3394     ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
3395
3396     event = create_dispevent();
3397
3398     EXPECT_REF(event, 1);
3399     hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, event);
3400     ok(hr == S_OK, "got 0x%08x\n", hr);
3401     EXPECT_REF(event, 2);
3402
3403     g_unexpectedcall = g_expectedcall = 0;
3404
3405     hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), url, async, dummy, dummy);
3406     ok(hr == S_OK, "got 0x%08x\n", hr);
3407
3408     ok(g_unexpectedcall == 0, "unexpected disp event call\n");
3409     ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
3410
3411     /* status code after ::open() */
3412     status = 0xdeadbeef;
3413     hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3414     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3415     ok(status == 0xdeadbeef, "got %d\n", status);
3416
3417     state = -1;
3418     hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3419     ok(hr == S_OK, "got 0x%08x\n", hr);
3420     ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
3421
3422     hr = IXMLHttpRequest_abort(pXMLHttpRequest);
3423     ok(hr == S_OK, "got 0x%08x\n", hr);
3424
3425     state = -1;
3426     hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3427     ok(hr == S_OK, "got 0x%08x\n", hr);
3428     ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
3429         "got %d, expected READYSTATE_UNINITIALIZED\n", state);
3430
3431     hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), url, async, dummy, dummy);
3432     ok(hr == S_OK, "got 0x%08x\n", hr);
3433
3434     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
3435     ok(hr == S_OK, "got 0x%08x\n", hr);
3436
3437     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
3438     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3439
3440     hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_(""), _bstr_("value1"));
3441     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3442
3443     SysFreeString(url);
3444
3445     hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3446     if (hr == INET_E_RESOURCE_NOT_FOUND)
3447     {
3448         skip("No connection could be made with crossover.codeweavers.com\n");
3449         IXMLHttpRequest_Release(pXMLHttpRequest);
3450         return;
3451     }
3452     ok(hr == S_OK, "got 0x%08x\n", hr);
3453
3454     /* status code after ::send() */
3455     status = 0xdeadbeef;
3456     hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3457     ok(hr == S_OK, "got 0x%08x\n", hr);
3458     ok(status == 200, "got %d\n", status);
3459
3460     /* another ::send() after completed request */
3461     hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3462     ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3463
3464     VariantClear(&varbody);
3465
3466     hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
3467     ok(hr == S_OK, "got 0x%08x\n", hr);
3468     /* the server currently returns "FAILED" because the Content-Type header is
3469      * not what the server expects */
3470     if(hr == S_OK)
3471     {
3472         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
3473             "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
3474         SysFreeString(bstrResponse);
3475     }
3476
3477     /* GET request */
3478     url = SysAllocString(xmltestW);
3479
3480     hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("GET"), url, async, dummy, dummy);
3481     ok(hr == S_OK, "got 0x%08x\n", hr);
3482
3483     V_VT(&varbody) = VT_EMPTY;
3484
3485     hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3486     if (hr == INET_E_RESOURCE_NOT_FOUND)
3487     {
3488         skip("No connection could be made with crossover.codeweavers.com\n");
3489         IXMLHttpRequest_Release(pXMLHttpRequest);
3490         return;
3491     }
3492     ok(hr == S_OK, "got 0x%08x\n", hr);
3493
3494     hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, NULL);
3495     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3496
3497     hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
3498     ok(hr == S_OK, "got 0x%08x\n", hr);
3499     if(hr == S_OK)
3500     {
3501         ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
3502             "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
3503         SysFreeString(bstrResponse);
3504     }
3505
3506     hr = IXMLHttpRequest_get_responseBody(pXMLHttpRequest, NULL);
3507     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3508
3509     V_VT(&varbody) = VT_EMPTY;
3510     hr = IXMLHttpRequest_get_responseBody(pXMLHttpRequest, &varbody);
3511     ok(hr == S_OK, "got 0x%08x\n", hr);
3512     ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
3513     ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
3514
3515     bound = -1;
3516     hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
3517     ok(hr == S_OK, "got 0x%08x\n", hr);
3518     ok(bound == 0, "got %d, expected zero bound\n", bound);
3519
3520     hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
3521     ok(hr == S_OK, "got 0x%08x\n", hr);
3522     ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrond body data\n");
3523     SafeArrayUnaccessData(V_ARRAY(&varbody));
3524
3525     VariantClear(&varbody);
3526
3527     SysFreeString(url);
3528
3529     hr = IXMLHttpRequest_QueryInterface(pXMLHttpRequest, &IID_IObjectSafety, (void**)&safety);
3530     ok(hr == S_OK, "ret %08x\n", hr );
3531     if(hr == S_OK)
3532     {
3533         test_IObjectSafety_common(safety);
3534
3535         IObjectSafety_Release(safety);
3536     }
3537
3538
3539     IDispatch_Release(event);
3540     IXMLHttpRequest_Release(pXMLHttpRequest);
3541     free_bstrs();
3542 }
3543
3544 static void test_IXMLDOMDocument2(void)
3545 {
3546     static const WCHAR emptyW[] = {0};
3547     IXMLDOMDocument2 *doc2, *dtddoc2;
3548     IXMLDOMDocument *doc;
3549     IXMLDOMParseError* err;
3550     IDispatchEx *dispex;
3551     VARIANT_BOOL b;
3552     VARIANT var;
3553     HRESULT r;
3554     LONG res;
3555     BSTR str;
3556
3557     doc = create_document(&IID_IXMLDOMDocument);
3558     if (!doc) return;
3559
3560     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
3561     if (!dtddoc2)
3562     {
3563         IXMLDOMDocument_Release(doc);
3564         return;
3565     }
3566
3567     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
3568     ok( r == S_OK, "ret %08x\n", r );
3569     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
3570
3571     ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
3572     ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
3573     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
3574
3575     err = NULL;
3576     ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
3577     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
3578     ok(err != NULL, "expected a pointer\n");
3579     if (err)
3580     {
3581         res = 0;
3582         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3583         /* XML_E_NOTWF */
3584         ok(res == E_XML_NOTWF, "got %08x\n", res);
3585         IXMLDOMParseError_Release(err);
3586     }
3587
3588     str = SysAllocString( szComplete4 );
3589     r = IXMLDOMDocument_loadXML( doc2, str, &b );
3590     ok( r == S_OK, "loadXML failed\n");
3591     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3592     SysFreeString( str );
3593
3594     ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
3595     ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
3596
3597     err = NULL;
3598     ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
3599     ok(err != NULL, "expected a pointer\n");
3600     if (err)
3601     {
3602         res = 0;
3603         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3604         /* XML_E_NODTD */
3605         ok(res == E_XML_NODTD, "got %08x\n", res);
3606         IXMLDOMParseError_Release(err);
3607     }
3608
3609     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
3610     ok( r == S_OK, "ret %08x\n", r );
3611     if(r == S_OK)
3612     {
3613         IDispatchEx_Release(dispex);
3614     }
3615
3616     /* we will check if the variant got cleared */
3617     IXMLDOMDocument2_AddRef(doc2);
3618     EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
3619
3620     V_VT(&var) = VT_UNKNOWN;
3621     V_UNKNOWN(&var) = (IUnknown *)doc2;
3622
3623     /* invalid calls */
3624     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
3625     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
3626     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
3627
3628     /* valid call */
3629     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
3630     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
3631     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
3632     V_VT(&var) = VT_R4;
3633
3634     /* the variant didn't get cleared*/
3635     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
3636
3637     /* setProperty tests */
3638     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
3639     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
3640     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
3641     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
3642     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3643     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
3644
3645     V_VT(&var) = VT_BSTR;
3646     V_BSTR(&var) = SysAllocString(emptyW);
3647     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
3648     ok(r == S_OK, "got 0x%08x\n", r);
3649     VariantClear(&var);
3650
3651     V_VT(&var) = VT_I2;
3652     V_I2(&var) = 0;
3653     r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
3654     ok(r == E_FAIL, "got 0x%08x\n", r);
3655
3656     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
3657     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
3658     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
3659     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
3660
3661     IXMLDOMDocument2_Release( doc2 );
3662     IXMLDOMDocument_Release( doc );
3663
3664     /* DTD validation */
3665     ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
3666     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
3667     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3668     err = NULL;
3669     ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
3670     ok(err != NULL, "expected pointer\n");
3671     if (err)
3672     {
3673         res = 0;
3674         ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
3675         ok(res == 0, "got %08x\n", res);
3676         IXMLDOMParseError_Release(err);
3677     }
3678
3679     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
3680     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3681     err = NULL;
3682     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3683     ok(err != NULL, "expected pointer\n");
3684     if (err)
3685     {
3686         res = 0;
3687         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3688         /* XML_ELEMENT_UNDECLARED */
3689         todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
3690         IXMLDOMParseError_Release(err);
3691     }
3692
3693     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
3694     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3695     err = NULL;
3696     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3697     ok(err != NULL, "expected pointer\n");
3698     if (err)
3699     {
3700         res = 0;
3701         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3702         /* XML_ELEMENT_ID_NOT_FOUND */
3703         todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
3704         IXMLDOMParseError_Release(err);
3705     }
3706
3707     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
3708     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3709     err = NULL;
3710     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3711     ok(err != NULL, "expected pointer\n");
3712     if (err)
3713     {
3714         res = 0;
3715         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3716         /* XML_EMPTY_NOT_ALLOWED */
3717         todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
3718         IXMLDOMParseError_Release(err);
3719     }
3720
3721     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
3722     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3723     err = NULL;
3724     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3725     ok(err != NULL, "expected pointer\n");
3726     if (err)
3727     {
3728         res = 0;
3729         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3730         /* XML_ROOT_NAME_MISMATCH */
3731         todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
3732         IXMLDOMParseError_Release(err);
3733     }
3734
3735     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
3736     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3737     err = NULL;
3738     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3739     ok(err != NULL, "expected pointer\n");
3740     if (err)
3741     {
3742         res = 0;
3743         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3744         /* XML_INVALID_CONTENT */
3745         todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
3746         IXMLDOMParseError_Release(err);
3747     }
3748
3749     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
3750     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3751     err = NULL;
3752     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3753     ok(err != NULL, "expected pointer\n");
3754     if (err)
3755     {
3756         res = 0;
3757         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3758         /* XML_ATTRIBUTE_NOT_DEFINED */
3759         todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
3760         IXMLDOMParseError_Release(err);
3761     }
3762
3763     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
3764     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3765     err = NULL;
3766     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3767     ok(err != NULL, "expected pointer\n");
3768     if (err)
3769     {
3770         res = 0;
3771         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3772         /* XML_ATTRIBUTE_FIXED */
3773         todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
3774         IXMLDOMParseError_Release(err);
3775     }
3776
3777     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
3778     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3779     err = NULL;
3780     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3781     ok(err != NULL, "expected pointer\n");
3782     if (err)
3783     {
3784         res = 0;
3785         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3786         /* XML_ATTRIBUTE_VALUE */
3787         todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
3788         IXMLDOMParseError_Release(err);
3789     }
3790
3791     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
3792     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3793     err = NULL;
3794     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3795     ok(err != NULL, "expected pointer\n");
3796     if (err)
3797     {
3798         res = 0;
3799         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3800         /* XML_ILLEGAL_TEXT */
3801         todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
3802         IXMLDOMParseError_Release(err);
3803     }
3804
3805     ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
3806     ok( b == VARIANT_TRUE, "failed to load XML string\n");
3807     err = NULL;
3808     ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3809     ok(err != NULL, "expected pointer\n");
3810     if (err)
3811     {
3812         res = 0;
3813         ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3814         /* XML_REQUIRED_ATTRIBUTE_MISSING */
3815         todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
3816         IXMLDOMParseError_Release(err);
3817     }
3818
3819     IXMLDOMDocument2_Release( dtddoc2 );
3820     free_bstrs();
3821 }
3822
3823 #define helper_ole_check(expr) { \
3824     HRESULT r = expr; \
3825     ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
3826 }
3827
3828 #define helper_expect_list_and_release(list, expstr) { \
3829     char *str = list_to_string(list); \
3830     ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
3831     if (list) IXMLDOMNodeList_Release(list); \
3832 }
3833
3834 #define helper_expect_bstr_and_release(bstr, str) { \
3835     ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
3836        "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
3837     SysFreeString(bstr); \
3838 }
3839
3840 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
3841 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
3842 {
3843     IXMLDOMNode *node1, *node2;
3844     IXMLDOMNodeList *list;
3845     BSTR bstr;
3846
3847     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
3848     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
3849     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
3850     helper_ole_check(IXMLDOMNodeList_reset(list));
3851     helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
3852
3853     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
3854     helper_expect_list_and_release(list, "T1.E1.E4.E1.E2.D1 E2.E1.E4.E1.E2.D1 E3.E1.E4.E1.E2.D1 T4.E1.E4.E1.E2.D1 E5.E1.E4.E1.E2.D1");
3855     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
3856     if (str)
3857     {
3858         helper_expect_bstr_and_release(bstr, str);
3859     }
3860     else
3861     {
3862         helper_expect_bstr_and_release(bstr, "This is a description.");
3863     }
3864     IXMLDOMNode_Release(node1);
3865
3866     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
3867     helper_expect_list_and_release(list, "T1.E2.E4.E1.E2.D1 E2.E2.E4.E1.E2.D1 T3.E2.E4.E1.E2.D1 E4.E2.E4.E1.E2.D1 T5.E2.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1 T7.E2.E4.E1.E2.D1");
3868     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
3869     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
3870     IXMLDOMNode_Release(node2);
3871 }
3872
3873 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
3874 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
3875 {
3876     IXMLDOMNode *node1, *node2;
3877     IXMLDOMNodeList *list;
3878     BSTR bstr;
3879
3880     helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
3881     helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
3882     helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
3883     helper_ole_check(IXMLDOMNodeList_reset(list));
3884     helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
3885
3886     helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
3887     helper_expect_list_and_release(list, "T1.E2.E8.E2.E2.D1 E2.E2.E8.E2.E2.D1 T3.E2.E8.E2.E2.D1 E4.E2.E8.E2.E2.D1 T5.E2.E8.E2.E2.D1 E6.E2.E8.E2.E2.D1 T7.E2.E8.E2.E2.D1");
3888     helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
3889     if (str)
3890     {
3891         helper_expect_bstr_and_release(bstr, str);
3892     }
3893     else
3894     {
3895         helper_expect_bstr_and_release(bstr, "\n                This is a description. \n            ");
3896     }
3897     IXMLDOMNode_Release(node1);
3898
3899     helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
3900     helper_expect_list_and_release(list, "T1.E4.E8.E2.E2.D1 E2.E4.E8.E2.E2.D1 T3.E4.E8.E2.E2.D1 E4.E4.E8.E2.E2.D1 T5.E4.E8.E2.E2.D1 E6.E4.E8.E2.E2.D1 T7.E4.E8.E2.E2.D1");
3901     helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
3902     helper_expect_bstr_and_release(bstr, "\n                This is a description with preserved whitespace. \n            ");
3903     IXMLDOMNode_Release(node2);
3904 }
3905
3906 static void test_whitespace(void)
3907 {
3908     VARIANT_BOOL b;
3909     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
3910
3911     doc1 = create_document(&IID_IXMLDOMDocument2);
3912     doc2 = create_document(&IID_IXMLDOMDocument2);
3913     if (!doc1 || !doc2) return;
3914
3915     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
3916     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
3917     ok(b == VARIANT_FALSE, "expected false\n");
3918     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
3919     ok(b == VARIANT_TRUE, "expected true\n");
3920
3921     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
3922     ok(b == VARIANT_TRUE, "failed to load XML string\n");
3923     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
3924     ok(b == VARIANT_TRUE, "failed to load XML string\n");
3925
3926     /* switch to XPath */
3927     ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3928     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3929
3930     check_ws_ignored(doc1, NULL);
3931     check_ws_preserved(doc2, NULL);
3932
3933     /* new instances copy the property */
3934     ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
3935     ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
3936
3937     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
3938     ok(b == VARIANT_FALSE, "expected false\n");
3939     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
3940     ok(b == VARIANT_TRUE, "expected true\n");
3941
3942     check_ws_ignored(doc3, NULL);
3943     check_ws_preserved(doc4, NULL);
3944
3945     /* setting after loading xml affects trimming of leading/trailing ws only */
3946     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
3947     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
3948
3949     /* the trailing "\n            " isn't there, because it was ws-only node */
3950     check_ws_ignored(doc1, "\n                This is a description. ");
3951     check_ws_preserved(doc2, "This is a description.");
3952
3953     /* it takes effect on reload */
3954     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
3955     ok(b == VARIANT_TRUE, "expected true\n");
3956     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
3957     ok(b == VARIANT_FALSE, "expected false\n");
3958
3959     ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
3960     ok(b == VARIANT_TRUE, "failed to load XML string\n");
3961     ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
3962     ok(b == VARIANT_TRUE, "failed to load XML string\n");
3963
3964     check_ws_preserved(doc1, NULL);
3965     check_ws_ignored(doc2, NULL);
3966
3967     /* other instances follow suit */
3968     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
3969     ok(b == VARIANT_TRUE, "expected true\n");
3970     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
3971     ok(b == VARIANT_FALSE, "expected false\n");
3972
3973     check_ws_preserved(doc3, NULL);
3974     check_ws_ignored(doc4, NULL);
3975
3976     IXMLDOMDocument_Release(doc1);
3977     IXMLDOMDocument_Release(doc2);
3978     IXMLDOMDocument_Release(doc3);
3979     IXMLDOMDocument_Release(doc4);
3980     free_bstrs();
3981 }
3982
3983 static void test_XPath(void)
3984 {
3985     VARIANT var;
3986     VARIANT_BOOL b;
3987     IXMLDOMDocument2 *doc;
3988     IXMLDOMNode *rootNode;
3989     IXMLDOMNode *elem1Node;
3990     IXMLDOMNode *node;
3991     IXMLDOMNodeList *list;
3992
3993     doc = create_document(&IID_IXMLDOMDocument2);
3994     if (!doc) return;
3995
3996     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b));
3997     ok(b == VARIANT_TRUE, "failed to load XML string\n");
3998
3999     /* switch to XPath */
4000     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4001
4002     /* some simple queries*/
4003     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list));
4004     ole_check(IXMLDOMNodeList_get_item(list, 0, &rootNode));
4005     ole_check(IXMLDOMNodeList_reset(list));
4006     expect_list_and_release(list, "E2.D1");
4007     if (rootNode == NULL)
4008         return;
4009
4010     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//c"), &list));
4011     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
4012
4013     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//c[@type]"), &list));
4014     expect_list_and_release(list, "E3.E2.E2.D1");
4015
4016     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
4017     /* using get_item for query results advances the position */
4018     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
4019     expect_node(node, "E2.E2.D1");
4020     IXMLDOMNode_Release(node);
4021     ole_check(IXMLDOMNodeList_nextNode(list, &node));
4022     expect_node(node, "E4.E2.D1");
4023     IXMLDOMNode_Release(node);
4024     ole_check(IXMLDOMNodeList_reset(list));
4025     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
4026
4027     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
4028     expect_list_and_release(list, "E2.D1");
4029
4030     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
4031     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
4032     ole_check(IXMLDOMNodeList_reset(list));
4033     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
4034
4035     /* select an attribute */
4036     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
4037     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
4038
4039     /* would evaluate to a number */
4040     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
4041     /* would evaluate to a boolean */
4042     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
4043     /* would evaluate to a string */
4044     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
4045
4046     /* no results */
4047     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
4048     expect_list_and_release(list, "");
4049     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
4050     expect_list_and_release(list, "");
4051     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
4052     expect_list_and_release(list, "");
4053     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
4054     expect_list_and_release(list, "");
4055
4056     /* foo undeclared in document node */
4057     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4058     /* undeclared in <root> node */
4059     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
4060     /* undeclared in <elem> node */
4061     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
4062     /* but this trick can be used */
4063     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
4064     expect_list_and_release(list, "E3.E4.E2.D1");
4065
4066     /* it has to be declared in SelectionNamespaces */
4067     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4068         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
4069
4070     /* now the namespace can be used */
4071     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//test:c"), &list));
4072     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4073     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
4074     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4075     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
4076     expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4077     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
4078     expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
4079
4080     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
4081     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4082         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
4083
4084     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4085
4086     VariantInit(&var);
4087     ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
4088     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4089     if (V_VT(&var) == VT_BSTR)
4090         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
4091
4092     /* extra attributes - same thing*/
4093     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4094         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
4095     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4096
4097     IXMLDOMNode_Release(rootNode);
4098     IXMLDOMNode_Release(elem1Node);
4099     IXMLDOMDocument_Release(doc);
4100     free_bstrs();
4101 }
4102
4103 static void test_cloneNode(void )
4104 {
4105     IXMLDOMDocument *doc, *doc2;
4106     VARIANT_BOOL b;
4107     IXMLDOMNodeList *pList;
4108     IXMLDOMNamedNodeMap *mapAttr;
4109     LONG length, length1;
4110     LONG attr_cnt, attr_cnt1;
4111     IXMLDOMNode *node;
4112     IXMLDOMNode *node_clone;
4113     IXMLDOMNode *node_first;
4114     HRESULT hr;
4115     BSTR str;
4116
4117     doc = create_document(&IID_IXMLDOMDocument);
4118     if (!doc) return;
4119
4120     str = SysAllocString( szComplete4 );
4121     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
4122     ok(b == VARIANT_TRUE, "failed to load XML string\n");
4123     SysFreeString(str);
4124
4125     hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
4126     ok( hr == S_OK, "ret %08x\n", hr );
4127     ok( node != NULL, "node %p\n", node );
4128
4129     /* Check invalid parameter */
4130     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
4131     ok( hr == E_INVALIDARG, "ret %08x\n", hr );
4132
4133     /* All Children */
4134     hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
4135     ok( hr == S_OK, "ret %08x\n", hr );
4136     ok( node_clone != NULL, "node %p\n", node );
4137
4138     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
4139     ok( hr == S_OK, "ret %08x\n", hr );
4140     hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
4141     ok( hr == S_OK, "ret %08x\n", hr );
4142     IXMLDOMDocument_Release(doc2);
4143     IXMLDOMNode_Release(node_first);
4144
4145     hr = IXMLDOMNode_get_childNodes(node, &pList);
4146     ok( hr == S_OK, "ret %08x\n", hr );
4147     length = 0;
4148     hr = IXMLDOMNodeList_get_length(pList, &length);
4149     ok( hr == S_OK, "ret %08x\n", hr );
4150     ok(length == 1, "got %d\n", length);
4151     IXMLDOMNodeList_Release(pList);
4152
4153     hr = IXMLDOMNode_get_attributes(node, &mapAttr);
4154     ok( hr == S_OK, "ret %08x\n", hr );
4155     attr_cnt = 0;
4156     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
4157     ok( hr == S_OK, "ret %08x\n", hr );
4158     ok(attr_cnt == 3, "got %d\n", attr_cnt);
4159     IXMLDOMNamedNodeMap_Release(mapAttr);
4160
4161     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
4162     ok( hr == S_OK, "ret %08x\n", hr );
4163     length1 = 0;
4164     hr = IXMLDOMNodeList_get_length(pList, &length1);
4165     ok(length1 == 1, "got %d\n", length1);
4166     ok( hr == S_OK, "ret %08x\n", hr );
4167     IXMLDOMNodeList_Release(pList);
4168
4169     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
4170     ok( hr == S_OK, "ret %08x\n", hr );
4171     attr_cnt1 = 0;
4172     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
4173     ok( hr == S_OK, "ret %08x\n", hr );
4174     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
4175     IXMLDOMNamedNodeMap_Release(mapAttr);
4176
4177     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
4178     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
4179     IXMLDOMNode_Release(node_clone);
4180
4181     /* No Children */
4182     hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
4183     ok( hr == S_OK, "ret %08x\n", hr );
4184     ok( node_clone != NULL, "node %p\n", node );
4185
4186     hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
4187     ok(hr == S_FALSE, "ret %08x\n", hr );
4188
4189     hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
4190     ok(hr == S_OK, "ret %08x\n", hr );
4191     hr = IXMLDOMNodeList_get_length(pList, &length1);
4192     ok(hr == S_OK, "ret %08x\n", hr );
4193     ok( length1 == 0, "Length should be 0 (%d)\n", length1);
4194     IXMLDOMNodeList_Release(pList);
4195
4196     hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
4197     ok(hr == S_OK, "ret %08x\n", hr );
4198     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
4199     ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
4200     IXMLDOMNamedNodeMap_Release(mapAttr);
4201
4202     ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
4203     ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
4204     IXMLDOMNode_Release(node_clone);
4205
4206     IXMLDOMNode_Release(node);
4207     IXMLDOMDocument_Release(doc);
4208     free_bstrs();
4209 }
4210
4211 static void test_xmlTypes(void)
4212 {
4213     IXMLDOMDocument *doc;
4214     IXMLDOMElement *pRoot;
4215     HRESULT hr;
4216     IXMLDOMComment *pComment;
4217     IXMLDOMElement *pElement;
4218     IXMLDOMAttribute *pAttribute;
4219     IXMLDOMNamedNodeMap *pAttribs;
4220     IXMLDOMCDATASection *pCDataSec;
4221     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
4222     IXMLDOMDocumentFragment *pDocFrag = NULL;
4223     IXMLDOMEntityReference *pEntityRef = NULL;
4224     BSTR str;
4225     IXMLDOMNode *pNextChild;
4226     VARIANT v;
4227     LONG len = 0;
4228
4229     doc = create_document(&IID_IXMLDOMDocument);
4230     if (!doc) return;
4231
4232     pNextChild = (void*)0xdeadbeef;
4233     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
4234     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4235
4236     pNextChild = (void*)0xdeadbeef;
4237     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
4238     ok(hr == S_FALSE, "ret %08x\n", hr );
4239     ok(pNextChild == NULL, "pDocChild not NULL\n");
4240
4241     /* test previous Sibling */
4242     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
4243     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4244
4245     pNextChild = (void*)0xdeadbeef;
4246     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
4247     ok(hr == S_FALSE, "ret %08x\n", hr );
4248     ok(pNextChild == NULL, "pNextChild not NULL\n");
4249
4250     /* test get_dataType */
4251     V_VT(&v) = VT_EMPTY;
4252     hr = IXMLDOMDocument_get_dataType(doc, &v);
4253     ok(hr == S_FALSE, "ret %08x\n", hr );
4254     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
4255     VariantClear(&v);
4256
4257     /* test implementation */
4258     hr = IXMLDOMDocument_get_implementation(doc, NULL);
4259     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4260
4261     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
4262     ok(hr == S_OK, "ret %08x\n", hr );
4263     if(hr == S_OK)
4264     {
4265         VARIANT_BOOL hasFeature = VARIANT_TRUE;
4266         BSTR sEmpty = SysAllocStringLen(NULL, 0);
4267
4268         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
4269         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4270
4271         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
4272         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4273
4274         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
4275         ok(hr == S_OK, "ret %08x\n", hr );
4276         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4277
4278         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
4279         ok(hr == S_OK, "ret %08x\n", hr );
4280         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
4281
4282         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
4283         ok(hr == S_OK, "ret %08x\n", hr );
4284         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
4285
4286         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
4287         ok(hr == S_OK, "ret %08x\n", hr );
4288         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4289
4290         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
4291         ok(hr == S_OK, "ret %08x\n", hr );
4292         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4293
4294         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
4295         ok(hr == S_OK, "ret %08x\n", hr );
4296         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4297
4298         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
4299         ok(hr == S_OK, "ret %08x\n", hr );
4300         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4301
4302         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
4303         ok(hr == S_OK, "ret %08x\n", hr );
4304         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4305
4306         SysFreeString(sEmpty);
4307         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
4308     }
4309
4310     pRoot = (IXMLDOMElement*)0x1;
4311     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
4312     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4313     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
4314
4315     pRoot = (IXMLDOMElement*)0x1;
4316     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
4317     ok(hr == E_FAIL, "ret %08x\n", hr );
4318     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
4319
4320     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
4321     ok(hr == S_OK, "ret %08x\n", hr );
4322     if(hr == S_OK)
4323     {
4324         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
4325         ok(hr == S_OK, "ret %08x\n", hr );
4326         if(hr == S_OK)
4327         {
4328             /* Comment */
4329             str = SysAllocString(szComment);
4330             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
4331             SysFreeString(str);
4332             ok(hr == S_OK, "ret %08x\n", hr );
4333             if(hr == S_OK)
4334             {
4335                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
4336                 ok(hr == S_OK, "ret %08x\n", hr );
4337
4338                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
4339                 ok(hr == S_OK, "ret %08x\n", hr );
4340                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
4341                 SysFreeString(str);
4342
4343                 hr = IXMLDOMComment_get_xml(pComment, &str);
4344                 ok(hr == S_OK, "ret %08x\n", hr );
4345                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
4346                 SysFreeString(str);
4347
4348                 /* put data Tests */
4349                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
4350                 ok(hr == S_OK, "ret %08x\n", hr );
4351
4352                 /* get data Tests */
4353                 hr = IXMLDOMComment_get_data(pComment, &str);
4354                 ok(hr == S_OK, "ret %08x\n", hr );
4355                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
4356                 SysFreeString(str);
4357
4358                 /* get data Tests */
4359                 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
4360                 ok(hr == S_OK, "ret %08x\n", hr );
4361                 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
4362                 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
4363                 VariantClear(&v);
4364
4365                 /* Confirm XML text is good */
4366                 hr = IXMLDOMComment_get_xml(pComment, &str);
4367                 ok(hr == S_OK, "ret %08x\n", hr );
4368                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
4369                 SysFreeString(str);
4370
4371                 /* Confirm we get the put_data Text back */
4372                 hr = IXMLDOMComment_get_text(pComment, &str);
4373                 ok(hr == S_OK, "ret %08x\n", hr );
4374                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
4375                 SysFreeString(str);
4376
4377                 /* test length property */
4378                 hr = IXMLDOMComment_get_length(pComment, &len);
4379                 ok(hr == S_OK, "ret %08x\n", hr );
4380                 ok(len == 21, "expected 21 got %d\n", len);
4381
4382                 /* test substringData */
4383                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
4384                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4385
4386                 /* test substringData - Invalid offset */
4387                 str = (BSTR)&szElement;
4388                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
4389                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4390                 ok( str == NULL, "incorrect string\n");
4391
4392                 /* test substringData - Invalid offset */
4393                 str = (BSTR)&szElement;
4394                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
4395                 ok(hr == S_FALSE, "ret %08x\n", hr );
4396                 ok( str == NULL, "incorrect string\n");
4397
4398                 /* test substringData - Invalid size */
4399                 str = (BSTR)&szElement;
4400                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
4401                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4402                 ok( str == NULL, "incorrect string\n");
4403
4404                 /* test substringData - Invalid size */
4405                 str = (BSTR)&szElement;
4406                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
4407                 ok(hr == S_FALSE, "ret %08x\n", hr );
4408                 ok( str == NULL, "incorrect string\n");
4409
4410                 /* test substringData - Start of string */
4411                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
4412                 ok(hr == S_OK, "ret %08x\n", hr );
4413                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
4414                 SysFreeString(str);
4415
4416                 /* test substringData - Middle of string */
4417                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
4418                 ok(hr == S_OK, "ret %08x\n", hr );
4419                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
4420                 SysFreeString(str);
4421
4422                 /* test substringData - End of string */
4423                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
4424                 ok(hr == S_OK, "ret %08x\n", hr );
4425                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
4426                 SysFreeString(str);
4427
4428                 /* test appendData */
4429                 hr = IXMLDOMComment_appendData(pComment, NULL);
4430                 ok(hr == S_OK, "ret %08x\n", hr );
4431
4432                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
4433                 ok(hr == S_OK, "ret %08x\n", hr );
4434
4435                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
4436                 ok(hr == S_OK, "ret %08x\n", hr );
4437
4438                 hr = IXMLDOMComment_get_text(pComment, &str);
4439                 ok(hr == S_OK, "ret %08x\n", hr );
4440                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4441                 SysFreeString(str);
4442
4443                 /* test insertData */
4444                 str = SysAllocStringLen(NULL, 0);
4445                 hr = IXMLDOMComment_insertData(pComment, -1, str);
4446                 ok(hr == S_OK, "ret %08x\n", hr );
4447
4448                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
4449                 ok(hr == S_OK, "ret %08x\n", hr );
4450
4451                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
4452                 ok(hr == S_OK, "ret %08x\n", hr );
4453
4454                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
4455                 ok(hr == S_OK, "ret %08x\n", hr );
4456
4457                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
4458                 ok(hr == S_OK, "ret %08x\n", hr );
4459
4460                 hr = IXMLDOMComment_insertData(pComment, 0, str);
4461                 ok(hr == S_OK, "ret %08x\n", hr );
4462                 SysFreeString(str);
4463
4464                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
4465                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4466
4467                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
4468                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4469
4470                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
4471                 ok(hr == S_OK, "ret %08x\n", hr );
4472
4473                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
4474                 ok(hr == S_OK, "ret %08x\n", hr );
4475
4476                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
4477                 ok(hr == S_OK, "ret %08x\n", hr );
4478
4479                 hr = IXMLDOMComment_get_text(pComment, &str);
4480                 ok(hr == S_OK, "ret %08x\n", hr );
4481                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4482                 SysFreeString(str);
4483
4484                 /* delete data */
4485                 /* invalid arguments */
4486                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
4487                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4488
4489                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
4490                 ok(hr == S_OK, "ret %08x\n", hr );
4491
4492                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
4493                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4494
4495                 hr = IXMLDOMComment_get_length(pComment, &len);
4496                 ok(hr == S_OK, "ret %08x\n", hr );
4497                 ok(len == 43, "expected 43 got %d\n", len);
4498
4499                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
4500                 ok(hr == S_OK, "ret %08x\n", hr );
4501
4502                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
4503                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4504
4505                 /* delete from start */
4506                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
4507                 ok(hr == S_OK, "ret %08x\n", hr );
4508
4509                 hr = IXMLDOMComment_get_length(pComment, &len);
4510                 ok(hr == S_OK, "ret %08x\n", hr );
4511                 ok(len == 38, "expected 38 got %d\n", len);
4512
4513                 hr = IXMLDOMComment_get_text(pComment, &str);
4514                 ok(hr == S_OK, "ret %08x\n", hr );
4515                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4516                 SysFreeString(str);
4517
4518                 /* delete from end */
4519                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
4520                 ok(hr == S_OK, "ret %08x\n", hr );
4521
4522                 hr = IXMLDOMComment_get_length(pComment, &len);
4523                 ok(hr == S_OK, "ret %08x\n", hr );
4524                 ok(len == 35, "expected 35 got %d\n", len);
4525
4526                 hr = IXMLDOMComment_get_text(pComment, &str);
4527                 ok(hr == S_OK, "ret %08x\n", hr );
4528                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4529                 SysFreeString(str);
4530
4531                 /* delete from inside */
4532                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
4533                 ok(hr == S_OK, "ret %08x\n", hr );
4534
4535                 hr = IXMLDOMComment_get_length(pComment, &len);
4536                 ok(hr == S_OK, "ret %08x\n", hr );
4537                 ok(len == 2, "expected 2 got %d\n", len);
4538
4539                 hr = IXMLDOMComment_get_text(pComment, &str);
4540                 ok(hr == S_OK, "ret %08x\n", hr );
4541                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4542                 SysFreeString(str);
4543
4544                 /* delete whole data ... */
4545                 hr = IXMLDOMComment_get_length(pComment, &len);
4546                 ok(hr == S_OK, "ret %08x\n", hr );
4547
4548                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
4549                 ok(hr == S_OK, "ret %08x\n", hr );
4550                 /* ... and try again with empty string */
4551                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
4552                 ok(hr == S_OK, "ret %08x\n", hr );
4553
4554                 /* ::replaceData() */
4555                 V_VT(&v) = VT_BSTR;
4556                 V_BSTR(&v) = SysAllocString(szstr1);
4557                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
4558                 ok(hr == S_OK, "ret %08x\n", hr );
4559                 VariantClear(&v);
4560
4561                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
4562                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4563                 hr = IXMLDOMComment_get_text(pComment, &str);
4564                 ok(hr == S_OK, "ret %08x\n", hr );
4565                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4566                 SysFreeString(str);
4567
4568                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
4569                 ok(hr == S_OK, "ret %08x\n", hr );
4570                 hr = IXMLDOMComment_get_text(pComment, &str);
4571                 ok(hr == S_OK, "ret %08x\n", hr );
4572                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4573                 SysFreeString(str);
4574
4575                 /* NULL pointer means delete */
4576                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
4577                 ok(hr == S_OK, "ret %08x\n", hr );
4578                 hr = IXMLDOMComment_get_text(pComment, &str);
4579                 ok(hr == S_OK, "ret %08x\n", hr );
4580                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4581                 SysFreeString(str);
4582
4583                 /* empty string means delete */
4584                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
4585                 ok(hr == S_OK, "ret %08x\n", hr );
4586                 hr = IXMLDOMComment_get_text(pComment, &str);
4587                 ok(hr == S_OK, "ret %08x\n", hr );
4588                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4589                 SysFreeString(str);
4590
4591                 /* zero count means insert */
4592                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
4593                 ok(hr == S_OK, "ret %08x\n", hr );
4594                 hr = IXMLDOMComment_get_text(pComment, &str);
4595                 ok(hr == S_OK, "ret %08x\n", hr );
4596                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4597                 SysFreeString(str);
4598
4599                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
4600                 ok(hr == S_OK, "ret %08x\n", hr );
4601
4602                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
4603                 ok(hr == S_OK, "ret %08x\n", hr );
4604                 hr = IXMLDOMComment_get_text(pComment, &str);
4605                 ok(hr == S_OK, "ret %08x\n", hr );
4606                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4607                 SysFreeString(str);
4608
4609                 /* nonempty string, count greater than its length */
4610                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
4611                 ok(hr == S_OK, "ret %08x\n", hr );
4612                 hr = IXMLDOMComment_get_text(pComment, &str);
4613                 ok(hr == S_OK, "ret %08x\n", hr );
4614                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4615                 SysFreeString(str);
4616
4617                 /* nonempty string, count less than its length */
4618                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
4619                 ok(hr == S_OK, "ret %08x\n", hr );
4620                 hr = IXMLDOMComment_get_text(pComment, &str);
4621                 ok(hr == S_OK, "ret %08x\n", hr );
4622                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4623                 SysFreeString(str);
4624
4625                 IXMLDOMComment_Release(pComment);
4626             }
4627
4628             /* Element */
4629             str = SysAllocString(szElement);
4630             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
4631             SysFreeString(str);
4632             ok(hr == S_OK, "ret %08x\n", hr );
4633             if(hr == S_OK)
4634             {
4635                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4636                 ok(hr == S_OK, "ret %08x\n", hr );
4637
4638                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
4639                 ok(hr == S_OK, "ret %08x\n", hr );
4640                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
4641                 SysFreeString(str);
4642
4643                 hr = IXMLDOMElement_get_xml(pElement, &str);
4644                 ok(hr == S_OK, "ret %08x\n", hr );
4645                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
4646                 SysFreeString(str);
4647
4648                 /* Attribute */
4649                 pAttribute = (IXMLDOMAttribute*)0x1;
4650                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
4651                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4652                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
4653
4654                 pAttribute = (IXMLDOMAttribute*)0x1;
4655                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
4656                 ok(hr == E_FAIL, "ret %08x\n", hr );
4657                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
4658
4659                 str = SysAllocString(szAttribute);
4660                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
4661                 SysFreeString(str);
4662                 ok(hr == S_OK, "ret %08x\n", hr );
4663                 if(hr == S_OK)
4664                 {
4665                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
4666
4667                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
4668                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4669
4670                     pNextChild = (IXMLDOMNode *)0x1;
4671                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
4672                     ok(hr == S_FALSE, "ret %08x\n", hr );
4673                     ok(pNextChild == NULL, "pNextChild not NULL\n");
4674
4675                     /* test Previous Sibling*/
4676                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
4677                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4678
4679                     pNextChild = (IXMLDOMNode *)0x1;
4680                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
4681                     ok(hr == S_FALSE, "ret %08x\n", hr );
4682                     ok(pNextChild == NULL, "pNextChild not NULL\n");
4683
4684                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
4685                     ok(hr == E_FAIL, "ret %08x\n", hr );
4686                     ok(pNewChild == NULL, "pNewChild not NULL\n");
4687
4688                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
4689                     ok(hr == S_OK, "ret %08x\n", hr );
4690                     if ( hr == S_OK )
4691                     {
4692                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
4693                         ok(hr == S_OK, "ret %08x\n", hr );
4694
4695                         IXMLDOMNamedNodeMap_Release(pAttribs);
4696                     }
4697
4698                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
4699                     ok(hr == S_OK, "ret %08x\n", hr );
4700                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
4701                     SysFreeString(str);
4702
4703                     /* test nodeName */
4704                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
4705                     ok(hr == S_OK, "ret %08x\n", hr );
4706                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
4707                     SysFreeString(str);
4708
4709                     /* test name property */
4710                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
4711                     ok(hr == S_OK, "ret %08x\n", hr );
4712                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
4713                     SysFreeString(str);
4714
4715                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
4716                     ok(hr == S_OK, "ret %08x\n", hr );
4717                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
4718                     SysFreeString(str);
4719
4720                     IXMLDOMAttribute_Release(pAttribute);
4721
4722                     /* Check Element again with the Add Attribute*/
4723                     hr = IXMLDOMElement_get_xml(pElement, &str);
4724                     ok(hr == S_OK, "ret %08x\n", hr );
4725                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
4726                     SysFreeString(str);
4727                 }
4728
4729                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
4730                 ok(hr == S_OK, "ret %08x\n", hr );
4731
4732                 hr = IXMLDOMElement_get_xml(pElement, &str);
4733                 ok(hr == S_OK, "ret %08x\n", hr );
4734                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
4735                 SysFreeString(str);
4736
4737                 /* Test for reversible escaping */
4738                 str = SysAllocString( szStrangeChars );
4739                 hr = IXMLDOMElement_put_text(pElement, str);
4740                 ok(hr == S_OK, "ret %08x\n", hr );
4741                 SysFreeString( str );
4742
4743                 hr = IXMLDOMElement_get_xml(pElement, &str);
4744                 ok(hr == S_OK, "ret %08x\n", hr );
4745                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
4746                 SysFreeString(str);
4747
4748                 hr = IXMLDOMElement_get_text(pElement, &str);
4749                 ok(hr == S_OK, "ret %08x\n", hr );
4750                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
4751                 SysFreeString(str);
4752
4753                 IXMLDOMElement_Release(pElement);
4754             }
4755
4756             /* CData Section */
4757             str = SysAllocString(szCData);
4758             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
4759             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4760
4761             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
4762             SysFreeString(str);
4763             ok(hr == S_OK, "ret %08x\n", hr );
4764             if(hr == S_OK)
4765             {
4766                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
4767                 VARIANT var;
4768
4769                 VariantInit(&var);
4770
4771                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
4772                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
4773
4774                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
4775                 ok(hr == S_OK, "ret %08x\n", hr );
4776
4777                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
4778                 ok(hr == S_OK, "ret %08x\n", hr );
4779                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
4780                 SysFreeString(str);
4781
4782                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
4783                 ok(hr == S_OK, "ret %08x\n", hr );
4784                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
4785                 SysFreeString(str);
4786
4787                 /* test lastChild */
4788                 pNextChild = (IXMLDOMNode*)0x1;
4789                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
4790                 ok(hr == S_FALSE, "ret %08x\n", hr );
4791                 ok(pNextChild == NULL, "pNextChild not NULL\n");
4792
4793                 /* put data Tests */
4794                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
4795                 ok(hr == S_OK, "ret %08x\n", hr );
4796
4797                 /* Confirm XML text is good */
4798                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
4799                 ok(hr == S_OK, "ret %08x\n", hr );
4800                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
4801                 SysFreeString(str);
4802
4803                 /* Confirm we get the put_data Text back */
4804                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4805                 ok(hr == S_OK, "ret %08x\n", hr );
4806                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4807                 SysFreeString(str);
4808
4809                 /* test length property */
4810                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4811                 ok(hr == S_OK, "ret %08x\n", hr );
4812                 ok(len == 21, "expected 21 got %d\n", len);
4813
4814                 /* test get nodeValue */
4815                 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
4816                 ok(hr == S_OK, "ret %08x\n", hr );
4817                 ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var));
4818                 ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4819                 VariantClear(&var);
4820
4821                 /* test get data */
4822                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
4823                 ok(hr == S_OK, "ret %08x\n", hr );
4824                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4825                 SysFreeString(str);
4826
4827                 /* test substringData */
4828                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
4829                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4830
4831                 /* test substringData - Invalid offset */
4832                 str = (BSTR)&szElement;
4833                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
4834                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4835                 ok( str == NULL, "incorrect string\n");
4836
4837                 /* test substringData - Invalid offset */
4838                 str = (BSTR)&szElement;
4839                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
4840                 ok(hr == S_FALSE, "ret %08x\n", hr );
4841                 ok( str == NULL, "incorrect string\n");
4842
4843                 /* test substringData - Invalid size */
4844                 str = (BSTR)&szElement;
4845                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
4846                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4847                 ok( str == NULL, "incorrect string\n");
4848
4849                 /* test substringData - Invalid size */
4850                 str = (BSTR)&szElement;
4851                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
4852                 ok(hr == S_FALSE, "ret %08x\n", hr );
4853                 ok( str == NULL, "incorrect string\n");
4854
4855                 /* test substringData - Start of string */
4856                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
4857                 ok(hr == S_OK, "ret %08x\n", hr );
4858                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
4859                 SysFreeString(str);
4860
4861                 /* test substringData - Middle of string */
4862                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
4863                 ok(hr == S_OK, "ret %08x\n", hr );
4864                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
4865                 SysFreeString(str);
4866
4867                 /* test substringData - End of string */
4868                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
4869                 ok(hr == S_OK, "ret %08x\n", hr );
4870                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
4871                 SysFreeString(str);
4872
4873                 /* test appendData */
4874                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
4875                 ok(hr == S_OK, "ret %08x\n", hr );
4876
4877                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
4878                 ok(hr == S_OK, "ret %08x\n", hr );
4879
4880                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
4881                 ok(hr == S_OK, "ret %08x\n", hr );
4882
4883                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4884                 ok(hr == S_OK, "ret %08x\n", hr );
4885                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4886                 SysFreeString(str);
4887
4888                 /* test insertData */
4889                 str = SysAllocStringLen(NULL, 0);
4890                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
4891                 ok(hr == S_OK, "ret %08x\n", hr );
4892
4893                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
4894                 ok(hr == S_OK, "ret %08x\n", hr );
4895
4896                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
4897                 ok(hr == S_OK, "ret %08x\n", hr );
4898
4899                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
4900                 ok(hr == S_OK, "ret %08x\n", hr );
4901
4902                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
4903                 ok(hr == S_OK, "ret %08x\n", hr );
4904
4905                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
4906                 ok(hr == S_OK, "ret %08x\n", hr );
4907                 SysFreeString(str);
4908
4909                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
4910                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4911
4912                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
4913                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4914
4915                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
4916                 ok(hr == S_OK, "ret %08x\n", hr );
4917
4918                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
4919                 ok(hr == S_OK, "ret %08x\n", hr );
4920
4921                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
4922                 ok(hr == S_OK, "ret %08x\n", hr );
4923
4924                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4925                 ok(hr == S_OK, "ret %08x\n", hr );
4926                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4927                 SysFreeString(str);
4928
4929                 /* delete data */
4930                 /* invalid arguments */
4931                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
4932                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4933
4934                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
4935                 ok(hr == S_OK, "ret %08x\n", hr );
4936
4937                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
4938                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4939
4940                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4941                 ok(hr == S_OK, "ret %08x\n", hr );
4942                 ok(len == 43, "expected 43 got %d\n", len);
4943
4944                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
4945                 ok(hr == S_OK, "ret %08x\n", hr );
4946
4947                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
4948                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4949
4950                 /* delete from start */
4951                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
4952                 ok(hr == S_OK, "ret %08x\n", hr );
4953
4954                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4955                 ok(hr == S_OK, "ret %08x\n", hr );
4956                 ok(len == 38, "expected 38 got %d\n", len);
4957
4958                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4959                 ok(hr == S_OK, "ret %08x\n", hr );
4960                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4961                 SysFreeString(str);
4962
4963                 /* delete from end */
4964                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
4965                 ok(hr == S_OK, "ret %08x\n", hr );
4966
4967                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4968                 ok(hr == S_OK, "ret %08x\n", hr );
4969                 ok(len == 35, "expected 35 got %d\n", len);
4970
4971                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4972                 ok(hr == S_OK, "ret %08x\n", hr );
4973                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4974                 SysFreeString(str);
4975
4976                 /* delete from inside */
4977                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
4978                 ok(hr == S_OK, "ret %08x\n", hr );
4979
4980                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4981                 ok(hr == S_OK, "ret %08x\n", hr );
4982                 ok(len == 2, "expected 2 got %d\n", len);
4983
4984                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4985                 ok(hr == S_OK, "ret %08x\n", hr );
4986                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4987                 SysFreeString(str);
4988
4989                 /* delete whole data ... */
4990                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4991                 ok(hr == S_OK, "ret %08x\n", hr );
4992
4993                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
4994                 ok(hr == S_OK, "ret %08x\n", hr );
4995
4996                 /* ... and try again with empty string */
4997                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
4998                 ok(hr == S_OK, "ret %08x\n", hr );
4999
5000                 /* ::replaceData() */
5001                 V_VT(&v) = VT_BSTR;
5002                 V_BSTR(&v) = SysAllocString(szstr1);
5003                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
5004                 ok(hr == S_OK, "ret %08x\n", hr );
5005                 VariantClear(&v);
5006
5007                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
5008                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5009                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5010                 ok(hr == S_OK, "ret %08x\n", hr );
5011                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5012                 SysFreeString(str);
5013
5014                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
5015                 ok(hr == S_OK, "ret %08x\n", hr );
5016                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5017                 ok(hr == S_OK, "ret %08x\n", hr );
5018                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5019                 SysFreeString(str);
5020
5021                 /* NULL pointer means delete */
5022                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
5023                 ok(hr == S_OK, "ret %08x\n", hr );
5024                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5025                 ok(hr == S_OK, "ret %08x\n", hr );
5026                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5027                 SysFreeString(str);
5028
5029                 /* empty string means delete */
5030                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
5031                 ok(hr == S_OK, "ret %08x\n", hr );
5032                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5033                 ok(hr == S_OK, "ret %08x\n", hr );
5034                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5035                 SysFreeString(str);
5036
5037                 /* zero count means insert */
5038                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
5039                 ok(hr == S_OK, "ret %08x\n", hr );
5040                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5041                 ok(hr == S_OK, "ret %08x\n", hr );
5042                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5043                 SysFreeString(str);
5044
5045                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
5046                 ok(hr == S_OK, "ret %08x\n", hr );
5047
5048                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
5049                 ok(hr == S_OK, "ret %08x\n", hr );
5050                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5051                 ok(hr == S_OK, "ret %08x\n", hr );
5052                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5053                 SysFreeString(str);
5054
5055                 /* nonempty string, count greater than its length */
5056                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
5057                 ok(hr == S_OK, "ret %08x\n", hr );
5058                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5059                 ok(hr == S_OK, "ret %08x\n", hr );
5060                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5061                 SysFreeString(str);
5062
5063                 /* nonempty string, count less than its length */
5064                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
5065                 ok(hr == S_OK, "ret %08x\n", hr );
5066                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5067                 ok(hr == S_OK, "ret %08x\n", hr );
5068                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5069                 SysFreeString(str);
5070
5071                 IXMLDOMCDATASection_Release(pCDataSec);
5072             }
5073
5074             /* Document Fragments */
5075             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
5076             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5077
5078             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
5079             ok(hr == S_OK, "ret %08x\n", hr );
5080             if(hr == S_OK)
5081             {
5082                 IXMLDOMNode *node;
5083
5084                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
5085                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5086
5087                 node = (IXMLDOMNode *)0x1;
5088                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
5089                 ok(hr == S_FALSE, "ret %08x\n", hr );
5090                 ok(node == NULL, "expected NULL, got %p\n", node);
5091
5092                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
5093                 ok(hr == S_OK, "ret %08x\n", hr );
5094
5095                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
5096                 ok(hr == S_OK, "ret %08x\n", hr );
5097                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
5098                 SysFreeString(str);
5099
5100                 /* test next Sibling*/
5101                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
5102                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5103
5104                 node = (IXMLDOMNode *)0x1;
5105                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
5106                 ok(hr == S_FALSE, "ret %08x\n", hr );
5107                 ok(node == NULL, "next sibling not NULL\n");
5108
5109                 /* test Previous Sibling*/
5110                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
5111                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5112
5113                 node = (IXMLDOMNode *)0x1;
5114                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
5115                 ok(hr == S_FALSE, "ret %08x\n", hr );
5116                 ok(node == NULL, "previous sibling not NULL\n");
5117
5118                 IXMLDOMDocumentFragment_Release(pDocFrag);
5119             }
5120
5121             /* Entity References */
5122             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
5123             ok(hr == E_FAIL, "ret %08x\n", hr );
5124             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
5125             ok(hr == E_FAIL, "ret %08x\n", hr );
5126
5127             str = SysAllocString(szEntityRef);
5128             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
5129             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5130
5131             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
5132             SysFreeString(str);
5133             ok(hr == S_OK, "ret %08x\n", hr );
5134             if(hr == S_OK)
5135             {
5136                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
5137                 ok(hr == S_OK, "ret %08x\n", hr );
5138
5139                 /* test get_xml*/
5140                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
5141                 ok(hr == S_OK, "ret %08x\n", hr );
5142                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
5143                 SysFreeString(str);
5144
5145                 IXMLDOMEntityReference_Release(pEntityRef);
5146             }
5147
5148             IXMLDOMElement_Release( pRoot );
5149         }
5150     }
5151
5152     IXMLDOMDocument_Release(doc);
5153
5154     free_bstrs();
5155 }
5156
5157 static void test_nodeTypeTests( void )
5158 {
5159     IXMLDOMDocument *doc = NULL;
5160     IXMLDOMElement *pRoot;
5161     IXMLDOMElement *pElement;
5162     HRESULT hr;
5163
5164     doc = create_document(&IID_IXMLDOMDocument);
5165     if (!doc) return;
5166
5167     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
5168     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5169
5170     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5171     ok(hr == S_OK, "ret %08x\n", hr );
5172     if(hr == S_OK)
5173     {
5174         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5175         ok(hr == S_OK, "ret %08x\n", hr );
5176         if(hr == S_OK)
5177         {
5178             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
5179             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5180
5181             /* Invalid Value */
5182             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
5183             ok(hr == E_FAIL, "ret %08x\n", hr );
5184
5185             /* NOTE:
5186              *   The name passed into put_dataType is case-insensitive. So many of the names
5187              *     have been changed to reflect this.
5188              */
5189             /* Boolean */
5190             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
5191             ok(hr == S_OK, "ret %08x\n", hr );
5192             if(hr == S_OK)
5193             {
5194                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5195
5196                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
5197                 ok(hr == S_OK, "ret %08x\n", hr );
5198
5199                 IXMLDOMElement_Release(pElement);
5200             }
5201
5202             /* String */
5203             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
5204             ok(hr == S_OK, "ret %08x\n", hr );
5205             if(hr == S_OK)
5206             {
5207                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5208
5209                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
5210                 ok(hr == S_OK, "ret %08x\n", hr );
5211
5212                 IXMLDOMElement_Release(pElement);
5213             }
5214
5215             /* Number */
5216             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
5217             ok(hr == S_OK, "ret %08x\n", hr );
5218             if(hr == S_OK)
5219             {
5220                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5221
5222                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
5223                 ok(hr == S_OK, "ret %08x\n", hr );
5224
5225                 IXMLDOMElement_Release(pElement);
5226             }
5227
5228             /* Int */
5229             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
5230             ok(hr == S_OK, "ret %08x\n", hr );
5231             if(hr == S_OK)
5232             {
5233                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5234
5235                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
5236                 ok(hr == S_OK, "ret %08x\n", hr );
5237
5238                 IXMLDOMElement_Release(pElement);
5239             }
5240
5241             /* Fixed */
5242             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
5243             ok(hr == S_OK, "ret %08x\n", hr );
5244             if(hr == S_OK)
5245             {
5246                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5247
5248                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
5249                 ok(hr == S_OK, "ret %08x\n", hr );
5250
5251                 IXMLDOMElement_Release(pElement);
5252             }
5253
5254             /* DateTime */
5255             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
5256             ok(hr == S_OK, "ret %08x\n", hr );
5257             if(hr == S_OK)
5258             {
5259                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5260
5261                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
5262                 ok(hr == S_OK, "ret %08x\n", hr );
5263
5264                 IXMLDOMElement_Release(pElement);
5265             }
5266
5267             /* DateTime TZ */
5268             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
5269             ok(hr == S_OK, "ret %08x\n", hr );
5270             if(hr == S_OK)
5271             {
5272                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5273
5274                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
5275                 ok(hr == S_OK, "ret %08x\n", hr );
5276
5277                 IXMLDOMElement_Release(pElement);
5278             }
5279
5280             /* Date */
5281             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
5282             ok(hr == S_OK, "ret %08x\n", hr );
5283             if(hr == S_OK)
5284             {
5285                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5286
5287                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
5288                 ok(hr == S_OK, "ret %08x\n", hr );
5289
5290                 IXMLDOMElement_Release(pElement);
5291             }
5292
5293             /* Time */
5294             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
5295             ok(hr == S_OK, "ret %08x\n", hr );
5296             if(hr == S_OK)
5297             {
5298                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5299
5300                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
5301                 ok(hr == S_OK, "ret %08x\n", hr );
5302
5303                 IXMLDOMElement_Release(pElement);
5304             }
5305
5306             /* Time.tz */
5307             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
5308             ok(hr == S_OK, "ret %08x\n", hr );
5309             if(hr == S_OK)
5310             {
5311                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5312
5313                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
5314                 ok(hr == S_OK, "ret %08x\n", hr );
5315
5316                 IXMLDOMElement_Release(pElement);
5317             }
5318
5319             /* I1 */
5320             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
5321             ok(hr == S_OK, "ret %08x\n", hr );
5322             if(hr == S_OK)
5323             {
5324                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5325
5326                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
5327                 ok(hr == S_OK, "ret %08x\n", hr );
5328
5329                 IXMLDOMElement_Release(pElement);
5330             }
5331
5332             /* I2 */
5333             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
5334             ok(hr == S_OK, "ret %08x\n", hr );
5335             if(hr == S_OK)
5336             {
5337                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5338
5339                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
5340                 ok(hr == S_OK, "ret %08x\n", hr );
5341
5342                 IXMLDOMElement_Release(pElement);
5343             }
5344
5345             /* I4 */
5346             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
5347             ok(hr == S_OK, "ret %08x\n", hr );
5348             if(hr == S_OK)
5349             {
5350                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5351
5352                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
5353                 ok(hr == S_OK, "ret %08x\n", hr );
5354
5355                 IXMLDOMElement_Release(pElement);
5356             }
5357
5358             /* UI1 */
5359             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
5360             ok(hr == S_OK, "ret %08x\n", hr );
5361             if(hr == S_OK)
5362             {
5363                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5364
5365                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
5366                 ok(hr == S_OK, "ret %08x\n", hr );
5367
5368                 IXMLDOMElement_Release(pElement);
5369             }
5370
5371             /* UI2 */
5372             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
5373             ok(hr == S_OK, "ret %08x\n", hr );
5374             if(hr == S_OK)
5375             {
5376                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5377
5378                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
5379                 ok(hr == S_OK, "ret %08x\n", hr );
5380
5381                 IXMLDOMElement_Release(pElement);
5382             }
5383
5384             /* UI4 */
5385             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
5386             ok(hr == S_OK, "ret %08x\n", hr );
5387             if(hr == S_OK)
5388             {
5389                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5390
5391                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
5392                 ok(hr == S_OK, "ret %08x\n", hr );
5393
5394                 IXMLDOMElement_Release(pElement);
5395             }
5396
5397             /* r4 */
5398             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
5399             ok(hr == S_OK, "ret %08x\n", hr );
5400             if(hr == S_OK)
5401             {
5402                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5403
5404                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
5405                 ok(hr == S_OK, "ret %08x\n", hr );
5406
5407                 IXMLDOMElement_Release(pElement);
5408             }
5409
5410             /* r8 */
5411             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
5412             ok(hr == S_OK, "ret %08x\n", hr );
5413             if(hr == S_OK)
5414             {
5415                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5416
5417                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
5418                 ok(hr == S_OK, "ret %08x\n", hr );
5419
5420                 IXMLDOMElement_Release(pElement);
5421             }
5422
5423             /* float */
5424             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
5425             ok(hr == S_OK, "ret %08x\n", hr );
5426             if(hr == S_OK)
5427             {
5428                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5429
5430                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
5431                 ok(hr == S_OK, "ret %08x\n", hr );
5432
5433                 IXMLDOMElement_Release(pElement);
5434             }
5435
5436             /* uuid */
5437             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
5438             ok(hr == S_OK, "ret %08x\n", hr );
5439             if(hr == S_OK)
5440             {
5441                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5442
5443                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
5444                 ok(hr == S_OK, "ret %08x\n", hr );
5445
5446                 IXMLDOMElement_Release(pElement);
5447             }
5448
5449             /* bin.hex */
5450             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
5451             ok(hr == S_OK, "ret %08x\n", hr );
5452             if(hr == S_OK)
5453             {
5454                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5455
5456                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
5457                 ok(hr == S_OK, "ret %08x\n", hr );
5458
5459                 IXMLDOMElement_Release(pElement);
5460             }
5461
5462             /* bin.base64 */
5463             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
5464             ok(hr == S_OK, "ret %08x\n", hr );
5465             if(hr == S_OK)
5466             {
5467                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5468
5469                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
5470                 ok(hr == S_OK, "ret %08x\n", hr );
5471
5472                 IXMLDOMElement_Release(pElement);
5473             }
5474
5475             /* Check changing types */
5476             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
5477             ok(hr == S_OK, "ret %08x\n", hr );
5478             if(hr == S_OK)
5479             {
5480                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5481
5482                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
5483                 ok(hr == S_OK, "ret %08x\n", hr );
5484
5485                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
5486                 ok(hr == S_OK, "ret %08x\n", hr );
5487
5488                 IXMLDOMElement_Release(pElement);
5489             }
5490
5491             IXMLDOMElement_Release(pRoot);
5492         }
5493     }
5494
5495     IXMLDOMDocument_Release(doc);
5496
5497     free_bstrs();
5498 }
5499
5500 static void test_DocumentSaveToDocument(void)
5501 {
5502     IXMLDOMDocument *doc, *doc2;
5503     IXMLDOMElement *pRoot;
5504     HRESULT hr;
5505
5506     doc = create_document(&IID_IXMLDOMDocument);
5507     if (!doc) return;
5508
5509     doc2 = create_document(&IID_IXMLDOMDocument);
5510     if (!doc2)
5511     {
5512         IXMLDOMDocument_Release(doc);
5513         return;
5514     }
5515
5516     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5517     ok(hr == S_OK, "ret %08x\n", hr );
5518     if(hr == S_OK)
5519     {
5520         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5521         ok(hr == S_OK, "ret %08x\n", hr );
5522         if(hr == S_OK)
5523         {
5524             VARIANT vDoc;
5525             BSTR sOrig;
5526             BSTR sNew;
5527
5528             V_VT(&vDoc) = VT_UNKNOWN;
5529             V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
5530
5531             hr = IXMLDOMDocument_save(doc, vDoc);
5532             ok(hr == S_OK, "ret %08x\n", hr );
5533
5534             hr = IXMLDOMDocument_get_xml(doc, &sOrig);
5535             ok(hr == S_OK, "ret %08x\n", hr );
5536
5537             hr = IXMLDOMDocument_get_xml(doc2, &sNew);
5538             ok(hr == S_OK, "ret %08x\n", hr );
5539
5540             ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as origial\n");
5541
5542             SysFreeString(sOrig);
5543             SysFreeString(sNew);
5544         }
5545         IXMLDOMElement_Release(pRoot);
5546     }
5547
5548     IXMLDOMDocument_Release(doc2);
5549     IXMLDOMDocument_Release(doc);
5550 }
5551
5552 static void test_DocumentSaveToFile(void)
5553 {
5554     IXMLDOMDocument *doc;
5555     IXMLDOMElement *pRoot;
5556     HANDLE file;
5557     char buffer[100];
5558     DWORD read = 0;
5559     HRESULT hr;
5560
5561     doc = create_document(&IID_IXMLDOMDocument);
5562     if (!doc) return;
5563
5564     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5565     ok(hr == S_OK, "ret %08x\n", hr );
5566     if(hr == S_OK)
5567     {
5568         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5569         ok(hr == S_OK, "ret %08x\n", hr );
5570         if(hr == S_OK)
5571         {
5572             VARIANT vFile;
5573
5574             V_VT(&vFile) = VT_BSTR;
5575             V_BSTR(&vFile) = _bstr_("test.xml");
5576
5577             hr = IXMLDOMDocument_save(doc, vFile);
5578             ok(hr == S_OK, "ret %08x\n", hr );
5579         }
5580     }
5581
5582     IXMLDOMElement_Release(pRoot);
5583     IXMLDOMDocument_Release(doc);
5584
5585     file = CreateFile("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
5586     ok(file != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
5587     if(file == INVALID_HANDLE_VALUE)
5588         return;
5589
5590     ReadFile(file, buffer, sizeof(buffer), &read, NULL);
5591     ok(read != 0, "could not read file\n");
5592     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
5593
5594     CloseHandle(file);
5595     DeleteFile("test.xml");
5596 }
5597
5598 static void test_testTransforms(void)
5599 {
5600     IXMLDOMDocument *doc, *docSS;
5601     IXMLDOMNode *pNode;
5602     VARIANT_BOOL bSucc;
5603
5604     HRESULT hr;
5605
5606     doc = create_document(&IID_IXMLDOMDocument);
5607     if (!doc) return;
5608
5609     docSS = create_document(&IID_IXMLDOMDocument);
5610     if (!docSS)
5611     {
5612         IXMLDOMDocument_Release(doc);
5613         return;
5614     }
5615
5616     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
5617     ok(hr == S_OK, "ret %08x\n", hr );
5618
5619     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
5620     ok(hr == S_OK, "ret %08x\n", hr );
5621
5622     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
5623     ok(hr == S_OK, "ret %08x\n", hr );
5624     if(hr == S_OK)
5625     {
5626         BSTR bOut;
5627
5628         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
5629         ok(hr == S_OK, "ret %08x\n", hr );
5630         ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
5631         SysFreeString(bOut);
5632
5633         IXMLDOMNode_Release(pNode);
5634     }
5635
5636     IXMLDOMDocument_Release(docSS);
5637     IXMLDOMDocument_Release(doc);
5638
5639     free_bstrs();
5640 }
5641
5642 static void test_Namespaces(void)
5643 {
5644     IXMLDOMDocument *doc;
5645     IXMLDOMNode *pNode;
5646     IXMLDOMNode *pNode2 = NULL;
5647     VARIANT_BOOL bSucc;
5648     HRESULT hr;
5649     BSTR str;
5650     static  const CHAR szNamespacesXML[] =
5651 "<?xml version=\"1.0\"?>\n"
5652 "<root xmlns:WEB='http://www.winehq.org'>\n"
5653 "<WEB:Site version=\"1.0\" />\n"
5654 "</root>";
5655
5656     doc = create_document(&IID_IXMLDOMDocument);
5657     if (!doc) return;
5658
5659     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szNamespacesXML), &bSucc);
5660     ok(hr == S_OK, "ret %08x\n", hr );
5661     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5662
5663     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root"), &pNode );
5664     ok(hr == S_OK, "ret %08x\n", hr );
5665     if(hr == S_OK)
5666     {
5667         hr = IXMLDOMNode_get_firstChild( pNode, &pNode2 );
5668         ok( hr == S_OK, "ret %08x\n", hr );
5669         ok( pNode2 != NULL, "pNode2 == NULL\n");
5670
5671         /* Test get_prefix */
5672         hr = IXMLDOMNode_get_prefix(pNode2, NULL);
5673         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5674         /* NOTE: Need to test that arg2 gets cleared on Error. */
5675
5676         hr = IXMLDOMNode_get_prefix(pNode2, &str);
5677         ok( hr == S_OK, "ret %08x\n", hr );
5678         ok( !lstrcmpW( str, _bstr_("WEB")), "incorrect prefix string\n");
5679         SysFreeString(str);
5680
5681         /* Test get_namespaceURI */
5682         hr = IXMLDOMNode_get_namespaceURI(pNode2, NULL);
5683         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5684         /* NOTE: Need to test that arg2 gets cleared on Error. */
5685
5686         hr = IXMLDOMNode_get_namespaceURI(pNode2, &str);
5687         ok( hr == S_OK, "ret %08x\n", hr );
5688         ok( !lstrcmpW( str, _bstr_("http://www.winehq.org")), "incorrect namespaceURI string\n");
5689         SysFreeString(str);
5690
5691         IXMLDOMNode_Release(pNode2);
5692         IXMLDOMNode_Release(pNode);
5693     }
5694
5695     IXMLDOMDocument_Release(doc);
5696
5697     free_bstrs();
5698 }
5699
5700 static void test_FormattingXML(void)
5701 {
5702     IXMLDOMDocument *doc;
5703     IXMLDOMElement *pElement;
5704     VARIANT_BOOL bSucc;
5705     HRESULT hr;
5706     BSTR str;
5707     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
5708     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
5709
5710     doc = create_document(&IID_IXMLDOMDocument);
5711     if (!doc) return;
5712
5713     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
5714     ok(hr == S_OK, "ret %08x\n", hr );
5715     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5716
5717     if(bSucc == VARIANT_TRUE)
5718     {
5719         hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
5720         ok(hr == S_OK, "ret %08x\n", hr );
5721         if(hr == S_OK)
5722         {
5723             hr = IXMLDOMElement_get_xml(pElement, &str);
5724             ok(hr == S_OK, "ret %08x\n", hr );
5725             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
5726             SysFreeString(str);
5727
5728             IXMLDOMElement_Release(pElement);
5729         }
5730     }
5731
5732     IXMLDOMDocument_Release(doc);
5733
5734     free_bstrs();
5735 }
5736
5737 typedef struct _nodetypedvalue_t {
5738     const char *name;
5739     VARTYPE type;
5740     const char *value; /* value in string format */
5741 } nodetypedvalue_t;
5742
5743 static const nodetypedvalue_t get_nodetypedvalue[] = {
5744     { "root/string",    VT_BSTR, "Wine" },
5745     { "root/string2",   VT_BSTR, "String" },
5746     { "root/number",    VT_BSTR, "12.44" },
5747     { "root/number2",   VT_BSTR, "-3.71e3" },
5748     { "root/int",       VT_I4,   "-13" },
5749     { "root/fixed",     VT_CY,   "7322.9371" },
5750     { "root/bool",      VT_BOOL, "-1" },
5751     { "root/datetime",  VT_DATE, "40135.14" },
5752     { "root/datetimetz",VT_DATE, "37813.59" },
5753     { "root/date",      VT_DATE, "665413" },
5754     { "root/time",      VT_DATE, "0.5813889" },
5755     { "root/timetz",    VT_DATE, "1.112512" },
5756     { "root/i1",        VT_I1,   "-13" },
5757     { "root/i2",        VT_I2,   "31915" },
5758     { "root/i4",        VT_I4,   "-312232" },
5759     { "root/ui1",       VT_UI1,  "123" },
5760     { "root/ui2",       VT_UI2,  "48282" },
5761     { "root/ui4",       VT_UI4,  "949281" },
5762     { "root/r4",        VT_R4,   "213124" },
5763     { "root/r8",        VT_R8,   "0.412" },
5764     { "root/float",     VT_R8,   "41221.421" },
5765     { "root/uuid",      VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
5766     { 0 }
5767 };
5768
5769 static void test_nodeTypedValue(void)
5770 {
5771     const nodetypedvalue_t *entry = get_nodetypedvalue;
5772     IXMLDOMDocumentType *doctype, *doctype2;
5773     IXMLDOMProcessingInstruction *pi;
5774     IXMLDOMDocumentFragment *frag;
5775     IXMLDOMDocument *doc, *doc2;
5776     IXMLDOMCDATASection *cdata;
5777     IXMLDOMComment *comment;
5778     IXMLDOMNode *node;
5779     VARIANT_BOOL b;
5780     VARIANT value;
5781     HRESULT hr;
5782
5783     doc = create_document(&IID_IXMLDOMDocument);
5784     if (!doc) return;
5785
5786     b = VARIANT_FALSE;
5787     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
5788     ok(hr == S_OK, "ret %08x\n", hr );
5789     ok(b == VARIANT_TRUE, "got %d\n", b);
5790
5791     hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
5792     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5793
5794     V_VT(&value) = VT_BSTR;
5795     V_BSTR(&value) = NULL;
5796     hr = IXMLDOMDocument_get_nodeValue(doc, &value);
5797     ok(hr == S_FALSE, "ret %08x\n", hr );
5798     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
5799
5800     hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
5801     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5802
5803     V_VT(&value) = VT_EMPTY;
5804     hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
5805     ok(hr == S_FALSE, "ret %08x\n", hr );
5806     ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
5807
5808     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
5809     ok(hr == S_OK, "ret %08x\n", hr );
5810
5811     V_VT(&value) = VT_BSTR;
5812     V_BSTR(&value) = NULL;
5813     hr = IXMLDOMNode_get_nodeValue(node, &value);
5814     ok(hr == S_FALSE, "ret %08x\n", hr );
5815     ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
5816
5817     hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
5818     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5819
5820     IXMLDOMNode_Release(node);
5821
5822     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
5823     ok(hr == S_OK, "ret %08x\n", hr );
5824     {
5825         BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
5826
5827         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
5828         ok(hr == S_OK, "ret %08x\n", hr );
5829         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
5830         ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
5831         if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
5832             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
5833         VariantClear(&value);
5834         IXMLDOMNode_Release(node);
5835     }
5836
5837     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binbase64"), &node);
5838     ok(hr == S_OK, "ret %08x\n", hr );
5839     {
5840         BYTE bytes[] = {0x62,0x61,0x73,0x65,0x36,0x34,0x20,0x74,0x65,0x73,0x74};
5841
5842         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
5843         ok(hr == S_OK, "ret %08x\n", hr );
5844         ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
5845         ok(V_ARRAY(&value)->rgsabound[0].cElements == 11, "incorrect array size\n");
5846         if(V_ARRAY(&value)->rgsabound[0].cElements == 11)
5847             ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
5848         VariantClear(&value);
5849         IXMLDOMNode_Release(node);
5850     }
5851
5852     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
5853     ok(hr == S_OK, "ret %08x\n", hr );
5854     {
5855         V_VT(&value) = VT_NULL;
5856         V_BSTR(&value) = (void*)0xdeadbeef;
5857         hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
5858         ok(hr == S_OK, "ret %08x\n", hr );
5859         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5860         ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
5861         IXMLDOMProcessingInstruction_Release(pi);
5862         VariantClear(&value);
5863     }
5864
5865     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee thats not right!"), &cdata);
5866     ok(hr == S_OK, "ret %08x\n", hr );
5867     {
5868         V_VT(&value) = VT_NULL;
5869         V_BSTR(&value) = (void*)0xdeadbeef;
5870         hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
5871         ok(hr == S_OK, "ret %08x\n", hr );
5872         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5873         ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee thats not right!")), "got wrong value\n");
5874         IXMLDOMCDATASection_Release(cdata);
5875         VariantClear(&value);
5876     }
5877
5878     hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
5879     ok(hr == S_OK, "ret %08x\n", hr );
5880     {
5881         V_VT(&value) = VT_NULL;
5882         V_BSTR(&value) = (void*)0xdeadbeef;
5883         hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
5884         ok(hr == S_OK, "ret %08x\n", hr );
5885         ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5886         ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
5887         IXMLDOMComment_Release(comment);
5888         VariantClear(&value);
5889     }
5890
5891     hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
5892     ok(hr == S_OK, "ret %08x\n", hr );
5893     {
5894         V_VT(&value) = VT_EMPTY;
5895         hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
5896         ok(hr == S_FALSE, "ret %08x\n", hr );
5897         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
5898         IXMLDOMDocumentFragment_Release(frag);
5899     }
5900
5901     doc2 = create_document(&IID_IXMLDOMDocument);
5902
5903     b = VARIANT_FALSE;
5904     hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
5905     ok(hr == S_OK, "ret %08x\n", hr );
5906     ok(b == VARIANT_TRUE, "got %d\n", b);
5907
5908     EXPECT_REF(doc2, 1);
5909
5910     hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
5911     ok(hr == S_OK, "ret %08x\n", hr );
5912
5913     EXPECT_REF(doc2, 1);
5914     todo_wine EXPECT_REF(doctype, 2);
5915
5916     {
5917         V_VT(&value) = VT_EMPTY;
5918         hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
5919         ok(hr == S_FALSE, "ret %08x\n", hr );
5920         ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
5921     }
5922
5923     hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
5924     ok(hr == S_OK, "ret %08x\n", hr );
5925     ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
5926
5927     IXMLDOMDocumentType_Release(doctype2);
5928     IXMLDOMDocumentType_Release(doctype);
5929
5930     IXMLDOMDocument_Release(doc2);
5931
5932     while (entry->name)
5933     {
5934         hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
5935         ok(hr == S_OK, "ret %08x\n", hr );
5936
5937         hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
5938         ok(hr == S_OK, "ret %08x\n", hr );
5939         ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
5940
5941         if (entry->type != VT_BSTR)
5942         {
5943            if (entry->type == VT_DATE ||
5944                entry->type == VT_R8 ||
5945                entry->type == VT_CY)
5946            {
5947                if (entry->type == VT_DATE)
5948                {
5949                    hr = VariantChangeType(&value, &value, 0, VT_R4);
5950                    ok(hr == S_OK, "ret %08x\n", hr );
5951                }
5952                hr = VariantChangeTypeEx(&value, &value,
5953                                         MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
5954                                         VARIANT_NOUSEROVERRIDE, VT_BSTR);
5955                ok(hr == S_OK, "ret %08x\n", hr );
5956            }
5957            else
5958            {
5959                hr = VariantChangeType(&value, &value, 0, VT_BSTR);
5960                ok(hr == S_OK, "ret %08x\n", hr );
5961            }
5962
5963            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
5964               "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
5965         }
5966         else
5967            ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
5968                "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
5969
5970         VariantClear( &value );
5971         IXMLDOMNode_Release(node);
5972
5973         entry++;
5974     }
5975
5976     IXMLDOMDocument_Release(doc);
5977     free_bstrs();
5978 }
5979
5980 static void test_TransformWithLoadingLocalFile(void)
5981 {
5982     IXMLDOMDocument *doc;
5983     IXMLDOMDocument *xsl;
5984     IXMLDOMNode *pNode;
5985     VARIANT_BOOL bSucc;
5986     HRESULT hr;
5987     HANDLE file;
5988     DWORD dwWritten;
5989     char lpPathBuffer[MAX_PATH];
5990     int i;
5991
5992     /* Create a Temp File. */
5993     GetTempPathA(MAX_PATH, lpPathBuffer);
5994     strcat(lpPathBuffer, "customers.xml" );
5995
5996     file = CreateFile(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
5997     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
5998     if(file == INVALID_HANDLE_VALUE)
5999         return;
6000
6001     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
6002     CloseHandle(file);
6003
6004     /* Correct path to not include a escape character. */
6005     for(i=0; i < strlen(lpPathBuffer); i++)
6006     {
6007         if(lpPathBuffer[i] == '\\')
6008             lpPathBuffer[i] = '/';
6009     }
6010
6011     doc = create_document(&IID_IXMLDOMDocument);
6012     if (!doc) return;
6013
6014     xsl = create_document(&IID_IXMLDOMDocument);
6015     if (!xsl)
6016     {
6017         IXMLDOMDocument2_Release(doc);
6018         return;
6019     }
6020
6021     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
6022     ok(hr == S_OK, "ret %08x\n", hr );
6023     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6024     if(bSucc == VARIANT_TRUE)
6025     {
6026         BSTR sXSL;
6027         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
6028         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
6029         BSTR sFileName = _bstr_(lpPathBuffer);
6030         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
6031
6032         sXSL = SysAllocStringLen(NULL, nLegnth);
6033         lstrcpyW(sXSL, sPart1);
6034         lstrcatW(sXSL, sFileName);
6035         lstrcatW(sXSL, sPart2);
6036
6037         hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
6038         ok(hr == S_OK, "ret %08x\n", hr );
6039         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6040         if(bSucc == VARIANT_TRUE)
6041         {
6042             BSTR sResult;
6043
6044             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
6045             ok(hr == S_OK, "ret %08x\n", hr );
6046             if(hr == S_OK)
6047             {
6048                 /* This will load the temp file via the XSL */
6049                 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
6050                 ok(hr == S_OK, "ret %08x\n", hr );
6051                 if(hr == S_OK)
6052                 {
6053                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
6054                     SysFreeString(sResult);
6055                 }
6056
6057                 IXMLDOMNode_Release(pNode);
6058             }
6059         }
6060
6061         SysFreeString(sXSL);
6062     }
6063
6064     IXMLDOMDocument_Release(doc);
6065     IXMLDOMDocument_Release(xsl);
6066
6067     DeleteFile(lpPathBuffer);
6068     free_bstrs();
6069 }
6070
6071 static void test_put_nodeValue(void)
6072 {
6073     static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
6074     IXMLDOMDocument *doc;
6075     IXMLDOMText *text;
6076     IXMLDOMEntityReference *entityref;
6077     IXMLDOMAttribute *attr;
6078     IXMLDOMNode *node;
6079     HRESULT hr;
6080     VARIANT data, type;
6081
6082     doc = create_document(&IID_IXMLDOMDocument);
6083     if (!doc) return;
6084
6085     /* test for unsupported types */
6086     /* NODE_DOCUMENT */
6087     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
6088     ok(hr == S_OK, "ret %08x\n", hr );
6089     V_VT(&data) = VT_BSTR;
6090     V_BSTR(&data) = _bstr_("one two three");
6091     hr = IXMLDOMNode_put_nodeValue(node, data);
6092     ok(hr == E_FAIL, "ret %08x\n", hr );
6093     IXMLDOMNode_Release(node);
6094
6095     /* NODE_DOCUMENT_FRAGMENT */
6096     V_VT(&type) = VT_I1;
6097     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
6098     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
6099     ok(hr == S_OK, "ret %08x\n", hr );
6100     V_VT(&data) = VT_BSTR;
6101     V_BSTR(&data) = _bstr_("one two three");
6102     hr = IXMLDOMNode_put_nodeValue(node, data);
6103     ok(hr == E_FAIL, "ret %08x\n", hr );
6104     IXMLDOMNode_Release(node);
6105
6106     /* NODE_ELEMENT */
6107     V_VT(&type) = VT_I1;
6108     V_I1(&type) = NODE_ELEMENT;
6109     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
6110     ok(hr == S_OK, "ret %08x\n", hr );
6111     V_VT(&data) = VT_BSTR;
6112     V_BSTR(&data) = _bstr_("one two three");
6113     hr = IXMLDOMNode_put_nodeValue(node, data);
6114     ok(hr == E_FAIL, "ret %08x\n", hr );
6115     IXMLDOMNode_Release(node);
6116
6117     /* NODE_ENTITY_REFERENCE */
6118     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
6119     ok(hr == S_OK, "ret %08x\n", hr );
6120
6121     V_VT(&data) = VT_BSTR;
6122     V_BSTR(&data) = _bstr_("one two three");
6123     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
6124     ok(hr == E_FAIL, "ret %08x\n", hr );
6125
6126     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
6127     ok(hr == S_OK, "ret %08x\n", hr );
6128     V_VT(&data) = VT_BSTR;
6129     V_BSTR(&data) = _bstr_("one two three");
6130     hr = IXMLDOMNode_put_nodeValue(node, data);
6131     ok(hr == E_FAIL, "ret %08x\n", hr );
6132     IXMLDOMNode_Release(node);
6133     IXMLDOMEntityReference_Release(entityref);
6134
6135     /* supported types */
6136     hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
6137     ok(hr == S_OK, "ret %08x\n", hr );
6138     V_VT(&data) = VT_BSTR;
6139     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
6140     hr = IXMLDOMText_put_nodeValue(text, data);
6141     ok(hr == S_OK, "ret %08x\n", hr );
6142     IXMLDOMText_Release(text);
6143
6144     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
6145     ok(hr == S_OK, "ret %08x\n", hr );
6146     V_VT(&data) = VT_BSTR;
6147     V_BSTR(&data) = _bstr_("Jeeves & Wooster");
6148     hr = IXMLDOMAttribute_put_nodeValue(attr, data);
6149     ok(hr == S_OK, "ret %08x\n", hr );
6150     hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
6151     ok(hr == S_OK, "ret %08x\n", hr );
6152     ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
6153         wine_dbgstr_w(V_BSTR(&data)));
6154     VariantClear(&data);
6155     IXMLDOMAttribute_Release(attr);
6156
6157     free_bstrs();
6158
6159     IXMLDOMDocument_Release(doc);
6160 }
6161
6162 static void test_document_IObjectSafety(void)
6163 {
6164     IXMLDOMDocument *doc;
6165     IObjectSafety *safety;
6166     HRESULT hr;
6167
6168     doc = create_document(&IID_IXMLDOMDocument);
6169     if (!doc) return;
6170
6171     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
6172     ok(hr == S_OK, "ret %08x\n", hr );
6173
6174     test_IObjectSafety_common(safety);
6175
6176     IObjectSafety_Release(safety);
6177
6178     IXMLDOMDocument_Release(doc);
6179 }
6180
6181 typedef struct _property_test_t {
6182     const GUID *guid;
6183     const char *clsid;
6184     const char *property;
6185     const char *value;
6186 } property_test_t;
6187
6188 static const property_test_t properties_test_data[] = {
6189     { &CLSID_DOMDocument,  "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
6190     { &CLSID_DOMDocument2,  "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
6191     { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
6192     { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
6193     { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
6194     { 0 }
6195 };
6196
6197 static void test_default_properties(void)
6198 {
6199     const property_test_t *entry = properties_test_data;
6200     IXMLDOMDocument2 *doc;
6201     VARIANT var;
6202     HRESULT hr;
6203
6204     while (entry->guid)
6205     {
6206         hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
6207         if (hr != S_OK)
6208         {
6209             win_skip("can't create %s instance\n", entry->clsid);
6210             entry++;
6211             continue;
6212         }
6213
6214         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
6215         ok(hr == S_OK, "got 0x%08x\n", hr);
6216         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
6217            entry->value, entry->clsid);
6218         VariantClear(&var);
6219
6220         IXMLDOMDocument2_Release(doc);
6221
6222         entry++;
6223     }
6224 }
6225
6226 static void test_XSLPattern(void)
6227 {
6228     IXMLDOMDocument2 *doc;
6229     IXMLDOMNodeList *list;
6230     VARIANT_BOOL b;
6231     LONG len;
6232
6233     doc = create_document(&IID_IXMLDOMDocument2);
6234     if (!doc) return;
6235
6236     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
6237     ok(b == VARIANT_TRUE, "failed to load XML string\n");
6238
6239     /* switch to XSLPattern */
6240     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
6241
6242     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
6243     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list));
6244     len = 0;
6245     ole_check(IXMLDOMNodeList_get_length(list, &len));
6246     /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
6247     ok(len == 3, "expected 3 entries in list, got %d\n", len);
6248     IXMLDOMNodeList_Release(list);
6249
6250     /* for XSLPattern start index is 0, for XPath it's 1 */
6251     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
6252     len = 0;
6253     ole_check(IXMLDOMNodeList_get_length(list, &len));
6254     ok(len != 0, "expected filled list\n");
6255     if (len)
6256         expect_list_and_release(list, "E1.E2.D1");
6257
6258     /* index() */
6259     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=1]"), &list));
6260     len = 0;
6261     ole_check(IXMLDOMNodeList_get_length(list, &len));
6262     ok(len != 0, "expected filled list\n");
6263     if (len)
6264         expect_list_and_release(list, "E2.E2.D1");
6265
6266     /* $eq$ */
6267     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $eq$ 1]"), &list));
6268     len = 0;
6269     ole_check(IXMLDOMNodeList_get_length(list, &len));
6270     ok(len != 0, "expected filled list\n");
6271     if (len)
6272         expect_list_and_release(list, "E2.E2.D1");
6273
6274     /* end() */
6275     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[end()]"), &list));
6276     len = 0;
6277     ole_check(IXMLDOMNodeList_get_length(list, &len));
6278     ok(len != 0, "expected filled list\n");
6279     if (len)
6280         expect_list_and_release(list, "E4.E2.D1");
6281
6282     /* $not$ */
6283     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$not$ end()]"), &list));
6284     len = 0;
6285     ole_check(IXMLDOMNodeList_get_length(list, &len));
6286     ok(len != 0, "expected filled list\n");
6287     if (len)
6288         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
6289
6290     /* !=/$ne$ */
6291     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() != 0]"), &list));
6292     len = 0;
6293     ole_check(IXMLDOMNodeList_get_length(list, &len));
6294     ok(len != 0, "expected filled list\n");
6295     if (len)
6296         expect_list_and_release(list, "E2.E2.D1 E3.E2.D1 E4.E2.D1");
6297     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $ne$ 0]"), &list));
6298     len = 0;
6299     ole_check(IXMLDOMNodeList_get_length(list, &len));
6300     ok(len != 0, "expected filled list\n");
6301     if (len)
6302         expect_list_and_release(list, "E2.E2.D1 E3.E2.D1 E4.E2.D1");
6303
6304     /* </$lt$ */
6305     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() < 2]"), &list));
6306     len = 0;
6307     ole_check(IXMLDOMNodeList_get_length(list, &len));
6308     ok(len != 0, "expected filled list\n");
6309     if (len)
6310         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6311     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $lt$ 2]"), &list));
6312     len = 0;
6313     ole_check(IXMLDOMNodeList_get_length(list, &len));
6314     ok(len != 0, "expected filled list\n");
6315     if (len)
6316         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6317
6318     /* <=/$le$ */
6319     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() <= 1]"), &list));
6320     len = 0;
6321     ole_check(IXMLDOMNodeList_get_length(list, &len));
6322     ok(len != 0, "expected filled list\n");
6323     if (len)
6324         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6325     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $le$ 1]"), &list));
6326     len = 0;
6327     ole_check(IXMLDOMNodeList_get_length(list, &len));
6328     ok(len != 0, "expected filled list\n");
6329     if (len)
6330         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6331
6332     /* >/$gt$ */
6333     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() > 1]"), &list));
6334     len = 0;
6335     ole_check(IXMLDOMNodeList_get_length(list, &len));
6336     ok(len != 0, "expected filled list\n");
6337     if (len)
6338         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6339     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $gt$ 1]"), &list));
6340     len = 0;
6341     ole_check(IXMLDOMNodeList_get_length(list, &len));
6342     ok(len != 0, "expected filled list\n");
6343     if (len)
6344         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6345
6346     /* >=/$ge$ */
6347     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() >= 2]"), &list));
6348     len = 0;
6349     ole_check(IXMLDOMNodeList_get_length(list, &len));
6350     ok(len != 0, "expected filled list\n");
6351     if (len)
6352         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6353     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $ge$ 2]"), &list));
6354     len = 0;
6355     ole_check(IXMLDOMNodeList_get_length(list, &len));
6356     ok(len != 0, "expected filled list\n");
6357     if (len)
6358         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6359
6360     /* $ieq$ */
6361     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ieq$ 'a2 field']"), &list));
6362     len = 0;
6363     ole_check(IXMLDOMNodeList_get_length(list, &len));
6364     ok(len != 0, "expected filled list\n");
6365     if (len)
6366         expect_list_and_release(list, "E2.E2.D1");
6367
6368     /* $ine$ */
6369     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ine$ 'a2 field']"), &list));
6370     len = 0;
6371     ole_check(IXMLDOMNodeList_get_length(list, &len));
6372     ok(len != 0, "expected filled list\n");
6373     if (len)
6374         expect_list_and_release(list, "E1.E2.D1 E3.E2.D1 E4.E2.D1");
6375
6376     /* $ilt$ */
6377     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ilt$ 'a3 field']"), &list));
6378     len = 0;
6379     ole_check(IXMLDOMNodeList_get_length(list, &len));
6380     ok(len != 0, "expected filled list\n");
6381     if (len)
6382         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6383
6384     /* $ile$ */
6385     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ile$ 'a2 field']"), &list));
6386     len = 0;
6387     ole_check(IXMLDOMNodeList_get_length(list, &len));
6388     ok(len != 0, "expected filled list\n");
6389     if (len)
6390         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6391
6392     /* $igt$ */
6393     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $igt$ 'a2 field']"), &list));
6394     len = 0;
6395     ole_check(IXMLDOMNodeList_get_length(list, &len));
6396     ok(len != 0, "expected filled list\n");
6397     if (len)
6398         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6399
6400     /* $ige$ */
6401     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ige$ 'a3 field']"), &list));
6402     len = 0;
6403     ole_check(IXMLDOMNodeList_get_length(list, &len));
6404     ok(len != 0, "expected filled list\n");
6405     if (len)
6406         expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6407
6408     /* $any$ */
6409     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$any$ *='B2 field']"), &list));
6410     len = 0;
6411     ole_check(IXMLDOMNodeList_get_length(list, &len));
6412     ok(len != 0, "expected filled list\n");
6413     if (len)
6414         expect_list_and_release(list, "E2.E2.D1");
6415
6416     /* $all$ */
6417     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$all$ *!='B2 field']"), &list));
6418     len = 0;
6419     ole_check(IXMLDOMNodeList_get_length(list, &len));
6420     ok(len != 0, "expected filled list\n");
6421     if (len)
6422         expect_list_and_release(list, "E1.E2.D1 E3.E2.D1 E4.E2.D1");
6423
6424     /* or/$or$/|| */
6425     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 or end()]"), &list));
6426     len = 0;
6427     ole_check(IXMLDOMNodeList_get_length(list, &len));
6428     ok(len != 0, "expected filled list\n");
6429     if (len)
6430         expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6431     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 $or$ end()]"), &list));
6432     len = 0;
6433     ole_check(IXMLDOMNodeList_get_length(list, &len));
6434     ok(len != 0, "expected filled list\n");
6435     if (len)
6436         expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6437     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 || end()]"), &list));
6438     len = 0;
6439     ole_check(IXMLDOMNodeList_get_length(list, &len));
6440     ok(len != 0, "expected filled list\n");
6441     if (len)
6442         expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6443
6444     /* and/$and$/&& */
6445     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 and $not$ end()]"), &list));
6446     len = 0;
6447     ole_check(IXMLDOMNodeList_get_length(list, &len));
6448     ok(len != 0, "expected filled list\n");
6449     if (len)
6450         expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6451     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 $and$ $not$ end()]"), &list));
6452     len = 0;
6453     ole_check(IXMLDOMNodeList_get_length(list, &len));
6454     ok(len != 0, "expected filled list\n");
6455     if (len)
6456         expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6457     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 && $not$ end()]"), &list));
6458     len = 0;
6459     ole_check(IXMLDOMNodeList_get_length(list, &len));
6460     ok(len != 0, "expected filled list\n");
6461     if (len)
6462         expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6463
6464     /* namespace handling */
6465     /* no registered namespaces */
6466     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
6467     list = NULL;
6468
6469     /* prefixes don't need to be registered, you may use them as they are in the doc */
6470     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//bar:x"), &list));
6471     len = 0;
6472     ole_check(IXMLDOMNodeList_get_length(list, &len));
6473     ok(len != 0, "expected filled list\n");
6474     if (len)
6475         expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
6476
6477     /* prefixes must be explicitly specified in the name */
6478     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:elem"), &list));
6479     len = 0;
6480     ole_check(IXMLDOMNodeList_get_length(list, &len));
6481     ok(len == 0, "expected empty list\n");
6482     IXMLDOMNodeList_Release(list);
6483
6484     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6485     len = 0;
6486     ole_check(IXMLDOMNodeList_get_length(list, &len));
6487     ok(len != 0, "expected filled list\n");
6488     if (len)
6489         expect_list_and_release(list, "E3.E4.E2.D1");
6490
6491     /* explicitly register prefix foo */
6492     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
6493
6494     /* now we get the same behavior as XPath */
6495     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6496     len = 0;
6497     ole_check(IXMLDOMNodeList_get_length(list, &len));
6498     ok(len != 0, "expected filled list\n");
6499     if (len)
6500         expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
6501
6502     /* set prefix foo to some nonexistent namespace */
6503     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'")));
6504
6505     /* the registered prefix takes precedence */
6506     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6507     len = 0;
6508     ole_check(IXMLDOMNodeList_get_length(list, &len));
6509     ok(len == 0, "expected empty list\n");
6510     IXMLDOMNodeList_Release(list);
6511
6512     IXMLDOMDocument2_Release(doc);
6513
6514     doc = create_document(&IID_IXMLDOMDocument2);
6515     if (!doc) return;
6516
6517     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b));
6518     ok(b == VARIANT_TRUE, "failed to load XML string\n");
6519     list = NULL;
6520
6521     /* attribute() */
6522     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute()"), &list));
6523     len = 0;
6524     ole_check(IXMLDOMNodeList_get_length(list, &len));
6525     ok(len == 0, "expected empty list\n");
6526     IXMLDOMNodeList_Release(list);
6527
6528     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute('depth')"), &list));
6529     len = 0;
6530     ole_check(IXMLDOMNodeList_get_length(list, &len));
6531     ok(len == 0, "expected empty list\n");
6532     IXMLDOMNodeList_Release(list);
6533
6534     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/attribute('depth')"), &list));
6535     len = 0;
6536     ole_check(IXMLDOMNodeList_get_length(list, &len));
6537     ok(len != 0, "expected filled list\n");
6538     expect_list_and_release(list, "A'depth'.E3.D1");
6539
6540     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/attribute()"), &list));
6541     len = 0;
6542     ole_check(IXMLDOMNodeList_get_length(list, &len));
6543     ok(len != 0, "expected filled list\n");
6544     expect_list_and_release(list, "A'id'.E3.E3.D1 A'depth'.E3.E3.D1");
6545
6546     list = NULL;
6547     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute(id)"), &list), E_FAIL);
6548     if (list)
6549         IXMLDOMNodeList_Release(list);
6550     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute('id')"), &list));
6551     len = 0;
6552     ole_check(IXMLDOMNodeList_get_length(list, &len));
6553     ok(len != 0, "expected filled list\n");
6554     if (len)
6555         expect_list_and_release(list, "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1");
6556
6557     /* comment() */
6558     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("comment()"), &list));
6559     len = 0;
6560     ole_check(IXMLDOMNodeList_get_length(list, &len));
6561     ok(len != 0, "expected filled list\n");
6562     if (len)
6563         expect_list_and_release(list, "C2.D1");
6564
6565     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//comment()"), &list));
6566     len = 0;
6567     ole_check(IXMLDOMNodeList_get_length(list, &len));
6568     ok(len != 0, "expected filled list\n");
6569     if (len)
6570         expect_list_and_release(list, "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1");
6571
6572     /* element() */
6573     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("element()"), &list));
6574     len = 0;
6575     ole_check(IXMLDOMNodeList_get_length(list, &len));
6576     ok(len != 0, "expected filled list\n");
6577     if (len)
6578         expect_list_and_release(list, "E3.D1");
6579
6580     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/y/element()"), &list));
6581     len = 0;
6582     ole_check(IXMLDOMNodeList_get_length(list, &len));
6583     ok(len != 0, "expected filled list\n");
6584     if (len)
6585         expect_list_and_release(list, "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1");
6586
6587     list = NULL;
6588     ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element(a)"), &list), E_FAIL);
6589     if (list)
6590         IXMLDOMNodeList_Release(list);
6591     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element('a')"), &list));
6592     len = 0;
6593     ole_check(IXMLDOMNodeList_get_length(list, &len));
6594     ok(len != 0, "expected filled list\n");
6595     if (len)
6596         expect_list_and_release(list, "E4.E3.E3.D1 E4.E4.E3.D1");
6597
6598     /* node() */
6599     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("node()"), &list));
6600     len = 0;
6601     ole_check(IXMLDOMNodeList_get_length(list, &len));
6602     ok(len != 0, "expected filled list\n");
6603     if (len)
6604         expect_list_and_release(list, "P1.D1 C2.D1 E3.D1");
6605
6606     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()"), &list));
6607     len = 0;
6608     ole_check(IXMLDOMNodeList_get_length(list, &len));
6609     ok(len != 0, "expected filled list\n");
6610     if (len)
6611         expect_list_and_release(list, "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
6612
6613     /* nodeType() */
6614     /* XML_ELEMENT_NODE */
6615     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=1]"), &list));
6616     len = 0;
6617     ole_check(IXMLDOMNodeList_get_length(list, &len));
6618     ok(len != 0, "expected filled list\n");
6619     if (len)
6620         expect_list_and_release(list, "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
6621     /* XML_TEXT_NODE */
6622     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=3]"), &list));
6623     len = 0;
6624     ole_check(IXMLDOMNodeList_get_length(list, &len));
6625     ok(len != 0, "expected filled list\n");
6626     if (len)
6627         expect_list_and_release(list, "T3.E3.E3.D1");
6628     /* XML_PI_NODE */
6629     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=7]"), &list));
6630     len = 0;
6631     ole_check(IXMLDOMNodeList_get_length(list, &len));
6632     ok(len != 0, "expected filled list\n");
6633     if (len)
6634         expect_list_and_release(list, "P1.E3.E3.D1");
6635     /* XML_COMMENT_NODE */
6636     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=8]"), &list));
6637     len = 0;
6638     ole_check(IXMLDOMNodeList_get_length(list, &len));
6639     ok(len != 0, "expected filled list\n");
6640     if (len)
6641         expect_list_and_release(list, "C2.E3.E3.D1");
6642
6643     /* pi() */
6644     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("pi()"), &list));
6645     if (list)
6646     {
6647         len = 0;
6648         ole_check(IXMLDOMNodeList_get_length(list, &len));
6649         ok(len != 0, "expected filled list\n");
6650         if (len)
6651             expect_list_and_release(list, "P1.D1");
6652     }
6653
6654     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//y/pi()"), &list));
6655     len = 0;
6656     ole_check(IXMLDOMNodeList_get_length(list, &len));
6657     ok(len != 0, "expected filled list\n");
6658     if (len)
6659         expect_list_and_release(list, "P1.E4.E3.D1");
6660
6661     /* textnode() */
6662     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/textnode()"), &list));
6663     len = 0;
6664     ole_check(IXMLDOMNodeList_get_length(list, &len));
6665     ok(len != 0, "expected filled list\n");
6666     if (len)
6667         expect_list_and_release(list, "T2.E3.D1");
6668
6669     ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/element()/textnode()"), &list));
6670     len = 0;
6671     ole_check(IXMLDOMNodeList_get_length(list, &len));
6672     ok(len != 0, "expected filled list\n");
6673     if (len)
6674         expect_list_and_release(list, "T3.E3.E3.D1 T3.E4.E3.D1");
6675
6676     IXMLDOMDocument2_Release(doc);
6677     free_bstrs();
6678 }
6679
6680 static void test_splitText(void)
6681 {
6682     IXMLDOMCDATASection *cdata;
6683     IXMLDOMElement *root;
6684     IXMLDOMDocument *doc;
6685     IXMLDOMText *text, *text2;
6686     IXMLDOMNode *node;
6687     VARIANT var;
6688     VARIANT_BOOL success;
6689     LONG length;
6690     HRESULT hr;
6691
6692     doc = create_document(&IID_IXMLDOMDocument);
6693     if (!doc) return;
6694
6695     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
6696     ok(hr == S_OK, "got 0x%08x\n", hr);
6697
6698     hr = IXMLDOMDocument_get_documentElement(doc, &root);
6699     ok(hr == S_OK, "got 0x%08x\n", hr);
6700
6701     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
6702     ok(hr == S_OK, "got 0x%08x\n", hr);
6703
6704     V_VT(&var) = VT_EMPTY;
6705     hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
6706     ok(hr == S_OK, "got 0x%08x\n", hr);
6707
6708     length = 0;
6709     hr = IXMLDOMCDATASection_get_length(cdata, &length);
6710     ok(hr == S_OK, "got 0x%08x\n", hr);
6711     ok(length > 0, "got %d\n", length);
6712
6713     hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
6714     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6715
6716     text = (void*)0xdeadbeef;
6717     /* negative offset */
6718     hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
6719     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6720     ok(text == (void*)0xdeadbeef, "got %p\n", text);
6721
6722     text = (void*)0xdeadbeef;
6723     /* offset outside data */
6724     hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
6725     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6726     ok(text == 0, "got %p\n", text);
6727
6728     text = (void*)0xdeadbeef;
6729     /* offset outside data */
6730     hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
6731     ok(hr == S_FALSE, "got 0x%08x\n", hr);
6732     ok(text == 0, "got %p\n", text);
6733
6734     /* no empty node created */
6735     node = (void*)0xdeadbeef;
6736     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
6737     ok(hr == S_FALSE, "got 0x%08x\n", hr);
6738     ok(node == 0, "got %p\n", text);
6739
6740     hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
6741     ok(hr == S_OK, "got 0x%08x\n", hr);
6742
6743     length = 0;
6744     hr = IXMLDOMText_get_length(text, &length);
6745     ok(hr == S_OK, "got 0x%08x\n", hr);
6746     ok(length == 7, "got %d\n", length);
6747
6748     hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
6749     ok(hr == S_OK, "got 0x%08x\n", hr);
6750     IXMLDOMNode_Release(node);
6751
6752     /* split new text node */
6753     hr = IXMLDOMText_get_length(text, &length);
6754     ok(hr == S_OK, "got 0x%08x\n", hr);
6755
6756     node = (void*)0xdeadbeef;
6757     hr = IXMLDOMText_get_nextSibling(text, &node);
6758     ok(hr == S_FALSE, "got 0x%08x\n", hr);
6759     ok(node == 0, "got %p\n", text);
6760
6761     hr = IXMLDOMText_splitText(text, 0, NULL);
6762     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6763
6764     text2 = (void*)0xdeadbeef;
6765     /* negative offset */
6766     hr = IXMLDOMText_splitText(text, -1, &text2);
6767     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6768     ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
6769
6770     text2 = (void*)0xdeadbeef;
6771     /* offset outside data */
6772     hr = IXMLDOMText_splitText(text, length + 1, &text2);
6773     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6774     ok(text2 == 0, "got %p\n", text2);
6775
6776     text2 = (void*)0xdeadbeef;
6777     /* offset outside data */
6778     hr = IXMLDOMText_splitText(text, length, &text2);
6779     ok(hr == S_FALSE, "got 0x%08x\n", hr);
6780     ok(text2 == 0, "got %p\n", text);
6781
6782     text2 = 0;
6783     hr = IXMLDOMText_splitText(text, 4, &text2);
6784     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
6785     if (text2) IXMLDOMText_Release(text2);
6786
6787     node = 0;
6788     hr = IXMLDOMText_get_nextSibling(text, &node);
6789     todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
6790     if (node) IXMLDOMNode_Release(node);
6791
6792     IXMLDOMText_Release(text);
6793     IXMLDOMElement_Release(root);
6794     IXMLDOMCDATASection_Release(cdata);
6795     free_bstrs();
6796 }
6797
6798 static void test_getQualifiedItem(void)
6799 {
6800     IXMLDOMDocument *doc;
6801     IXMLDOMElement *element;
6802     IXMLDOMNode *pr_node, *node;
6803     IXMLDOMNodeList *root_list;
6804     IXMLDOMNamedNodeMap *map;
6805     VARIANT_BOOL b;
6806     BSTR str;
6807     LONG len;
6808     HRESULT hr;
6809
6810     doc = create_document(&IID_IXMLDOMDocument);
6811     if (!doc) return;
6812
6813     str = SysAllocString( szComplete4 );
6814     hr = IXMLDOMDocument_loadXML( doc, str, &b );
6815     ok( hr == S_OK, "loadXML failed\n");
6816     ok( b == VARIANT_TRUE, "failed to load XML string\n");
6817     SysFreeString( str );
6818
6819     hr = IXMLDOMDocument_get_documentElement(doc, &element);
6820     ok( hr == S_OK, "ret %08x\n", hr);
6821
6822     hr = IXMLDOMElement_get_childNodes(element, &root_list);
6823     ok( hr == S_OK, "ret %08x\n", hr);
6824
6825     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
6826     ok( hr == S_OK, "ret %08x\n", hr);
6827     IXMLDOMNodeList_Release(root_list);
6828
6829     hr = IXMLDOMNode_get_attributes(pr_node, &map);
6830     ok( hr == S_OK, "ret %08x\n", hr);
6831     IXMLDOMNode_Release(pr_node);
6832
6833     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
6834     ok( hr == S_OK, "ret %08x\n", hr);
6835     ok( len == 3, "length %d\n", len);
6836
6837     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
6838     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6839
6840     node = (void*)0xdeadbeef;
6841     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
6842     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6843     ok( node == (void*)0xdeadbeef, "got %p\n", node);
6844
6845     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
6846     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6847
6848     hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
6849     ok( hr == S_OK, "ret %08x\n", hr);
6850     IXMLDOMNode_Release(node);
6851
6852     IXMLDOMNamedNodeMap_Release( map );
6853     IXMLDOMElement_Release( element );
6854     IXMLDOMDocument_Release( doc );
6855     free_bstrs();
6856 }
6857
6858 static void test_removeQualifiedItem(void)
6859 {
6860     IXMLDOMDocument *doc;
6861     IXMLDOMElement *element;
6862     IXMLDOMNode *pr_node, *node;
6863     IXMLDOMNodeList *root_list;
6864     IXMLDOMNamedNodeMap *map;
6865     VARIANT_BOOL b;
6866     BSTR str;
6867     LONG len;
6868     HRESULT hr;
6869
6870     doc = create_document(&IID_IXMLDOMDocument);
6871     if (!doc) return;
6872
6873     str = SysAllocString( szComplete4 );
6874     hr = IXMLDOMDocument_loadXML( doc, str, &b );
6875     ok( hr == S_OK, "loadXML failed\n");
6876     ok( b == VARIANT_TRUE, "failed to load XML string\n");
6877     SysFreeString( str );
6878
6879     hr = IXMLDOMDocument_get_documentElement(doc, &element);
6880     ok( hr == S_OK, "ret %08x\n", hr);
6881
6882     hr = IXMLDOMElement_get_childNodes(element, &root_list);
6883     ok( hr == S_OK, "ret %08x\n", hr);
6884
6885     hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
6886     ok( hr == S_OK, "ret %08x\n", hr);
6887     IXMLDOMNodeList_Release(root_list);
6888
6889     hr = IXMLDOMNode_get_attributes(pr_node, &map);
6890     ok( hr == S_OK, "ret %08x\n", hr);
6891     IXMLDOMNode_Release(pr_node);
6892
6893     hr = IXMLDOMNamedNodeMap_get_length(map, &len);
6894     ok( hr == S_OK, "ret %08x\n", hr);
6895     ok( len == 3, "length %d\n", len);
6896
6897     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
6898     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6899
6900     node = (void*)0xdeadbeef;
6901     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
6902     ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6903     ok( node == (void*)0xdeadbeef, "got %p\n", node);
6904
6905     /* out pointer is optional */
6906     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
6907     ok( hr == S_OK, "ret %08x\n", hr);
6908
6909     /* already removed */
6910     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
6911     ok( hr == S_FALSE, "ret %08x\n", hr);
6912
6913     hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
6914     ok( hr == S_OK, "ret %08x\n", hr);
6915     IXMLDOMNode_Release(node);
6916
6917     IXMLDOMNamedNodeMap_Release( map );
6918     IXMLDOMElement_Release( element );
6919     IXMLDOMDocument_Release( doc );
6920     free_bstrs();
6921 }
6922
6923 #define check_default_props(doc) _check_default_props(__LINE__, doc)
6924 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
6925 {
6926     VARIANT_BOOL b;
6927     VARIANT var;
6928     HRESULT hr;
6929
6930     VariantInit(&var);
6931     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
6932     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
6933     VariantClear(&var);
6934
6935     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
6936     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
6937     VariantClear(&var);
6938
6939     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
6940     ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
6941
6942     hr = IXMLDOMDocument2_get_schemas(doc, &var);
6943     ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
6944     VariantClear(&var);
6945 }
6946
6947 #define check_set_props(doc) _check_set_props(__LINE__, doc)
6948 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
6949 {
6950     VARIANT_BOOL b;
6951     VARIANT var;
6952
6953     VariantInit(&var);
6954     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
6955     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
6956     VariantClear(&var);
6957
6958     helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
6959     ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
6960     VariantClear(&var);
6961
6962     helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
6963     ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
6964
6965     helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
6966     ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
6967     VariantClear(&var);
6968 }
6969
6970 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
6971 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
6972 {
6973     VARIANT var;
6974
6975     VariantInit(&var);
6976     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
6977     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
6978     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
6979     V_VT(&var) = VT_DISPATCH;
6980     V_DISPATCH(&var) = NULL;
6981     helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
6982     ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
6983     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
6984     VariantClear(&var);
6985 }
6986
6987 #define unset_props(doc) _unset_props(__LINE__, doc)
6988 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
6989 {
6990     VARIANT var;
6991
6992     VariantInit(&var);
6993     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
6994     helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
6995     helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
6996     V_VT(&var) = VT_NULL;
6997     helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
6998     VariantClear(&var);
6999 }
7000
7001 static void test_get_ownerDocument(void)
7002 {
7003     IXMLDOMDocument *doc1, *doc2, *doc3;
7004     IXMLDOMDocument2 *doc, *doc_owner;
7005     IXMLDOMNode *node;
7006     IXMLDOMSchemaCollection *cache;
7007     VARIANT_BOOL b;
7008     VARIANT var;
7009     BSTR str;
7010
7011     doc = create_document(&IID_IXMLDOMDocument2);
7012     cache = create_cache(&IID_IXMLDOMSchemaCollection);
7013     if (!doc || !cache)
7014     {
7015         if (doc) IXMLDOMDocument2_Release(doc);
7016         if (cache) IXMLDOMSchemaCollection_Release(cache);
7017         return;
7018     }
7019
7020     VariantInit(&var);
7021
7022     str = SysAllocString(szComplete4);
7023     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
7024     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7025     SysFreeString(str);
7026
7027     check_default_props(doc);
7028
7029     /* set properties and check that new instances use them */
7030     set_props(doc, cache);
7031     check_set_props(doc);
7032
7033     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7034     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
7035
7036     /* new interface keeps props */
7037     ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7038     ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
7039     check_set_props(doc_owner);
7040     IXMLDOMDocument2_Release(doc_owner);
7041
7042     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
7043     IXMLDOMNode_Release(node);
7044
7045     ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
7046
7047     /* reload */
7048     str = SysAllocString(szComplete4);
7049     ole_check(IXMLDOMDocument2_loadXML(doc, str, &b));
7050     ok(b == VARIANT_TRUE, "failed to load XML string\n");
7051     SysFreeString(str);
7052
7053     /* properties retained even after reload */
7054     check_set_props(doc);
7055
7056     ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7057     ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
7058     IXMLDOMNode_Release(node);
7059
7060     ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7061     ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
7062     check_set_props(doc_owner);
7063
7064     /* changing properties for one instance changes them for all */
7065     unset_props(doc_owner);
7066     check_default_props(doc_owner);
7067     check_default_props(doc);
7068
7069     IXMLDOMSchemaCollection_Release(cache);
7070     IXMLDOMDocument_Release(doc1);
7071     IXMLDOMDocument_Release(doc2);
7072     IXMLDOMDocument_Release(doc3);
7073     IXMLDOMDocument2_Release(doc);
7074     IXMLDOMDocument2_Release(doc_owner);
7075     free_bstrs();
7076 }
7077
7078 static void test_setAttributeNode(void)
7079 {
7080     IXMLDOMDocument *doc, *doc2;
7081     IXMLDOMElement *elem, *elem2;
7082     IXMLDOMAttribute *attr, *attr2, *ret_attr;
7083     VARIANT_BOOL b;
7084     HRESULT hr;
7085     VARIANT v;
7086     BSTR str;
7087     ULONG ref1, ref2;
7088
7089     doc = create_document(&IID_IXMLDOMDocument);
7090     if (!doc) return;
7091
7092     str = SysAllocString( szComplete4 );
7093     hr = IXMLDOMDocument2_loadXML( doc, str, &b );
7094     ok( hr == S_OK, "loadXML failed\n");
7095     ok( b == VARIANT_TRUE, "failed to load XML string\n");
7096     SysFreeString( str );
7097
7098     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7099     ok( hr == S_OK, "got 0x%08x\n", hr);
7100
7101     hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
7102     ok( hr == S_OK, "got 0x%08x\n", hr);
7103     ok( elem2 != elem, "got same instance\n");
7104
7105     ret_attr = (void*)0xdeadbeef;
7106     hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
7107     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7108     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7109
7110     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7111     ok( hr == S_OK, "got 0x%08x\n", hr);
7112
7113     ref1 = IXMLDOMElement_AddRef(elem);
7114     IXMLDOMElement_Release(elem);
7115
7116     ret_attr = (void*)0xdeadbeef;
7117     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7118     ok( hr == S_OK, "got 0x%08x\n", hr);
7119     ok( ret_attr == NULL, "got %p\n", ret_attr);
7120
7121     /* no reference added */
7122     ref2 = IXMLDOMElement_AddRef(elem);
7123     IXMLDOMElement_Release(elem);
7124     ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
7125
7126     EXPECT_CHILDREN(elem);
7127     EXPECT_CHILDREN(elem2);
7128
7129     IXMLDOMElement_Release(elem2);
7130
7131     attr2 = NULL;
7132     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
7133     ok( hr == S_OK, "got 0x%08x\n", hr);
7134     ok( attr2 != attr, "got same instance %p\n", attr2);
7135     IXMLDOMAttribute_Release(attr2);
7136
7137     /* try to add it another time */
7138     ret_attr = (void*)0xdeadbeef;
7139     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7140     ok( hr == E_FAIL, "got 0x%08x\n", hr);
7141     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7142
7143     IXMLDOMElement_Release(elem);
7144
7145     /* initialy used element is released, attribute still 'has' a container */
7146     hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7147     ok( hr == S_OK, "got 0x%08x\n", hr);
7148     ret_attr = (void*)0xdeadbeef;
7149     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7150     ok( hr == E_FAIL, "got 0x%08x\n", hr);
7151     ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7152     IXMLDOMElement_Release(elem);
7153
7154     /* add attribute already attached to another document */
7155     doc2 = create_document(&IID_IXMLDOMDocument);
7156
7157     str = SysAllocString( szComplete4 );
7158     hr = IXMLDOMDocument_loadXML( doc2, str, &b );
7159     ok( hr == S_OK, "loadXML failed\n");
7160     ok( b == VARIANT_TRUE, "failed to load XML string\n");
7161     SysFreeString( str );
7162
7163     hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
7164     ok( hr == S_OK, "got 0x%08x\n", hr);
7165     hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
7166     ok( hr == E_FAIL, "got 0x%08x\n", hr);
7167     IXMLDOMElement_Release(elem);
7168
7169     IXMLDOMAttribute_Release(attr);
7170
7171     /* create element, add attribute, see if it's copied or linked */
7172     hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
7173     ok( hr == S_OK, "got 0x%08x\n", hr);
7174
7175     attr = NULL;
7176     hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7177     ok(hr == S_OK, "got 0x%08x\n", hr);
7178     ok(attr != NULL, "got %p\n", attr);
7179
7180     ref1 = IXMLDOMAttribute_AddRef(attr);
7181     IXMLDOMAttribute_Release(attr);
7182
7183     V_VT(&v) = VT_BSTR;
7184     V_BSTR(&v) = _bstr_("attrvalue1");
7185     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
7186     ok( hr == S_OK, "got 0x%08x\n", hr);
7187
7188     str = NULL;
7189     hr = IXMLDOMAttribute_get_xml(attr, &str);
7190     ok( hr == S_OK, "got 0x%08x\n", hr);
7191     ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
7192         "got %s\n", wine_dbgstr_w(str));
7193     SysFreeString(str);
7194
7195     ret_attr = (void*)0xdeadbeef;
7196     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7197     ok(hr == S_OK, "got 0x%08x\n", hr);
7198     ok(ret_attr == NULL, "got %p\n", ret_attr);
7199
7200     /* attribute reference increased */
7201     ref2 = IXMLDOMAttribute_AddRef(attr);
7202     IXMLDOMAttribute_Release(attr);
7203     ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
7204
7205     hr = IXMLDOMElement_get_xml(elem, &str);
7206     ok( hr == S_OK, "got 0x%08x\n", hr);
7207     ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
7208         "got %s\n", wine_dbgstr_w(str));
7209     SysFreeString(str);
7210
7211     V_VT(&v) = VT_BSTR;
7212     V_BSTR(&v) = _bstr_("attrvalue2");
7213     hr = IXMLDOMAttribute_put_nodeValue(attr, v);
7214     ok( hr == S_OK, "got 0x%08x\n", hr);
7215
7216     hr = IXMLDOMElement_get_xml(elem, &str);
7217     ok( hr == S_OK, "got 0x%08x\n", hr);
7218     todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
7219         "got %s\n", wine_dbgstr_w(str));
7220     SysFreeString(str);
7221
7222     IXMLDOMElement_Release(elem);
7223     IXMLDOMAttribute_Release(attr);
7224     IXMLDOMDocument_Release(doc2);
7225     IXMLDOMDocument_Release(doc);
7226 }
7227
7228 static void test_put_dataType(void)
7229 {
7230     IXMLDOMCDATASection *cdata;
7231     IXMLDOMDocument *doc;
7232     VARIANT_BOOL b;
7233     HRESULT hr;
7234     BSTR str;
7235
7236     doc = create_document(&IID_IXMLDOMDocument);
7237     if (!doc) return;
7238
7239     str = SysAllocString( szComplete4 );
7240     hr = IXMLDOMDocument_loadXML( doc, str, &b );
7241     ok( hr == S_OK, "loadXML failed\n");
7242     ok( b == VARIANT_TRUE, "failed to load XML string\n");
7243     SysFreeString( str );
7244
7245     hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
7246     ok( hr == S_OK, "got 0x%08x\n", hr);
7247     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
7248     ok( hr == E_FAIL, "got 0x%08x\n", hr);
7249     hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
7250     ok( hr == E_FAIL, "got 0x%08x\n", hr);
7251     IXMLDOMCDATASection_Release(cdata);
7252
7253     IXMLDOMDocument_Release(doc);
7254     free_bstrs();
7255 }
7256
7257 static void test_createNode(void)
7258 {
7259     IXMLDOMDocument *doc;
7260     IXMLDOMElement *elem;
7261     IXMLDOMNode *node;
7262     VARIANT v, var;
7263     BSTR prefix, str;
7264     HRESULT hr;
7265     ULONG ref;
7266
7267     doc = create_document(&IID_IXMLDOMDocument);
7268     if (!doc) return;
7269
7270     EXPECT_REF(doc, 1);
7271
7272     /* reference count tests */
7273     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
7274     ok( hr == S_OK, "got 0x%08x\n", hr);
7275
7276     /* initial reference is 2 */
7277 todo_wine {
7278     EXPECT_REF(elem, 2);
7279     ref = IXMLDOMElement_Release(elem);
7280     ok(ref == 1, "got %d\n", ref);
7281     /* it's released already, attempt to release now will crash it */
7282 }
7283
7284     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
7285     ok( hr == S_OK, "got 0x%08x\n", hr);
7286     todo_wine EXPECT_REF(elem, 2);
7287     IXMLDOMDocument_Release(doc);
7288     todo_wine EXPECT_REF(elem, 2);
7289     IXMLDOMElement_Release(elem);
7290
7291     doc = create_document(&IID_IXMLDOMDocument);
7292
7293     /* NODE_ELEMENT nodes */
7294     /* 1. specified namespace */
7295     V_VT(&v) = VT_I4;
7296     V_I4(&v) = NODE_ELEMENT;
7297
7298     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
7299     ok( hr == S_OK, "got 0x%08x\n", hr);
7300     prefix = NULL;
7301     hr = IXMLDOMNode_get_prefix(node, &prefix);
7302     ok( hr == S_OK, "got 0x%08x\n", hr);
7303     ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
7304     SysFreeString(prefix);
7305     IXMLDOMNode_Release(node);
7306
7307     /* 2. default namespace */
7308     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
7309     ok( hr == S_OK, "got 0x%08x\n", hr);
7310     prefix = (void*)0xdeadbeef;
7311     hr = IXMLDOMNode_get_prefix(node, &prefix);
7312     ok( hr == S_FALSE, "got 0x%08x\n", hr);
7313     ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
7314     /* check dump */
7315     hr = IXMLDOMNode_get_xml(node, &str);
7316     ok( hr == S_OK, "got 0x%08x\n", hr);
7317     ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
7318         "got %s\n", wine_dbgstr_w(str));
7319     SysFreeString(str);
7320
7321     hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
7322     ok( hr == S_OK, "got 0x%08x\n", hr);
7323
7324     V_VT(&var) = VT_BSTR;
7325     hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
7326     ok( hr == S_FALSE, "got 0x%08x\n", hr);
7327     ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
7328
7329     str = NULL;
7330     hr = IXMLDOMElement_get_namespaceURI(elem, &str);
7331     ok( hr == S_OK, "got 0x%08x\n", hr);
7332     ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
7333     SysFreeString(str);
7334
7335     IXMLDOMElement_Release(elem);
7336     IXMLDOMNode_Release(node);
7337
7338     IXMLDOMDocument_Release(doc);
7339     free_bstrs();
7340 }
7341
7342 static void test_get_prefix(void)
7343 {
7344     IXMLDOMDocumentFragment *fragment;
7345     IXMLDOMCDATASection *cdata;
7346     IXMLDOMElement *element;
7347     IXMLDOMComment *comment;
7348     IXMLDOMDocument *doc;
7349     HRESULT hr;
7350     BSTR str;
7351
7352     doc = create_document(&IID_IXMLDOMDocument);
7353     if (!doc) return;
7354
7355     /* nodes that can't support prefix */
7356     /* 1. document */
7357     str = (void*)0xdeadbeef;
7358     hr = IXMLDOMDocument_get_prefix(doc, &str);
7359     ok( hr == S_FALSE, "got 0x%08x\n", hr);
7360     ok( str == 0, "got %p\n", str);
7361
7362     hr = IXMLDOMDocument_get_prefix(doc, NULL);
7363     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7364
7365     /* 2. cdata */
7366     hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
7367     ok(hr == S_OK, "got %08x\n", hr );
7368
7369     str = (void*)0xdeadbeef;
7370     hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
7371     ok(hr == S_FALSE, "got %08x\n", hr);
7372     ok( str == 0, "got %p\n", str);
7373
7374     hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
7375     ok(hr == E_INVALIDARG, "got %08x\n", hr);
7376     IXMLDOMCDATASection_Release(cdata);
7377
7378     /* 3. comment */
7379     hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
7380     ok(hr == S_OK, "got %08x\n", hr );
7381
7382     str = (void*)0xdeadbeef;
7383     hr = IXMLDOMComment_get_prefix(comment, &str);
7384     ok(hr == S_FALSE, "got %08x\n", hr);
7385     ok( str == 0, "got %p\n", str);
7386
7387     hr = IXMLDOMComment_get_prefix(comment, NULL);
7388     ok(hr == E_INVALIDARG, "got %08x\n", hr);
7389     IXMLDOMComment_Release(comment);
7390
7391     /* 4. fragment */
7392     hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
7393     ok(hr == S_OK, "got %08x\n", hr );
7394
7395     str = (void*)0xdeadbeef;
7396     hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
7397     ok(hr == S_FALSE, "got %08x\n", hr);
7398     ok( str == 0, "got %p\n", str);
7399
7400     hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
7401     ok(hr == E_INVALIDARG, "got %08x\n", hr);
7402     IXMLDOMDocumentFragment_Release(fragment);
7403
7404     /* no prefix */
7405     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
7406     ok( hr == S_OK, "got 0x%08x\n", hr);
7407
7408     hr = IXMLDOMElement_get_prefix(element, NULL);
7409     ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7410
7411     str = (void*)0xdeadbeef;
7412     hr = IXMLDOMElement_get_prefix(element, &str);
7413     ok( hr == S_FALSE, "got 0x%08x\n", hr);
7414     ok( str == 0, "got %p\n", str);
7415
7416     IXMLDOMElement_Release(element);
7417
7418     /* with prefix */
7419     hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
7420     ok( hr == S_OK, "got 0x%08x\n", hr);
7421
7422     str = (void*)0xdeadbeef;
7423     hr = IXMLDOMElement_get_prefix(element, &str);
7424     ok( hr == S_OK, "got 0x%08x\n", hr);
7425     ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
7426     SysFreeString(str);
7427
7428     str = (void*)0xdeadbeef;
7429     hr = IXMLDOMElement_get_namespaceURI(element, &str);
7430     ok( hr == S_FALSE, "got 0x%08x\n", hr);
7431     ok( str == 0, "got %p\n", str);
7432
7433     IXMLDOMElement_Release(element);
7434
7435     IXMLDOMDocument_Release(doc);
7436     free_bstrs();
7437 }
7438
7439 static void test_selectSingleNode(void)
7440 {
7441     IXMLDOMDocument *doc;
7442     IXMLDOMNodeList *list;
7443     IXMLDOMNode *node;
7444     VARIANT_BOOL b;
7445     HRESULT hr;
7446     LONG len;
7447     BSTR str;
7448
7449     doc = create_document(&IID_IXMLDOMDocument);
7450     if (!doc) return;
7451
7452     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
7453     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7454
7455     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
7456     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7457
7458     str = SysAllocString( szComplete4 );
7459     hr = IXMLDOMDocument_loadXML( doc, str, &b );
7460     ok( hr == S_OK, "loadXML failed\n");
7461     ok( b == VARIANT_TRUE, "failed to load XML string\n");
7462     SysFreeString( str );
7463
7464     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
7465     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7466
7467     hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
7468     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7469
7470     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
7471     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7472
7473     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
7474     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7475
7476     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
7477     ok(hr == S_OK, "got 0x%08x\n", hr);
7478     IXMLDOMNode_Release(node);
7479
7480     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
7481     ok(hr == S_OK, "got 0x%08x\n", hr);
7482     IXMLDOMNodeList_Release(list);
7483
7484     list = (void*)0xdeadbeef;
7485     hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
7486     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7487     ok(list == (void*)0xdeadbeef, "got %p\n", list);
7488
7489     node = (void*)0xdeadbeef;
7490     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
7491     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7492     ok(node == 0, "got %p\n", node);
7493
7494     list = (void*)0xdeadbeef;
7495     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
7496     ok(hr == S_OK, "got 0x%08x\n", hr);
7497     len = 1;
7498     hr = IXMLDOMNodeList_get_length(list, &len);
7499     ok(hr == S_OK, "got 0x%08x\n", hr);
7500     ok(len == 0, "got %d\n", len);
7501     IXMLDOMNodeList_Release(list);
7502
7503     IXMLDOMDocument_Release(doc);
7504     free_bstrs();
7505 }
7506
7507 static void test_events(void)
7508 {
7509     IConnectionPointContainer *conn;
7510     IConnectionPoint *point;
7511     IXMLDOMDocument *doc;
7512     HRESULT hr;
7513     VARIANT v;
7514     IDispatch *event;
7515
7516     doc = create_document(&IID_IXMLDOMDocument);
7517     if (!doc) return;
7518
7519     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
7520     ok(hr == S_OK, "got 0x%08x\n", hr);
7521
7522     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
7523     ok(hr == S_OK, "got 0x%08x\n", hr);
7524     IConnectionPoint_Release(point);
7525     hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
7526     ok(hr == S_OK, "got 0x%08x\n", hr);
7527     IConnectionPoint_Release(point);
7528     hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
7529     ok(hr == S_OK, "got 0x%08x\n", hr);
7530     IConnectionPoint_Release(point);
7531
7532     IConnectionPointContainer_Release(conn);
7533
7534     /* ready state callback */
7535     VariantInit(&v);
7536     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7537     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
7538
7539     event = create_dispevent();
7540     V_VT(&v) = VT_UNKNOWN;
7541     V_UNKNOWN(&v) = (IUnknown*)event;
7542
7543     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7544     ok(hr == S_OK, "got 0x%08x\n", hr);
7545     EXPECT_REF(event, 2);
7546
7547     V_VT(&v) = VT_DISPATCH;
7548     V_DISPATCH(&v) = event;
7549
7550     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7551     ok(hr == S_OK, "got 0x%08x\n", hr);
7552     EXPECT_REF(event, 2);
7553
7554     /* VT_NULL doesn't reset event handler */
7555     V_VT(&v) = VT_NULL;
7556     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7557     ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
7558     EXPECT_REF(event, 2);
7559
7560     V_VT(&v) = VT_DISPATCH;
7561     V_DISPATCH(&v) = NULL;
7562
7563     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7564     ok(hr == S_OK, "got 0x%08x\n", hr);
7565     EXPECT_REF(event, 1);
7566
7567     V_VT(&v) = VT_UNKNOWN;
7568     V_DISPATCH(&v) = NULL;
7569     hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7570     ok(hr == S_OK, "got 0x%08x\n", hr);
7571
7572     IDispatch_Release(event);
7573
7574     IXMLDOMDocument_Release(doc);
7575 }
7576
7577 static void test_createProcessingInstruction(void)
7578 {
7579     static const WCHAR bodyW[] = {'t','e','s','t',0};
7580     IXMLDOMProcessingInstruction *pi;
7581     IXMLDOMDocument *doc;
7582     WCHAR buff[10];
7583     HRESULT hr;
7584
7585     doc = create_document(&IID_IXMLDOMDocument);
7586     if (!doc) return;
7587
7588     /* test for BSTR handling, pass broken BSTR */
7589     memcpy(&buff[2], bodyW, sizeof(bodyW));
7590     /* just a big length */
7591     *(DWORD*)buff = 0xf0f0;
7592     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
7593     ok(hr == S_OK, "got 0x%08x\n", hr);
7594
7595     IXMLDOMProcessingInstruction_Release(pi);
7596     IXMLDOMDocument_Release(doc);
7597 }
7598
7599 static void test_put_nodeTypedValue(void)
7600 {
7601     IXMLDOMDocument *doc;
7602     IXMLDOMElement *elem;
7603     VARIANT type;
7604     HRESULT hr;
7605
7606     doc = create_document(&IID_IXMLDOMDocument);
7607     if (!doc) return;
7608
7609     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
7610     ok(hr == S_OK, "got 0x%08x\n", hr);
7611
7612     V_VT(&type) = VT_EMPTY;
7613     hr = IXMLDOMElement_get_dataType(elem, &type);
7614     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7615     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
7616
7617     /* set typed value for untyped node */
7618     V_VT(&type) = VT_I1;
7619     V_I1(&type) = 1;
7620     hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
7621     ok(hr == S_OK, "got 0x%08x\n", hr);
7622
7623     V_VT(&type) = VT_EMPTY;
7624     hr = IXMLDOMElement_get_dataType(elem, &type);
7625     ok(hr == S_FALSE, "got 0x%08x\n", hr);
7626     ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
7627
7628     /* no type info stored */
7629     V_VT(&type) = VT_EMPTY;
7630     hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
7631     ok(hr == S_OK, "got 0x%08x\n", hr);
7632     ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
7633     ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
7634        "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
7635     VariantClear(&type);
7636
7637     IXMLDOMElement_Release(elem);
7638     IXMLDOMDocument_Release(doc);
7639     free_bstrs();
7640 }
7641
7642 static void test_get_xml(void)
7643 {
7644     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
7645     IXMLDOMProcessingInstruction *pi;
7646     IXMLDOMNode *first;
7647     IXMLDOMDocument *doc;
7648     VARIANT_BOOL b;
7649     VARIANT v;
7650     BSTR xml;
7651     HRESULT hr;
7652
7653     doc = create_document(&IID_IXMLDOMDocument);
7654     if (!doc) return;
7655
7656     b = VARIANT_TRUE;
7657     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
7658     ok(hr == S_OK, "got 0x%08x\n", hr);
7659     ok( b == VARIANT_TRUE, "got %d\n", b);
7660
7661     hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
7662                              _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
7663     ok(hr == S_OK, "got 0x%08x\n", hr);
7664
7665     hr = IXMLDOMDocument_get_firstChild(doc, &first);
7666     ok(hr == S_OK, "got 0x%08x\n", hr);
7667
7668     V_UNKNOWN(&v) = (IUnknown*)first;
7669     V_VT(&v) = VT_UNKNOWN;
7670
7671     hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
7672     ok(hr == S_OK, "got 0x%08x\n", hr);
7673
7674     IXMLDOMProcessingInstruction_Release(pi);
7675     IXMLDOMNode_Release(first);
7676
7677     hr = IXMLDOMDocument_get_xml(doc, &xml);
7678     ok(hr == S_OK, "got 0x%08x\n", hr);
7679
7680     ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
7681         "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
7682     SysFreeString(xml);
7683
7684     IXMLDOMDocument_Release(doc);
7685     free_bstrs();
7686 }
7687
7688 static void test_xsltemplate(void)
7689 {
7690     IXSLTemplate *template;
7691     IXSLProcessor *processor;
7692     IXMLDOMDocument *doc, *doc2;
7693     IStream *stream;
7694     VARIANT_BOOL b;
7695     HRESULT hr;
7696     ULONG ref1, ref2;
7697     VARIANT v;
7698
7699     template = create_xsltemplate(&IID_IXSLTemplate);
7700     if (!template) return;
7701
7702     /* works as reset */
7703     hr = IXSLTemplate_putref_stylesheet(template, NULL);
7704     ok(hr == S_OK, "got 0x%08x\n", hr);
7705
7706     doc = create_document(&IID_IXMLDOMDocument);
7707
7708     b = VARIANT_TRUE;
7709     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
7710     ok(hr == S_OK, "got 0x%08x\n", hr);
7711     ok( b == VARIANT_TRUE, "got %d\n", b);
7712
7713     /* putref with non-xsl document */
7714     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7715     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
7716
7717     b = VARIANT_TRUE;
7718     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
7719     ok(hr == S_OK, "got 0x%08x\n", hr);
7720     ok( b == VARIANT_TRUE, "got %d\n", b);
7721
7722     /* not a freethreaded document */
7723     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7724     todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
7725
7726     IXMLDOMDocument_Release(doc);
7727
7728     hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
7729     if (hr != S_OK)
7730     {
7731         win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
7732         IXSLTemplate_Release(template);
7733         return;
7734     }
7735
7736     b = VARIANT_TRUE;
7737     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
7738     ok(hr == S_OK, "got 0x%08x\n", hr);
7739     ok( b == VARIANT_TRUE, "got %d\n", b);
7740
7741     /* freethreaded document */
7742     ref1 = IXMLDOMDocument_AddRef(doc);
7743     IXMLDOMDocument_Release(doc);
7744     hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7745     ok(hr == S_OK, "got 0x%08x\n", hr);
7746     ref2 = IXMLDOMDocument_AddRef(doc);
7747     IXMLDOMDocument_Release(doc);
7748     ok(ref2 > ref1, "got %d\n", ref2);
7749
7750     /* processor */
7751     hr = IXSLTemplate_createProcessor(template, NULL);
7752     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7753
7754     EXPECT_REF(template, 1);
7755     hr = IXSLTemplate_createProcessor(template, &processor);
7756     ok(hr == S_OK, "got 0x%08x\n", hr);
7757     EXPECT_REF(template, 2);
7758
7759     /* input no set yet */
7760     V_VT(&v) = VT_BSTR;
7761     V_BSTR(&v) = NULL;
7762     hr = IXSLProcessor_get_input(processor, &v);
7763 todo_wine {
7764     ok(hr == S_OK, "got 0x%08x\n", hr);
7765     ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
7766 }
7767
7768     hr = IXSLProcessor_get_output(processor, NULL);
7769     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7770
7771     /* reset before it was set */
7772     V_VT(&v) = VT_EMPTY;
7773     hr = IXSLProcessor_put_output(processor, v);
7774     ok(hr == S_OK, "got 0x%08x\n", hr);
7775
7776     CreateStreamOnHGlobal(NULL, TRUE, &stream);
7777     EXPECT_REF(stream, 1);
7778
7779     V_VT(&v) = VT_UNKNOWN;
7780     V_UNKNOWN(&v) = (IUnknown*)stream;
7781     hr = IXSLProcessor_put_output(processor, v);
7782     ok(hr == S_OK, "got 0x%08x\n", hr);
7783
7784     /* it seems processor grabs 2 references */
7785     todo_wine EXPECT_REF(stream, 3);
7786
7787     V_VT(&v) = VT_EMPTY;
7788     hr = IXSLProcessor_get_output(processor, &v);
7789     ok(hr == S_OK, "got 0x%08x\n", hr);
7790     ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
7791     ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
7792
7793     todo_wine EXPECT_REF(stream, 4);
7794     VariantClear(&v);
7795
7796     hr = IXSLProcessor_transform(processor, NULL);
7797     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7798
7799     /* reset and check stream refcount */
7800     V_VT(&v) = VT_EMPTY;
7801     hr = IXSLProcessor_put_output(processor, v);
7802     ok(hr == S_OK, "got 0x%08x\n", hr);
7803
7804     EXPECT_REF(stream, 1);
7805
7806     IStream_Release(stream);
7807
7808     /* no output interface set, check output */
7809     doc2 = create_document(&IID_IXMLDOMDocument);
7810
7811     b = VARIANT_TRUE;
7812     hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
7813     ok(hr == S_OK, "got 0x%08x\n", hr);
7814     ok( b == VARIANT_TRUE, "got %d\n", b);
7815
7816     V_VT(&v) = VT_UNKNOWN;
7817     V_UNKNOWN(&v) = (IUnknown*)doc2;
7818     hr = IXSLProcessor_put_input(processor, v);
7819     ok(hr == S_OK, "got 0x%08x\n", hr);
7820
7821     hr = IXSLProcessor_transform(processor, &b);
7822     ok(hr == S_OK, "got 0x%08x\n", hr);
7823
7824     V_VT(&v) = VT_EMPTY;
7825     hr = IXSLProcessor_get_output(processor, &v);
7826     ok(hr == S_OK, "got 0x%08x\n", hr);
7827     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
7828     /* we currently output one '\n' instead of empty string */
7829     todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7830     IXMLDOMDocument_Release(doc2);
7831     VariantClear(&v);
7832
7833     IXSLProcessor_Release(processor);
7834
7835     /* drop reference */
7836     hr = IXSLTemplate_putref_stylesheet(template, NULL);
7837     ok(hr == S_OK, "got 0x%08x\n", hr);
7838     ref2 = IXMLDOMDocument_AddRef(doc);
7839     IXMLDOMDocument_Release(doc);
7840     ok(ref2 == ref1, "got %d\n", ref2);
7841
7842     IXMLDOMDocument_Release(doc);
7843     IXSLTemplate_Release(template);
7844     free_bstrs();
7845 }
7846
7847 static void test_insertBefore(void)
7848 {
7849     IXMLDOMDocument *doc, *doc2;
7850     IXMLDOMAttribute *attr;
7851     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
7852     IXMLDOMNode *node, *newnode;
7853     HRESULT hr;
7854     VARIANT v;
7855     BSTR p;
7856
7857     doc = create_document(&IID_IXMLDOMDocument);
7858
7859     /* insertBefore behaviour for attribute node */
7860     V_VT(&v) = VT_I4;
7861     V_I4(&v) = NODE_ATTRIBUTE;
7862
7863     attr = NULL;
7864     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
7865     ok(hr == S_OK, "got 0x%08x\n", hr);
7866     ok(attr != NULL, "got %p\n", attr);
7867
7868     /* attribute to attribute */
7869     V_VT(&v) = VT_I4;
7870     V_I4(&v) = NODE_ATTRIBUTE;
7871     newnode = NULL;
7872     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
7873     ok(hr == S_OK, "got 0x%08x\n", hr);
7874     ok(newnode != NULL, "got %p\n", newnode);
7875
7876     V_VT(&v) = VT_NULL;
7877     node = (void*)0xdeadbeef;
7878     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7879     ok(hr == E_FAIL, "got 0x%08x\n", hr);
7880     ok(node == NULL, "got %p\n", node);
7881
7882     V_VT(&v) = VT_UNKNOWN;
7883     V_UNKNOWN(&v) = (IUnknown*)attr;
7884     node = (void*)0xdeadbeef;
7885     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7886     todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7887     ok(node == NULL, "got %p\n", node);
7888     IXMLDOMNode_Release(newnode);
7889
7890     /* cdata to attribute */
7891     V_VT(&v) = VT_I4;
7892     V_I4(&v) = NODE_CDATA_SECTION;
7893     newnode = NULL;
7894     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
7895     ok(hr == S_OK, "got 0x%08x\n", hr);
7896     ok(newnode != NULL, "got %p\n", newnode);
7897
7898     V_VT(&v) = VT_NULL;
7899     node = (void*)0xdeadbeef;
7900     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7901     ok(hr == E_FAIL, "got 0x%08x\n", hr);
7902     ok(node == NULL, "got %p\n", node);
7903     IXMLDOMNode_Release(newnode);
7904
7905     /* comment to attribute */
7906     V_VT(&v) = VT_I4;
7907     V_I4(&v) = NODE_COMMENT;
7908     newnode = NULL;
7909     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
7910     ok(hr == S_OK, "got 0x%08x\n", hr);
7911     ok(newnode != NULL, "got %p\n", newnode);
7912
7913     V_VT(&v) = VT_NULL;
7914     node = (void*)0xdeadbeef;
7915     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7916     ok(hr == E_FAIL, "got 0x%08x\n", hr);
7917     ok(node == NULL, "got %p\n", node);
7918     IXMLDOMNode_Release(newnode);
7919
7920     /* element to attribute */
7921     V_VT(&v) = VT_I4;
7922     V_I4(&v) = NODE_ELEMENT;
7923     newnode = NULL;
7924     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
7925     ok(hr == S_OK, "got 0x%08x\n", hr);
7926     ok(newnode != NULL, "got %p\n", newnode);
7927
7928     V_VT(&v) = VT_NULL;
7929     node = (void*)0xdeadbeef;
7930     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7931     ok(hr == E_FAIL, "got 0x%08x\n", hr);
7932     ok(node == NULL, "got %p\n", node);
7933     IXMLDOMNode_Release(newnode);
7934
7935     /* pi to attribute */
7936     V_VT(&v) = VT_I4;
7937     V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
7938     newnode = NULL;
7939     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
7940     ok(hr == S_OK, "got 0x%08x\n", hr);
7941     ok(newnode != NULL, "got %p\n", newnode);
7942
7943     V_VT(&v) = VT_NULL;
7944     node = (void*)0xdeadbeef;
7945     hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7946     ok(hr == E_FAIL, "got 0x%08x\n", hr);
7947     ok(node == NULL, "got %p\n", node);
7948     IXMLDOMNode_Release(newnode);
7949     IXMLDOMAttribute_Release(attr);
7950
7951     /* insertBefore for elements */
7952     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
7953     ok(hr == S_OK, "got 0x%08x\n", hr);
7954
7955     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
7956     ok(hr == S_OK, "got 0x%08x\n", hr);
7957
7958     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
7959     ok(hr == S_OK, "got 0x%08x\n", hr);
7960
7961     EXPECT_NO_CHILDREN(elem1);
7962     EXPECT_NO_CHILDREN(elem2);
7963     EXPECT_NO_CHILDREN(elem3);
7964
7965     todo_wine EXPECT_REF(elem2, 2);
7966
7967     V_VT(&v) = VT_NULL;
7968     node = NULL;
7969     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
7970     ok(hr == S_OK, "got 0x%08x\n", hr);
7971     ok(node == (void*)elem2, "got %p\n", node);
7972
7973     EXPECT_CHILDREN(elem1);
7974     todo_wine EXPECT_REF(elem2, 3);
7975     IXMLDOMNode_Release(node);
7976
7977     /* again for already linked node */
7978     V_VT(&v) = VT_NULL;
7979     node = NULL;
7980     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
7981     ok(hr == S_OK, "got 0x%08x\n", hr);
7982     ok(node == (void*)elem2, "got %p\n", node);
7983
7984     EXPECT_CHILDREN(elem1);
7985
7986     /* increments each time */
7987     todo_wine EXPECT_REF(elem2, 3);
7988     IXMLDOMNode_Release(node);
7989
7990     /* try to add to another element */
7991     V_VT(&v) = VT_NULL;
7992     node = (void*)0xdeadbeef;
7993     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
7994     ok(hr == S_OK, "got 0x%08x\n", hr);
7995     ok(node == (void*)elem2, "got %p\n", node);
7996
7997     EXPECT_CHILDREN(elem3);
7998     EXPECT_NO_CHILDREN(elem1);
7999
8000     IXMLDOMNode_Release(node);
8001
8002     /* cross document case - try to add as child to a node created with other doc */
8003     doc2 = create_document(&IID_IXMLDOMDocument);
8004
8005     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
8006     ok(hr == S_OK, "got 0x%08x\n", hr);
8007     todo_wine EXPECT_REF(elem4, 2);
8008
8009     /* same name, another instance */
8010     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
8011     ok(hr == S_OK, "got 0x%08x\n", hr);
8012     todo_wine EXPECT_REF(elem5, 2);
8013
8014     todo_wine EXPECT_REF(elem3, 2);
8015     V_VT(&v) = VT_NULL;
8016     node = NULL;
8017     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
8018     ok(hr == S_OK, "got 0x%08x\n", hr);
8019     ok(node == (void*)elem4, "got %p\n", node);
8020     todo_wine EXPECT_REF(elem4, 3);
8021     todo_wine EXPECT_REF(elem3, 2);
8022     IXMLDOMNode_Release(node);
8023
8024     V_VT(&v) = VT_NULL;
8025     node = NULL;
8026     hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
8027     ok(hr == S_OK, "got 0x%08x\n", hr);
8028     ok(node == (void*)elem5, "got %p\n", node);
8029     todo_wine EXPECT_REF(elem4, 2);
8030     todo_wine EXPECT_REF(elem5, 3);
8031     IXMLDOMNode_Release(node);
8032
8033     IXMLDOMDocument_Release(doc2);
8034
8035     IXMLDOMElement_Release(elem1);
8036     IXMLDOMElement_Release(elem2);
8037     IXMLDOMElement_Release(elem3);
8038     IXMLDOMElement_Release(elem4);
8039     IXMLDOMElement_Release(elem5);
8040
8041     /* elements with same default namespace */
8042     V_VT(&v) = VT_I4;
8043     V_I4(&v) = NODE_ELEMENT;
8044     elem1 = NULL;
8045     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
8046     ok(hr == S_OK, "got 0x%08x\n", hr);
8047     ok(elem1 != NULL, "got %p\n", elem1);
8048
8049     V_VT(&v) = VT_I4;
8050     V_I4(&v) = NODE_ELEMENT;
8051     elem2 = NULL;
8052     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
8053     ok(hr == S_OK, "got 0x%08x\n", hr);
8054     ok(elem2 != NULL, "got %p\n", elem2);
8055
8056     /* check contents so far */
8057     p = NULL;
8058     hr = IXMLDOMElement_get_xml(elem1, &p);
8059     ok(hr == S_OK, "got 0x%08x\n", hr);
8060     ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8061     SysFreeString(p);
8062
8063     p = NULL;
8064     hr = IXMLDOMElement_get_xml(elem2, &p);
8065     ok(hr == S_OK, "got 0x%08x\n", hr);
8066     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8067     SysFreeString(p);
8068
8069     V_VT(&v) = VT_NULL;
8070     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
8071     ok(hr == S_OK, "got 0x%08x\n", hr);
8072
8073     /* get_xml depends on context, for top node it omits child namespace attribute,
8074        but at child level it's still returned */
8075     p = NULL;
8076     hr = IXMLDOMElement_get_xml(elem1, &p);
8077     ok(hr == S_OK, "got 0x%08x\n", hr);
8078     todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
8079         "got %s\n", wine_dbgstr_w(p));
8080     SysFreeString(p);
8081
8082     p = NULL;
8083     hr = IXMLDOMElement_get_xml(elem2, &p);
8084     ok(hr == S_OK, "got 0x%08x\n", hr);
8085     ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8086     SysFreeString(p);
8087
8088     IXMLDOMElement_Release(elem1);
8089     IXMLDOMElement_Release(elem2);
8090
8091     /* child without default namespace added to node with default namespace */
8092     V_VT(&v) = VT_I4;
8093     V_I4(&v) = NODE_ELEMENT;
8094     elem1 = NULL;
8095     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
8096     ok(hr == S_OK, "got 0x%08x\n", hr);
8097     ok(elem1 != NULL, "got %p\n", elem1);
8098
8099     V_VT(&v) = VT_I4;
8100     V_I4(&v) = NODE_ELEMENT;
8101     elem2 = NULL;
8102     hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
8103     ok(hr == S_OK, "got 0x%08x\n", hr);
8104     ok(elem2 != NULL, "got %p\n", elem2);
8105
8106     EXPECT_REF(elem2, 1);
8107     V_VT(&v) = VT_NULL;
8108     hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
8109     ok(hr == S_OK, "got 0x%08x\n", hr);
8110     EXPECT_REF(elem2, 1);
8111
8112     p = NULL;
8113     hr = IXMLDOMElement_get_xml(elem2, &p);
8114     ok(hr == S_OK, "got 0x%08x\n", hr);
8115     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
8116     SysFreeString(p);
8117
8118     hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
8119     ok(hr == S_OK, "got 0x%08x\n", hr);
8120
8121     p = NULL;
8122     hr = IXMLDOMElement_get_xml(elem2, &p);
8123     ok(hr == S_OK, "got 0x%08x\n", hr);
8124     ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
8125     SysFreeString(p);
8126
8127     IXMLDOMElement_Release(elem1);
8128     IXMLDOMElement_Release(elem2);
8129     IXMLDOMDocument_Release(doc);
8130 }
8131
8132 static void test_appendChild(void)
8133 {
8134     IXMLDOMDocument *doc, *doc2;
8135     IXMLDOMElement *elem, *elem2;
8136     HRESULT hr;
8137
8138     doc = create_document(&IID_IXMLDOMDocument);
8139     doc2 = create_document(&IID_IXMLDOMDocument);
8140
8141     hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8142     ok(hr == S_OK, "got 0x%08x\n", hr);
8143
8144     hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
8145     ok(hr == S_OK, "got 0x%08x\n", hr);
8146
8147     EXPECT_REF(doc, 1);
8148     todo_wine EXPECT_REF(elem, 2);
8149     EXPECT_REF(doc2, 1);
8150     todo_wine EXPECT_REF(elem2, 2);
8151     EXPECT_NO_CHILDREN(doc);
8152     EXPECT_NO_CHILDREN(doc2);
8153
8154     /* append from another document */
8155     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
8156     ok(hr == S_OK, "got 0x%08x\n", hr);
8157
8158     EXPECT_REF(doc, 1);
8159     todo_wine EXPECT_REF(elem, 2);
8160     EXPECT_REF(doc2, 1);
8161     todo_wine EXPECT_REF(elem2, 2);
8162     EXPECT_NO_CHILDREN(doc);
8163     EXPECT_CHILDREN(doc2);
8164
8165     IXMLDOMElement_Release(elem);
8166     IXMLDOMElement_Release(elem2);
8167     IXMLDOMDocument_Release(doc);
8168     IXMLDOMDocument_Release(doc2);
8169 }
8170
8171 static void test_get_doctype(void)
8172 {
8173     IXMLDOMDocumentType *doctype;
8174     IXMLDOMDocument *doc;
8175     HRESULT hr;
8176
8177     doc = create_document(&IID_IXMLDOMDocument);
8178
8179     hr = IXMLDOMDocument_get_doctype(doc, NULL);
8180     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8181
8182     doctype = (void*)0xdeadbeef;
8183     hr = IXMLDOMDocument_get_doctype(doc, &doctype);
8184     ok(hr == S_FALSE, "got 0x%08x\n", hr);
8185     ok(doctype == NULL, "got %p\n", doctype);
8186
8187     IXMLDOMDocument_Release(doc);
8188 }
8189
8190 static void test_get_tagName(void)
8191 {
8192     IXMLDOMDocument *doc;
8193     IXMLDOMElement *elem, *elem2;
8194     HRESULT hr;
8195     BSTR str;
8196
8197     doc = create_document(&IID_IXMLDOMDocument);
8198
8199     hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
8200     ok(hr == S_OK, "got 0x%08x\n", hr);
8201
8202     hr = IXMLDOMElement_get_tagName(elem, NULL);
8203     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8204
8205     str = NULL;
8206     hr = IXMLDOMElement_get_tagName(elem, &str);
8207     ok(hr == S_OK, "got 0x%08x\n", hr);
8208     ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
8209     SysFreeString(str);
8210
8211     hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
8212     ok(hr == S_OK, "got 0x%08x\n", hr);
8213
8214     str = NULL;
8215     hr = IXMLDOMElement_get_tagName(elem2, &str);
8216     ok(hr == S_OK, "got 0x%08x\n", hr);
8217     ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
8218     SysFreeString(str);
8219
8220     IXMLDOMDocument_Release(elem);
8221     IXMLDOMDocument_Release(elem2);
8222     IXMLDOMDocument_Release(doc);
8223     free_bstrs();
8224 }
8225
8226 typedef struct _get_datatype_t {
8227     DOMNodeType type;
8228     const char *name;
8229     VARTYPE vt;
8230     HRESULT hr;
8231 } get_datatype_t;
8232
8233 static const get_datatype_t get_datatype[] = {
8234     { NODE_ELEMENT,                "element",   VT_NULL, S_FALSE },
8235     { NODE_ATTRIBUTE,              "attr",      VT_NULL, S_FALSE },
8236     { NODE_TEXT,                   "text",      VT_NULL, S_FALSE },
8237     { NODE_CDATA_SECTION ,         "cdata",     VT_NULL, S_FALSE },
8238     { NODE_ENTITY_REFERENCE,       "entityref", VT_NULL, S_FALSE },
8239     { NODE_PROCESSING_INSTRUCTION, "pi",        VT_NULL, S_FALSE },
8240     { NODE_COMMENT,                "comment",   VT_NULL, S_FALSE },
8241     { NODE_DOCUMENT_FRAGMENT,      "docfrag",   VT_NULL, S_FALSE },
8242     { 0 }
8243 };
8244
8245 static void test_get_dataType(void)
8246 {
8247     IXMLDOMDocument *doc;
8248     const get_datatype_t *entry = get_datatype;
8249
8250     doc = create_document(&IID_IXMLDOMDocument);
8251
8252     while (entry->type)
8253     {
8254         IXMLDOMNode *node = NULL;
8255         VARIANT var, type;
8256         HRESULT hr;
8257
8258         V_VT(&var) = VT_I4;
8259         V_I4(&var) = entry->type;
8260         hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
8261         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8262
8263         hr = IXMLDOMNode_get_dataType(node, NULL);
8264         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8265
8266         VariantInit(&type);
8267         hr = IXMLDOMNode_get_dataType(node, &type);
8268         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
8269             hr, entry->hr, entry->type);
8270         ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
8271             V_VT(&type), entry->vt, entry->type);
8272         VariantClear(&type);
8273
8274         IXMLDOMNode_Release(node);
8275
8276         entry++;
8277     }
8278
8279     IXMLDOMDocument_Release(doc);
8280     free_bstrs();
8281 }
8282
8283 typedef struct _get_node_typestring_t {
8284     DOMNodeType type;
8285     const char *string;
8286 } get_node_typestring_t;
8287
8288 static const get_node_typestring_t get_node_typestring[] = {
8289     { NODE_ELEMENT,                "element"               },
8290     { NODE_ATTRIBUTE,              "attribute"             },
8291     { NODE_TEXT,                   "text"                  },
8292     { NODE_CDATA_SECTION ,         "cdatasection"          },
8293     { NODE_ENTITY_REFERENCE,       "entityreference"       },
8294     { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
8295     { NODE_COMMENT,                "comment"               },
8296     { NODE_DOCUMENT_FRAGMENT,      "documentfragment"      },
8297     { 0 }
8298 };
8299
8300 static void test_get_nodeTypeString(void)
8301 {
8302     const get_node_typestring_t *entry = get_node_typestring;
8303     IXMLDOMDocument *doc;
8304     HRESULT hr;
8305     BSTR str;
8306
8307     doc = create_document(&IID_IXMLDOMDocument);
8308
8309     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
8310     ok(hr == S_OK, "got 0x%08x\n", hr);
8311     ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
8312     SysFreeString(str);
8313
8314     while (entry->type)
8315     {
8316         IXMLDOMNode *node = NULL;
8317         VARIANT var;
8318
8319         V_VT(&var) = VT_I4;
8320         V_I4(&var) = entry->type;
8321         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
8322         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8323
8324         hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
8325         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8326
8327         hr = IXMLDOMNode_get_nodeTypeString(node, &str);
8328         ok(hr == S_OK, "got 0x%08x\n", hr);
8329         ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
8330             wine_dbgstr_w(str), entry->string, entry->type);
8331         SysFreeString(str);
8332
8333         entry++;
8334     }
8335
8336     IXMLDOMDocument_Release(doc);
8337     free_bstrs();
8338 }
8339
8340 typedef struct _get_attributes_t {
8341     DOMNodeType type;
8342     HRESULT hr;
8343 } get_attributes_t;
8344
8345 static const get_attributes_t get_attributes[] = {
8346     { NODE_ATTRIBUTE,              S_FALSE },
8347     { NODE_TEXT,                   S_FALSE },
8348     { NODE_CDATA_SECTION ,         S_FALSE },
8349     { NODE_ENTITY_REFERENCE,       S_FALSE },
8350     { NODE_PROCESSING_INSTRUCTION, S_FALSE },
8351     { NODE_COMMENT,                S_FALSE },
8352     { NODE_DOCUMENT_FRAGMENT,      S_FALSE },
8353     { 0 }
8354 };
8355
8356 static void test_get_attributes(void)
8357 {
8358     const get_attributes_t *entry = get_attributes;
8359     IXMLDOMNamedNodeMap *map;
8360     IXMLDOMDocument *doc;
8361     IXMLDOMNode *node;
8362     VARIANT_BOOL b;
8363     HRESULT hr;
8364     BSTR str;
8365
8366     doc = create_document(&IID_IXMLDOMDocument);
8367
8368     str = SysAllocString( szComplete3 );
8369     hr = IXMLDOMDocument_loadXML(doc, str, &b);
8370     SysFreeString(str);
8371
8372     hr = IXMLDOMDocument_get_attributes(doc, NULL);
8373     ok(hr == E_INVALIDARG, "got %08x\n", hr);
8374
8375     map = (void*)0xdeadbeef;
8376     hr = IXMLDOMDocument_get_attributes(doc, &map);
8377     ok(hr == S_FALSE, "got %08x\n", hr);
8378     ok(map == NULL, "got %p\n", map);
8379
8380     /* first child is <?xml ?> */
8381     hr = IXMLDOMDocument_get_firstChild(doc, &node);
8382     ok(hr == S_OK, "got %08x\n", hr);
8383
8384     hr = IXMLDOMNode_get_attributes(node, &map);
8385     todo_wine ok(hr == S_OK, "got %08x\n", hr);
8386
8387     if (hr == S_OK)
8388     {
8389         IXMLDOMNode_Release(node);
8390
8391         node = NULL;
8392         hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
8393         ok(hr == S_OK, "got %08x\n", hr);
8394         ok(node != NULL, "got %p\n", node);
8395
8396         hr = IXMLDOMNode_get_nodeName(node, &str);
8397         ok(hr == S_OK, "got %08x\n", hr);
8398         ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
8399         SysFreeString(str);
8400
8401         IXMLDOMNamedNodeMap_Release(map);
8402     }
8403
8404     IXMLDOMNode_Release(node);
8405
8406     while (entry->type)
8407     {
8408         VARIANT var;
8409
8410         node = NULL;
8411
8412         V_VT(&var) = VT_I4;
8413         V_I4(&var) = entry->type;
8414         hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
8415         ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8416
8417         hr = IXMLDOMNode_get_attributes(node, NULL);
8418         ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8419
8420         map = (void*)0xdeadbeef;
8421         hr = IXMLDOMNode_get_attributes(node, &map);
8422         ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
8423             hr, entry->hr, entry->type);
8424         ok(map == NULL, "got %p\n", map);
8425
8426         entry++;
8427     }
8428
8429     IXMLDOMDocument_Release(doc);
8430     free_bstrs();
8431 }
8432
8433 START_TEST(domdoc)
8434 {
8435     IXMLDOMDocument *doc;
8436     HRESULT hr;
8437
8438     hr = CoInitialize( NULL );
8439     ok( hr == S_OK, "failed to init com\n");
8440     if (hr != S_OK)
8441         return;
8442
8443     test_XMLHTTP();
8444
8445     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
8446     if (hr != S_OK)
8447     {
8448         win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
8449         return;
8450     }
8451
8452     IXMLDOMDocument_Release(doc);
8453
8454     test_domdoc();
8455     test_persiststreaminit();
8456     test_domnode();
8457     test_refs();
8458     test_create();
8459     test_getElementsByTagName();
8460     test_get_text();
8461     test_get_childNodes();
8462     test_get_firstChild();
8463     test_get_lastChild();
8464     test_removeChild();
8465     test_replaceChild();
8466     test_removeNamedItem();
8467     test_IXMLDOMDocument2();
8468     test_whitespace();
8469     test_XPath();
8470     test_XSLPattern();
8471     test_cloneNode();
8472     test_xmlTypes();
8473     test_nodeTypeTests();
8474     test_DocumentSaveToDocument();
8475     test_DocumentSaveToFile();
8476     test_testTransforms();
8477     test_Namespaces();
8478     test_FormattingXML();
8479     test_nodeTypedValue();
8480     test_TransformWithLoadingLocalFile();
8481     test_put_nodeValue();
8482     test_document_IObjectSafety();
8483     test_splitText();
8484     test_getQualifiedItem();
8485     test_removeQualifiedItem();
8486     test_get_ownerDocument();
8487     test_setAttributeNode();
8488     test_put_dataType();
8489     test_createNode();
8490     test_get_prefix();
8491     test_default_properties();
8492     test_selectSingleNode();
8493     test_events();
8494     test_createProcessingInstruction();
8495     test_put_nodeTypedValue();
8496     test_get_xml();
8497     test_insertBefore();
8498     test_appendChild();
8499     test_get_doctype();
8500     test_get_tagName();
8501     test_get_dataType();
8502     test_get_nodeTypeString();
8503     test_get_attributes();
8504     test_xsltemplate();
8505
8506     CoUninitialize();
8507 }