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