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