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