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