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