msxml3: Implemented more data types handling xmlnode_get_nodeTypedValue.
[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  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22
23 #define COBJMACROS
24
25 #include "windows.h"
26 #include "ole2.h"
27 #include "xmldom.h"
28 #include "msxml2.h"
29 #include "msxml2did.h"
30 #include "dispex.h"
31 #include <stdio.h>
32 #include <assert.h>
33
34 #include "wine/test.h"
35
36 static const WCHAR szEmpty[] = { 0 };
37 static const WCHAR szIncomplete[] = {
38     '<','?','x','m','l',' ',
39     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
40 };
41 static const WCHAR szComplete1[] = {
42     '<','?','x','m','l',' ',
43     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
44     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
45 };
46 static const WCHAR szComplete2[] = {
47     '<','?','x','m','l',' ',
48     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
49     '<','o','>','<','/','o','>','\n',0
50 };
51 static const WCHAR szComplete3[] = {
52     '<','?','x','m','l',' ',
53     'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
54     '<','a','>','<','/','a','>','\n',0
55 };
56 static const WCHAR szComplete4[] = {
57     '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
58     '<','l','c',' ','d','l','=','\'','s','t','r','1','\'','>','\n',
59         '<','b','s',' ','v','r','=','\'','s','t','r','2','\'',' ','s','z','=','\'','1','2','3','4','\'','>',
60             'f','n','1','.','t','x','t','\n',
61         '<','/','b','s','>','\n',
62         '<','p','r',' ','i','d','=','\'','s','t','r','3','\'',' ','v','r','=','\'','1','.','2','.','3','\'',' ',
63                     'p','n','=','\'','w','i','n','e',' ','2','0','0','5','0','8','0','4','\'','>','\n',
64             'f','n','2','.','t','x','t','\n',
65         '<','/','p','r','>','\n',
66         '<','e','m','p','t','y','>','<','/','e','m','p','t','y','>','\n',
67         '<','f','o','>','\n',
68             '<','b','a','>','\n',
69                 'f','1','\n',
70             '<','/','b','a','>','\n',
71         '<','/','f','o','>','\n',
72     '<','/','l','c','>','\n',0
73 };
74 static const WCHAR szComplete5[] = {
75     '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
76     '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','"',
77     ' ','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','"','>',
78         '<','S',':','s','c','o','p','e','>',
79             '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
80         '<','/','S',':','s','c','o','p','e','>',
81         '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
82             '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
83             'c','o','m','p','u','t','e','r',
84         '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
85     '<','/','S',':','s','e','a','r','c','h','>',0
86 };
87
88 static const CHAR szExampleXML[] =
89 "<?xml version='1.0' encoding='utf-8'?>\n"
90 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
91 "    <elem>\n"
92 "        <a>A1 field</a>\n"
93 "        <b>B1 field</b>\n"
94 "        <c>C1 field</c>\n"
95 "        <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
96 "            <html xmlns='http://www.w3.org/1999/xhtml'>\n"
97 "                This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
98 "            </html>\n"
99 "        </description>\n"
100 "    </elem>\n"
101 "\n"
102 "    <elem>\n"
103 "        <a>A2 field</a>\n"
104 "        <b>B2 field</b>\n"
105 "        <c type=\"old\">C2 field</c>\n"
106 "    </elem>\n"
107 "\n"
108 "    <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
109 "        <a>A3 field</a>\n"
110 "        <b>B3 field</b>\n"
111 "        <c>C3 field</c>\n"
112 "    </elem>\n"
113 "\n"
114 "    <elem>\n"
115 "        <a>A4 field</a>\n"
116 "        <b>B4 field</b>\n"
117 "        <foo:c>C4 field</foo:c>\n"
118 "    </elem>\n"
119 "</root>\n";
120
121 static  const CHAR szTransformXML[] =
122 "<?xml version=\"1.0\"?>\n"
123 "<greeting>\n"
124 "Hello World\n"
125 "</greeting>";
126
127 static  const CHAR szTransformSSXML[] =
128 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
129 "   <xsl:output method=\"html\"/>\n"
130 "   <xsl:template match=\"/\">\n"
131 "       <xsl:apply-templates select=\"greeting\"/>\n"
132 "   </xsl:template>\n"
133 "   <xsl:template match=\"greeting\">\n"
134 "       <html>\n"
135 "           <body>\n"
136 "               <h1>\n"
137 "                   <xsl:value-of select=\".\"/>\n"
138 "               </h1>\n"
139 "           </body>\n"
140 "       </html>\n"
141 "   </xsl:template>\n"
142 "</xsl:stylesheet>";
143
144 static  const CHAR szTransformOutput[] =
145 "<html><body><h1>"
146 "Hello World"
147 "</h1></body></html>";
148
149 static const CHAR szTypeValueXML[] =
150 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
151 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
152 "   <string>Wine</string>\n"
153 "   <string2 dt:dt=\"string\">String</string2>\n"
154 "   <number dt:dt=\"number\">12.44</number>\n"
155 "   <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
156 "   <int dt:dt=\"int\">-13</int>\n"
157 "   <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
158 "   <bool dt:dt=\"boolean\">1</bool>\n"
159 "   <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
160 "   <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
161 "   <date dt:dt=\"date\">3721-11-01</date>\n"
162 "   <time dt:dt=\"time\">13:57:12.31321</time>\n"
163 "   <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
164 "   <i1 dt:dt=\"i1\">-13</i1>\n"
165 "   <i2 dt:dt=\"i2\">31915</i2>\n"
166 "   <i4 dt:dt=\"i4\">-312232</i4>\n"
167 "   <ui1 dt:dt=\"ui1\">123</ui1>\n"
168 "   <ui2 dt:dt=\"ui2\">48282</ui2>\n"
169 "   <ui4 dt:dt=\"ui4\">949281</ui4>\n"
170 "   <r4 dt:dt=\"r4\">213124.0</r4>\n"
171 "   <r8 dt:dt=\"r8\">0.412</r8>\n"
172 "   <float dt:dt=\"float\">41221.421</float>\n"
173 "   <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
174 "</root>";
175
176 static const CHAR szBasicTransformSSXMLPart1[] =
177 "<?xml version=\"1.0\"?>"
178 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
179 "<xsl:output method=\"html\"/>\n"
180 "<xsl:template match=\"/\">"
181 "<HTML><BODY><TABLE>"
182 "        <xsl:apply-templates select='document(\"";
183
184 static const CHAR szBasicTransformSSXMLPart2[] =
185 "\")/bottle/wine'>"
186 "           <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
187 "        </xsl:apply-templates>"
188 "</TABLE></BODY></HTML>"
189 "</xsl:template>"
190 "<xsl:template match=\"bottle\">"
191 "   <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
192 "</xsl:template>"
193 "<xsl:template match=\"name\">"
194 "   <TD><xsl:apply-templates /></TD>"
195 "</xsl:template>"
196 "<xsl:template match=\"cost\">"
197 "   <TD><xsl:apply-templates /></TD>"
198 "</xsl:template>"
199 "</xsl:stylesheet>";
200
201 static const CHAR szBasicTransformXML[] =
202 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
203
204 static const CHAR szBasicTransformOutput[] =
205 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
206
207 static const WCHAR szNonExistentFile[] = {
208     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
209 };
210 static const WCHAR szDocument[] = {
211     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
212 };
213
214 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
215 static WCHAR szdl[] = { 'd','l',0 };
216 static const WCHAR szvr[] = { 'v','r',0 };
217 static const WCHAR szlc[] = { 'l','c',0 };
218 static WCHAR szbs[] = { 'b','s',0 };
219 static const WCHAR szstr1[] = { 's','t','r','1',0 };
220 static const WCHAR szstr2[] = { 's','t','r','2',0 };
221 static const WCHAR szstar[] = { '*',0 };
222 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
223
224 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
225 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
226 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
227
228 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
229 static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
230 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
231 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
232                                 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
233 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
234                                 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
235
236 static WCHAR szAttribute[] = {'A','t','t','r',0 };
237 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
238
239 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
240                           ' ','n','o','t',' ','r','i','g','h','t','!', 0};
241 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
242                              'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
243                              '!',']',']','>',0};
244 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
245 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
246
247 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
248 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
249 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
250
251 #define expect_bstr_eq_and_free(bstr, expect) { \
252     BSTR bstrExp = alloc_str_from_narrow(expect); \
253     ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
254     SysFreeString(bstr); \
255     SysFreeString(bstrExp); \
256 }
257
258 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
259
260 #define ole_check(expr) { \
261     HRESULT r = expr; \
262     ok(r == S_OK, #expr " returned %x\n", r); \
263 }
264
265 #define ole_expect(expr, expect) { \
266     HRESULT r = expr; \
267     ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
268 }
269
270 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
271
272 static BSTR alloc_str_from_narrow(const char *str)
273 {
274     int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
275     BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
276     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
277     return ret;
278 }
279
280 BSTR alloced_bstrs[256];
281 int alloced_bstrs_count = 0;
282
283 static BSTR _bstr_(const char *str)
284 {
285     assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
286     alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
287     return alloced_bstrs[alloced_bstrs_count++];
288 }
289
290 static void free_bstrs(void)
291 {
292     int i;
293     for (i = 0; i < alloced_bstrs_count; i++)
294         SysFreeString(alloced_bstrs[i]);
295     alloced_bstrs_count = 0;
296 }
297
298 static VARIANT _variantbstr_(const char *str)
299 {
300     VARIANT v;
301     V_VT(&v) = VT_BSTR;
302     V_BSTR(&v) = _bstr_(str);
303     return v;
304 }
305
306 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
307 {
308     for (;;)
309     {
310         while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
311         while (*sRight == '\r' || *sRight == '\n') sRight++;
312         if (*sLeft != *sRight) return FALSE;
313         if (!*sLeft) return TRUE;
314         sLeft++;
315         sRight++;
316     }
317 }
318
319 static BOOL compareIgnoreReturnsWhitespace(BSTR sLeft, BSTR sRight)
320 {
321     /* MSXML3 inserts whitespace where as libxml doesn't. */
322     for (;;)
323     {
324         while (*sLeft == '\r' || *sLeft == '\n' || *sLeft == ' ') sLeft++;
325         while (*sRight == '\r' || *sRight == '\n' || *sRight == ' ') sRight++;
326         if (*sLeft != *sRight) return FALSE;
327         if (!*sLeft) return TRUE;
328         sLeft++;
329         sRight++;
330     }
331 }
332
333 static void get_str_for_type(DOMNodeType type, char *buf)
334 {
335     switch (type)
336     {
337         case NODE_ATTRIBUTE:
338             strcpy(buf, "A");
339             break;
340         case NODE_ELEMENT:
341             strcpy(buf, "E");
342             break;
343         case NODE_DOCUMENT:
344             strcpy(buf, "D");
345             break;
346         default:
347             wsprintfA(buf, "[%d]", type);
348     }
349 }
350
351 #define test_disp(u) _test_disp(__LINE__,u)
352 static void _test_disp(unsigned line, IUnknown *unk)
353 {
354     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
355     IDispatchEx *dispex;
356     DWORD dwProps = 0;
357     BSTR sName;
358     UINT ticnt;
359     IUnknown *pUnk;
360     HRESULT hres;
361
362     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
363     ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
364     if(FAILED(hres))
365         return;
366
367     ticnt = 0xdeadbeef;
368     hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
369     ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
370     ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
371
372     sName = SysAllocString( szstar );
373     hres = IDispatchEx_DeleteMemberByName(dispex, sName, fdexNameCaseSensitive);
374     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
375     SysFreeString( sName );
376
377     hres = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
378     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
379
380     hres = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &dwProps);
381     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
382     ok(dwProps == 0, "expected 0 got %d\n", dwProps);
383
384     hres = IDispatchEx_GetMemberName(dispex, dispid, &sName);
385     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
386     if(SUCCEEDED(hres))
387         SysFreeString(sName);
388
389     hres = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
390     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
391
392     hres = IDispatchEx_GetNameSpaceParent(dispex, &pUnk);
393     ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
394     if(hres == S_OK && pUnk)
395         IUnknown_Release(pUnk);
396
397     IDispatchEx_Release(dispex);
398 }
399
400 static int get_node_position(IXMLDOMNode *node)
401 {
402     HRESULT r;
403     int pos = 0;
404
405     IXMLDOMNode_AddRef(node);
406     do
407     {
408         IXMLDOMNode *new_node;
409
410         pos++;
411         r = IXMLDOMNode_get_previousSibling(node, &new_node);
412         ok(SUCCEEDED(r), "get_previousSibling failed\n");
413         IXMLDOMNode_Release(node);
414         node = new_node;
415     } while (r == S_OK);
416     return pos;
417 }
418
419 static void node_to_string(IXMLDOMNode *node, char *buf)
420 {
421     HRESULT r = S_OK;
422     DOMNodeType type;
423
424     if (node == NULL)
425     {
426         lstrcpyA(buf, "(null)");
427         return;
428     }
429
430     IXMLDOMNode_AddRef(node);
431     while (r == S_OK)
432     {
433         IXMLDOMNode *new_node;
434
435         ole_check(IXMLDOMNode_get_nodeType(node, &type));
436         get_str_for_type(type, buf);
437         buf+=strlen(buf);
438
439         if (type == NODE_ATTRIBUTE)
440         {
441             BSTR bstr;
442             ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
443             *(buf++) = '\'';
444             wsprintfA(buf, "%ws", bstr);
445             buf += strlen(buf);
446             *(buf++) = '\'';
447             SysFreeString(bstr);
448
449             r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
450         }
451         else
452         {
453             int pos = get_node_position(node);
454             DOMNodeType parent_type = NODE_INVALID;
455             r = IXMLDOMNode_get_parentNode(node, &new_node);
456
457             /* currently wine doesn't create a node for the <?xml ... ?>. To be able to test query
458              * results we "fix" it */
459             if (r == S_OK)
460                 ole_check(IXMLDOMNode_get_nodeType(new_node, &parent_type));
461             if ((parent_type == NODE_DOCUMENT) && type != NODE_PROCESSING_INSTRUCTION && pos==1)
462             {
463                 todo_wine ok(FALSE, "The first child of the document node in MSXML is the <?xml ... ?> processing instruction\n");
464                 pos++;
465             }
466             wsprintf(buf, "%d", pos);
467             buf += strlen(buf);
468         }
469
470         ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
471         IXMLDOMNode_Release(node);
472         node = new_node;
473         if (r == S_OK)
474             *(buf++) = '.';
475     }
476
477     *buf = 0;
478 }
479
480 static char *list_to_string(IXMLDOMNodeList *list)
481 {
482     static char buf[4096];
483     char *pos = buf;
484     LONG len = 0;
485     int i;
486
487     if (list == NULL)
488     {
489         lstrcpyA(buf, "(null)");
490         return buf;
491     }
492     ole_check(IXMLDOMNodeList_get_length(list, &len));
493     for (i = 0; i < len; i++)
494     {
495         IXMLDOMNode *node;
496         if (i > 0)
497             *(pos++) = ' ';
498         ole_check(IXMLDOMNodeList_nextNode(list, &node));
499         node_to_string(node, pos);
500         pos += strlen(pos);
501         IXMLDOMNode_Release(node);
502     }
503     *pos = 0;
504     return buf;
505 }
506
507 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, exptected %s\n", str, expstr); }
508 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, exptected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
509
510 static void test_domdoc( void )
511 {
512     HRESULT r;
513     IXMLDOMDocument *doc = NULL;
514     IXMLDOMParseError *error;
515     IXMLDOMElement *element = NULL;
516     IXMLDOMNode *node;
517     IXMLDOMText *nodetext = NULL;
518     IXMLDOMComment *node_comment = NULL;
519     IXMLDOMAttribute *node_attr = NULL;
520     IXMLDOMNode *nodeChild = NULL;
521     IXMLDOMProcessingInstruction *nodePI = NULL;
522     ISupportErrorInfo *support_error = NULL;
523     VARIANT_BOOL b;
524     VARIANT var;
525     BSTR str;
526     LONG code;
527     LONG nLength = 0;
528
529     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
530         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
531     if( r != S_OK )
532         return;
533
534     test_disp((IUnknown*)doc);
535
536     /* try some stupid things */
537     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
538     ok( r == S_FALSE, "loadXML failed\n");
539
540     b = VARIANT_TRUE;
541     r = IXMLDOMDocument_loadXML( doc, NULL, &b );
542     ok( r == S_FALSE, "loadXML failed\n");
543     ok( b == VARIANT_FALSE, "failed to load XML string\n");
544
545     /* try to load a document from a nonexistent file */
546     b = VARIANT_TRUE;
547     str = SysAllocString( szNonExistentFile );
548     VariantInit(&var);
549     V_VT(&var) = VT_BSTR;
550     V_BSTR(&var) = str;
551
552     r = IXMLDOMDocument_load( doc, var, &b);
553     ok( r == S_FALSE, "load (from file) failed\n");
554     ok( b == VARIANT_FALSE, "failed to load XML file\n");
555     SysFreeString( str );
556
557     /* try load an empty document */
558     b = VARIANT_TRUE;
559     str = SysAllocString( szEmpty );
560     r = IXMLDOMDocument_loadXML( doc, str, &b );
561     ok( r == S_FALSE, "loadXML failed\n");
562     ok( b == VARIANT_FALSE, "failed to load XML string\n");
563     SysFreeString( str );
564
565     r = IXMLDOMDocument_get_async( doc, &b );
566     ok( r == S_OK, "get_async failed (%08x)\n", r);
567     ok( b == VARIANT_TRUE, "Wrong default value\n");
568
569     /* check that there's no document element */
570     element = NULL;
571     r = IXMLDOMDocument_get_documentElement( doc, &element );
572     ok( r == S_FALSE, "should be no document element\n");
573
574     /* try finding a node */
575     node = NULL;
576     str = SysAllocString( szstr1 );
577     r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
578     ok( r == S_FALSE, "ret %08x\n", r );
579     SysFreeString( str );
580
581     b = VARIANT_TRUE;
582     str = SysAllocString( szIncomplete );
583     r = IXMLDOMDocument_loadXML( doc, str, &b );
584     ok( r == S_FALSE, "loadXML failed\n");
585     ok( b == VARIANT_FALSE, "failed to load XML string\n");
586     SysFreeString( str );
587
588     /* check that there's no document element */
589     element = (IXMLDOMElement*)1;
590     r = IXMLDOMDocument_get_documentElement( doc, &element );
591     ok( r == S_FALSE, "should be no document element\n");
592     ok( element == NULL, "Element should be NULL\n");
593
594     /* try to load something valid */
595     b = VARIANT_FALSE;
596     str = SysAllocString( szComplete1 );
597     r = IXMLDOMDocument_loadXML( doc, str, &b );
598     ok( r == S_OK, "loadXML failed\n");
599     ok( b == VARIANT_TRUE, "failed to load XML string\n");
600     SysFreeString( str );
601
602     /* check if nodename is correct */
603     r = IXMLDOMDocument_get_nodeName( doc, NULL );
604     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
605
606     /* content doesn't matter here */
607     str = NULL;
608     r = IXMLDOMDocument_get_nodeName( doc, &str );
609     ok ( r == S_OK, "get_nodeName wrong code\n");
610     ok ( str != NULL, "str is null\n");
611     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
612     SysFreeString( str );
613
614     /* test put_text */
615     r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
616     ok( r == E_FAIL, "ret %08x\n", r );
617
618     /* check that there's a document element */
619     element = NULL;
620     r = IXMLDOMDocument_get_documentElement( doc, &element );
621     ok( r == S_OK, "should be a document element\n");
622     if( element )
623     {
624         IObjectIdentity *ident;
625         BSTR tag = NULL;
626
627         test_disp((IUnknown*)element);
628
629         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (LPVOID*)&ident );
630         ok( r == E_NOINTERFACE, "ret %08x\n", r);
631
632         /* check if the tag is correct */
633         r = IXMLDOMElement_get_tagName( element, &tag );
634         ok( r == S_OK, "couldn't get tag name\n");
635         ok( tag != NULL, "tag was null\n");
636         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
637         SysFreeString( tag );
638
639         /* figure out what happens if we try to reload the document */
640         str = SysAllocString( szComplete2 );
641         r = IXMLDOMDocument_loadXML( doc, str, &b );
642         ok( r == S_OK, "loadXML failed\n");
643         ok( b == VARIANT_TRUE, "failed to load XML string\n");
644         SysFreeString( str );
645
646         /* check if the tag is still correct */
647         tag = NULL;
648         r = IXMLDOMElement_get_tagName( element, &tag );
649         ok( r == S_OK, "couldn't get tag name\n");
650         ok( tag != NULL, "tag was null\n");
651         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
652         SysFreeString( tag );
653
654         IXMLDOMElement_Release( element );
655         element = NULL;
656     }
657
658     /* as soon as we call loadXML again, the document element will disappear */
659     b = 2;
660     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
661     ok( r == S_FALSE, "loadXML failed\n");
662     ok( b == 2, "variant modified\n");
663     r = IXMLDOMDocument_get_documentElement( doc, &element );
664     ok( r == S_FALSE, "should be no document element\n");
665
666     /* try to load something else simple and valid */
667     b = VARIANT_FALSE;
668     str = SysAllocString( szComplete3 );
669     r = IXMLDOMDocument_loadXML( doc, str, &b );
670     ok( r == S_OK, "loadXML failed\n");
671     ok( b == VARIANT_TRUE, "failed to load XML string\n");
672     SysFreeString( str );
673
674     /* try something a little more complicated */
675     b = FALSE;
676     str = SysAllocString( szComplete4 );
677     r = IXMLDOMDocument_loadXML( doc, str, &b );
678     ok( r == S_OK, "loadXML failed\n");
679     ok( b == VARIANT_TRUE, "failed to load XML string\n");
680     SysFreeString( str );
681
682     r = IXMLDOMDocument_get_parseError( doc, &error );
683     ok( r == S_OK, "returns %08x\n", r );
684
685     r = IXMLDOMParseError_get_errorCode( error, &code );
686     ok( r == S_FALSE, "returns %08x\n", r );
687     ok( code == 0, "code %d\n", code );
688     IXMLDOMParseError_Release( error );
689
690      /* test createTextNode */
691     str = SysAllocString( szOpen );
692     r = IXMLDOMDocument_createTextNode(doc, str, NULL);
693     ok( r == E_INVALIDARG, "returns %08x\n", r );
694     r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
695     ok( r == S_OK, "returns %08x\n", r );
696     SysFreeString( str );
697     if(nodetext)
698     {
699         IXMLDOMNamedNodeMap *pAttribs;
700
701         r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (LPVOID*)&element);
702         ok(r == E_NOINTERFACE, "ret %08x\n", r );
703
704         /* Text Last Child Checks */
705         r = IXMLDOMText_get_lastChild(nodetext, NULL);
706         ok(r == E_INVALIDARG, "ret %08x\n", r );
707
708         nodeChild = (IXMLDOMNode*)0x1;
709         r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
710         ok(r == S_FALSE, "ret %08x\n", r );
711         ok(nodeChild == NULL, "nodeChild not NULL\n");
712
713         /* test get_attributes */
714         r = IXMLDOMText_get_attributes( nodetext, NULL );
715         ok( r == E_INVALIDARG, "get_attributes returned wrong code\n");
716
717         pAttribs = (IXMLDOMNamedNodeMap*)0x1;
718         r = IXMLDOMText_get_attributes( nodetext, &pAttribs);
719         ok(r == S_FALSE, "ret %08x\n", r );
720         ok( pAttribs == NULL, "pAttribs not NULL\n");
721
722         /* test get_dataType */
723         r = IXMLDOMText_get_dataType(nodetext, &var);
724         ok(r == S_FALSE, "ret %08x\n", r );
725         ok( V_VT(&var) == VT_NULL, "incorrect dataType type\n");
726         VariantClear(&var);
727
728         /* test length property */
729         r = IXMLDOMText_get_length(nodetext, NULL);
730         ok(r == E_INVALIDARG, "ret %08x\n", r );
731
732         r = IXMLDOMText_get_length(nodetext, &nLength);
733         ok(r == S_OK, "ret %08x\n", r );
734         ok(nLength == 4, "expected 4 got %d\n", nLength);
735
736         /* test nodeTypeString */
737         r = IXMLDOMText_get_nodeTypeString(nodetext, &str);
738         ok(r == S_OK, "ret %08x\n", r );
739         ok( !lstrcmpW( str, _bstr_("text") ), "incorrect nodeTypeString string\n");
740         SysFreeString(str);
741
742         /* put data Tests */
743         r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
744         ok(r == S_OK, "ret %08x\n", r );
745
746         /* get data Tests */
747         r = IXMLDOMText_get_data(nodetext, &str);
748         ok(r == S_OK, "ret %08x\n", r );
749         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
750         SysFreeString(str);
751
752         /* Confirm XML text is good */
753         r = IXMLDOMText_get_xml(nodetext, &str);
754         ok(r == S_OK, "ret %08x\n", r );
755         ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
756         SysFreeString(str);
757
758         /* Confirm we get the put_data Text back */
759         r = IXMLDOMText_get_text(nodetext, &str);
760         ok(r == S_OK, "ret %08x\n", r );
761         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
762         SysFreeString(str);
763
764         /* test substringData */
765         r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
766         ok(r == E_INVALIDARG, "ret %08x\n", r );
767
768         /* test substringData - Invalid offset */
769         str = (BSTR)&szElement;
770         r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
771         ok(r == E_INVALIDARG, "ret %08x\n", r );
772         ok( str == NULL, "incorrect string\n");
773
774         /* test substringData - Invalid offset */
775         str = (BSTR)&szElement;
776         r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
777         ok(r == S_FALSE, "ret %08x\n", r );
778         ok( str == NULL, "incorrect string\n");
779
780         /* test substringData - Invalid size */
781         str = (BSTR)&szElement;
782         r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
783         ok(r == E_INVALIDARG, "ret %08x\n", r );
784         ok( str == NULL, "incorrect string\n");
785
786         /* test substringData - Invalid size */
787         str = (BSTR)&szElement;
788         r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
789         ok(r == S_FALSE, "ret %08x\n", r );
790         ok( str == NULL, "incorrect string\n");
791
792         /* test substringData - Start of string */
793         r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
794         ok(r == S_OK, "ret %08x\n", r );
795         ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
796         SysFreeString(str);
797
798         /* test substringData - Middle of string */
799         r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
800         ok(r == S_OK, "ret %08x\n", r );
801         ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
802         SysFreeString(str);
803
804         /* test substringData - End of string */
805         r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
806         ok(r == S_OK, "ret %08x\n", r );
807         ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
808         SysFreeString(str);
809
810         /* test appendData */
811         r = IXMLDOMText_appendData(nodetext, NULL);
812         ok(r == S_OK, "ret %08x\n", r );
813
814         r = IXMLDOMText_appendData(nodetext, _bstr_(""));
815         ok(r == S_OK, "ret %08x\n", r );
816
817         r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
818         ok(r == S_OK, "ret %08x\n", r );
819
820         r = IXMLDOMText_get_text(nodetext, &str);
821         ok(r == S_OK, "ret %08x\n", r );
822         ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
823         SysFreeString(str);
824
825         /* test insertData */
826         str = SysAllocStringLen(NULL, 0);
827         r = IXMLDOMText_insertData(nodetext, -1, str);
828         ok(r == S_OK, "ret %08x\n", r );
829
830         r = IXMLDOMText_insertData(nodetext, -1, NULL);
831         ok(r == S_OK, "ret %08x\n", r );
832
833         r = IXMLDOMText_insertData(nodetext, 1000, str);
834         ok(r == S_OK, "ret %08x\n", r );
835
836         r = IXMLDOMText_insertData(nodetext, 1000, NULL);
837         ok(r == S_OK, "ret %08x\n", r );
838
839         r = IXMLDOMText_insertData(nodetext, 0, NULL);
840         ok(r == S_OK, "ret %08x\n", r );
841
842         r = IXMLDOMText_insertData(nodetext, 0, str);
843         ok(r == S_OK, "ret %08x\n", r );
844         SysFreeString(str);
845
846         r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
847         ok(r == E_INVALIDARG, "ret %08x\n", r );
848
849         r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
850         ok(r == E_INVALIDARG, "ret %08x\n", r );
851
852         r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
853         ok(r == S_OK, "ret %08x\n", r );
854
855         r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
856         ok(r == S_OK, "ret %08x\n", r );
857
858         r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
859         ok(r == S_OK, "ret %08x\n", r );
860
861         r = IXMLDOMText_get_text(nodetext, &str);
862         ok(r == S_OK, "ret %08x\n", r );
863         ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
864         SysFreeString(str);
865
866         /* test put_data */
867         V_VT(&var) = VT_BSTR;
868         V_BSTR(&var) = SysAllocString(szstr1);
869         r = IXMLDOMText_put_nodeValue(nodetext, var);
870         ok(r == S_OK, "ret %08x\n", r );
871         VariantClear(&var);
872
873         r = IXMLDOMText_get_text(nodetext, &str);
874         ok(r == S_OK, "ret %08x\n", r );
875         ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string\n");
876         SysFreeString(str);
877
878         /* test put_data */
879         V_VT(&var) = VT_I4;
880         V_I4(&var) = 99;
881         r = IXMLDOMText_put_nodeValue(nodetext, var);
882         ok(r == S_OK, "ret %08x\n", r );
883         VariantClear(&var);
884
885         r = IXMLDOMText_get_text(nodetext, &str);
886         ok(r == S_OK, "ret %08x\n", r );
887         ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string\n");
888         SysFreeString(str);
889
890         IXMLDOMText_Release( nodetext );
891     }
892
893     /* test Create Comment */
894     r = IXMLDOMDocument_createComment(doc, NULL, NULL);
895     ok( r == E_INVALIDARG, "returns %08x\n", r );
896     r = IXMLDOMDocument_createComment(doc, szComment, &node_comment);
897     ok( r == S_OK, "returns %08x\n", r );
898     if(node_comment)
899     {
900         /* Last Child Checks */
901         r = IXMLDOMComment_get_lastChild(node_comment, NULL);
902         ok(r == E_INVALIDARG, "ret %08x\n", r );
903
904         nodeChild = (IXMLDOMNode*)0x1;
905         r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
906         ok(r == S_FALSE, "ret %08x\n", r );
907         ok(nodeChild == NULL, "pLastChild not NULL\n");
908
909         IXMLDOMComment_Release( node_comment );
910     }
911
912     /* test Create Attribute */
913     r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
914     ok( r == E_INVALIDARG, "returns %08x\n", r );
915     r = IXMLDOMDocument_createAttribute(doc, szAttribute, &node_attr);
916     ok( r == S_OK, "returns %08x\n", r );
917     IXMLDOMText_Release( node_attr);
918
919     /* test Processing Instruction */
920     str = SysAllocStringLen(NULL, 0);
921     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
922     ok( r == E_INVALIDARG, "returns %08x\n", r );
923     r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
924     ok( r == E_FAIL, "returns %08x\n", r );
925     r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
926     ok( r == E_FAIL, "returns %08x\n", r );
927     SysFreeString(str);
928
929     r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
930     ok( r == S_OK, "returns %08x\n", r );
931     if(nodePI)
932     {
933         /* Last Child Checks */
934         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
935         ok(r == E_INVALIDARG, "ret %08x\n", r );
936
937         nodeChild = (IXMLDOMNode*)0x1;
938         r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
939         ok(r == S_FALSE, "ret %08x\n", r );
940         ok(nodeChild == NULL, "nodeChild not NULL\n");
941
942         r = IXMLDOMProcessingInstruction_get_dataType(nodePI, &var);
943         ok(r == S_FALSE, "ret %08x\n", r );
944         ok( V_VT(&var) == VT_NULL, "incorrect dataType type\n");
945         VariantClear(&var);
946
947         /* test nodeName */
948         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
949         ok(r == S_OK, "ret %08x\n", r );
950         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
951         SysFreeString(str);
952
953         /* test Target */
954         r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
955         ok(r == S_OK, "ret %08x\n", r );
956         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
957         SysFreeString(str);
958
959         /* test nodeTypeString */
960         r = IXMLDOMProcessingInstruction_get_nodeTypeString(nodePI, &str);
961         ok(r == S_OK, "ret %08x\n", r );
962         ok( !lstrcmpW( str, _bstr_("processinginstruction") ), "incorrect nodeTypeString string\n");
963         SysFreeString(str);
964
965         /* test get_nodeValue */
966         r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
967         ok(r == S_OK, "ret %08x\n", r );
968         ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
969         VariantClear(&var);
970
971         /* test get_data */
972         r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
973         ok(r == S_OK, "ret %08x\n", r );
974         ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
975         SysFreeString(str);
976
977         /* test put_data */
978         r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
979         ok(r == E_FAIL, "ret %08x\n", r );
980
981         /* test put_data */
982         V_VT(&var) = VT_BSTR;
983         V_BSTR(&var) = SysAllocString(szOpen);  /* Doesn't matter what the string is, cannot set an xml node. */
984         r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
985         ok(r == E_FAIL, "ret %08x\n", r );
986         VariantClear(&var);
987
988         /* test get nodeName */
989         r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
990         ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
991         ok(r == S_OK, "ret %08x\n", r );
992         SysFreeString(str);
993
994         IXMLDOMProcessingInstruction_Release(nodePI);
995     }
996
997     r = IXMLDOMDocument_QueryInterface( doc, &IID_ISupportErrorInfo, (LPVOID*)&support_error );
998     ok( r == S_OK, "ret %08x\n", r );
999     if(r == S_OK)
1000     {
1001         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMDocument );
1002         todo_wine ok( r == S_OK, "ret %08x\n", r );
1003         ISupportErrorInfo_Release( support_error );
1004     }
1005
1006     r = IXMLDOMDocument_Release( doc );
1007     ok( r == 0, "document ref count incorrect\n");
1008
1009     free_bstrs();
1010 }
1011
1012 static void test_domnode( void )
1013 {
1014     HRESULT r;
1015     IXMLDOMDocument *doc = NULL, *owner = NULL;
1016     IXMLDOMElement *element = NULL;
1017     IXMLDOMNamedNodeMap *map = NULL;
1018     IXMLDOMNode *node = NULL, *next = NULL;
1019     IXMLDOMNodeList *list = NULL;
1020     IXMLDOMAttribute *attr = NULL;
1021     DOMNodeType type = NODE_INVALID;
1022     VARIANT_BOOL b;
1023     BSTR str;
1024     VARIANT var;
1025     LONG count;
1026
1027     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1028         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1029     if( r != S_OK )
1030         return;
1031
1032     b = FALSE;
1033     str = SysAllocString( szComplete4 );
1034     r = IXMLDOMDocument_loadXML( doc, str, &b );
1035     ok( r == S_OK, "loadXML failed\n");
1036     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1037     SysFreeString( str );
1038
1039     if (doc)
1040     {
1041         b = 1;
1042         r = IXMLDOMNode_hasChildNodes( doc, &b );
1043         ok( r == S_OK, "hasChildNoes bad return\n");
1044         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1045
1046         r = IXMLDOMDocument_get_documentElement( doc, &element );
1047         ok( r == S_OK, "should be a document element\n");
1048         ok( element != NULL, "should be an element\n");
1049     }
1050     else
1051         ok( FALSE, "no document\n");
1052
1053     VariantInit(&var);
1054     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1055
1056     r = IXMLDOMNode_get_nodeValue( doc, NULL );
1057     ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
1058
1059     r = IXMLDOMNode_get_nodeValue( doc, &var );
1060     ok( r == S_FALSE, "nextNode returned wrong code\n");
1061     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1062     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1063
1064     if (element)
1065     {
1066         owner = NULL;
1067         r = IXMLDOMNode_get_ownerDocument( element, &owner );
1068         ok( r == S_OK, "get_ownerDocument return code\n");
1069         ok( owner != doc, "get_ownerDocument return\n");
1070
1071         type = NODE_INVALID;
1072         r = IXMLDOMNode_get_nodeType( element, &type);
1073         ok( r == S_OK, "getNamedItem returned wrong code\n");
1074         ok( type == NODE_ELEMENT, "node not an element\n");
1075
1076         str = NULL;
1077         r = IXMLDOMNode_get_baseName( element, &str );
1078         ok( r == S_OK, "get_baseName returned wrong code\n");
1079         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
1080         SysFreeString(str);
1081
1082         /* check if nodename is correct */
1083         r = IXMLDOMElement_get_nodeName( element, NULL );
1084         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1085     
1086         /* content doesn't matter here */
1087         str = NULL;
1088         r = IXMLDOMElement_get_nodeName( element, &str );
1089         ok ( r == S_OK, "get_nodeName wrong code\n");
1090         ok ( str != NULL, "str is null\n");
1091         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
1092         SysFreeString( str );
1093
1094         str = SysAllocString( szNonExistentFile );      
1095         V_VT(&var) = VT_I4;
1096         V_I4(&var) = 0x1234;
1097         r = IXMLDOMElement_getAttribute( element, str, &var );
1098         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
1099         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
1100         VariantClear(&var);
1101
1102         r = IXMLDOMElement_getAttributeNode( element, str, NULL);
1103         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1104
1105         attr = (IXMLDOMAttribute*)0xdeadbeef;
1106         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1107         ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1108         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1109         SysFreeString( str );
1110
1111         attr = (IXMLDOMAttribute*)0xdeadbeef;
1112         str = _bstr_("nonExisitingAttribute");
1113         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1114         ok( r == S_FALSE, "getAttributeNode ret %08x\n", r );
1115         ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1116         SysFreeString( str );
1117
1118         str = SysAllocString( szdl );   
1119         V_VT(&var) = VT_I4;
1120         V_I4(&var) = 0x1234;
1121         r = IXMLDOMElement_getAttribute( element, str, &var );
1122         ok( r == S_OK, "getAttribute ret %08x\n", r );
1123         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
1124         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
1125         VariantClear( &var );
1126
1127         r = IXMLDOMElement_getAttribute( element, NULL, &var );
1128         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1129
1130         r = IXMLDOMElement_getAttribute( element, str, NULL );
1131         ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1132
1133         attr = NULL;
1134         r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1135         ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
1136         ok( attr != NULL, "getAttributeNode returned NULL\n" );
1137         if(attr)
1138             IXMLDOMAttribute_Release(attr);
1139
1140         SysFreeString( str );
1141
1142         r = IXMLDOMElement_get_attributes( element, &map );
1143         ok( r == S_OK, "get_attributes returned wrong code\n");
1144         ok( map != NULL, "should be attributes\n");
1145
1146         b = 1;
1147         r = IXMLDOMNode_hasChildNodes( element, &b );
1148         ok( r == S_OK, "hasChildNoes bad return\n");
1149         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1150     }
1151     else
1152         ok( FALSE, "no element\n");
1153
1154     if (map)
1155     {
1156         ISupportErrorInfo *support_error;
1157         r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (LPVOID*)&support_error );
1158         ok( r == S_OK, "ret %08x\n", r );
1159
1160         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
1161 todo_wine
1162 {
1163         ok( r == S_OK, "ret %08x\n", r );
1164 }
1165         ISupportErrorInfo_Release( support_error );
1166
1167         str = SysAllocString( szdl );
1168         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1169         ok( r == S_OK, "getNamedItem returned wrong code\n");
1170         ok( node != NULL, "should be attributes\n");
1171         IXMLDOMNode_Release(node);
1172         SysFreeString( str );
1173
1174         str = SysAllocString( szdl );
1175         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
1176         ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
1177         SysFreeString( str );
1178
1179         /* something that isn't in szComplete4 */
1180         str = SysAllocString( szOpen );
1181         node = (IXMLDOMNode *) 1;
1182         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1183         ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
1184         ok( node == NULL, "getNamedItem should have returned NULL\n");
1185         SysFreeString( str );
1186
1187         /* test indexed access of attributes */
1188         r = IXMLDOMNamedNodeMap_get_length( map, NULL );
1189         ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
1190
1191         r = IXMLDOMNamedNodeMap_get_length( map, &count );
1192         ok ( r == S_OK, "get_length wrong code\n");
1193         ok ( count == 1, "get_length != 1\n");
1194
1195         node = NULL;
1196         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
1197         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
1198         ok ( node == NULL, "there is no node\n");
1199
1200         node = NULL;
1201         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
1202         ok ( r == S_FALSE, "get_item (1) wrong code\n");
1203         ok ( node == NULL, "there is no attribute\n");
1204
1205         node = NULL;
1206         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
1207         ok ( r == S_OK, "get_item (0) wrong code\n");
1208         ok ( node != NULL, "should be attribute\n");
1209
1210         r = IXMLDOMNode_get_nodeName( node, NULL );
1211         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1212
1213         /* content doesn't matter here */
1214         str = NULL;
1215         r = IXMLDOMNode_get_nodeName( node, &str );
1216         ok ( r == S_OK, "get_nodeName wrong code\n");
1217         ok ( str != NULL, "str is null\n");
1218         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
1219         SysFreeString( str );
1220
1221         /* test sequential access of attributes */
1222         node = NULL;
1223         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1224         ok ( r == S_OK, "nextNode (first time) wrong code\n");
1225         ok ( node != NULL, "nextNode, should be attribute\n");
1226
1227         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1228         ok ( r != S_OK, "nextNode (second time) wrong code\n");
1229         ok ( node == NULL, "nextNode, there is no attribute\n");
1230
1231         r = IXMLDOMNamedNodeMap_reset( map );
1232         ok ( r == S_OK, "reset should return S_OK\n");
1233
1234         r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1235         ok ( r == S_OK, "nextNode (third time) wrong code\n");
1236         ok ( node != NULL, "nextNode, should be attribute\n");
1237     }
1238     else
1239         ok( FALSE, "no map\n");
1240
1241     if (node)
1242     {
1243         type = NODE_INVALID;
1244         r = IXMLDOMNode_get_nodeType( node, &type);
1245         ok( r == S_OK, "getNamedItem returned wrong code\n");
1246         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
1247
1248         str = NULL;
1249         r = IXMLDOMNode_get_baseName( node, NULL );
1250         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
1251
1252         str = NULL;
1253         r = IXMLDOMNode_get_baseName( node, &str );
1254         ok( r == S_OK, "get_baseName returned wrong code\n");
1255         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
1256         SysFreeString( str );
1257
1258         r = IXMLDOMNode_get_nodeValue( node, &var );
1259         ok( r == S_OK, "returns %08x\n", r );
1260         ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
1261         ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
1262         VariantClear(&var);
1263
1264         r = IXMLDOMNode_get_childNodes( node, NULL );
1265         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
1266
1267         r = IXMLDOMNode_get_childNodes( node, &list );
1268         ok( r == S_OK, "get_childNodes returned wrong code\n");
1269
1270         if (list)
1271         {
1272             r = IXMLDOMNodeList_nextNode( list, &next );
1273             ok( r == S_OK, "nextNode returned wrong code\n");
1274         }
1275         else
1276             ok( FALSE, "no childlist\n");
1277
1278         if (next)
1279         {
1280             b = 1;
1281             r = IXMLDOMNode_hasChildNodes( next, &b );
1282             ok( r == S_FALSE, "hasChildNoes bad return\n");
1283             ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
1284
1285             type = NODE_INVALID;
1286             r = IXMLDOMNode_get_nodeType( next, &type);
1287             ok( r == S_OK, "getNamedItem returned wrong code\n");
1288             ok( type == NODE_TEXT, "node not text\n");
1289
1290             str = (BSTR) 1;
1291             r = IXMLDOMNode_get_baseName( next, &str );
1292             ok( r == S_FALSE, "get_baseName returned wrong code\n");
1293             ok( str == NULL, "basename was wrong\n");
1294             SysFreeString(str);
1295         }
1296         else
1297             ok( FALSE, "no next\n");
1298
1299         if (next)
1300             IXMLDOMNode_Release( next );
1301         next = NULL;
1302         if (list)
1303             IXMLDOMNodeList_Release( list );
1304         list = NULL;
1305         if (node)
1306             IXMLDOMNode_Release( node );
1307     }
1308     else
1309         ok( FALSE, "no node\n");
1310     node = NULL;
1311
1312     if (map)
1313         IXMLDOMNamedNodeMap_Release( map );
1314
1315     /* now traverse the tree from the root element */
1316     if (element)
1317     {
1318         IXMLDOMNode *node;
1319         r = IXMLDOMNode_get_childNodes( element, &list );
1320         ok( r == S_OK, "get_childNodes returned wrong code\n");
1321
1322         /* using get_item for child list doesn't advance the position */
1323         ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
1324         expect_node(node, "E2.E2.D1");
1325         IXMLDOMNode_Release(node);
1326         ole_check(IXMLDOMNodeList_nextNode(list, &node));
1327         expect_node(node, "E1.E2.D1");
1328         IXMLDOMNode_Release(node);
1329         ole_check(IXMLDOMNodeList_reset(list));
1330
1331         IXMLDOMNodeList_AddRef(list);
1332         expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
1333         ole_check(IXMLDOMNodeList_reset(list));
1334     }
1335     else
1336         ok( FALSE, "no element\n");
1337
1338     node = (void*)0xdeadbeef;
1339     r = IXMLDOMNode_selectSingleNode( element, szdl, &node );
1340     ok( r == S_FALSE, "ret %08x\n", r );
1341     ok( node == NULL, "node %p\n", node );
1342     r = IXMLDOMNode_selectSingleNode( element, szbs, &node );
1343     ok( r == S_OK, "ret %08x\n", r );
1344     r = IXMLDOMNode_Release( node );
1345     ok( r == 0, "ret %08x\n", r );
1346
1347     if (list)
1348     {
1349         r = IXMLDOMNodeList_QueryInterface(list, &IID_IDispatch, NULL);
1350         ok( r == E_INVALIDARG || r == E_POINTER, "ret %08x\n", r );
1351
1352         r = IXMLDOMNodeList_get_item(list, 0, NULL);
1353         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1354
1355         r = IXMLDOMNodeList_get_length(list, NULL);
1356         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1357
1358         r = IXMLDOMNodeList_get_length( list, &count );
1359         ok( r == S_OK, "get_length returns %08x\n", r );
1360         ok( count == 4, "get_length got %d\n", count );
1361
1362         r = IXMLDOMNodeList_nextNode(list, NULL);
1363         ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1364
1365         r = IXMLDOMNodeList_nextNode( list, &node );
1366         ok( r == S_OK, "nextNode returned wrong code\n");
1367     }
1368     else
1369         ok( FALSE, "no list\n");
1370
1371     if (node)
1372     {
1373         type = NODE_INVALID;
1374         r = IXMLDOMNode_get_nodeType( node, &type);
1375         ok( r == S_OK, "getNamedItem returned wrong code\n");
1376         ok( type == NODE_ELEMENT, "node not text\n");
1377
1378         VariantInit(&var);
1379         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1380         r = IXMLDOMNode_get_nodeValue( node, &var );
1381         ok( r == S_FALSE, "nextNode returned wrong code\n");
1382         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1383         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1384
1385         r = IXMLDOMNode_hasChildNodes( node, NULL );
1386         ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
1387
1388         b = 1;
1389         r = IXMLDOMNode_hasChildNodes( node, &b );
1390         ok( r == S_OK, "hasChildNoes bad return\n");
1391         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1392
1393         str = NULL;
1394         r = IXMLDOMNode_get_baseName( node, &str );
1395         ok( r == S_OK, "get_baseName returned wrong code\n");
1396         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
1397         SysFreeString(str);
1398     }
1399     else
1400         ok( FALSE, "no node\n");
1401
1402     if (node)
1403         IXMLDOMNode_Release( node );
1404     if (list)
1405         IXMLDOMNodeList_Release( list );
1406     if (element)
1407         IXMLDOMElement_Release( element );
1408
1409     b = FALSE;
1410     str = SysAllocString( szComplete5 );
1411     r = IXMLDOMDocument_loadXML( doc, str, &b );
1412     ok( r == S_OK, "loadXML failed\n");
1413     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1414     SysFreeString( str );
1415
1416     b = 1;
1417     r = IXMLDOMNode_hasChildNodes( doc, &b );
1418     ok( r == S_OK, "hasChildNoes bad return\n");
1419     ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1420
1421     r = IXMLDOMDocument_get_documentElement( doc, &element );
1422     ok( r == S_OK, "should be a document element\n");
1423     ok( element != NULL, "should be an element\n");
1424
1425     if (element)
1426     {
1427         static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
1428         BSTR tag = NULL;
1429
1430         /* check if the tag is correct */
1431         r = IXMLDOMElement_get_tagName( element, &tag );
1432         ok( r == S_OK, "couldn't get tag name\n");
1433         ok( tag != NULL, "tag was null\n");
1434         ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
1435         SysFreeString( tag );
1436     }
1437
1438     if (element)
1439         IXMLDOMElement_Release( element );
1440     if (doc)
1441         ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
1442 }
1443
1444 static void test_refs(void)
1445 {
1446     HRESULT r;
1447     BSTR str;
1448     VARIANT_BOOL b;
1449     IXMLDOMDocument *doc = NULL;
1450     IXMLDOMElement *element = NULL;
1451     IXMLDOMNode *node = NULL, *node2;
1452     IXMLDOMNodeList *node_list = NULL;
1453     LONG ref;
1454     IUnknown *unk, *unk2;
1455
1456     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1457         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1458     if( r != S_OK )
1459         return;
1460     ref = IXMLDOMDocument_Release(doc);
1461     ok( ref == 0, "ref %d\n", ref);
1462
1463     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1464         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1465     if( r != S_OK )
1466         return;
1467
1468     str = SysAllocString( szComplete4 );
1469     r = IXMLDOMDocument_loadXML( doc, str, &b );
1470     ok( r == S_OK, "loadXML failed\n");
1471     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1472     SysFreeString( str );
1473
1474     ref = IXMLDOMDocument_AddRef( doc );
1475     ok( ref == 2, "ref %d\n", ref );
1476     ref = IXMLDOMDocument_AddRef( doc );
1477     ok( ref == 3, "ref %d\n", ref );
1478     IXMLDOMDocument_Release( doc );
1479     IXMLDOMDocument_Release( doc );
1480
1481     r = IXMLDOMDocument_get_documentElement( doc, &element );
1482     ok( r == S_OK, "should be a document element\n");
1483     ok( element != NULL, "should be an element\n");
1484
1485     ref = IXMLDOMDocument_AddRef( doc );
1486     ok( ref == 2, "ref %d\n", ref );
1487     IXMLDOMDocument_Release( doc );
1488
1489     r = IXMLDOMElement_get_childNodes( element, &node_list );
1490     ok( r == S_OK, "rets %08x\n", r);
1491
1492     ref = IXMLDOMNodeList_AddRef( node_list );
1493     ok( ref == 2, "ref %d\n", ref );
1494     IXMLDOMNodeList_Release( node_list );
1495
1496     IXMLDOMNodeList_get_item( node_list, 0, &node );
1497     ok( r == S_OK, "rets %08x\n", r);
1498
1499     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
1500     ok( r == S_OK, "rets %08x\n", r);
1501
1502     ref = IXMLDOMNode_AddRef( node );
1503     ok( ref == 2, "ref %d\n", ref );
1504     IXMLDOMNode_Release( node );
1505
1506     ref = IXMLDOMNode_Release( node );
1507     ok( ref == 0, "ref %d\n", ref );
1508     ref = IXMLDOMNode_Release( node2 );
1509     ok( ref == 0, "ref %d\n", ref );
1510
1511     ref = IXMLDOMNodeList_Release( node_list );
1512     ok( ref == 0, "ref %d\n", ref );
1513
1514     ok( node != node2, "node %p node2 %p\n", node, node2 );
1515
1516     ref = IXMLDOMDocument_Release( doc );
1517     ok( ref == 0, "ref %d\n", ref );
1518
1519     ref = IXMLDOMElement_AddRef( element );
1520     todo_wine {
1521     ok( ref == 3, "ref %d\n", ref );
1522     }
1523     IXMLDOMElement_Release( element );
1524
1525     /* IUnknown must be unique however we obtain it */
1526     r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (LPVOID*)&unk );
1527     ok( r == S_OK, "rets %08x\n", r );
1528     r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (LPVOID*)&node );
1529     ok( r == S_OK, "rets %08x\n", r );
1530     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk2 );
1531     ok( r == S_OK, "rets %08x\n", r );
1532     ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
1533
1534     IUnknown_Release( unk2 );
1535     IUnknown_Release( unk );
1536     IXMLDOMNode_Release( node );
1537
1538     IXMLDOMElement_Release( element );
1539
1540 }
1541
1542 static void test_create(void)
1543 {
1544     static const WCHAR szOne[] = {'1',0};
1545     static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
1546     HRESULT r;
1547     VARIANT var;
1548     BSTR str, name;
1549     IXMLDOMDocument *doc;
1550     IXMLDOMElement *element;
1551     IXMLDOMNode *root, *node, *child;
1552     IXMLDOMNamedNodeMap *attr_map;
1553     IUnknown *unk;
1554     LONG ref;
1555     LONG num;
1556
1557     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1558         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1559     if( r != S_OK )
1560         return;
1561
1562     V_VT(&var) = VT_I1;
1563     V_I1(&var) = NODE_ELEMENT;
1564     str = SysAllocString( szlc );
1565     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1566     ok( r == S_OK, "returns %08x\n", r );
1567     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
1568
1569     V_VT(&var) = VT_R4;
1570     V_R4(&var) = NODE_ELEMENT;
1571     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1572     ok( r == S_OK, "returns %08x\n", r );
1573     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
1574
1575     V_VT(&var) = VT_BSTR;
1576     V_BSTR(&var) = SysAllocString( szOne );
1577     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1578     ok( r == S_OK, "returns %08x\n", r );
1579     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
1580     VariantClear(&var);
1581
1582     V_VT(&var) = VT_BSTR;
1583     V_BSTR(&var) = SysAllocString( szOneGarbage );
1584     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1585     ok( r == E_INVALIDARG, "returns %08x\n", r );
1586     if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
1587     VariantClear(&var);
1588
1589     V_VT(&var) = VT_I4;
1590     V_I4(&var) = NODE_ELEMENT;
1591     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1592     ok( r == S_OK, "returns %08x\n", r );
1593     r = IXMLDOMDocument_appendChild( doc, node, &root );
1594     ok( r == S_OK, "returns %08x\n", r );
1595     ok( node == root, "%p %p\n", node, root );
1596
1597     ref = IXMLDOMNode_AddRef( node );
1598     ok(ref == 3, "ref %d\n", ref);
1599     IXMLDOMNode_Release( node );
1600
1601     ref = IXMLDOMNode_Release( node );
1602     ok(ref == 1, "ref %d\n", ref);
1603     SysFreeString( str );
1604
1605     V_VT(&var) = VT_I4;
1606     V_I4(&var) = NODE_ELEMENT;
1607     str = SysAllocString( szbs );
1608     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1609     ok( r == S_OK, "returns %08x\n", r );
1610     SysFreeString( str );
1611
1612     ref = IXMLDOMNode_AddRef( node );
1613     ok(ref == 2, "ref = %d\n", ref);
1614     IXMLDOMNode_Release( node );
1615
1616     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk );
1617     ok( r == S_OK, "returns %08x\n", r );
1618
1619     ref = IXMLDOMNode_AddRef( unk );
1620     ok(ref == 3, "ref = %d\n", ref);
1621     IXMLDOMNode_Release( unk );
1622
1623     V_VT(&var) = VT_EMPTY;
1624     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
1625     ok( r == S_OK, "returns %08x\n", r );
1626     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
1627     IXMLDOMNode_Release( child );
1628     IUnknown_Release( unk );
1629
1630
1631     V_VT(&var) = VT_NULL;
1632     V_DISPATCH(&var) = (IDispatch*)node;
1633     r = IXMLDOMNode_insertBefore( root, node, var, &child );
1634     ok( r == S_OK, "returns %08x\n", r );
1635     ok( node == child, "%p %p\n", node, child );
1636     IXMLDOMNode_Release( child );
1637
1638
1639     V_VT(&var) = VT_NULL;
1640     V_DISPATCH(&var) = (IDispatch*)node;
1641     r = IXMLDOMNode_insertBefore( root, node, var, NULL );
1642     ok( r == S_OK, "returns %08x\n", r );
1643     IXMLDOMNode_Release( node );
1644
1645     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (LPVOID*)&element );
1646     ok( r == S_OK, "returns %08x\n", r );
1647
1648     r = IXMLDOMElement_get_attributes( element, &attr_map );
1649     ok( r == S_OK, "returns %08x\n", r );
1650     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
1651     ok( r == S_OK, "returns %08x\n", r );
1652     ok( num == 0, "num %d\n", num );
1653     IXMLDOMNamedNodeMap_Release( attr_map );
1654
1655     V_VT(&var) = VT_BSTR;
1656     V_BSTR(&var) = SysAllocString( szstr1 );
1657     name = SysAllocString( szdl );
1658     r = IXMLDOMElement_setAttribute( element, name, var );
1659     ok( r == S_OK, "returns %08x\n", r );
1660     r = IXMLDOMElement_get_attributes( element, &attr_map );
1661     ok( r == S_OK, "returns %08x\n", r );
1662     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
1663     ok( r == S_OK, "returns %08x\n", r );
1664     ok( num == 1, "num %d\n", num );
1665     IXMLDOMNamedNodeMap_Release( attr_map );
1666     VariantClear(&var);
1667
1668     V_VT(&var) = VT_BSTR;
1669     V_BSTR(&var) = SysAllocString( szstr2 );
1670     r = IXMLDOMElement_setAttribute( element, name, var );
1671     ok( r == S_OK, "returns %08x\n", r );
1672     r = IXMLDOMElement_get_attributes( element, &attr_map );
1673     ok( r == S_OK, "returns %08x\n", r );
1674     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
1675     ok( r == S_OK, "returns %08x\n", r );
1676     ok( num == 1, "num %d\n", num );
1677     IXMLDOMNamedNodeMap_Release( attr_map );
1678     VariantClear(&var);
1679     r = IXMLDOMElement_getAttribute( element, name, &var );
1680     ok( r == S_OK, "returns %08x\n", r );
1681     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
1682     VariantClear(&var);
1683     SysFreeString(name);
1684
1685     V_VT(&var) = VT_BSTR;
1686     V_BSTR(&var) = SysAllocString( szstr1 );
1687     name = SysAllocString( szlc );
1688     r = IXMLDOMElement_setAttribute( element, name, var );
1689     ok( r == S_OK, "returns %08x\n", r );
1690     r = IXMLDOMElement_get_attributes( element, &attr_map );
1691     ok( r == S_OK, "returns %08x\n", r );
1692     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
1693     ok( r == S_OK, "returns %08x\n", r );
1694     ok( num == 2, "num %d\n", num );
1695     IXMLDOMNamedNodeMap_Release( attr_map );
1696     VariantClear(&var);
1697     SysFreeString(name);
1698
1699     V_VT(&var) = VT_I4;
1700     V_I4(&var) = 10;
1701     name = SysAllocString( szbs );
1702     r = IXMLDOMElement_setAttribute( element, name, var );
1703     ok( r == S_OK, "returns %08x\n", r );
1704     VariantClear(&var);
1705     r = IXMLDOMElement_getAttribute( element, name, &var );
1706     ok( r == S_OK, "returns %08x\n", r );
1707     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
1708     VariantClear(&var);
1709     SysFreeString(name);
1710
1711     /* Create an Attribute */
1712     V_VT(&var) = VT_I4;
1713     V_I4(&var) = NODE_ATTRIBUTE;
1714     str = SysAllocString( szAttribute );
1715     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1716     ok( r == S_OK, "returns %08x\n", r );
1717     ok( node != NULL, "node was null\n");
1718     SysFreeString(str);
1719
1720     if(r == S_OK)
1721     {
1722         r = IXMLDOMNode_get_nodeTypeString(node, &str);
1723         ok( r == S_OK, "returns %08x\n", r );
1724         ok( !lstrcmpW( str, _bstr_("attribute") ), "incorrect nodeTypeString string\n");
1725         SysFreeString(str);
1726         IXMLDOMNode_Release( node );
1727     }
1728
1729     IXMLDOMElement_Release( element );
1730     IXMLDOMNode_Release( root );
1731     IXMLDOMDocument_Release( doc );
1732 }
1733
1734 static void test_getElementsByTagName(void)
1735 {
1736     HRESULT r;
1737     BSTR str;
1738     VARIANT_BOOL b;
1739     IXMLDOMDocument *doc;
1740     IXMLDOMNodeList *node_list;
1741     LONG len;
1742
1743     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1744         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1745     if( r != S_OK )
1746         return;
1747
1748     str = SysAllocString( szComplete4 );
1749     r = IXMLDOMDocument_loadXML( doc, str, &b );
1750     ok( r == S_OK, "loadXML failed\n");
1751     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1752     SysFreeString( str );
1753
1754     str = SysAllocString( szstar );
1755     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
1756     ok( r == S_OK, "ret %08x\n", r );
1757     r = IXMLDOMNodeList_get_length( node_list, &len );
1758     ok( r == S_OK, "ret %08x\n", r );
1759     ok( len == 6, "len %d\n", len );
1760
1761     test_disp((IUnknown*)node_list);
1762
1763     IXMLDOMNodeList_Release( node_list );
1764     SysFreeString( str );
1765
1766     str = SysAllocString( szbs );
1767     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
1768     ok( r == S_OK, "ret %08x\n", r );
1769     r = IXMLDOMNodeList_get_length( node_list, &len );
1770     ok( r == S_OK, "ret %08x\n", r );
1771     ok( len == 1, "len %d\n", len );
1772     IXMLDOMNodeList_Release( node_list );
1773     SysFreeString( str );
1774
1775     str = SysAllocString( szdl );
1776     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
1777     ok( r == S_OK, "ret %08x\n", r );
1778     r = IXMLDOMNodeList_get_length( node_list, &len );
1779     ok( r == S_OK, "ret %08x\n", r );
1780     ok( len == 0, "len %d\n", len );
1781     IXMLDOMNodeList_Release( node_list );
1782     SysFreeString( str );
1783
1784     str = SysAllocString( szstr1 );
1785     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
1786     ok( r == S_OK, "ret %08x\n", r );
1787     r = IXMLDOMNodeList_get_length( node_list, &len );
1788     ok( r == S_OK, "ret %08x\n", r );
1789     ok( len == 0, "len %d\n", len );
1790     IXMLDOMNodeList_Release( node_list );
1791     SysFreeString( str );
1792
1793     IXMLDOMDocument_Release( doc );
1794 }
1795
1796 static void test_get_text(void)
1797 {
1798     HRESULT r;
1799     BSTR str;
1800     VARIANT_BOOL b;
1801     IXMLDOMDocument *doc;
1802     IXMLDOMNode *node, *node2, *node3;
1803     IXMLDOMNode *nodeRoot;
1804     IXMLDOMNodeList *node_list;
1805     IXMLDOMNamedNodeMap *node_map;
1806     LONG len;
1807
1808     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1809         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1810     if( r != S_OK )
1811         return;
1812
1813     str = SysAllocString( szComplete4 );
1814     r = IXMLDOMDocument_loadXML( doc, str, &b );
1815     ok( r == S_OK, "loadXML failed\n");
1816     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1817     SysFreeString( str );
1818
1819     str = SysAllocString( szbs );
1820     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
1821     ok( r == S_OK, "ret %08x\n", r );
1822     SysFreeString(str);
1823
1824     /* Test to get all child node text. */
1825     r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (LPVOID*)&nodeRoot);
1826     ok( r == S_OK, "ret %08x\n", r );
1827     if(r == S_OK)
1828     {
1829         r = IXMLDOMNode_get_text( nodeRoot, &str );
1830         ok( r == S_OK, "ret %08x\n", r );
1831         ok( compareIgnoreReturnsWhitespace(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text\n");
1832         SysFreeString(str);
1833
1834         IXMLDOMNode_Release(nodeRoot);
1835     }
1836
1837     if (0) {
1838     /* this test crashes on win9x */
1839     r = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL);
1840     ok( r == E_INVALIDARG, "ret %08x\n", r );
1841     }
1842
1843     r = IXMLDOMNodeList_get_length( node_list, NULL );
1844     ok( r == E_INVALIDARG, "ret %08x\n", r );
1845
1846     r = IXMLDOMNodeList_get_length( node_list, &len );
1847     ok( r == S_OK, "ret %08x\n", r );
1848     ok( len == 1, "expect 1 got %d\n", len );
1849
1850     r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
1851     ok( r == E_INVALIDARG, "ret %08x\n", r );
1852
1853     r = IXMLDOMNodeList_nextNode( node_list, NULL );
1854     ok( r == E_INVALIDARG, "ret %08x\n", r );
1855
1856     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
1857     ok( r == S_OK, "ret %08x\n", r ); 
1858     IXMLDOMNodeList_Release( node_list );
1859
1860     /* Invalid output parameter*/
1861     r = IXMLDOMNode_get_text( node, NULL );
1862     ok( r == E_INVALIDARG, "ret %08x\n", r );
1863
1864     r = IXMLDOMNode_get_text( node, &str );
1865     ok( r == S_OK, "ret %08x\n", r );
1866     ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
1867     SysFreeString(str);
1868
1869     r = IXMLDOMNode_get_attributes( node, &node_map );
1870     ok( r == S_OK, "ret %08x\n", r );
1871     
1872     str = SysAllocString( szvr );
1873     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
1874     ok( r == S_OK, "ret %08x\n", r );
1875     SysFreeString(str);
1876
1877     r = IXMLDOMNode_get_text( node2, &str );
1878     ok( r == S_OK, "ret %08x\n", r );
1879     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
1880     SysFreeString(str);
1881
1882     r = IXMLDOMNode_get_firstChild( node2, &node3 );
1883     ok( r == S_OK, "ret %08x\n", r );
1884
1885     r = IXMLDOMNode_get_text( node3, &str );
1886     ok( r == S_OK, "ret %08x\n", r );
1887     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
1888     SysFreeString(str);
1889
1890
1891     IXMLDOMNode_Release( node3 );
1892     IXMLDOMNode_Release( node2 );
1893     IXMLDOMNamedNodeMap_Release( node_map );
1894     IXMLDOMNode_Release( node );
1895     IXMLDOMDocument_Release( doc );
1896 }
1897
1898 static void test_get_childNodes(void)
1899 {
1900     HRESULT r;
1901     BSTR str;
1902     VARIANT_BOOL b;
1903     IXMLDOMDocument *doc;
1904     IXMLDOMElement *element;
1905     IXMLDOMNode *node, *node2;
1906     IXMLDOMNodeList *node_list, *node_list2;
1907     LONG len;
1908
1909     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1910         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1911     if( r != S_OK )
1912         return;
1913
1914     str = SysAllocString( szComplete4 );
1915     r = IXMLDOMDocument_loadXML( doc, str, &b );
1916     ok( r == S_OK, "loadXML failed\n");
1917     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1918     SysFreeString( str );
1919
1920     r = IXMLDOMDocument_get_documentElement( doc, &element );
1921     ok( r == S_OK, "ret %08x\n", r);
1922
1923     r = IXMLDOMElement_get_childNodes( element, &node_list );
1924     ok( r == S_OK, "ret %08x\n", r);
1925
1926     r = IXMLDOMNodeList_get_length( node_list, &len );
1927     ok( r == S_OK, "ret %08x\n", r);
1928     ok( len == 4, "len %d\n", len);
1929
1930     r = IXMLDOMNodeList_get_item( node_list, 2, &node );
1931     ok( r == S_OK, "ret %08x\n", r);
1932
1933     r = IXMLDOMNode_get_childNodes( node, &node_list2 );
1934     ok( r == S_OK, "ret %08x\n", r);
1935
1936     r = IXMLDOMNodeList_get_length( node_list2, &len );
1937     ok( r == S_OK, "ret %08x\n", r);
1938     ok( len == 0, "len %d\n", len);
1939
1940     r = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
1941     ok( r == S_FALSE, "ret %08x\n", r);
1942
1943     IXMLDOMNodeList_Release( node_list2 );
1944     IXMLDOMNode_Release( node );
1945     IXMLDOMNodeList_Release( node_list );
1946     IXMLDOMElement_Release( element );
1947     IXMLDOMDocument_Release( doc );
1948 }
1949
1950 static void test_removeChild(void)
1951 {
1952     HRESULT r;
1953     BSTR str;
1954     VARIANT_BOOL b;
1955     IXMLDOMDocument *doc;
1956     IXMLDOMElement *element, *lc_element;
1957     IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
1958     IXMLDOMNodeList *root_list, *fo_list;
1959
1960     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
1961         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1962     if( r != S_OK )
1963         return;
1964
1965     str = SysAllocString( szComplete4 );
1966     r = IXMLDOMDocument_loadXML( doc, str, &b );
1967     ok( r == S_OK, "loadXML failed\n");
1968     ok( b == VARIANT_TRUE, "failed to load XML string\n");
1969     SysFreeString( str );
1970
1971     r = IXMLDOMDocument_get_documentElement( doc, &element );
1972     ok( r == S_OK, "ret %08x\n", r);
1973
1974     r = IXMLDOMElement_get_childNodes( element, &root_list );
1975     ok( r == S_OK, "ret %08x\n", r);
1976
1977     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
1978     ok( r == S_OK, "ret %08x\n", r);
1979  
1980     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
1981     ok( r == S_OK, "ret %08x\n", r);
1982  
1983     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
1984     ok( r == S_OK, "ret %08x\n", r);
1985
1986     /* invalid parameter: NULL ptr */
1987     removed_node = (void*)0xdeadbeef;
1988     r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
1989     ok( r == E_INVALIDARG, "ret %08x\n", r );
1990     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
1991
1992     /* ba_node is a descendant of element, but not a direct child. */
1993     removed_node = (void*)0xdeadbeef;
1994     r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
1995     ok( r == E_INVALIDARG, "ret %08x\n", r );
1996     ok( removed_node == NULL, "%p\n", removed_node );
1997
1998     r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
1999     ok( r == S_OK, "ret %08x\n", r);
2000     ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
2001
2002     /* try removing already removed child */
2003     temp_node = (void*)0xdeadbeef;
2004     r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
2005     ok( r == E_INVALIDARG, "ret %08x\n", r);
2006     ok( temp_node == NULL, "%p\n", temp_node );
2007
2008     /* the removed node has no parent anymore */
2009     r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
2010     ok( r == S_FALSE, "ret %08x\n", r);
2011     ok( temp_node == NULL, "%p\n", temp_node );
2012
2013     IXMLDOMNode_Release( removed_node );
2014     IXMLDOMNode_Release( ba_node );
2015     IXMLDOMNodeList_Release( fo_list );
2016
2017     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2018     ok( r == S_OK, "ret %08x\n", r);
2019
2020     r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (LPVOID*)&lc_element );
2021     ok( r == S_OK, "ret %08x\n", r);
2022
2023     /* MS quirk: passing wrong interface pointer works, too */
2024     r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
2025     ok( r == S_OK, "ret %08x\n", r);
2026
2027     r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
2028     ok( r == S_FALSE, "ret %08x\n", r);
2029     ok( temp_node == NULL, "%p\n", temp_node );
2030
2031     IXMLDOMNode_Release( lc_node );
2032     IXMLDOMNodeList_Release( root_list );
2033     IXMLDOMElement_Release( element );
2034     IXMLDOMDocument_Release( doc );
2035 }
2036
2037 static void test_replaceChild(void)
2038 {
2039     HRESULT r;
2040     BSTR str;
2041     VARIANT_BOOL b;
2042     IXMLDOMDocument *doc;
2043     IXMLDOMElement *element, *ba_element;
2044     IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
2045     IXMLDOMNodeList *root_list, *fo_list;
2046     IUnknown * unk1, *unk2;
2047     LONG len;
2048
2049     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2050         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2051     if( r != S_OK )
2052         return;
2053
2054     str = SysAllocString( szComplete4 );
2055     r = IXMLDOMDocument_loadXML( doc, str, &b );
2056     ok( r == S_OK, "loadXML failed\n");
2057     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2058     SysFreeString( str );
2059
2060     r = IXMLDOMDocument_get_documentElement( doc, &element );
2061     ok( r == S_OK, "ret %08x\n", r);
2062
2063     r = IXMLDOMElement_get_childNodes( element, &root_list );
2064     ok( r == S_OK, "ret %08x\n", r);
2065
2066     r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2067     ok( r == S_OK, "ret %08x\n", r);
2068
2069     r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
2070     ok( r == S_OK, "ret %08x\n", r);
2071
2072     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2073     ok( r == S_OK, "ret %08x\n", r);
2074
2075     r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
2076     ok( r == S_OK, "ret %08x\n", r);
2077
2078     IXMLDOMNodeList_Release( fo_list );
2079
2080     /* invalid parameter: NULL ptr for element to remove */
2081     removed_node = (void*)0xdeadbeef;
2082     r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
2083     ok( r == E_INVALIDARG, "ret %08x\n", r );
2084     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2085
2086     /* invalid parameter: NULL for replacement element. (Sic!) */
2087     removed_node = (void*)0xdeadbeef;
2088     r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
2089     ok( r == E_INVALIDARG, "ret %08x\n", r );
2090     ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2091
2092     /* invalid parameter: OldNode is not a child */
2093     removed_node = (void*)0xdeadbeef;
2094     r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
2095     ok( r == E_INVALIDARG, "ret %08x\n", r );
2096     ok( removed_node == NULL, "%p\n", removed_node );
2097
2098     /* invalid parameter: would create loop */
2099     removed_node = (void*)0xdeadbeef;
2100     r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
2101     ok( r == E_FAIL, "ret %08x\n", r );
2102     ok( removed_node == NULL, "%p\n", removed_node );
2103
2104     r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
2105     ok( r == S_OK, "ret %08x\n", r );
2106
2107     r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
2108     ok( r == S_OK, "ret %08x\n", r );
2109
2110     /* ba_node and temp_node refer to the same node, yet they
2111        are different interface pointers */
2112     ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
2113     r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
2114     ok( r == S_OK, "ret %08x\n", r );
2115     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
2116     ok( r == S_OK, "ret %08x\n", r );
2117     todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
2118
2119     IUnknown_Release( unk1 );
2120     IUnknown_Release( unk2 );
2121
2122     /* ba_node should have been removed from below fo_node */
2123     r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2124     ok( r == S_OK, "ret %08x\n", r );
2125
2126     /* MS quirk: replaceChild also accepts elements instead of nodes */
2127     r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
2128     ok( r == S_OK, "ret %08x\n", r );
2129
2130     r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
2131     ok( r == S_OK, "ret %08x\n", r );
2132
2133     r = IXMLDOMNodeList_get_length( fo_list, &len);
2134     ok( r == S_OK, "ret %08x\n", r );
2135     ok( len == 0, "len %d\n", len);
2136
2137     IXMLDOMNodeList_Release( fo_list );
2138
2139     IXMLDOMNode_Release(ba_node);
2140     IXMLDOMNode_Release(fo_node);
2141     IXMLDOMNode_Release(temp_node);
2142     IXMLDOMNodeList_Release( root_list );
2143     IXMLDOMElement_Release( element );
2144     IXMLDOMDocument_Release( doc );
2145 }
2146
2147 static void test_removeNamedItem(void)
2148 {
2149     IXMLDOMDocument *doc;
2150     IXMLDOMElement *element;
2151     IXMLDOMNode *pr_node, *removed_node, *removed_node2;
2152     IXMLDOMNodeList *root_list;
2153     IXMLDOMNamedNodeMap * pr_attrs;
2154     VARIANT_BOOL b;
2155     BSTR str;
2156     LONG len;
2157     HRESULT r;
2158
2159     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2160         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2161     if( r != S_OK )
2162         return;
2163
2164     str = SysAllocString( szComplete4 );
2165     r = IXMLDOMDocument_loadXML( doc, str, &b );
2166     ok( r == S_OK, "loadXML failed\n");
2167     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2168     SysFreeString( str );
2169
2170     r = IXMLDOMDocument_get_documentElement( doc, &element );
2171     ok( r == S_OK, "ret %08x\n", r);
2172
2173     r = IXMLDOMElement_get_childNodes( element, &root_list );
2174     ok( r == S_OK, "ret %08x\n", r);
2175
2176     r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
2177     ok( r == S_OK, "ret %08x\n", r);
2178
2179     r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
2180     ok( r == S_OK, "ret %08x\n", r);
2181
2182     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
2183     ok( r == S_OK, "ret %08x\n", r);
2184     ok( len == 3, "length %d\n", len);
2185
2186     removed_node = (void*)0xdeadbeef;
2187     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
2188     ok ( r == E_INVALIDARG, "ret %08x\n", r);
2189     ok ( removed_node == (void*)0xdeadbeef, "removed_node == %p\n", removed_node);
2190
2191     removed_node = (void*)0xdeadbeef;
2192     str = SysAllocString(szvr);
2193     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
2194     ok ( r == S_OK, "ret %08x\n", r);
2195
2196     removed_node2 = (void*)0xdeadbeef;
2197     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
2198     ok ( r == S_FALSE, "ret %08x\n", r);
2199     ok ( removed_node2 == NULL, "removed_node == %p\n", removed_node2 );
2200
2201     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
2202     ok( r == S_OK, "ret %08x\n", r);
2203     ok( len == 2, "length %d\n", len);
2204
2205     r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
2206     ok ( r == S_OK, "ret %08x\n", r);
2207     IXMLDOMNode_Release(removed_node);
2208
2209     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
2210     ok( r == S_OK, "ret %08x\n", r);
2211     ok( len == 3, "length %d\n", len);
2212
2213     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
2214     ok ( r == S_OK, "ret %08x\n", r);
2215
2216     r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
2217     ok( r == S_OK, "ret %08x\n", r);
2218     ok( len == 2, "length %d\n", len);
2219
2220     r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
2221     ok ( r == S_FALSE, "ret %08x\n", r);
2222
2223     SysFreeString(str);
2224
2225     IXMLDOMNamedNodeMap_Release( pr_attrs );
2226     IXMLDOMNode_Release( pr_node );
2227     IXMLDOMNodeList_Release( root_list );
2228     IXMLDOMElement_Release( element );
2229     IXMLDOMDocument_Release( doc );
2230 }
2231
2232 static void test_XMLHTTP(void)
2233 {
2234     static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
2235     static WCHAR wszPOST[] = {'P','O','S','T',0};
2236     static WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
2237         'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
2238         'p','o','s','t','t','e','s','t','.','p','h','p',0};
2239     static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
2240     IXMLHttpRequest *pXMLHttpRequest;
2241     BSTR bstrResponse;
2242     VARIANT dummy;
2243     VARIANT varfalse;
2244     VARIANT varbody;
2245     HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
2246                                   CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest,
2247                                   (void **)&pXMLHttpRequest);
2248     ok(hr == S_OK, "CoCreateInstance(CLSID_XMLHTTPRequest) should have succeeded instead of failing with 0x%08x\n", hr);
2249     if (hr != S_OK)
2250         return;
2251
2252     VariantInit(&dummy);
2253     V_VT(&dummy) = VT_ERROR;
2254     V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
2255     VariantInit(&varfalse);
2256     V_VT(&varfalse) = VT_BOOL;
2257     V_BOOL(&varfalse) = VARIANT_FALSE;
2258     V_VT(&varbody) = VT_BSTR;
2259     V_BSTR(&varbody) = SysAllocString(wszBody);
2260
2261     hr = IXMLHttpRequest_open(pXMLHttpRequest, wszPOST, wszUrl, varfalse, dummy, dummy);
2262     todo_wine ok(hr == S_OK, "IXMLHttpRequest_open should have succeeded instead of failing with 0x%08x\n", hr);
2263
2264     hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
2265     todo_wine ok(hr == S_OK, "IXMLHttpRequest_send should have succeeded instead of failing with 0x%08x\n", hr);
2266     VariantClear(&varbody);
2267
2268     hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
2269     todo_wine ok(hr == S_OK, "IXMLHttpRequest_get_responseText should have succeeded instead of failing with 0x%08x\n", hr);
2270     /* the server currently returns "FAILED" because the Content-Type header is
2271      * not what the server expects */
2272     if(hr == S_OK)
2273     {
2274         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)), "bstrResponse differs from what was expected\n");
2275         SysFreeString(bstrResponse);
2276     }
2277
2278     IXMLHttpRequest_Release(pXMLHttpRequest);
2279 }
2280
2281 static void test_IXMLDOMDocument2(void)
2282 {
2283     HRESULT r;
2284     VARIANT_BOOL b;
2285     BSTR str;
2286     IXMLDOMDocument *doc;
2287     IXMLDOMDocument2 *doc2;
2288     IDispatchEx *dispex;
2289     VARIANT var;
2290     int ref;
2291
2292     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2293         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2294     if( r != S_OK )
2295         return;
2296
2297     str = SysAllocString( szComplete4 );
2298     r = IXMLDOMDocument_loadXML( doc, str, &b );
2299     ok( r == S_OK, "loadXML failed\n");
2300     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2301     SysFreeString( str );
2302
2303     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
2304     ok( r == S_OK, "ret %08x\n", r );
2305     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
2306
2307     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
2308     ok( r == S_OK, "ret %08x\n", r );
2309     if(r == S_OK)
2310     {
2311         IDispatchEx_Release(dispex);
2312     }
2313
2314     /* we will check if the variant got cleared */
2315     ref = IXMLDOMDocument2_AddRef(doc2);
2316     expect_eq(ref, 3, int, "%d");  /* doc, doc2, AddRef*/
2317     V_VT(&var) = VT_UNKNOWN;
2318     V_UNKNOWN(&var) = (IUnknown *)doc2;
2319
2320     /* invalid calls */
2321     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
2322     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
2323     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
2324
2325     /* valid call */
2326     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
2327     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2328     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
2329     V_VT(&var) = VT_R4;
2330
2331     /* the variant didn't get cleared*/
2332     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
2333
2334     /* setProperty tests */
2335     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
2336     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
2337     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
2338     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
2339     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
2340     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
2341
2342     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
2343     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
2344     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2345     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
2346
2347     IXMLDOMDocument2_Release( doc2 );
2348     IXMLDOMDocument_Release( doc );
2349     free_bstrs();
2350 }
2351
2352 static void test_XPath(void)
2353 {
2354     HRESULT r;
2355     VARIANT var;
2356     VARIANT_BOOL b;
2357     IXMLDOMDocument2 *doc;
2358     IXMLDOMNode *rootNode;
2359     IXMLDOMNode *elem1Node;
2360     IXMLDOMNode *node;
2361     IXMLDOMNodeList *list;
2362
2363     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2364         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
2365     if( r != S_OK )
2366         return;
2367
2368     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b));
2369     ok(b == VARIANT_TRUE, "failed to load XML string\n");
2370
2371     /* switch to XPath */
2372     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
2373
2374     /* some simple queries*/
2375     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list));
2376     ole_check(IXMLDOMNodeList_get_item(list, 0, &rootNode));
2377     ole_check(IXMLDOMNodeList_reset(list));
2378     expect_list_and_release(list, "E2.D1");
2379     if (rootNode == NULL)
2380         return;
2381
2382     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//c"), &list));
2383     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
2384
2385     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//c[@type]"), &list));
2386     expect_list_and_release(list, "E3.E2.E2.D1");
2387
2388     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
2389     /* using get_item for query results advances the position */
2390     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2391     expect_node(node, "E2.E2.D1");
2392     IXMLDOMNode_Release(node);
2393     ole_check(IXMLDOMNodeList_nextNode(list, &node));
2394     expect_node(node, "E4.E2.D1");
2395     IXMLDOMNode_Release(node);
2396     ole_check(IXMLDOMNodeList_reset(list));
2397     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
2398
2399     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
2400     expect_list_and_release(list, "E2.D1");
2401
2402     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
2403     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
2404     ole_check(IXMLDOMNodeList_reset(list));
2405     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
2406
2407     /* select an attribute */
2408     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
2409     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
2410
2411     /* would evaluate to a number */
2412     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
2413     /* would evaluate to a boolean */
2414     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
2415     /* would evaluate to a string */
2416     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
2417
2418     /* no results */
2419     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
2420     expect_list_and_release(list, "");
2421     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
2422     expect_list_and_release(list, "");
2423     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
2424     expect_list_and_release(list, "");
2425
2426     /* foo undeclared in document node */
2427     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2428     /* undeclared in <root> node */
2429     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
2430     /* undeclared in <elem> node */
2431     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
2432     /* but this trick can be used */
2433     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
2434     expect_list_and_release(list, "E3.E4.E2.D1");
2435
2436     /* it has to be declared in SelectionNamespaces */
2437     todo_wine ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2438         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
2439
2440     /* now the namespace can be used */
2441     todo_wine ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//test:c"), &list));
2442     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2443     todo_wine ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
2444     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2445     todo_wine ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
2446     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2447     todo_wine ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
2448     todo_wine expect_list_and_release(list, "E5.E1.E4.E1.E2.D1");
2449
2450     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
2451     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2452         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
2453
2454     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2455
2456     VariantInit(&var);
2457     todo_wine ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
2458     todo_wine expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2459     if (V_VT(&var) == VT_BSTR)
2460         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
2461
2462     /* extra attributes - same thing*/
2463     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2464         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
2465     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2466
2467     IXMLDOMNode_Release(rootNode);
2468     IXMLDOMNode_Release(elem1Node);
2469     IXMLDOMDocument_Release(doc);
2470     free_bstrs();
2471 }
2472
2473 static void test_cloneNode(void )
2474 {
2475     IXMLDOMDocument *doc = NULL;
2476     VARIANT_BOOL b;
2477     IXMLDOMNodeList *pList;
2478     IXMLDOMNamedNodeMap *mapAttr;
2479     LONG nLength = 0, nLength1 = 0;
2480     LONG nAttrCnt = 0, nAttrCnt1 = 0;
2481     IXMLDOMNode *node;
2482     IXMLDOMNode *node_clone;
2483     IXMLDOMNode *node_first;
2484     HRESULT r;
2485     BSTR str;
2486     static const WCHAR szSearch[] = { 'l', 'c', '/', 'p', 'r', 0 };
2487
2488     r = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
2489     if( r != S_OK )
2490         return;
2491
2492     str = SysAllocString( szComplete4 );
2493     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
2494     ok(b == VARIANT_TRUE, "failed to load XML string\n");
2495     SysFreeString(str);
2496
2497     if(!b)
2498         return;
2499
2500     str = SysAllocString( szSearch);
2501     r = IXMLDOMNode_selectSingleNode(doc, str, &node);
2502     ok( r == S_OK, "ret %08x\n", r );
2503     ok( node != NULL, "node %p\n", node );
2504     SysFreeString(str);
2505
2506     if(!node)
2507     {
2508         IXMLDOMDocument_Release(doc);
2509         return;
2510     }
2511
2512     /* Check invalid parameter */
2513     r = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
2514     ok( r == E_INVALIDARG, "ret %08x\n", r );
2515
2516     /* All Children */
2517     r = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
2518     ok( r == S_OK, "ret %08x\n", r );
2519     ok( node_clone != NULL, "node %p\n", node );
2520
2521     if(!node_clone)
2522     {
2523         IXMLDOMDocument_Release(doc);
2524         IXMLDOMNode_Release(node);
2525         return;
2526     }
2527
2528     r = IXMLDOMNode_get_firstChild(node_clone, &node_first);
2529     ok( r == S_OK, "ret %08x\n", r );
2530     if(r == S_OK)
2531     {
2532         IXMLDOMDocument *doc2;
2533
2534         r = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
2535         ok( r == S_OK, "ret %08x\n", r );
2536         if(r == S_OK)
2537             IXMLDOMDocument_Release(doc2);
2538
2539         IXMLDOMNode_Release(node_first);
2540     }
2541
2542     r = IXMLDOMNode_get_childNodes(node, &pList);
2543     ok( r == S_OK, "ret %08x\n", r );
2544     if (pList)
2545         {
2546                 IXMLDOMNodeList_get_length(pList, &nLength);
2547                 IXMLDOMNodeList_Release(pList);
2548         }
2549
2550     r = IXMLDOMNode_get_attributes(node, &mapAttr);
2551     ok( r == S_OK, "ret %08x\n", r );
2552     if(mapAttr)
2553     {
2554         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt);
2555         IXMLDOMNamedNodeMap_Release(mapAttr);
2556     }
2557
2558     r = IXMLDOMNode_get_childNodes(node_clone, &pList);
2559     ok( r == S_OK, "ret %08x\n", r );
2560     if (pList)
2561         {
2562                 IXMLDOMNodeList_get_length(pList, &nLength1);
2563                 IXMLDOMNodeList_Release(pList);
2564         }
2565
2566     r = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
2567     ok( r == S_OK, "ret %08x\n", r );
2568     if(mapAttr)
2569     {
2570         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt1);
2571         IXMLDOMNamedNodeMap_Release(mapAttr);
2572     }
2573
2574     ok(nLength == nLength1, "wrong Child count (%d, %d)\n", nLength, nLength1);
2575     ok(nAttrCnt == nAttrCnt1, "wrong Attribute count (%d, %d)\n", nAttrCnt, nAttrCnt1);
2576     IXMLDOMNode_Release(node_clone);
2577
2578     /* No Children */
2579     r = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
2580     ok( r == S_OK, "ret %08x\n", r );
2581     ok( node_clone != NULL, "node %p\n", node );
2582
2583     if(!node_clone)
2584     {
2585         IXMLDOMDocument_Release(doc);
2586         IXMLDOMNode_Release(node);
2587         return;
2588     }
2589
2590     r = IXMLDOMNode_get_firstChild(node_clone, &node_first);
2591     ok( r == S_FALSE, "ret %08x\n", r );
2592     if(r == S_OK)
2593     {
2594         IXMLDOMDocument *doc2;
2595
2596         r = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
2597         ok( r == S_OK, "ret %08x\n", r );
2598         if(r == S_OK)
2599             IXMLDOMDocument_Release(doc2);
2600
2601         IXMLDOMNode_Release(node_first);
2602     }
2603
2604     r = IXMLDOMNode_get_childNodes(node_clone, &pList);
2605     ok( r == S_OK, "ret %08x\n", r );
2606     if (pList)
2607         {
2608                 IXMLDOMNodeList_get_length(pList, &nLength1);
2609         ok( nLength1 == 0, "Length should be 0 (%d)\n", nLength1);
2610                 IXMLDOMNodeList_Release(pList);
2611         }
2612
2613     r = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
2614     ok( r == S_OK, "ret %08x\n", r );
2615     if(mapAttr)
2616     {
2617         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt1);
2618         ok( nAttrCnt1 == 3, "Attribute count should be 3 (%d)\n", nAttrCnt1);
2619         IXMLDOMNamedNodeMap_Release(mapAttr);
2620     }
2621
2622     ok(nLength != nLength1, "wrong Child count (%d, %d)\n", nLength, nLength1);
2623     ok(nAttrCnt == nAttrCnt1, "wrong Attribute count (%d, %d)\n", nAttrCnt, nAttrCnt1);
2624     IXMLDOMNode_Release(node_clone);
2625
2626
2627     IXMLDOMNode_Release(node);
2628     IXMLDOMDocument_Release(doc);
2629 }
2630
2631 static void test_xmlTypes(void)
2632 {
2633     IXMLDOMDocument *doc = NULL;
2634     IXMLDOMElement *pRoot;
2635     HRESULT hr;
2636     IXMLDOMComment *pComment;
2637     IXMLDOMElement *pElement;
2638     IXMLDOMAttribute *pAttrubute;
2639     IXMLDOMNamedNodeMap *pAttribs;
2640     IXMLDOMCDATASection *pCDataSec;
2641     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
2642     IXMLDOMDocumentFragment *pDocFrag = NULL;
2643     IXMLDOMEntityReference *pEntityRef = NULL;
2644     BSTR str;
2645     IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;   /* Used for testing Siblings */
2646     VARIANT v;
2647     LONG len = 0;
2648
2649     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
2650     if( hr != S_OK )
2651         return;
2652
2653     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
2654     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2655
2656     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
2657     ok(hr == S_FALSE, "ret %08x\n", hr );
2658     ok(pNextChild == NULL, "pDocChild not NULL\n");
2659
2660     /* test previous Sibling */
2661     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
2662     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2663
2664     pNextChild = (IXMLDOMNode *)0x1;
2665     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
2666     ok(hr == S_FALSE, "ret %08x\n", hr );
2667     ok(pNextChild == NULL, "pNextChild not NULL\n");
2668
2669     /* test get_attributes */
2670     hr = IXMLDOMDocument_get_attributes( doc, NULL );
2671     ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
2672
2673     pAttribs = (IXMLDOMNamedNodeMap*)0x1;
2674     hr = IXMLDOMDocument_get_attributes( doc, &pAttribs);
2675     ok(hr == S_FALSE, "ret %08x\n", hr );
2676     ok( pAttribs == NULL, "pAttribs not NULL\n");
2677
2678     /* test get_dataType */
2679     hr = IXMLDOMDocument_get_dataType(doc, &v);
2680     ok(hr == S_FALSE, "ret %08x\n", hr );
2681     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
2682     VariantClear(&v);
2683
2684     /* test nodeTypeString */
2685     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
2686     ok(hr == S_OK, "ret %08x\n", hr );
2687     ok( !lstrcmpW( str, _bstr_("document") ), "incorrect nodeTypeString string\n");
2688     SysFreeString(str);
2689
2690     /* test implementation */
2691     hr = IXMLDOMDocument_get_implementation(doc, NULL);
2692     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2693
2694     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
2695     ok(hr == S_OK, "ret %08x\n", hr );
2696     if(hr == S_OK)
2697     {
2698         VARIANT_BOOL hasFeature = VARIANT_TRUE;
2699         BSTR sEmpty = SysAllocStringLen(NULL, 0);
2700
2701         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
2702         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2703
2704         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
2705         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2706
2707         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
2708         ok(hr == S_OK, "ret %08x\n", hr );
2709         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
2710
2711         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
2712         ok(hr == S_OK, "ret %08x\n", hr );
2713         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
2714
2715         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
2716         ok(hr == S_OK, "ret %08x\n", hr );
2717         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
2718
2719         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
2720         ok(hr == S_OK, "ret %08x\n", hr );
2721         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
2722
2723         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
2724         ok(hr == S_OK, "ret %08x\n", hr );
2725         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
2726
2727         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
2728         ok(hr == S_OK, "ret %08x\n", hr );
2729         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
2730
2731         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
2732         ok(hr == S_OK, "ret %08x\n", hr );
2733         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
2734
2735         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
2736         ok(hr == S_OK, "ret %08x\n", hr );
2737         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
2738
2739         SysFreeString(sEmpty);
2740         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
2741     }
2742
2743
2744
2745     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
2746     ok(hr == S_OK, "ret %08x\n", hr );
2747     if(hr == S_OK)
2748     {
2749         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
2750         ok(hr == S_OK, "ret %08x\n", hr );
2751         if(hr == S_OK)
2752         {
2753             /* Comment */
2754             hr = IXMLDOMDocument_createComment(doc, szComment, &pComment);
2755             ok(hr == S_OK, "ret %08x\n", hr );
2756             if(hr == S_OK)
2757             {
2758                 /* test get_attributes */
2759                 hr = IXMLDOMComment_get_attributes( pComment, NULL );
2760                 ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
2761
2762                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
2763                 hr = IXMLDOMComment_get_attributes( pComment, &pAttribs);
2764                 ok(hr == S_FALSE, "ret %08x\n", hr );
2765                 ok( pAttribs == NULL, "pAttribs not NULL\n");
2766
2767                 /* test nodeTypeString */
2768                 hr = IXMLDOMComment_get_nodeTypeString(pComment, &str);
2769                 ok(hr == S_OK, "ret %08x\n", hr );
2770                 ok( !lstrcmpW( str, _bstr_("comment") ), "incorrect nodeTypeString string\n");
2771                 SysFreeString(str);
2772
2773                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
2774                 ok(hr == S_OK, "ret %08x\n", hr );
2775
2776                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
2777                 ok(hr == S_OK, "ret %08x\n", hr );
2778                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
2779                 SysFreeString(str);
2780
2781                 hr = IXMLDOMComment_get_xml(pComment, &str);
2782                 ok(hr == S_OK, "ret %08x\n", hr );
2783                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
2784                 SysFreeString(str);
2785
2786                 hr = IXMLDOMComment_get_dataType(pComment, &v);
2787                 ok(hr == S_FALSE, "ret %08x\n", hr );
2788                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
2789                 VariantClear(&v);
2790
2791                 /* put data Tests */
2792                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
2793                 ok(hr == S_OK, "ret %08x\n", hr );
2794
2795                 /* get data Tests */
2796                 hr = IXMLDOMComment_get_data(pComment, &str);
2797                 ok(hr == S_OK, "ret %08x\n", hr );
2798                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
2799                 SysFreeString(str);
2800
2801                 /* get data Tests */
2802                 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
2803                 ok(hr == S_OK, "ret %08x\n", hr );
2804                 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
2805                 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
2806                 VariantClear(&v);
2807
2808                 /* Confirm XML text is good */
2809                 hr = IXMLDOMComment_get_xml(pComment, &str);
2810                 ok(hr == S_OK, "ret %08x\n", hr );
2811                 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
2812                 SysFreeString(str);
2813
2814                 /* Confirm we get the put_data Text back */
2815                 hr = IXMLDOMComment_get_text(pComment, &str);
2816                 ok(hr == S_OK, "ret %08x\n", hr );
2817                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
2818                 SysFreeString(str);
2819
2820                 /* test length property */
2821                 hr = IXMLDOMComment_get_length(pComment, &len);
2822                 ok(hr == S_OK, "ret %08x\n", hr );
2823                 ok(len == 21, "expected 21 got %d\n", len);
2824
2825                 /* test substringData */
2826                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
2827                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2828
2829                 /* test substringData - Invalid offset */
2830                 str = (BSTR)&szElement;
2831                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
2832                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2833                 ok( str == NULL, "incorrect string\n");
2834
2835                 /* test substringData - Invalid offset */
2836                 str = (BSTR)&szElement;
2837                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
2838                 ok(hr == S_FALSE, "ret %08x\n", hr );
2839                 ok( str == NULL, "incorrect string\n");
2840
2841                 /* test substringData - Invalid size */
2842                 str = (BSTR)&szElement;
2843                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
2844                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2845                 ok( str == NULL, "incorrect string\n");
2846
2847                 /* test substringData - Invalid size */
2848                 str = (BSTR)&szElement;
2849                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
2850                 ok(hr == S_FALSE, "ret %08x\n", hr );
2851                 ok( str == NULL, "incorrect string\n");
2852
2853                 /* test substringData - Start of string */
2854                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
2855                 ok(hr == S_OK, "ret %08x\n", hr );
2856                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
2857                 SysFreeString(str);
2858
2859                 /* test substringData - Middle of string */
2860                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
2861                 ok(hr == S_OK, "ret %08x\n", hr );
2862                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
2863                 SysFreeString(str);
2864
2865                 /* test substringData - End of string */
2866                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
2867                 ok(hr == S_OK, "ret %08x\n", hr );
2868                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
2869                 SysFreeString(str);
2870
2871                 /* test appendData */
2872                 hr = IXMLDOMComment_appendData(pComment, NULL);
2873                 ok(hr == S_OK, "ret %08x\n", hr );
2874
2875                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
2876                 ok(hr == S_OK, "ret %08x\n", hr );
2877
2878                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
2879                 ok(hr == S_OK, "ret %08x\n", hr );
2880
2881                 hr = IXMLDOMComment_get_text(pComment, &str);
2882                 ok(hr == S_OK, "ret %08x\n", hr );
2883                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
2884                 SysFreeString(str);
2885
2886                 /* test insertData */
2887                 str = SysAllocStringLen(NULL, 0);
2888                 hr = IXMLDOMComment_insertData(pComment, -1, str);
2889                 ok(hr == S_OK, "ret %08x\n", hr );
2890
2891                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
2892                 ok(hr == S_OK, "ret %08x\n", hr );
2893
2894                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
2895                 ok(hr == S_OK, "ret %08x\n", hr );
2896
2897                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
2898                 ok(hr == S_OK, "ret %08x\n", hr );
2899
2900                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
2901                 ok(hr == S_OK, "ret %08x\n", hr );
2902
2903                 hr = IXMLDOMComment_insertData(pComment, 0, str);
2904                 ok(hr == S_OK, "ret %08x\n", hr );
2905                 SysFreeString(str);
2906
2907                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
2908                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2909
2910                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
2911                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2912
2913                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
2914                 ok(hr == S_OK, "ret %08x\n", hr );
2915
2916                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
2917                 ok(hr == S_OK, "ret %08x\n", hr );
2918
2919                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
2920                 ok(hr == S_OK, "ret %08x\n", hr );
2921
2922                 hr = IXMLDOMComment_get_text(pComment, &str);
2923                 ok(hr == S_OK, "ret %08x\n", hr );
2924                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
2925                 SysFreeString(str);
2926
2927                 IXMLDOMComment_Release(pComment);
2928             }
2929
2930             /* Element */
2931             hr = IXMLDOMDocument_createElement(doc, szElement, &pElement);
2932             ok(hr == S_OK, "ret %08x\n", hr );
2933             if(hr == S_OK)
2934             {
2935                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
2936                 ok(hr == S_OK, "ret %08x\n", hr );
2937
2938                 /* test nodeTypeString */
2939                 hr = IXMLDOMDocument_get_nodeTypeString(pElement, &str);
2940                 ok(hr == S_OK, "ret %08x\n", hr );
2941                 ok( !lstrcmpW( str, _bstr_("element") ), "incorrect nodeTypeString string\n");
2942                 SysFreeString(str);
2943
2944                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
2945                 ok(hr == S_OK, "ret %08x\n", hr );
2946                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
2947                 SysFreeString(str);
2948
2949                 hr = IXMLDOMElement_get_xml(pElement, &str);
2950                 ok(hr == S_OK, "ret %08x\n", hr );
2951                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
2952                 SysFreeString(str);
2953
2954                 hr = IXMLDOMElement_get_dataType(pElement, &v);
2955                 ok(hr == S_FALSE, "ret %08x\n", hr );
2956                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
2957                 VariantClear(&v);
2958
2959                  /* Attribute */
2960                 hr = IXMLDOMDocument_createAttribute(doc, szAttribute, &pAttrubute);
2961                 ok(hr == S_OK, "ret %08x\n", hr );
2962                 if(hr == S_OK)
2963                 {
2964                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
2965
2966                     hr = IXMLDOMAttribute_get_nextSibling(pAttrubute, NULL);
2967                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2968
2969                     pNextChild = (IXMLDOMNode *)0x1;
2970                     hr = IXMLDOMAttribute_get_nextSibling(pAttrubute, &pNextChild);
2971                     ok(hr == S_FALSE, "ret %08x\n", hr );
2972                     ok(pNextChild == NULL, "pNextChild not NULL\n");
2973
2974                     /* test Previous Sibling*/
2975                     hr = IXMLDOMAttribute_get_previousSibling(pAttrubute, NULL);
2976                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
2977
2978                     pNextChild = (IXMLDOMNode *)0x1;
2979                     hr = IXMLDOMAttribute_get_previousSibling(pAttrubute, &pNextChild);
2980                     ok(hr == S_FALSE, "ret %08x\n", hr );
2981                     ok(pNextChild == NULL, "pNextChild not NULL\n");
2982
2983                     /* test get_attributes */
2984                     hr = IXMLDOMAttribute_get_attributes( pAttrubute, NULL );
2985                     ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
2986
2987                     pAttribs = (IXMLDOMNamedNodeMap*)0x1;
2988                     hr = IXMLDOMAttribute_get_attributes( pAttrubute, &pAttribs);
2989                     ok(hr == S_FALSE, "ret %08x\n", hr );
2990                     ok( pAttribs == NULL, "pAttribs not NULL\n");
2991
2992                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttrubute, &pNewChild);
2993                     ok(hr == E_FAIL, "ret %08x\n", hr );
2994                     ok(pNewChild == NULL, "pNewChild not NULL\n");
2995
2996                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
2997                     ok(hr == S_OK, "ret %08x\n", hr );
2998                     if ( hr == S_OK )
2999                     {
3000                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttrubute, NULL );
3001                         ok(hr == S_OK, "ret %08x\n", hr );
3002
3003                         IXMLDOMNamedNodeMap_Release(pAttribs);
3004                     }
3005
3006                     hr = IXMLDOMAttribute_get_nodeName(pAttrubute, &str);
3007                     ok(hr == S_OK, "ret %08x\n", hr );
3008                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
3009                     SysFreeString(str);
3010
3011                     /* test nodeTypeString */
3012                     hr = IXMLDOMAttribute_get_nodeTypeString(pAttrubute, &str);
3013                     ok(hr == S_OK, "ret %08x\n", hr );
3014                     ok( !lstrcmpW( str, _bstr_("attribute") ), "incorrect nodeTypeString string\n");
3015                     SysFreeString(str);
3016
3017                     /* test nodeName */
3018                     hr = IXMLDOMAttribute_get_nodeName(pAttrubute, &str);
3019                     ok(hr == S_OK, "ret %08x\n", hr );
3020                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
3021                     SysFreeString(str);
3022
3023                     /* test name property */
3024                     hr = IXMLDOMAttribute_get_name(pAttrubute, &str);
3025                     ok(hr == S_OK, "ret %08x\n", hr );
3026                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
3027                     SysFreeString(str);
3028
3029                     hr = IXMLDOMAttribute_get_xml(pAttrubute, &str);
3030                     ok(hr == S_OK, "ret %08x\n", hr );
3031                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
3032                     SysFreeString(str);
3033
3034                     hr = IXMLDOMAttribute_get_dataType(pAttrubute, &v);
3035                     ok(hr == S_FALSE, "ret %08x\n", hr );
3036                     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3037                     VariantClear(&v);
3038
3039                     IXMLDOMAttribute_Release(pAttrubute);
3040
3041                     /* Check Element again with the Add Attribute*/
3042                     hr = IXMLDOMElement_get_xml(pElement, &str);
3043                     ok(hr == S_OK, "ret %08x\n", hr );
3044                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
3045                     SysFreeString(str);
3046                 }
3047
3048                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
3049                 ok(hr == S_OK, "ret %08x\n", hr );
3050
3051                 hr = IXMLDOMElement_get_xml(pElement, &str);
3052                 ok(hr == S_OK, "ret %08x\n", hr );
3053                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
3054                 SysFreeString(str);
3055
3056                 /* Test for reversible escaping */
3057                 str = SysAllocString( szStrangeChars );
3058                 hr = IXMLDOMElement_put_text(pElement, str);
3059                 ok(hr == S_OK, "ret %08x\n", hr );
3060                 SysFreeString( str );
3061
3062                 hr = IXMLDOMElement_get_xml(pElement, &str);
3063                 ok(hr == S_OK, "ret %08x\n", hr );
3064                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
3065                 SysFreeString(str);
3066
3067                 hr = IXMLDOMElement_get_text(pElement, &str);
3068                 ok(hr == S_OK, "ret %08x\n", hr );
3069                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
3070                 SysFreeString(str);
3071
3072                 IXMLDOMElement_Release(pElement);
3073             }
3074
3075             /* CData Section */
3076             hr = IXMLDOMDocument_createCDATASection(doc, szCData, NULL);
3077             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3078
3079             hr = IXMLDOMDocument_createCDATASection(doc, szCData, &pCDataSec);
3080             ok(hr == S_OK, "ret %08x\n", hr );
3081             if(hr == S_OK)
3082             {
3083                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
3084                 VARIANT var;
3085
3086                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (LPVOID*)&pElement);
3087                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
3088
3089                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
3090                 ok(hr == S_OK, "ret %08x\n", hr );
3091
3092                 /* get Attribute Tests */
3093                 hr = IXMLDOMCDATASection_get_attributes(pCDataSec, NULL);
3094                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3095
3096                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3097                 hr = IXMLDOMCDATASection_get_attributes(pCDataSec, &pAttribs);
3098                 ok(hr == S_FALSE, "ret %08x\n", hr );
3099                 ok(pAttribs == NULL, "pAttribs != NULL\n");
3100
3101                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
3102                 ok(hr == S_OK, "ret %08x\n", hr );
3103                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
3104                 SysFreeString(str);
3105
3106                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
3107                 ok(hr == S_OK, "ret %08x\n", hr );
3108                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
3109                 SysFreeString(str);
3110
3111                 /* test lastChild */
3112                 pNextChild = (IXMLDOMNode*)0x1;
3113                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
3114                 ok(hr == S_FALSE, "ret %08x\n", hr );
3115                 ok(pNextChild == NULL, "pNextChild not NULL\n");
3116
3117                 /* test get_dataType */
3118                 hr = IXMLDOMCDATASection_get_dataType(pCDataSec, NULL);
3119                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3120
3121                 hr = IXMLDOMCDATASection_get_dataType(pCDataSec, &v);
3122                 ok(hr == S_FALSE, "ret %08x\n", hr );
3123                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3124                 VariantClear(&v);
3125
3126                 /* test nodeTypeString */
3127                 hr = IXMLDOMCDATASection_get_nodeTypeString(pCDataSec, &str);
3128                 ok(hr == S_OK, "ret %08x\n", hr );
3129                 ok( !lstrcmpW( str, _bstr_("cdatasection") ), "incorrect nodeTypeString string\n");
3130                 SysFreeString(str);
3131
3132                 /* put data Tests */
3133                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
3134                 ok(hr == S_OK, "ret %08x\n", hr );
3135
3136                 /* Confirm XML text is good */
3137                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
3138                 ok(hr == S_OK, "ret %08x\n", hr );
3139                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
3140                 SysFreeString(str);
3141
3142                 /* Confirm we get the put_data Text back */
3143                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3144                 ok(hr == S_OK, "ret %08x\n", hr );
3145                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3146                 SysFreeString(str);
3147
3148                 /* test length property */
3149                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3150                 ok(hr == S_OK, "ret %08x\n", hr );
3151                 ok(len == 21, "expected 21 got %d\n", len);
3152
3153                 /* test get nodeValue */
3154                 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
3155                 ok(hr == S_OK, "ret %08x\n", hr );
3156                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3157                 VariantClear(&var);
3158
3159                 /* test get data */
3160                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
3161                 ok(hr == S_OK, "ret %08x\n", hr );
3162                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3163                 SysFreeString(str);
3164
3165                 /* test substringData */
3166                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
3167                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3168
3169                 /* test substringData - Invalid offset */
3170                 str = (BSTR)&szElement;
3171                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
3172                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3173                 ok( str == NULL, "incorrect string\n");
3174
3175                 /* test substringData - Invalid offset */
3176                 str = (BSTR)&szElement;
3177                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
3178                 ok(hr == S_FALSE, "ret %08x\n", hr );
3179                 ok( str == NULL, "incorrect string\n");
3180
3181                 /* test substringData - Invalid size */
3182                 str = (BSTR)&szElement;
3183                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
3184                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3185                 ok( str == NULL, "incorrect string\n");
3186
3187                 /* test substringData - Invalid size */
3188                 str = (BSTR)&szElement;
3189                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
3190                 ok(hr == S_FALSE, "ret %08x\n", hr );
3191                 ok( str == NULL, "incorrect string\n");
3192
3193                 /* test substringData - Start of string */
3194                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
3195                 ok(hr == S_OK, "ret %08x\n", hr );
3196                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
3197                 SysFreeString(str);
3198
3199                 /* test substringData - Middle of string */
3200                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
3201                 ok(hr == S_OK, "ret %08x\n", hr );
3202                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
3203                 SysFreeString(str);
3204
3205                 /* test substringData - End of string */
3206                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
3207                 ok(hr == S_OK, "ret %08x\n", hr );
3208                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
3209                 SysFreeString(str);
3210
3211                 /* test appendData */
3212                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
3213                 ok(hr == S_OK, "ret %08x\n", hr );
3214
3215                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
3216                 ok(hr == S_OK, "ret %08x\n", hr );
3217
3218                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
3219                 ok(hr == S_OK, "ret %08x\n", hr );
3220
3221                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3222                 ok(hr == S_OK, "ret %08x\n", hr );
3223                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
3224                 SysFreeString(str);
3225
3226                 /* test insertData */
3227                 str = SysAllocStringLen(NULL, 0);
3228                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
3229                 ok(hr == S_OK, "ret %08x\n", hr );
3230
3231                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
3232                 ok(hr == S_OK, "ret %08x\n", hr );
3233
3234                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
3235                 ok(hr == S_OK, "ret %08x\n", hr );
3236
3237                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
3238                 ok(hr == S_OK, "ret %08x\n", hr );
3239
3240                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
3241                 ok(hr == S_OK, "ret %08x\n", hr );
3242
3243                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
3244                 ok(hr == S_OK, "ret %08x\n", hr );
3245                 SysFreeString(str);
3246
3247                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
3248                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3249
3250                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
3251                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3252
3253                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
3254                 ok(hr == S_OK, "ret %08x\n", hr );
3255
3256                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
3257                 ok(hr == S_OK, "ret %08x\n", hr );
3258
3259                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
3260                 ok(hr == S_OK, "ret %08x\n", hr );
3261
3262                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3263                 ok(hr == S_OK, "ret %08x\n", hr );
3264                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
3265                 SysFreeString(str);
3266
3267                 IXMLDOMCDATASection_Release(pCDataSec);
3268             }
3269
3270             /* Document Fragments */
3271             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
3272             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3273
3274             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
3275             ok(hr == S_OK, "ret %08x\n", hr );
3276             if(hr == S_OK)
3277             {
3278                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
3279
3280                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
3281                 ok(hr == S_OK, "ret %08x\n", hr );
3282
3283                 /* get Attribute Tests */
3284                 hr = IXMLDOMDocumentFragment_get_attributes(pDocFrag, NULL);
3285                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3286
3287                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3288                 hr = IXMLDOMDocumentFragment_get_attributes(pDocFrag, &pAttribs);
3289                 ok(hr == S_FALSE, "ret %08x\n", hr );
3290                 ok(pAttribs == NULL, "pAttribs != NULL\n");
3291
3292                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
3293                 ok(hr == S_OK, "ret %08x\n", hr );
3294                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
3295                 SysFreeString(str);
3296
3297                 /* test next Sibling*/
3298                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
3299                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3300
3301                 pNextChild = (IXMLDOMNode *)0x1;
3302                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &pNextChild);
3303                 ok(hr == S_FALSE, "ret %08x\n", hr );
3304                 ok(pNextChild == NULL, "pNextChild not NULL\n");
3305
3306                 /* test Previous Sibling*/
3307                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
3308                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3309
3310                 pNextChild = (IXMLDOMNode *)0x1;
3311                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &pNextChild);
3312                 ok(hr == S_FALSE, "ret %08x\n", hr );
3313                 ok(pNextChild == NULL, "pNextChild not NULL\n");
3314
3315                 /* test get_dataType */
3316                 hr = IXMLDOMDocumentFragment_get_dataType(pDocFrag, NULL);
3317                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3318
3319                 hr = IXMLDOMDocumentFragment_get_dataType(pDocFrag, &v);
3320                 ok(hr == S_FALSE, "ret %08x\n", hr );
3321                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3322                 VariantClear(&v);
3323
3324                 /* test nodeTypeString */
3325                 hr = IXMLDOMDocumentFragment_get_nodeTypeString(pDocFrag, &str);
3326                 ok(hr == S_OK, "ret %08x\n", hr );
3327                 ok( !lstrcmpW( str, _bstr_("documentfragment") ), "incorrect nodeTypeString string\n");
3328                 SysFreeString(str);
3329
3330                 IXMLDOMDocumentFragment_Release(pDocFrag);
3331             }
3332
3333             /* Entity References */
3334             hr = IXMLDOMDocument_createEntityReference(doc, szEntityRef, NULL);
3335             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3336
3337             hr = IXMLDOMDocument_createEntityReference(doc, szEntityRef, &pEntityRef);
3338             ok(hr == S_OK, "ret %08x\n", hr );
3339             if(hr == S_OK)
3340             {
3341                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
3342                 ok(hr == S_OK, "ret %08x\n", hr );
3343
3344                 /* get Attribute Tests */
3345                 hr = IXMLDOMEntityReference_get_attributes(pEntityRef, NULL);
3346                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3347
3348                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3349                 hr = IXMLDOMEntityReference_get_attributes(pEntityRef, &pAttribs);
3350                 ok(hr == S_FALSE, "ret %08x\n", hr );
3351                 ok(pAttribs == NULL, "pAttribs != NULL\n");
3352
3353                 /* test dataType */
3354                 hr = IXMLDOMEntityReference_get_dataType(pEntityRef, &v);
3355                 ok(hr == S_FALSE, "ret %08x\n", hr );
3356                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3357                 VariantClear(&v);
3358
3359                 /* test nodeTypeString */
3360                 hr = IXMLDOMEntityReference_get_nodeTypeString(pEntityRef, &str);
3361                 ok(hr == S_OK, "ret %08x\n", hr );
3362                 ok( !lstrcmpW( str, _bstr_("entityreference") ), "incorrect nodeTypeString string\n");
3363                 SysFreeString(str);
3364
3365                 /* test get_xml*/
3366                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
3367                 ok(hr == S_OK, "ret %08x\n", hr );
3368                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
3369                 SysFreeString(str);
3370
3371                 IXMLDOMEntityReference_Release(pEntityRef);
3372             }
3373
3374             IXMLDOMElement_Release( pRoot );
3375         }
3376     }
3377
3378     IXMLDOMDocument_Release(doc);
3379
3380     free_bstrs();
3381 }
3382
3383 static void test_nodeTypeTests( void )
3384 {
3385     IXMLDOMDocument *doc = NULL;
3386     IXMLDOMElement *pRoot;
3387     IXMLDOMElement *pElement;
3388     HRESULT hr;
3389
3390     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3391     if( hr != S_OK )
3392         return;
3393
3394     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
3395     ok(hr == S_OK, "ret %08x\n", hr );
3396     if(hr == S_OK)
3397     {
3398         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
3399         ok(hr == S_OK, "ret %08x\n", hr );
3400         if(hr == S_OK)
3401         {
3402             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
3403             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3404
3405             /* Invalid Value */
3406             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
3407             ok(hr == E_FAIL, "ret %08x\n", hr );
3408
3409             /* NOTE:
3410              *   The name passed into put_dataType is case-insensitive. So many of the names
3411              *     have been changed to reflect this.
3412              */
3413             /* Boolean */
3414             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
3415             ok(hr == S_OK, "ret %08x\n", hr );
3416             if(hr == S_OK)
3417             {
3418                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3419
3420                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
3421                 ok(hr == S_OK, "ret %08x\n", hr );
3422
3423                 IXMLDOMElement_Release(pElement);
3424             }
3425
3426             /* String */
3427             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
3428             ok(hr == S_OK, "ret %08x\n", hr );
3429             if(hr == S_OK)
3430             {
3431                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3432
3433                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
3434                 ok(hr == S_OK, "ret %08x\n", hr );
3435
3436                 IXMLDOMElement_Release(pElement);
3437             }
3438
3439             /* Number */
3440             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
3441             ok(hr == S_OK, "ret %08x\n", hr );
3442             if(hr == S_OK)
3443             {
3444                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3445
3446                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
3447                 ok(hr == S_OK, "ret %08x\n", hr );
3448
3449                 IXMLDOMElement_Release(pElement);
3450             }
3451
3452             /* Int */
3453             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
3454             ok(hr == S_OK, "ret %08x\n", hr );
3455             if(hr == S_OK)
3456             {
3457                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3458
3459                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
3460                 ok(hr == S_OK, "ret %08x\n", hr );
3461
3462                 IXMLDOMElement_Release(pElement);
3463             }
3464
3465             /* Fixed */
3466             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
3467             ok(hr == S_OK, "ret %08x\n", hr );
3468             if(hr == S_OK)
3469             {
3470                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3471
3472                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
3473                 ok(hr == S_OK, "ret %08x\n", hr );
3474
3475                 IXMLDOMElement_Release(pElement);
3476             }
3477
3478             /* DateTime */
3479             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
3480             ok(hr == S_OK, "ret %08x\n", hr );
3481             if(hr == S_OK)
3482             {
3483                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3484
3485                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
3486                 ok(hr == S_OK, "ret %08x\n", hr );
3487
3488                 IXMLDOMElement_Release(pElement);
3489             }
3490
3491             /* DateTime TZ */
3492             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
3493             ok(hr == S_OK, "ret %08x\n", hr );
3494             if(hr == S_OK)
3495             {
3496                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3497
3498                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
3499                 ok(hr == S_OK, "ret %08x\n", hr );
3500
3501                 IXMLDOMElement_Release(pElement);
3502             }
3503
3504             /* Date */
3505             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
3506             ok(hr == S_OK, "ret %08x\n", hr );
3507             if(hr == S_OK)
3508             {
3509                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3510
3511                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
3512                 ok(hr == S_OK, "ret %08x\n", hr );
3513
3514                 IXMLDOMElement_Release(pElement);
3515             }
3516
3517             /* Time */
3518             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
3519             ok(hr == S_OK, "ret %08x\n", hr );
3520             if(hr == S_OK)
3521             {
3522                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3523
3524                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
3525                 ok(hr == S_OK, "ret %08x\n", hr );
3526
3527                 IXMLDOMElement_Release(pElement);
3528             }
3529
3530             /* Time.tz */
3531             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
3532             ok(hr == S_OK, "ret %08x\n", hr );
3533             if(hr == S_OK)
3534             {
3535                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3536
3537                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
3538                 ok(hr == S_OK, "ret %08x\n", hr );
3539
3540                 IXMLDOMElement_Release(pElement);
3541             }
3542
3543             /* I1 */
3544             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
3545             ok(hr == S_OK, "ret %08x\n", hr );
3546             if(hr == S_OK)
3547             {
3548                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3549
3550                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
3551                 ok(hr == S_OK, "ret %08x\n", hr );
3552
3553                 IXMLDOMElement_Release(pElement);
3554             }
3555
3556             /* I2 */
3557             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
3558             ok(hr == S_OK, "ret %08x\n", hr );
3559             if(hr == S_OK)
3560             {
3561                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3562
3563                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
3564                 ok(hr == S_OK, "ret %08x\n", hr );
3565
3566                 IXMLDOMElement_Release(pElement);
3567             }
3568
3569             /* I4 */
3570             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
3571             ok(hr == S_OK, "ret %08x\n", hr );
3572             if(hr == S_OK)
3573             {
3574                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3575
3576                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
3577                 ok(hr == S_OK, "ret %08x\n", hr );
3578
3579                 IXMLDOMElement_Release(pElement);
3580             }
3581
3582             /* UI1 */
3583             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
3584             ok(hr == S_OK, "ret %08x\n", hr );
3585             if(hr == S_OK)
3586             {
3587                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3588
3589                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
3590                 ok(hr == S_OK, "ret %08x\n", hr );
3591
3592                 IXMLDOMElement_Release(pElement);
3593             }
3594
3595             /* UI2 */
3596             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
3597             ok(hr == S_OK, "ret %08x\n", hr );
3598             if(hr == S_OK)
3599             {
3600                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3601
3602                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
3603                 ok(hr == S_OK, "ret %08x\n", hr );
3604
3605                 IXMLDOMElement_Release(pElement);
3606             }
3607
3608             /* UI4 */
3609             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
3610             ok(hr == S_OK, "ret %08x\n", hr );
3611             if(hr == S_OK)
3612             {
3613                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3614
3615                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
3616                 ok(hr == S_OK, "ret %08x\n", hr );
3617
3618                 IXMLDOMElement_Release(pElement);
3619             }
3620
3621             /* r4 */
3622             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
3623             ok(hr == S_OK, "ret %08x\n", hr );
3624             if(hr == S_OK)
3625             {
3626                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3627
3628                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
3629                 ok(hr == S_OK, "ret %08x\n", hr );
3630
3631                 IXMLDOMElement_Release(pElement);
3632             }
3633
3634             /* r8 */
3635             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
3636             ok(hr == S_OK, "ret %08x\n", hr );
3637             if(hr == S_OK)
3638             {
3639                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3640
3641                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
3642                 ok(hr == S_OK, "ret %08x\n", hr );
3643
3644                 IXMLDOMElement_Release(pElement);
3645             }
3646
3647             /* float */
3648             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
3649             ok(hr == S_OK, "ret %08x\n", hr );
3650             if(hr == S_OK)
3651             {
3652                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3653
3654                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
3655                 ok(hr == S_OK, "ret %08x\n", hr );
3656
3657                 IXMLDOMElement_Release(pElement);
3658             }
3659
3660             /* uuid */
3661             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
3662             ok(hr == S_OK, "ret %08x\n", hr );
3663             if(hr == S_OK)
3664             {
3665                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3666
3667                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
3668                 ok(hr == S_OK, "ret %08x\n", hr );
3669
3670                 IXMLDOMElement_Release(pElement);
3671             }
3672
3673             /* bin.hex */
3674             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
3675             ok(hr == S_OK, "ret %08x\n", hr );
3676             if(hr == S_OK)
3677             {
3678                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3679
3680                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
3681                 ok(hr == S_OK, "ret %08x\n", hr );
3682
3683                 IXMLDOMElement_Release(pElement);
3684             }
3685
3686             /* bin.base64 */
3687             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
3688             ok(hr == S_OK, "ret %08x\n", hr );
3689             if(hr == S_OK)
3690             {
3691                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3692
3693                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
3694                 ok(hr == S_OK, "ret %08x\n", hr );
3695
3696                 IXMLDOMElement_Release(pElement);
3697             }
3698
3699             /* Check changing types */
3700             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
3701             ok(hr == S_OK, "ret %08x\n", hr );
3702             if(hr == S_OK)
3703             {
3704                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3705
3706                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
3707                 ok(hr == S_OK, "ret %08x\n", hr );
3708
3709                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
3710                 ok(hr == S_OK, "ret %08x\n", hr );
3711
3712                 IXMLDOMElement_Release(pElement);
3713             }
3714
3715             IXMLDOMElement_Release(pRoot);
3716         }
3717     }
3718
3719     IXMLDOMDocument_Release(doc);
3720
3721     free_bstrs();
3722 }
3723
3724 static void test_DocumentSaveToDocument(void)
3725 {
3726     IXMLDOMDocument *doc = NULL;
3727     IXMLDOMDocument *doc2 = NULL;
3728     IXMLDOMElement *pRoot;
3729
3730     HRESULT hr;
3731
3732     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3733     if( hr != S_OK )
3734         return;
3735
3736     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc2 );
3737     if( hr != S_OK )
3738     {
3739         IXMLDOMDocument_Release(doc);
3740         return;
3741     }
3742
3743     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
3744     ok(hr == S_OK, "ret %08x\n", hr );
3745     if(hr == S_OK)
3746     {
3747         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
3748         ok(hr == S_OK, "ret %08x\n", hr );
3749         if(hr == S_OK)
3750         {
3751             VARIANT vDoc;
3752             BSTR sOrig;
3753             BSTR sNew;
3754
3755             V_VT(&vDoc) = VT_UNKNOWN;
3756             V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
3757
3758             hr = IXMLDOMDocument_save(doc, vDoc);
3759             ok(hr == S_OK, "ret %08x\n", hr );
3760
3761             hr = IXMLDOMDocument_get_xml(doc, &sOrig);
3762             ok(hr == S_OK, "ret %08x\n", hr );
3763
3764             hr = IXMLDOMDocument_get_xml(doc2, &sNew);
3765             ok(hr == S_OK, "ret %08x\n", hr );
3766
3767             ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as origial\n");
3768
3769             SysFreeString(sOrig);
3770             SysFreeString(sNew);
3771         }
3772     }
3773
3774     IXMLDOMDocument_Release(doc2);
3775     IXMLDOMDocument_Release(doc);
3776 }
3777
3778 static void test_DocumentSaveToFile(void)
3779 {
3780     IXMLDOMDocument *doc = NULL;
3781     IXMLDOMElement *pRoot;
3782     HANDLE file;
3783     char buffer[100];
3784     DWORD read = 0;
3785     HRESULT hr;
3786
3787     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3788     if( hr != S_OK )
3789         return;
3790
3791     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
3792     ok(hr == S_OK, "ret %08x\n", hr );
3793     if(hr == S_OK)
3794     {
3795         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
3796         ok(hr == S_OK, "ret %08x\n", hr );
3797         if(hr == S_OK)
3798         {
3799             VARIANT vFile;
3800
3801             V_VT(&vFile) = VT_BSTR;
3802             V_BSTR(&vFile) = _bstr_("test.xml");
3803
3804             hr = IXMLDOMDocument_save(doc, vFile);
3805             ok(hr == S_OK, "ret %08x\n", hr );
3806         }
3807     }
3808
3809     IXMLDOMElement_Release(pRoot);
3810     IXMLDOMDocument_Release(doc);
3811
3812     file = CreateFile("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
3813     ok(file != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
3814     if(file == INVALID_HANDLE_VALUE)
3815         return;
3816
3817     ReadFile(file, buffer, sizeof(buffer), &read, NULL);
3818     ok(read != 0, "could not read file\n");
3819     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
3820
3821     CloseHandle(file);
3822     DeleteFile("test.xml");
3823 }
3824
3825 static void test_testTransforms(void)
3826 {
3827     IXMLDOMDocument *doc = NULL;
3828     IXMLDOMDocument *docSS = NULL;
3829     IXMLDOMNode *pNode;
3830     VARIANT_BOOL bSucc;
3831
3832     HRESULT hr;
3833
3834     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3835     if( hr != S_OK )
3836         return;
3837
3838     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&docSS );
3839     if( hr != S_OK )
3840     {
3841         IXMLDOMDocument_Release(doc);
3842         return;
3843     }
3844
3845     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
3846     ok(hr == S_OK, "ret %08x\n", hr );
3847
3848     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
3849     ok(hr == S_OK, "ret %08x\n", hr );
3850
3851     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (LPVOID*)&pNode );
3852     ok(hr == S_OK, "ret %08x\n", hr );
3853     if(hr == S_OK)
3854     {
3855         BSTR bOut;
3856
3857         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
3858         ok(hr == S_OK, "ret %08x\n", hr );
3859         ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
3860         SysFreeString(bOut);
3861
3862         IXMLDOMNode_Release(pNode);
3863     }
3864
3865     IXMLDOMDocument_Release(docSS);
3866     IXMLDOMDocument_Release(doc);
3867
3868     free_bstrs();
3869 }
3870
3871 static void test_Namespaces(void)
3872 {
3873     IXMLDOMDocument2 *doc = NULL;
3874     IXMLDOMNode *pNode;
3875     IXMLDOMNode *pNode2 = NULL;
3876     VARIANT_BOOL bSucc;
3877     HRESULT hr;
3878     BSTR str;
3879     static  const CHAR szNamespacesXML[] =
3880 "<?xml version=\"1.0\"?>\n"
3881 "<root xmlns:WEB='http://www.winehq.org'>\n"
3882 "<WEB:Site version=\"1.0\" />\n"
3883 "</root>";
3884
3885     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3886     if( hr != S_OK )
3887         return;
3888
3889     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNamespacesXML), &bSucc);
3890     ok(hr == S_OK, "ret %08x\n", hr );
3891     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
3892
3893     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root"), &pNode );
3894     ok(hr == S_OK, "ret %08x\n", hr );
3895     if(hr == S_OK)
3896     {
3897         hr = IXMLDOMNode_get_firstChild( pNode, &pNode2 );
3898         ok( hr == S_OK, "ret %08x\n", hr );
3899         ok( pNode2 != NULL, "pNode2 == NULL\n");
3900
3901         /* Test get_prefix */
3902         hr = IXMLDOMNode_get_prefix(pNode2, NULL);
3903         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
3904         /* NOTE: Need to test that arg2 gets cleared on Error. */
3905
3906         hr = IXMLDOMNode_get_prefix(pNode2, &str);
3907         ok( hr == S_OK, "ret %08x\n", hr );
3908         ok( !lstrcmpW( str, _bstr_("WEB")), "incorrect prefix string\n");
3909         SysFreeString(str);
3910
3911         /* Test get_namespaceURI */
3912         hr = IXMLDOMNode_get_namespaceURI(pNode2, NULL);
3913         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
3914         /* NOTE: Need to test that arg2 gets cleared on Error. */
3915
3916         hr = IXMLDOMNode_get_namespaceURI(pNode2, &str);
3917         ok( hr == S_OK, "ret %08x\n", hr );
3918         ok( !lstrcmpW( str, _bstr_("http://www.winehq.org")), "incorrect namespaceURI string\n");
3919         SysFreeString(str);
3920
3921         IXMLDOMNode_Release(pNode2);
3922         IXMLDOMNode_Release(pNode);
3923     }
3924
3925     IXMLDOMDocument2_Release(doc);
3926
3927     free_bstrs();
3928 }
3929
3930 static void test_FormattingXML(void)
3931 {
3932     IXMLDOMDocument2 *doc = NULL;
3933     IXMLDOMElement *pElement;
3934     VARIANT_BOOL bSucc;
3935     HRESULT hr;
3936     BSTR str;
3937     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
3938     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
3939
3940     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3941     if( hr != S_OK )
3942         return;
3943
3944     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
3945     ok(hr == S_OK, "ret %08x\n", hr );
3946     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
3947
3948     if(bSucc == VARIANT_TRUE)
3949     {
3950         hr = IXMLDOMDocument2_get_documentElement(doc, &pElement);
3951         ok(hr == S_OK, "ret %08x\n", hr );
3952         if(hr == S_OK)
3953         {
3954             hr = IXMLDOMElement_get_xml(pElement, &str);
3955             ok(hr == S_OK, "ret %08x\n", hr );
3956             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
3957             SysFreeString(str);
3958
3959             IXMLDOMElement_Release(pElement);
3960         }
3961     }
3962
3963     IXMLDOMDocument2_Release(doc);
3964
3965     free_bstrs();
3966 }
3967
3968 static void test_NodeTypeValue(void)
3969 {
3970     IXMLDOMDocument2 *doc = NULL;
3971     IXMLDOMNode *pNode;
3972     VARIANT_BOOL bSucc;
3973     HRESULT hr;
3974     VARIANT v;
3975
3976     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3977     if( hr != S_OK )
3978         return;
3979
3980     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
3981     ok(hr == S_OK, "ret %08x\n", hr );
3982     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
3983     if(bSucc == VARIANT_TRUE)
3984     {
3985         hr = IXMLDOMDocument2_get_nodeValue(doc, NULL);
3986         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3987
3988         V_VT(&v) = VT_BSTR;
3989         V_BSTR(&v) = NULL;
3990         hr = IXMLDOMDocument2_get_nodeValue(doc, &v);
3991         ok(hr == S_FALSE, "ret %08x\n", hr );
3992         ok(V_VT(&v) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&v));
3993
3994         hr = IXMLDOMDocument2_get_nodeTypedValue(doc, NULL);
3995         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3996
3997         hr = IXMLDOMDocument2_get_nodeTypedValue(doc, &v);
3998         ok(hr == S_FALSE, "ret %08x\n", hr );
3999
4000         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/string"), &pNode);
4001         ok(hr == S_OK, "ret %08x\n", hr );
4002         if(hr == S_OK)
4003         {
4004             V_VT(&v) = VT_BSTR;
4005             V_BSTR(&v) = NULL;
4006             hr = IXMLDOMNode_get_nodeValue(pNode, &v);
4007             ok(hr == S_FALSE, "ret %08x\n", hr );
4008             ok(V_VT(&v) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&v));
4009
4010             hr = IXMLDOMNode_get_nodeTypedValue(pNode, NULL);
4011             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4012
4013             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4014             ok(hr == S_OK, "ret %08x\n", hr );
4015             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4016             ok(!lstrcmpW( V_BSTR(&v), _bstr_("Wine") ), "incorrect value\n");
4017             VariantClear( &v );
4018
4019             IXMLDOMNode_Release(pNode);
4020         }
4021
4022         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/string2"), &pNode);
4023         ok(hr == S_OK, "ret %08x\n", hr );
4024         if(hr == S_OK)
4025         {
4026             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4027             ok(hr == S_OK, "ret %08x\n", hr );
4028             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4029             ok(!lstrcmpW( V_BSTR(&v), _bstr_("String") ), "incorrect value\n");
4030             VariantClear( &v );
4031
4032             IXMLDOMNode_Release(pNode);
4033         }
4034
4035         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/number"), &pNode);
4036         ok(hr == S_OK, "ret %08x\n", hr );
4037         if(hr == S_OK)
4038         {
4039             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4040             ok(hr == S_OK, "ret %08x\n", hr );
4041             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4042             ok(!lstrcmpW( V_BSTR(&v), _bstr_("12.44") ), "incorrect value\n");
4043             VariantClear( &v );
4044
4045             IXMLDOMNode_Release(pNode);
4046         }
4047
4048         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/number2"), &pNode);
4049         ok(hr == S_OK, "ret %08x\n", hr );
4050         if(hr == S_OK)
4051         {
4052             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4053             ok(hr == S_OK, "ret %08x\n", hr );
4054             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4055             ok(!lstrcmpW( V_BSTR(&v), _bstr_("-3.71e3") ), "incorrect value\n");
4056             VariantClear( &v );
4057
4058             IXMLDOMNode_Release(pNode);
4059         }
4060
4061         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/int"), &pNode);
4062         ok(hr == S_OK, "ret %08x\n", hr );
4063         if(hr == S_OK)
4064         {
4065             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4066             ok(hr == S_OK, "ret %08x\n", hr );
4067             ok(V_VT(&v) == VT_I4, "incorrect type\n");
4068             ok(V_I4(&v) == -13, "incorrect value\n");
4069             VariantClear( &v );
4070
4071             IXMLDOMNode_Release(pNode);
4072         }
4073
4074         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/fixed"), &pNode);
4075         ok(hr == S_OK, "ret %08x\n", hr );
4076         if(hr == S_OK)
4077         {
4078             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4079             ok(hr == S_OK, "ret %08x\n", hr );
4080             ok(V_VT(&v) == VT_CY, "incorrect type\n");
4081             VariantClear(&v);
4082
4083             IXMLDOMNode_Release(pNode);
4084         }
4085
4086         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/bool"), &pNode);
4087         ok(hr == S_OK, "ret %08x\n", hr );
4088         if(hr == S_OK)
4089         {
4090             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4091             ok(hr == S_OK, "ret %08x\n", hr );
4092             ok(V_VT(&v) == VT_BOOL, "incorrect type\n");
4093             ok(V_BOOL(&v) == VARIANT_TRUE, "incorrect value\n");
4094             VariantClear( &v );
4095
4096             IXMLDOMNode_Release(pNode);
4097         }
4098
4099         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetime"), &pNode);
4100         ok(hr == S_OK, "ret %08x\n", hr );
4101         if(hr == S_OK)
4102         {
4103             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4104             ok(hr == S_OK, "ret %08x\n", hr );
4105             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4106             double_eq(40135.13996527778, V_DATE(&v));
4107             VariantClear( &v );
4108
4109             IXMLDOMNode_Release(pNode);
4110         }
4111
4112         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetimetz"), &pNode);
4113         ok(hr == S_OK, "ret %08x\n", hr );
4114         if(hr == S_OK)
4115         {
4116             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4117             ok(hr == S_OK, "ret %08x\n", hr );
4118             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4119             double_eq(37813.59302083334, V_DATE(&v));
4120             VariantClear( &v );
4121
4122             IXMLDOMNode_Release(pNode);
4123         }
4124
4125         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/date"), &pNode);
4126         ok(hr == S_OK, "ret %08x\n", hr );
4127         if(hr == S_OK)
4128         {
4129             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4130             ok(hr == S_OK, "ret %08x\n", hr );
4131             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4132             double_eq(665413.0, V_DATE(&v));
4133             VariantClear( &v );
4134
4135             IXMLDOMNode_Release(pNode);
4136         }
4137
4138         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/time"), &pNode);
4139         ok(hr == S_OK, "ret %08x\n", hr );
4140         if(hr == S_OK)
4141         {
4142             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4143             ok(hr == S_OK, "ret %08x\n", hr );
4144             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4145             double_eq(0.5813888888888888, V_DATE(&v));
4146             VariantClear( &v );
4147
4148             IXMLDOMNode_Release(pNode);
4149         }
4150
4151         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/timetz"), &pNode);
4152         ok(hr == S_OK, "ret %08x\n", hr );
4153         if(hr == S_OK)
4154         {
4155             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4156             ok(hr == S_OK, "ret %08x\n", hr );
4157             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4158             double_eq(1.112511574074074, V_DATE(&v));
4159             VariantClear( &v );
4160
4161             IXMLDOMNode_Release(pNode);
4162         }
4163
4164         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i1"), &pNode);
4165         ok(hr == S_OK, "ret %08x\n", hr );
4166         if(hr == S_OK)
4167         {
4168             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4169             ok(hr == S_OK, "ret %08x\n", hr );
4170             ok(V_VT(&v) == VT_I1, "incorrect type\n");
4171             ok(V_I1(&v) == -13, "incorrect value\n");
4172             VariantClear( &v );
4173
4174             IXMLDOMNode_Release(pNode);
4175         }
4176
4177         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i2"), &pNode);
4178         ok(hr == S_OK, "ret %08x\n", hr );
4179         if(hr == S_OK)
4180         {
4181             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4182             ok(hr == S_OK, "ret %08x\n", hr );
4183             ok(V_VT(&v) == VT_I2, "incorrect type\n");
4184             ok(V_I2(&v) == 31915, "incorrect value\n");
4185             VariantClear( &v );
4186
4187             IXMLDOMNode_Release(pNode);
4188         }
4189
4190         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i4"), &pNode);
4191         ok(hr == S_OK, "ret %08x\n", hr );
4192         if(hr == S_OK)
4193         {
4194             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4195             ok(hr == S_OK, "ret %08x\n", hr );
4196             ok(V_VT(&v) == VT_I4, "incorrect type\n");
4197             ok(V_I4(&v) == -312232, "incorrect value\n");
4198             VariantClear(&v);
4199
4200             IXMLDOMNode_Release(pNode);
4201         }
4202
4203         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui1"), &pNode);
4204         ok(hr == S_OK, "ret %08x\n", hr );
4205         if(hr == S_OK)
4206         {
4207             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4208             ok(hr == S_OK, "ret %08x\n", hr );
4209             ok(V_VT(&v) == VT_UI1, "incorrect type\n");
4210             ok(V_UI1(&v) == 123, "incorrect value\n");
4211             VariantClear(&v);
4212
4213             IXMLDOMNode_Release(pNode);
4214         }
4215
4216         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui2"), &pNode);
4217         ok(hr == S_OK, "ret %08x\n", hr );
4218         if(hr == S_OK)
4219         {
4220             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4221             ok(hr == S_OK, "ret %08x\n", hr );
4222             ok(V_VT(&v) == VT_UI2, "incorrect type\n");
4223             ok(V_UI2(&v) == 48282, "incorrect value\n");
4224             VariantClear(&v);
4225
4226             IXMLDOMNode_Release(pNode);
4227         }
4228
4229         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui4"), &pNode);
4230         ok(hr == S_OK, "ret %08x\n", hr );
4231         if(hr == S_OK)
4232         {
4233             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4234             ok(hr == S_OK, "ret %08x\n", hr );
4235             ok(V_VT(&v) == VT_UI4, "incorrect type\n");
4236             ok(V_UI4(&v) == 949281, "incorrect value\n");
4237             VariantClear(&v);
4238
4239             IXMLDOMNode_Release(pNode);
4240         }
4241
4242         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/r4"), &pNode);
4243         ok(hr == S_OK, "ret %08x\n", hr );
4244         if(hr == S_OK)
4245         {
4246             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4247             ok(hr == S_OK, "ret %08x\n", hr );
4248             ok(V_VT(&v) == VT_R4, "incorrect type\n");
4249             double_eq(213124.0, V_R4(&v));
4250             VariantClear(&v);
4251
4252             IXMLDOMNode_Release(pNode);
4253         }
4254
4255         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/r8"), &pNode);
4256         ok(hr == S_OK, "ret %08x\n", hr );
4257         if(hr == S_OK)
4258         {
4259             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4260             ok(hr == S_OK, "ret %08x\n", hr );
4261             ok(V_VT(&v) == VT_R8, "incorrect type\n");
4262             double_eq(0.412, V_R8(&v));
4263             VariantClear(&v);
4264
4265             IXMLDOMNode_Release(pNode);
4266         }
4267
4268         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/float"), &pNode);
4269         ok(hr == S_OK, "ret %08x\n", hr );
4270         if(hr == S_OK)
4271         {
4272             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4273             ok(hr == S_OK, "ret %08x\n", hr );
4274             ok(V_VT(&v) == VT_R8, "incorrect type\n");
4275             double_eq(41221.421, V_R8(&v));
4276             VariantClear(&v);
4277
4278             IXMLDOMNode_Release(pNode);
4279         }
4280
4281         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/uuid"), &pNode);
4282         ok(hr == S_OK, "ret %08x\n", hr );
4283         if(hr == S_OK)
4284         {
4285             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4286             ok(hr == S_OK, "ret %08x\n", hr );
4287             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4288             ok(!lstrcmpW(V_BSTR(&v), _bstr_("333C7BC4-460F-11D0-BC04-0080C7055a83")), "incorrect value\n");
4289             VariantClear(&v);
4290
4291             IXMLDOMNode_Release(pNode);
4292         }
4293     }
4294
4295     IXMLDOMDocument2_Release(doc);
4296
4297     free_bstrs();
4298 }
4299
4300 static void test_TransformWithLoadingLocalFile(void)
4301 {
4302     IXMLDOMDocument2 *doc = NULL;
4303     IXMLDOMDocument2 *xsl = NULL;
4304     IXMLDOMNode *pNode;
4305     VARIANT_BOOL bSucc;
4306     HRESULT hr;
4307     HANDLE file;
4308     DWORD dwWritten;
4309     char lpPathBuffer[MAX_PATH];
4310     int i;
4311
4312     /* Create a Temp File. */
4313     GetTempPathA(MAX_PATH, lpPathBuffer);
4314     strcat(lpPathBuffer, "customers.xml" );
4315
4316     file = CreateFile(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
4317     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
4318     if(file == INVALID_HANDLE_VALUE)
4319         return;
4320
4321     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
4322     CloseHandle(file);
4323
4324     /* Correct path to not include a escape character. */
4325     for(i=0; i < strlen(lpPathBuffer); i++)
4326     {
4327         if(lpPathBuffer[i] == '\\')
4328             lpPathBuffer[i] = '/';
4329     }
4330
4331     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4332     if( hr != S_OK )
4333         return;
4334
4335     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&xsl );
4336     if( hr != S_OK )
4337     {
4338         IXMLDOMDocument2_Release(doc);
4339         return;
4340     }
4341
4342     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
4343     ok(hr == S_OK, "ret %08x\n", hr );
4344     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
4345     if(bSucc == VARIANT_TRUE)
4346     {
4347         BSTR sXSL;
4348         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
4349         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
4350         BSTR sFileName = _bstr_(lpPathBuffer);
4351         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
4352
4353         sXSL = SysAllocStringLen(NULL, nLegnth);
4354         lstrcpyW(sXSL, sPart1);
4355         lstrcatW(sXSL, sFileName);
4356         lstrcatW(sXSL, sPart2);
4357
4358         hr = IXMLDOMDocument2_loadXML(xsl, sXSL, &bSucc);
4359         ok(hr == S_OK, "ret %08x\n", hr );
4360         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
4361         if(bSucc == VARIANT_TRUE)
4362         {
4363             BSTR sResult;
4364
4365             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (LPVOID*)&pNode );
4366             ok(hr == S_OK, "ret %08x\n", hr );
4367             if(hr == S_OK)
4368             {
4369                 /* This will load the temp file via the XSL */
4370                 hr = IXMLDOMDocument2_transformNode(doc, pNode, &sResult);
4371                 ok(hr == S_OK, "ret %08x\n", hr );
4372                 if(hr == S_OK)
4373                 {
4374                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
4375                     SysFreeString(sResult);
4376                 }
4377
4378                 IXMLDOMNode_Release(pNode);
4379             }
4380         }
4381
4382         SysFreeString(sXSL);
4383     }
4384
4385     IXMLDOMDocument2_Release(doc);
4386     IXMLDOMDocument2_Release(xsl);
4387
4388     DeleteFile(lpPathBuffer);
4389     free_bstrs();
4390 }
4391
4392 START_TEST(domdoc)
4393 {
4394     HRESULT r;
4395
4396     r = CoInitialize( NULL );
4397     ok( r == S_OK, "failed to init com\n");
4398
4399     test_domdoc();
4400     test_domnode();
4401     test_refs();
4402     test_create();
4403     test_getElementsByTagName();
4404     test_get_text();
4405     test_get_childNodes();
4406     test_removeChild();
4407     test_replaceChild();
4408     test_removeNamedItem();
4409     test_XMLHTTP();
4410     test_IXMLDOMDocument2();
4411     test_XPath();
4412     test_cloneNode();
4413     test_xmlTypes();
4414     test_nodeTypeTests();
4415     test_DocumentSaveToDocument();
4416     test_DocumentSaveToFile();
4417     test_testTransforms();
4418     test_Namespaces();
4419     test_FormattingXML();
4420     test_NodeTypeValue();
4421     test_TransformWithLoadingLocalFile();
4422
4423     CoUninitialize();
4424 }