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