samlib: Add stubbed samlib.dll.
[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     if (hr == INET_E_RESOURCE_NOT_FOUND)
2754     {
2755         skip("No connection could be made with crossover.codeweavers.com\n");
2756         IXMLHttpRequest_Release(pXMLHttpRequest);
2757         return;
2758     }
2759     todo_wine ok(hr == S_OK, "IXMLHttpRequest_send should have succeeded instead of failing with 0x%08x\n", hr);
2760     VariantClear(&varbody);
2761
2762     hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
2763     todo_wine ok(hr == S_OK, "IXMLHttpRequest_get_responseText should have succeeded instead of failing with 0x%08x\n", hr);
2764     /* the server currently returns "FAILED" because the Content-Type header is
2765      * not what the server expects */
2766     if(hr == S_OK)
2767     {
2768         ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)), "bstrResponse differs from what was expected\n");
2769         SysFreeString(bstrResponse);
2770     }
2771
2772     IXMLHttpRequest_Release(pXMLHttpRequest);
2773 }
2774
2775 static void test_IXMLDOMDocument2(void)
2776 {
2777     HRESULT r;
2778     VARIANT_BOOL b;
2779     BSTR str;
2780     IXMLDOMDocument *doc;
2781     IXMLDOMDocument2 *doc2;
2782     IDispatchEx *dispex;
2783     VARIANT var;
2784     int ref;
2785
2786     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2787         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2788     if( r != S_OK )
2789         return;
2790
2791     str = SysAllocString( szComplete4 );
2792     r = IXMLDOMDocument_loadXML( doc, str, &b );
2793     ok( r == S_OK, "loadXML failed\n");
2794     ok( b == VARIANT_TRUE, "failed to load XML string\n");
2795     SysFreeString( str );
2796
2797     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
2798     ok( r == S_OK, "ret %08x\n", r );
2799     ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
2800
2801     r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
2802     ok( r == S_OK, "ret %08x\n", r );
2803     if(r == S_OK)
2804     {
2805         IDispatchEx_Release(dispex);
2806     }
2807
2808     /* we will check if the variant got cleared */
2809     ref = IXMLDOMDocument2_AddRef(doc2);
2810     expect_eq(ref, 3, int, "%d");  /* doc, doc2, AddRef*/
2811     V_VT(&var) = VT_UNKNOWN;
2812     V_UNKNOWN(&var) = (IUnknown *)doc2;
2813
2814     /* invalid calls */
2815     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
2816     expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
2817     ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
2818
2819     /* valid call */
2820     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
2821     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2822     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
2823     V_VT(&var) = VT_R4;
2824
2825     /* the variant didn't get cleared*/
2826     expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
2827
2828     /* setProperty tests */
2829     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
2830     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
2831     ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
2832     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
2833     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
2834     ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
2835
2836     /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
2837     ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
2838     expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2839     expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
2840
2841     IXMLDOMDocument2_Release( doc2 );
2842     IXMLDOMDocument_Release( doc );
2843     free_bstrs();
2844 }
2845
2846 static void test_XPath(void)
2847 {
2848     HRESULT r;
2849     VARIANT var;
2850     VARIANT_BOOL b;
2851     IXMLDOMDocument2 *doc;
2852     IXMLDOMNode *rootNode;
2853     IXMLDOMNode *elem1Node;
2854     IXMLDOMNode *node;
2855     IXMLDOMNodeList *list;
2856
2857     r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2858         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
2859     if( r != S_OK )
2860         return;
2861
2862     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b));
2863     ok(b == VARIANT_TRUE, "failed to load XML string\n");
2864
2865     /* switch to XPath */
2866     ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
2867
2868     /* some simple queries*/
2869     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list));
2870     ole_check(IXMLDOMNodeList_get_item(list, 0, &rootNode));
2871     ole_check(IXMLDOMNodeList_reset(list));
2872     expect_list_and_release(list, "E2.D1");
2873     if (rootNode == NULL)
2874         return;
2875
2876     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//c"), &list));
2877     expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
2878
2879     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//c[@type]"), &list));
2880     expect_list_and_release(list, "E3.E2.E2.D1");
2881
2882     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
2883     /* using get_item for query results advances the position */
2884     ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
2885     expect_node(node, "E2.E2.D1");
2886     IXMLDOMNode_Release(node);
2887     ole_check(IXMLDOMNodeList_nextNode(list, &node));
2888     expect_node(node, "E4.E2.D1");
2889     IXMLDOMNode_Release(node);
2890     ole_check(IXMLDOMNodeList_reset(list));
2891     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
2892
2893     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
2894     expect_list_and_release(list, "E2.D1");
2895
2896     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
2897     ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
2898     ole_check(IXMLDOMNodeList_reset(list));
2899     expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
2900
2901     /* select an attribute */
2902     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
2903     expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
2904
2905     /* would evaluate to a number */
2906     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
2907     /* would evaluate to a boolean */
2908     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
2909     /* would evaluate to a string */
2910     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
2911
2912     /* no results */
2913     ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
2914     expect_list_and_release(list, "");
2915     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
2916     expect_list_and_release(list, "");
2917     ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
2918     expect_list_and_release(list, "");
2919
2920     /* foo undeclared in document node */
2921     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2922     /* undeclared in <root> node */
2923     ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
2924     /* undeclared in <elem> node */
2925     ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
2926     /* but this trick can be used */
2927     ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
2928     expect_list_and_release(list, "E3.E4.E2.D1");
2929
2930     /* it has to be declared in SelectionNamespaces */
2931     todo_wine ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2932         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
2933
2934     /* now the namespace can be used */
2935     todo_wine ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//test:c"), &list));
2936     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2937     todo_wine ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
2938     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2939     todo_wine ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
2940     todo_wine expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
2941     todo_wine ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
2942     todo_wine expect_list_and_release(list, "E5.E1.E4.E1.E2.D1");
2943
2944     /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
2945     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2946         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
2947
2948     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2949
2950     VariantInit(&var);
2951     todo_wine ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
2952     todo_wine expect_eq(V_VT(&var), VT_BSTR, int, "%x");
2953     if (V_VT(&var) == VT_BSTR)
2954         expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
2955
2956     /* extra attributes - same thing*/
2957     ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
2958         _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
2959     ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
2960
2961     IXMLDOMNode_Release(rootNode);
2962     IXMLDOMNode_Release(elem1Node);
2963     IXMLDOMDocument_Release(doc);
2964     free_bstrs();
2965 }
2966
2967 static void test_cloneNode(void )
2968 {
2969     IXMLDOMDocument *doc = NULL;
2970     VARIANT_BOOL b;
2971     IXMLDOMNodeList *pList;
2972     IXMLDOMNamedNodeMap *mapAttr;
2973     LONG nLength = 0, nLength1 = 0;
2974     LONG nAttrCnt = 0, nAttrCnt1 = 0;
2975     IXMLDOMNode *node;
2976     IXMLDOMNode *node_clone;
2977     IXMLDOMNode *node_first;
2978     HRESULT r;
2979     BSTR str;
2980     static const WCHAR szSearch[] = { 'l', 'c', '/', 'p', 'r', 0 };
2981
2982     r = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
2983     if( r != S_OK )
2984         return;
2985
2986     str = SysAllocString( szComplete4 );
2987     ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
2988     ok(b == VARIANT_TRUE, "failed to load XML string\n");
2989     SysFreeString(str);
2990
2991     if(!b)
2992         return;
2993
2994     str = SysAllocString( szSearch);
2995     r = IXMLDOMNode_selectSingleNode(doc, str, &node);
2996     ok( r == S_OK, "ret %08x\n", r );
2997     ok( node != NULL, "node %p\n", node );
2998     SysFreeString(str);
2999
3000     if(!node)
3001     {
3002         IXMLDOMDocument_Release(doc);
3003         return;
3004     }
3005
3006     /* Check invalid parameter */
3007     r = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
3008     ok( r == E_INVALIDARG, "ret %08x\n", r );
3009
3010     /* All Children */
3011     r = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
3012     ok( r == S_OK, "ret %08x\n", r );
3013     ok( node_clone != NULL, "node %p\n", node );
3014
3015     if(!node_clone)
3016     {
3017         IXMLDOMDocument_Release(doc);
3018         IXMLDOMNode_Release(node);
3019         return;
3020     }
3021
3022     r = IXMLDOMNode_get_firstChild(node_clone, &node_first);
3023     ok( r == S_OK, "ret %08x\n", r );
3024     if(r == S_OK)
3025     {
3026         IXMLDOMDocument *doc2;
3027
3028         r = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
3029         ok( r == S_OK, "ret %08x\n", r );
3030         if(r == S_OK)
3031             IXMLDOMDocument_Release(doc2);
3032
3033         IXMLDOMNode_Release(node_first);
3034     }
3035
3036     r = IXMLDOMNode_get_childNodes(node, &pList);
3037     ok( r == S_OK, "ret %08x\n", r );
3038     if (pList)
3039         {
3040                 IXMLDOMNodeList_get_length(pList, &nLength);
3041                 IXMLDOMNodeList_Release(pList);
3042         }
3043
3044     r = IXMLDOMNode_get_attributes(node, &mapAttr);
3045     ok( r == S_OK, "ret %08x\n", r );
3046     if(mapAttr)
3047     {
3048         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt);
3049         IXMLDOMNamedNodeMap_Release(mapAttr);
3050     }
3051
3052     r = IXMLDOMNode_get_childNodes(node_clone, &pList);
3053     ok( r == S_OK, "ret %08x\n", r );
3054     if (pList)
3055         {
3056                 IXMLDOMNodeList_get_length(pList, &nLength1);
3057                 IXMLDOMNodeList_Release(pList);
3058         }
3059
3060     r = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
3061     ok( r == S_OK, "ret %08x\n", r );
3062     if(mapAttr)
3063     {
3064         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt1);
3065         IXMLDOMNamedNodeMap_Release(mapAttr);
3066     }
3067
3068     ok(nLength == nLength1, "wrong Child count (%d, %d)\n", nLength, nLength1);
3069     ok(nAttrCnt == nAttrCnt1, "wrong Attribute count (%d, %d)\n", nAttrCnt, nAttrCnt1);
3070     IXMLDOMNode_Release(node_clone);
3071
3072     /* No Children */
3073     r = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
3074     ok( r == S_OK, "ret %08x\n", r );
3075     ok( node_clone != NULL, "node %p\n", node );
3076
3077     if(!node_clone)
3078     {
3079         IXMLDOMDocument_Release(doc);
3080         IXMLDOMNode_Release(node);
3081         return;
3082     }
3083
3084     r = IXMLDOMNode_get_firstChild(node_clone, &node_first);
3085     ok( r == S_FALSE, "ret %08x\n", r );
3086     if(r == S_OK)
3087     {
3088         IXMLDOMDocument *doc2;
3089
3090         r = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
3091         ok( r == S_OK, "ret %08x\n", r );
3092         if(r == S_OK)
3093             IXMLDOMDocument_Release(doc2);
3094
3095         IXMLDOMNode_Release(node_first);
3096     }
3097
3098     r = IXMLDOMNode_get_childNodes(node_clone, &pList);
3099     ok( r == S_OK, "ret %08x\n", r );
3100     if (pList)
3101         {
3102                 IXMLDOMNodeList_get_length(pList, &nLength1);
3103         ok( nLength1 == 0, "Length should be 0 (%d)\n", nLength1);
3104                 IXMLDOMNodeList_Release(pList);
3105         }
3106
3107     r = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
3108     ok( r == S_OK, "ret %08x\n", r );
3109     if(mapAttr)
3110     {
3111         IXMLDOMNamedNodeMap_get_length(mapAttr, &nAttrCnt1);
3112         ok( nAttrCnt1 == 3, "Attribute count should be 3 (%d)\n", nAttrCnt1);
3113         IXMLDOMNamedNodeMap_Release(mapAttr);
3114     }
3115
3116     ok(nLength != nLength1, "wrong Child count (%d, %d)\n", nLength, nLength1);
3117     ok(nAttrCnt == nAttrCnt1, "wrong Attribute count (%d, %d)\n", nAttrCnt, nAttrCnt1);
3118     IXMLDOMNode_Release(node_clone);
3119
3120
3121     IXMLDOMNode_Release(node);
3122     IXMLDOMDocument_Release(doc);
3123 }
3124
3125 static void test_xmlTypes(void)
3126 {
3127     IXMLDOMDocument *doc = NULL;
3128     IXMLDOMElement *pRoot;
3129     HRESULT hr;
3130     IXMLDOMComment *pComment;
3131     IXMLDOMElement *pElement;
3132     IXMLDOMAttribute *pAttribute;
3133     IXMLDOMNamedNodeMap *pAttribs;
3134     IXMLDOMCDATASection *pCDataSec;
3135     IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
3136     IXMLDOMDocumentFragment *pDocFrag = NULL;
3137     IXMLDOMEntityReference *pEntityRef = NULL;
3138     BSTR str;
3139     IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;   /* Used for testing Siblings */
3140     VARIANT v;
3141     LONG len = 0;
3142
3143     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
3144     if( hr != S_OK )
3145         return;
3146
3147     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
3148     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3149
3150     hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
3151     ok(hr == S_FALSE, "ret %08x\n", hr );
3152     ok(pNextChild == NULL, "pDocChild not NULL\n");
3153
3154     /* test previous Sibling */
3155     hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
3156     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3157
3158     pNextChild = (IXMLDOMNode *)0x1;
3159     hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
3160     ok(hr == S_FALSE, "ret %08x\n", hr );
3161     ok(pNextChild == NULL, "pNextChild not NULL\n");
3162
3163     /* test get_attributes */
3164     hr = IXMLDOMDocument_get_attributes( doc, NULL );
3165     ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
3166
3167     pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3168     hr = IXMLDOMDocument_get_attributes( doc, &pAttribs);
3169     ok(hr == S_FALSE, "ret %08x\n", hr );
3170     ok( pAttribs == NULL, "pAttribs not NULL\n");
3171
3172     /* test get_dataType */
3173     hr = IXMLDOMDocument_get_dataType(doc, &v);
3174     ok(hr == S_FALSE, "ret %08x\n", hr );
3175     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3176     VariantClear(&v);
3177
3178     /* test nodeTypeString */
3179     hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
3180     ok(hr == S_OK, "ret %08x\n", hr );
3181     ok( !lstrcmpW( str, _bstr_("document") ), "incorrect nodeTypeString string\n");
3182     SysFreeString(str);
3183
3184     /* test implementation */
3185     hr = IXMLDOMDocument_get_implementation(doc, NULL);
3186     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3187
3188     hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
3189     ok(hr == S_OK, "ret %08x\n", hr );
3190     if(hr == S_OK)
3191     {
3192         VARIANT_BOOL hasFeature = VARIANT_TRUE;
3193         BSTR sEmpty = SysAllocStringLen(NULL, 0);
3194
3195         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
3196         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3197
3198         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
3199         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3200
3201         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
3202         ok(hr == S_OK, "ret %08x\n", hr );
3203         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
3204
3205         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
3206         ok(hr == S_OK, "ret %08x\n", hr );
3207         ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
3208
3209         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
3210         ok(hr == S_OK, "ret %08x\n", hr );
3211         ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
3212
3213         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
3214         ok(hr == S_OK, "ret %08x\n", hr );
3215         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
3216
3217         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
3218         ok(hr == S_OK, "ret %08x\n", hr );
3219         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
3220
3221         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
3222         ok(hr == S_OK, "ret %08x\n", hr );
3223         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
3224
3225         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
3226         ok(hr == S_OK, "ret %08x\n", hr );
3227         ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
3228
3229         hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
3230         ok(hr == S_OK, "ret %08x\n", hr );
3231         ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
3232
3233         SysFreeString(sEmpty);
3234         IXMLDOMImplementation_Release(pIXMLDOMImplementation);
3235     }
3236
3237     pRoot = (IXMLDOMElement*)0x1;
3238     hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
3239     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3240     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
3241
3242     pRoot = (IXMLDOMElement*)0x1;
3243     hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
3244     ok(hr == E_FAIL, "ret %08x\n", hr );
3245     ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
3246
3247     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
3248     ok(hr == S_OK, "ret %08x\n", hr );
3249     if(hr == S_OK)
3250     {
3251         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
3252         ok(hr == S_OK, "ret %08x\n", hr );
3253         if(hr == S_OK)
3254         {
3255             /* Comment */
3256             str = SysAllocString(szComment);
3257             hr = IXMLDOMDocument_createComment(doc, str, &pComment);
3258             SysFreeString(str);
3259             ok(hr == S_OK, "ret %08x\n", hr );
3260             if(hr == S_OK)
3261             {
3262                 /* test get_attributes */
3263                 hr = IXMLDOMComment_get_attributes( pComment, NULL );
3264                 ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
3265
3266                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3267                 hr = IXMLDOMComment_get_attributes( pComment, &pAttribs);
3268                 ok(hr == S_FALSE, "ret %08x\n", hr );
3269                 ok( pAttribs == NULL, "pAttribs not NULL\n");
3270
3271                 /* test nodeTypeString */
3272                 hr = IXMLDOMComment_get_nodeTypeString(pComment, &str);
3273                 ok(hr == S_OK, "ret %08x\n", hr );
3274                 ok( !lstrcmpW( str, _bstr_("comment") ), "incorrect nodeTypeString string\n");
3275                 SysFreeString(str);
3276
3277                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
3278                 ok(hr == S_OK, "ret %08x\n", hr );
3279
3280                 hr = IXMLDOMComment_get_nodeName(pComment, &str);
3281                 ok(hr == S_OK, "ret %08x\n", hr );
3282                 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
3283                 SysFreeString(str);
3284
3285                 hr = IXMLDOMComment_get_xml(pComment, &str);
3286                 ok(hr == S_OK, "ret %08x\n", hr );
3287                 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
3288                 SysFreeString(str);
3289
3290                 hr = IXMLDOMComment_get_dataType(pComment, &v);
3291                 ok(hr == S_FALSE, "ret %08x\n", hr );
3292                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3293                 VariantClear(&v);
3294
3295                 /* put data Tests */
3296                 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
3297                 ok(hr == S_OK, "ret %08x\n", hr );
3298
3299                 /* get data Tests */
3300                 hr = IXMLDOMComment_get_data(pComment, &str);
3301                 ok(hr == S_OK, "ret %08x\n", hr );
3302                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
3303                 SysFreeString(str);
3304
3305                 /* get data Tests */
3306                 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
3307                 ok(hr == S_OK, "ret %08x\n", hr );
3308                 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
3309                 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
3310                 VariantClear(&v);
3311
3312                 /* Confirm XML text is good */
3313                 hr = IXMLDOMComment_get_xml(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                 /* Confirm we get the put_data Text back */
3319                 hr = IXMLDOMComment_get_text(pComment, &str);
3320                 ok(hr == S_OK, "ret %08x\n", hr );
3321                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
3322                 SysFreeString(str);
3323
3324                 /* test length property */
3325                 hr = IXMLDOMComment_get_length(pComment, &len);
3326                 ok(hr == S_OK, "ret %08x\n", hr );
3327                 ok(len == 21, "expected 21 got %d\n", len);
3328
3329                 /* test substringData */
3330                 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
3331                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3332
3333                 /* test substringData - Invalid offset */
3334                 str = (BSTR)&szElement;
3335                 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
3336                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3337                 ok( str == NULL, "incorrect string\n");
3338
3339                 /* test substringData - Invalid offset */
3340                 str = (BSTR)&szElement;
3341                 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
3342                 ok(hr == S_FALSE, "ret %08x\n", hr );
3343                 ok( str == NULL, "incorrect string\n");
3344
3345                 /* test substringData - Invalid size */
3346                 str = (BSTR)&szElement;
3347                 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
3348                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3349                 ok( str == NULL, "incorrect string\n");
3350
3351                 /* test substringData - Invalid size */
3352                 str = (BSTR)&szElement;
3353                 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
3354                 ok(hr == S_FALSE, "ret %08x\n", hr );
3355                 ok( str == NULL, "incorrect string\n");
3356
3357                 /* test substringData - Start of string */
3358                 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
3359                 ok(hr == S_OK, "ret %08x\n", hr );
3360                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
3361                 SysFreeString(str);
3362
3363                 /* test substringData - Middle of string */
3364                 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
3365                 ok(hr == S_OK, "ret %08x\n", hr );
3366                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
3367                 SysFreeString(str);
3368
3369                 /* test substringData - End of string */
3370                 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
3371                 ok(hr == S_OK, "ret %08x\n", hr );
3372                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
3373                 SysFreeString(str);
3374
3375                 /* test appendData */
3376                 hr = IXMLDOMComment_appendData(pComment, NULL);
3377                 ok(hr == S_OK, "ret %08x\n", hr );
3378
3379                 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
3380                 ok(hr == S_OK, "ret %08x\n", hr );
3381
3382                 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
3383                 ok(hr == S_OK, "ret %08x\n", hr );
3384
3385                 hr = IXMLDOMComment_get_text(pComment, &str);
3386                 ok(hr == S_OK, "ret %08x\n", hr );
3387                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
3388                 SysFreeString(str);
3389
3390                 /* test insertData */
3391                 str = SysAllocStringLen(NULL, 0);
3392                 hr = IXMLDOMComment_insertData(pComment, -1, str);
3393                 ok(hr == S_OK, "ret %08x\n", hr );
3394
3395                 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
3396                 ok(hr == S_OK, "ret %08x\n", hr );
3397
3398                 hr = IXMLDOMComment_insertData(pComment, 1000, str);
3399                 ok(hr == S_OK, "ret %08x\n", hr );
3400
3401                 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
3402                 ok(hr == S_OK, "ret %08x\n", hr );
3403
3404                 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
3405                 ok(hr == S_OK, "ret %08x\n", hr );
3406
3407                 hr = IXMLDOMComment_insertData(pComment, 0, str);
3408                 ok(hr == S_OK, "ret %08x\n", hr );
3409                 SysFreeString(str);
3410
3411                 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
3412                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3413
3414                 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
3415                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3416
3417                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
3418                 ok(hr == S_OK, "ret %08x\n", hr );
3419
3420                 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
3421                 ok(hr == S_OK, "ret %08x\n", hr );
3422
3423                 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
3424                 ok(hr == S_OK, "ret %08x\n", hr );
3425
3426                 hr = IXMLDOMComment_get_text(pComment, &str);
3427                 ok(hr == S_OK, "ret %08x\n", hr );
3428                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
3429                 SysFreeString(str);
3430
3431                 /* delete data */
3432                 /* invalid arguments */
3433                 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
3434                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3435
3436                 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
3437                 ok(hr == S_OK, "ret %08x\n", hr );
3438
3439                 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
3440                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3441
3442                 hr = IXMLDOMComment_get_length(pComment, &len);
3443                 ok(hr == S_OK, "ret %08x\n", hr );
3444                 ok(len == 43, "expected 43 got %d\n", len);
3445
3446                 hr = IXMLDOMComment_deleteData(pComment, len, 1);
3447                 ok(hr == S_OK, "ret %08x\n", hr );
3448
3449                 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
3450                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3451
3452                 /* delete from start */
3453                 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
3454                 ok(hr == S_OK, "ret %08x\n", hr );
3455
3456                 hr = IXMLDOMComment_get_length(pComment, &len);
3457                 ok(hr == S_OK, "ret %08x\n", hr );
3458                 ok(len == 38, "expected 38 got %d\n", len);
3459
3460                 hr = IXMLDOMComment_get_text(pComment, &str);
3461                 ok(hr == S_OK, "ret %08x\n", hr );
3462                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
3463                 SysFreeString(str);
3464
3465                 /* delete from end */
3466                 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
3467                 ok(hr == S_OK, "ret %08x\n", hr );
3468
3469                 hr = IXMLDOMComment_get_length(pComment, &len);
3470                 ok(hr == S_OK, "ret %08x\n", hr );
3471                 ok(len == 35, "expected 35 got %d\n", len);
3472
3473                 hr = IXMLDOMComment_get_text(pComment, &str);
3474                 ok(hr == S_OK, "ret %08x\n", hr );
3475                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string\n");
3476                 SysFreeString(str);
3477
3478                 /* delete from inside */
3479                 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
3480                 ok(hr == S_OK, "ret %08x\n", hr );
3481
3482                 hr = IXMLDOMComment_get_length(pComment, &len);
3483                 ok(hr == S_OK, "ret %08x\n", hr );
3484                 ok(len == 2, "expected 2 got %d\n", len);
3485
3486                 hr = IXMLDOMComment_get_text(pComment, &str);
3487                 ok(hr == S_OK, "ret %08x\n", hr );
3488                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string\n");
3489                 SysFreeString(str);
3490
3491                 /* delete whole data ... */
3492                 hr = IXMLDOMComment_get_length(pComment, &len);
3493                 ok(hr == S_OK, "ret %08x\n", hr );
3494
3495                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
3496                 ok(hr == S_OK, "ret %08x\n", hr );
3497                 /* ... and try again with empty string */
3498                 hr = IXMLDOMComment_deleteData(pComment, 0, len);
3499                 ok(hr == S_OK, "ret %08x\n", hr );
3500
3501                 /* ::replaceData() */
3502                 V_VT(&v) = VT_BSTR;
3503                 V_BSTR(&v) = SysAllocString(szstr1);
3504                 hr = IXMLDOMComment_put_nodeValue(pComment, v);
3505                 ok(hr == S_OK, "ret %08x\n", hr );
3506                 VariantClear(&v);
3507
3508                 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
3509                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3510                 hr = IXMLDOMComment_get_text(pComment, &str);
3511                 ok(hr == S_OK, "ret %08x\n", hr );
3512                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
3513                 SysFreeString(str);
3514
3515                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
3516                 ok(hr == S_OK, "ret %08x\n", hr );
3517                 hr = IXMLDOMComment_get_text(pComment, &str);
3518                 ok(hr == S_OK, "ret %08x\n", hr );
3519                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
3520                 SysFreeString(str);
3521
3522                 /* NULL pointer means delete */
3523                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
3524                 ok(hr == S_OK, "ret %08x\n", hr );
3525                 hr = IXMLDOMComment_get_text(pComment, &str);
3526                 ok(hr == S_OK, "ret %08x\n", hr );
3527                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string\n");
3528                 SysFreeString(str);
3529
3530                 /* empty string means delete */
3531                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
3532                 ok(hr == S_OK, "ret %08x\n", hr );
3533                 hr = IXMLDOMComment_get_text(pComment, &str);
3534                 ok(hr == S_OK, "ret %08x\n", hr );
3535                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string\n");
3536                 SysFreeString(str);
3537
3538                 /* zero count means insert */
3539                 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
3540                 ok(hr == S_OK, "ret %08x\n", hr );
3541                 hr = IXMLDOMComment_get_text(pComment, &str);
3542                 ok(hr == S_OK, "ret %08x\n", hr );
3543                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string\n");
3544                 SysFreeString(str);
3545
3546                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
3547                 ok(hr == S_OK, "ret %08x\n", hr );
3548
3549                 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
3550                 ok(hr == S_OK, "ret %08x\n", hr );
3551                 hr = IXMLDOMComment_get_text(pComment, &str);
3552                 ok(hr == S_OK, "ret %08x\n", hr );
3553                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string\n");
3554                 SysFreeString(str);
3555
3556                 /* nonempty string, count greater than its length */
3557                 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
3558                 ok(hr == S_OK, "ret %08x\n", hr );
3559                 hr = IXMLDOMComment_get_text(pComment, &str);
3560                 ok(hr == S_OK, "ret %08x\n", hr );
3561                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string\n");
3562                 SysFreeString(str);
3563
3564                 /* nonempty string, count less than its length */
3565                 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
3566                 ok(hr == S_OK, "ret %08x\n", hr );
3567                 hr = IXMLDOMComment_get_text(pComment, &str);
3568                 ok(hr == S_OK, "ret %08x\n", hr );
3569                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string\n");
3570                 SysFreeString(str);
3571
3572                 IXMLDOMComment_Release(pComment);
3573             }
3574
3575             /* Element */
3576             str = SysAllocString(szElement);
3577             hr = IXMLDOMDocument_createElement(doc, str, &pElement);
3578             SysFreeString(str);
3579             ok(hr == S_OK, "ret %08x\n", hr );
3580             if(hr == S_OK)
3581             {
3582                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
3583                 ok(hr == S_OK, "ret %08x\n", hr );
3584
3585                 /* test nodeTypeString */
3586                 hr = IXMLDOMDocument_get_nodeTypeString(pElement, &str);
3587                 ok(hr == S_OK, "ret %08x\n", hr );
3588                 ok( !lstrcmpW( str, _bstr_("element") ), "incorrect nodeTypeString string\n");
3589                 SysFreeString(str);
3590
3591                 hr = IXMLDOMElement_get_nodeName(pElement, &str);
3592                 ok(hr == S_OK, "ret %08x\n", hr );
3593                 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
3594                 SysFreeString(str);
3595
3596                 hr = IXMLDOMElement_get_xml(pElement, &str);
3597                 ok(hr == S_OK, "ret %08x\n", hr );
3598                 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
3599                 SysFreeString(str);
3600
3601                 hr = IXMLDOMElement_get_dataType(pElement, &v);
3602                 ok(hr == S_FALSE, "ret %08x\n", hr );
3603                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3604                 VariantClear(&v);
3605
3606                 /* Attribute */
3607                 pAttribute = (IXMLDOMAttribute*)0x1;
3608                 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
3609                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3610                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
3611
3612                 pAttribute = (IXMLDOMAttribute*)0x1;
3613                 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
3614                 ok(hr == E_FAIL, "ret %08x\n", hr );
3615                 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
3616
3617                 str = SysAllocString(szAttribute);
3618                 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
3619                 SysFreeString(str);
3620                 ok(hr == S_OK, "ret %08x\n", hr );
3621                 if(hr == S_OK)
3622                 {
3623                     IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
3624
3625                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
3626                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3627
3628                     pNextChild = (IXMLDOMNode *)0x1;
3629                     hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
3630                     ok(hr == S_FALSE, "ret %08x\n", hr );
3631                     ok(pNextChild == NULL, "pNextChild not NULL\n");
3632
3633                     /* test Previous Sibling*/
3634                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
3635                     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3636
3637                     pNextChild = (IXMLDOMNode *)0x1;
3638                     hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
3639                     ok(hr == S_FALSE, "ret %08x\n", hr );
3640                     ok(pNextChild == NULL, "pNextChild not NULL\n");
3641
3642                     /* test get_attributes */
3643                     hr = IXMLDOMAttribute_get_attributes( pAttribute, NULL );
3644                     ok( hr == E_INVALIDARG, "get_attributes returned wrong code\n");
3645
3646                     pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3647                     hr = IXMLDOMAttribute_get_attributes( pAttribute, &pAttribs);
3648                     ok(hr == S_FALSE, "ret %08x\n", hr );
3649                     ok( pAttribs == NULL, "pAttribs not NULL\n");
3650
3651                     hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
3652                     ok(hr == E_FAIL, "ret %08x\n", hr );
3653                     ok(pNewChild == NULL, "pNewChild not NULL\n");
3654
3655                     hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
3656                     ok(hr == S_OK, "ret %08x\n", hr );
3657                     if ( hr == S_OK )
3658                     {
3659                         hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
3660                         ok(hr == S_OK, "ret %08x\n", hr );
3661
3662                         IXMLDOMNamedNodeMap_Release(pAttribs);
3663                     }
3664
3665                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
3666                     ok(hr == S_OK, "ret %08x\n", hr );
3667                     ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
3668                     SysFreeString(str);
3669
3670                     /* test nodeTypeString */
3671                     hr = IXMLDOMAttribute_get_nodeTypeString(pAttribute, &str);
3672                     ok(hr == S_OK, "ret %08x\n", hr );
3673                     ok( !lstrcmpW( str, _bstr_("attribute") ), "incorrect nodeTypeString string\n");
3674                     SysFreeString(str);
3675
3676                     /* test nodeName */
3677                     hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
3678                     ok(hr == S_OK, "ret %08x\n", hr );
3679                     ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
3680                     SysFreeString(str);
3681
3682                     /* test name property */
3683                     hr = IXMLDOMAttribute_get_name(pAttribute, &str);
3684                     ok(hr == S_OK, "ret %08x\n", hr );
3685                     ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
3686                     SysFreeString(str);
3687
3688                     hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
3689                     ok(hr == S_OK, "ret %08x\n", hr );
3690                     ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
3691                     SysFreeString(str);
3692
3693                     hr = IXMLDOMAttribute_get_dataType(pAttribute, &v);
3694                     ok(hr == S_FALSE, "ret %08x\n", hr );
3695                     ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3696                     VariantClear(&v);
3697
3698                     IXMLDOMAttribute_Release(pAttribute);
3699
3700                     /* Check Element again with the Add Attribute*/
3701                     hr = IXMLDOMElement_get_xml(pElement, &str);
3702                     ok(hr == S_OK, "ret %08x\n", hr );
3703                     ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
3704                     SysFreeString(str);
3705                 }
3706
3707                 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
3708                 ok(hr == S_OK, "ret %08x\n", hr );
3709
3710                 hr = IXMLDOMElement_get_xml(pElement, &str);
3711                 ok(hr == S_OK, "ret %08x\n", hr );
3712                 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
3713                 SysFreeString(str);
3714
3715                 /* Test for reversible escaping */
3716                 str = SysAllocString( szStrangeChars );
3717                 hr = IXMLDOMElement_put_text(pElement, str);
3718                 ok(hr == S_OK, "ret %08x\n", hr );
3719                 SysFreeString( str );
3720
3721                 hr = IXMLDOMElement_get_xml(pElement, &str);
3722                 ok(hr == S_OK, "ret %08x\n", hr );
3723                 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
3724                 SysFreeString(str);
3725
3726                 hr = IXMLDOMElement_get_text(pElement, &str);
3727                 ok(hr == S_OK, "ret %08x\n", hr );
3728                 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
3729                 SysFreeString(str);
3730
3731                 IXMLDOMElement_Release(pElement);
3732             }
3733
3734             /* CData Section */
3735             str = SysAllocString(szCData);
3736             hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
3737             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3738
3739             hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
3740             SysFreeString(str);
3741             ok(hr == S_OK, "ret %08x\n", hr );
3742             if(hr == S_OK)
3743             {
3744                 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
3745                 VARIANT var;
3746
3747                 VariantInit(&var);
3748
3749                 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (LPVOID*)&pElement);
3750                 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
3751
3752                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
3753                 ok(hr == S_OK, "ret %08x\n", hr );
3754
3755                 /* get Attribute Tests */
3756                 hr = IXMLDOMCDATASection_get_attributes(pCDataSec, NULL);
3757                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3758
3759                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
3760                 hr = IXMLDOMCDATASection_get_attributes(pCDataSec, &pAttribs);
3761                 ok(hr == S_FALSE, "ret %08x\n", hr );
3762                 ok(pAttribs == NULL, "pAttribs != NULL\n");
3763
3764                 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
3765                 ok(hr == S_OK, "ret %08x\n", hr );
3766                 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
3767                 SysFreeString(str);
3768
3769                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
3770                 ok(hr == S_OK, "ret %08x\n", hr );
3771                 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
3772                 SysFreeString(str);
3773
3774                 /* test lastChild */
3775                 pNextChild = (IXMLDOMNode*)0x1;
3776                 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
3777                 ok(hr == S_FALSE, "ret %08x\n", hr );
3778                 ok(pNextChild == NULL, "pNextChild not NULL\n");
3779
3780                 /* test get_dataType */
3781                 hr = IXMLDOMCDATASection_get_dataType(pCDataSec, NULL);
3782                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3783
3784                 hr = IXMLDOMCDATASection_get_dataType(pCDataSec, &v);
3785                 ok(hr == S_FALSE, "ret %08x\n", hr );
3786                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
3787                 VariantClear(&v);
3788
3789                 /* test nodeTypeString */
3790                 hr = IXMLDOMCDATASection_get_nodeTypeString(pCDataSec, &str);
3791                 ok(hr == S_OK, "ret %08x\n", hr );
3792                 ok( !lstrcmpW( str, _bstr_("cdatasection") ), "incorrect nodeTypeString string\n");
3793                 SysFreeString(str);
3794
3795                 /* put data Tests */
3796                 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
3797                 ok(hr == S_OK, "ret %08x\n", hr );
3798
3799                 /* Confirm XML text is good */
3800                 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
3801                 ok(hr == S_OK, "ret %08x\n", hr );
3802                 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
3803                 SysFreeString(str);
3804
3805                 /* Confirm we get the put_data Text back */
3806                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3807                 ok(hr == S_OK, "ret %08x\n", hr );
3808                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3809                 SysFreeString(str);
3810
3811                 /* test length property */
3812                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3813                 ok(hr == S_OK, "ret %08x\n", hr );
3814                 ok(len == 21, "expected 21 got %d\n", len);
3815
3816                 /* test get nodeValue */
3817                 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
3818                 ok(hr == S_OK, "ret %08x\n", hr );
3819                 ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var));
3820                 ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3821                 VariantClear(&var);
3822
3823                 /* test get data */
3824                 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
3825                 ok(hr == S_OK, "ret %08x\n", hr );
3826                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
3827                 SysFreeString(str);
3828
3829                 /* test substringData */
3830                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
3831                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3832
3833                 /* test substringData - Invalid offset */
3834                 str = (BSTR)&szElement;
3835                 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
3836                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3837                 ok( str == NULL, "incorrect string\n");
3838
3839                 /* test substringData - Invalid offset */
3840                 str = (BSTR)&szElement;
3841                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
3842                 ok(hr == S_FALSE, "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, 0, -1, &str);
3848                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3849                 ok( str == NULL, "incorrect string\n");
3850
3851                 /* test substringData - Invalid size */
3852                 str = (BSTR)&szElement;
3853                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
3854                 ok(hr == S_FALSE, "ret %08x\n", hr );
3855                 ok( str == NULL, "incorrect string\n");
3856
3857                 /* test substringData - Start of string */
3858                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
3859                 ok(hr == S_OK, "ret %08x\n", hr );
3860                 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
3861                 SysFreeString(str);
3862
3863                 /* test substringData - Middle of string */
3864                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
3865                 ok(hr == S_OK, "ret %08x\n", hr );
3866                 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
3867                 SysFreeString(str);
3868
3869                 /* test substringData - End of string */
3870                 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
3871                 ok(hr == S_OK, "ret %08x\n", hr );
3872                 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
3873                 SysFreeString(str);
3874
3875                 /* test appendData */
3876                 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
3877                 ok(hr == S_OK, "ret %08x\n", hr );
3878
3879                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
3880                 ok(hr == S_OK, "ret %08x\n", hr );
3881
3882                 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
3883                 ok(hr == S_OK, "ret %08x\n", hr );
3884
3885                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3886                 ok(hr == S_OK, "ret %08x\n", hr );
3887                 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
3888                 SysFreeString(str);
3889
3890                 /* test insertData */
3891                 str = SysAllocStringLen(NULL, 0);
3892                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
3893                 ok(hr == S_OK, "ret %08x\n", hr );
3894
3895                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
3896                 ok(hr == S_OK, "ret %08x\n", hr );
3897
3898                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
3899                 ok(hr == S_OK, "ret %08x\n", hr );
3900
3901                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
3902                 ok(hr == S_OK, "ret %08x\n", hr );
3903
3904                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
3905                 ok(hr == S_OK, "ret %08x\n", hr );
3906
3907                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
3908                 ok(hr == S_OK, "ret %08x\n", hr );
3909                 SysFreeString(str);
3910
3911                 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
3912                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3913
3914                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
3915                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3916
3917                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
3918                 ok(hr == S_OK, "ret %08x\n", hr );
3919
3920                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
3921                 ok(hr == S_OK, "ret %08x\n", hr );
3922
3923                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
3924                 ok(hr == S_OK, "ret %08x\n", hr );
3925
3926                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3927                 ok(hr == S_OK, "ret %08x\n", hr );
3928                 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
3929                 SysFreeString(str);
3930
3931                 /* delete data */
3932                 /* invalid arguments */
3933                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
3934                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3935
3936                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
3937                 ok(hr == S_OK, "ret %08x\n", hr );
3938
3939                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
3940                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3941
3942                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3943                 ok(hr == S_OK, "ret %08x\n", hr );
3944                 ok(len == 43, "expected 43 got %d\n", len);
3945
3946                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
3947                 ok(hr == S_OK, "ret %08x\n", hr );
3948
3949                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
3950                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
3951
3952                 /* delete from start */
3953                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
3954                 ok(hr == S_OK, "ret %08x\n", hr );
3955
3956                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3957                 ok(hr == S_OK, "ret %08x\n", hr );
3958                 ok(len == 38, "expected 38 got %d\n", len);
3959
3960                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3961                 ok(hr == S_OK, "ret %08x\n", hr );
3962                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
3963                 SysFreeString(str);
3964
3965                 /* delete from end */
3966                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
3967                 ok(hr == S_OK, "ret %08x\n", hr );
3968
3969                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3970                 ok(hr == S_OK, "ret %08x\n", hr );
3971                 ok(len == 35, "expected 35 got %d\n", len);
3972
3973                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3974                 ok(hr == S_OK, "ret %08x\n", hr );
3975                 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string\n");
3976                 SysFreeString(str);
3977
3978                 /* delete from inside */
3979                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
3980                 ok(hr == S_OK, "ret %08x\n", hr );
3981
3982                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3983                 ok(hr == S_OK, "ret %08x\n", hr );
3984                 ok(len == 2, "expected 2 got %d\n", len);
3985
3986                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
3987                 ok(hr == S_OK, "ret %08x\n", hr );
3988                 ok( !lstrcmpW( str, _bstr_("  ") ), "incorrect get_text string\n");
3989                 SysFreeString(str);
3990
3991                 /* delete whole data ... */
3992                 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
3993                 ok(hr == S_OK, "ret %08x\n", hr );
3994
3995                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
3996                 ok(hr == S_OK, "ret %08x\n", hr );
3997
3998                 /* ... and try again with empty string */
3999                 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
4000                 ok(hr == S_OK, "ret %08x\n", hr );
4001
4002                 /* ::replaceData() */
4003                 V_VT(&v) = VT_BSTR;
4004                 V_BSTR(&v) = SysAllocString(szstr1);
4005                 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
4006                 ok(hr == S_OK, "ret %08x\n", hr );
4007                 VariantClear(&v);
4008
4009                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
4010                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4011                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4012                 ok(hr == S_OK, "ret %08x\n", hr );
4013                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
4014                 SysFreeString(str);
4015
4016                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
4017                 ok(hr == S_OK, "ret %08x\n", hr );
4018                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4019                 ok(hr == S_OK, "ret %08x\n", hr );
4020                 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
4021                 SysFreeString(str);
4022
4023                 /* NULL pointer means delete */
4024                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
4025                 ok(hr == S_OK, "ret %08x\n", hr );
4026                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4027                 ok(hr == S_OK, "ret %08x\n", hr );
4028                 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string\n");
4029                 SysFreeString(str);
4030
4031                 /* empty string means delete */
4032                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
4033                 ok(hr == S_OK, "ret %08x\n", hr );
4034                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4035                 ok(hr == S_OK, "ret %08x\n", hr );
4036                 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string\n");
4037                 SysFreeString(str);
4038
4039                 /* zero count means insert */
4040                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
4041                 ok(hr == S_OK, "ret %08x\n", hr );
4042                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4043                 ok(hr == S_OK, "ret %08x\n", hr );
4044                 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string\n");
4045                 SysFreeString(str);
4046
4047                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
4048                 ok(hr == S_OK, "ret %08x\n", hr );
4049
4050                 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
4051                 ok(hr == S_OK, "ret %08x\n", hr );
4052                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4053                 ok(hr == S_OK, "ret %08x\n", hr );
4054                 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string\n");
4055                 SysFreeString(str);
4056
4057                 /* nonempty string, count greater than its length */
4058                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
4059                 ok(hr == S_OK, "ret %08x\n", hr );
4060                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4061                 ok(hr == S_OK, "ret %08x\n", hr );
4062                 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string\n");
4063                 SysFreeString(str);
4064
4065                 /* nonempty string, count less than its length */
4066                 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
4067                 ok(hr == S_OK, "ret %08x\n", hr );
4068                 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4069                 ok(hr == S_OK, "ret %08x\n", hr );
4070                 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string\n");
4071                 SysFreeString(str);
4072
4073                 IXMLDOMCDATASection_Release(pCDataSec);
4074             }
4075
4076             /* Document Fragments */
4077             hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
4078             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4079
4080             hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
4081             ok(hr == S_OK, "ret %08x\n", hr );
4082             if(hr == S_OK)
4083             {
4084                 IXMLDOMNode *node;
4085
4086                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
4087                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4088
4089                 node = (IXMLDOMNode *)0x1;
4090                 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
4091                 ok(hr == S_FALSE, "ret %08x\n", hr );
4092                 ok(node == NULL, "expected NULL, got %p\n", node);
4093
4094                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
4095                 ok(hr == S_OK, "ret %08x\n", hr );
4096
4097                 /* get Attribute Tests */
4098                 hr = IXMLDOMDocumentFragment_get_attributes(pDocFrag, NULL);
4099                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4100
4101                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
4102                 hr = IXMLDOMDocumentFragment_get_attributes(pDocFrag, &pAttribs);
4103                 ok(hr == S_FALSE, "ret %08x\n", hr );
4104                 ok(pAttribs == NULL, "pAttribs != NULL\n");
4105
4106                 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
4107                 ok(hr == S_OK, "ret %08x\n", hr );
4108                 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
4109                 SysFreeString(str);
4110
4111                 /* test next Sibling*/
4112                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
4113                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4114
4115                 node = (IXMLDOMNode *)0x1;
4116                 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
4117                 ok(hr == S_FALSE, "ret %08x\n", hr );
4118                 ok(node == NULL, "next sibling not NULL\n");
4119
4120                 /* test Previous Sibling*/
4121                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
4122                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4123
4124                 node = (IXMLDOMNode *)0x1;
4125                 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
4126                 ok(hr == S_FALSE, "ret %08x\n", hr );
4127                 ok(node == NULL, "previous sibling not NULL\n");
4128
4129                 /* test get_dataType */
4130                 hr = IXMLDOMDocumentFragment_get_dataType(pDocFrag, NULL);
4131                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4132
4133                 hr = IXMLDOMDocumentFragment_get_dataType(pDocFrag, &v);
4134                 ok(hr == S_FALSE, "ret %08x\n", hr );
4135                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
4136                 VariantClear(&v);
4137
4138                 /* test nodeTypeString */
4139                 hr = IXMLDOMDocumentFragment_get_nodeTypeString(pDocFrag, &str);
4140                 ok(hr == S_OK, "ret %08x\n", hr );
4141                 ok( !lstrcmpW( str, _bstr_("documentfragment") ), "incorrect nodeTypeString string\n");
4142                 SysFreeString(str);
4143
4144                 IXMLDOMDocumentFragment_Release(pDocFrag);
4145             }
4146
4147             /* Entity References */
4148             hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
4149             ok(hr == E_FAIL, "ret %08x\n", hr );
4150             hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
4151             ok(hr == E_FAIL, "ret %08x\n", hr );
4152
4153             str = SysAllocString(szEntityRef);
4154             hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
4155             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4156
4157             hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
4158             SysFreeString(str);
4159             ok(hr == S_OK, "ret %08x\n", hr );
4160             if(hr == S_OK)
4161             {
4162                 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
4163                 ok(hr == S_OK, "ret %08x\n", hr );
4164
4165                 /* get Attribute Tests */
4166                 hr = IXMLDOMEntityReference_get_attributes(pEntityRef, NULL);
4167                 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4168
4169                 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
4170                 hr = IXMLDOMEntityReference_get_attributes(pEntityRef, &pAttribs);
4171                 ok(hr == S_FALSE, "ret %08x\n", hr );
4172                 ok(pAttribs == NULL, "pAttribs != NULL\n");
4173
4174                 /* test dataType */
4175                 hr = IXMLDOMEntityReference_get_dataType(pEntityRef, &v);
4176                 ok(hr == S_FALSE, "ret %08x\n", hr );
4177                 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
4178                 VariantClear(&v);
4179
4180                 /* test nodeTypeString */
4181                 hr = IXMLDOMEntityReference_get_nodeTypeString(pEntityRef, &str);
4182                 ok(hr == S_OK, "ret %08x\n", hr );
4183                 ok( !lstrcmpW( str, _bstr_("entityreference") ), "incorrect nodeTypeString string\n");
4184                 SysFreeString(str);
4185
4186                 /* test get_xml*/
4187                 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
4188                 ok(hr == S_OK, "ret %08x\n", hr );
4189                 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
4190                 SysFreeString(str);
4191
4192                 IXMLDOMEntityReference_Release(pEntityRef);
4193             }
4194
4195             IXMLDOMElement_Release( pRoot );
4196         }
4197     }
4198
4199     IXMLDOMDocument_Release(doc);
4200
4201     free_bstrs();
4202 }
4203
4204 static void test_nodeTypeTests( void )
4205 {
4206     IXMLDOMDocument *doc = NULL;
4207     IXMLDOMElement *pRoot;
4208     IXMLDOMElement *pElement;
4209     HRESULT hr;
4210
4211     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4212     if( hr != S_OK )
4213         return;
4214
4215     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
4216     ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4217
4218     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
4219     ok(hr == S_OK, "ret %08x\n", hr );
4220     if(hr == S_OK)
4221     {
4222         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
4223         ok(hr == S_OK, "ret %08x\n", hr );
4224         if(hr == S_OK)
4225         {
4226             hr = IXMLDOMElement_put_dataType(pRoot, NULL);
4227             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4228
4229             /* Invalid Value */
4230             hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
4231             ok(hr == E_FAIL, "ret %08x\n", hr );
4232
4233             /* NOTE:
4234              *   The name passed into put_dataType is case-insensitive. So many of the names
4235              *     have been changed to reflect this.
4236              */
4237             /* Boolean */
4238             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
4239             ok(hr == S_OK, "ret %08x\n", hr );
4240             if(hr == S_OK)
4241             {
4242                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4243
4244                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
4245                 ok(hr == S_OK, "ret %08x\n", hr );
4246
4247                 IXMLDOMElement_Release(pElement);
4248             }
4249
4250             /* String */
4251             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
4252             ok(hr == S_OK, "ret %08x\n", hr );
4253             if(hr == S_OK)
4254             {
4255                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4256
4257                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
4258                 ok(hr == S_OK, "ret %08x\n", hr );
4259
4260                 IXMLDOMElement_Release(pElement);
4261             }
4262
4263             /* Number */
4264             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
4265             ok(hr == S_OK, "ret %08x\n", hr );
4266             if(hr == S_OK)
4267             {
4268                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4269
4270                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
4271                 ok(hr == S_OK, "ret %08x\n", hr );
4272
4273                 IXMLDOMElement_Release(pElement);
4274             }
4275
4276             /* Int */
4277             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
4278             ok(hr == S_OK, "ret %08x\n", hr );
4279             if(hr == S_OK)
4280             {
4281                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4282
4283                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
4284                 ok(hr == S_OK, "ret %08x\n", hr );
4285
4286                 IXMLDOMElement_Release(pElement);
4287             }
4288
4289             /* Fixed */
4290             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
4291             ok(hr == S_OK, "ret %08x\n", hr );
4292             if(hr == S_OK)
4293             {
4294                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4295
4296                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
4297                 ok(hr == S_OK, "ret %08x\n", hr );
4298
4299                 IXMLDOMElement_Release(pElement);
4300             }
4301
4302             /* DateTime */
4303             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
4304             ok(hr == S_OK, "ret %08x\n", hr );
4305             if(hr == S_OK)
4306             {
4307                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4308
4309                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
4310                 ok(hr == S_OK, "ret %08x\n", hr );
4311
4312                 IXMLDOMElement_Release(pElement);
4313             }
4314
4315             /* DateTime TZ */
4316             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
4317             ok(hr == S_OK, "ret %08x\n", hr );
4318             if(hr == S_OK)
4319             {
4320                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4321
4322                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
4323                 ok(hr == S_OK, "ret %08x\n", hr );
4324
4325                 IXMLDOMElement_Release(pElement);
4326             }
4327
4328             /* Date */
4329             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
4330             ok(hr == S_OK, "ret %08x\n", hr );
4331             if(hr == S_OK)
4332             {
4333                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4334
4335                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
4336                 ok(hr == S_OK, "ret %08x\n", hr );
4337
4338                 IXMLDOMElement_Release(pElement);
4339             }
4340
4341             /* Time */
4342             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
4343             ok(hr == S_OK, "ret %08x\n", hr );
4344             if(hr == S_OK)
4345             {
4346                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4347
4348                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
4349                 ok(hr == S_OK, "ret %08x\n", hr );
4350
4351                 IXMLDOMElement_Release(pElement);
4352             }
4353
4354             /* Time.tz */
4355             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
4356             ok(hr == S_OK, "ret %08x\n", hr );
4357             if(hr == S_OK)
4358             {
4359                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4360
4361                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
4362                 ok(hr == S_OK, "ret %08x\n", hr );
4363
4364                 IXMLDOMElement_Release(pElement);
4365             }
4366
4367             /* I1 */
4368             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
4369             ok(hr == S_OK, "ret %08x\n", hr );
4370             if(hr == S_OK)
4371             {
4372                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4373
4374                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
4375                 ok(hr == S_OK, "ret %08x\n", hr );
4376
4377                 IXMLDOMElement_Release(pElement);
4378             }
4379
4380             /* I2 */
4381             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
4382             ok(hr == S_OK, "ret %08x\n", hr );
4383             if(hr == S_OK)
4384             {
4385                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4386
4387                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
4388                 ok(hr == S_OK, "ret %08x\n", hr );
4389
4390                 IXMLDOMElement_Release(pElement);
4391             }
4392
4393             /* I4 */
4394             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
4395             ok(hr == S_OK, "ret %08x\n", hr );
4396             if(hr == S_OK)
4397             {
4398                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4399
4400                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
4401                 ok(hr == S_OK, "ret %08x\n", hr );
4402
4403                 IXMLDOMElement_Release(pElement);
4404             }
4405
4406             /* UI1 */
4407             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
4408             ok(hr == S_OK, "ret %08x\n", hr );
4409             if(hr == S_OK)
4410             {
4411                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4412
4413                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
4414                 ok(hr == S_OK, "ret %08x\n", hr );
4415
4416                 IXMLDOMElement_Release(pElement);
4417             }
4418
4419             /* UI2 */
4420             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
4421             ok(hr == S_OK, "ret %08x\n", hr );
4422             if(hr == S_OK)
4423             {
4424                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4425
4426                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
4427                 ok(hr == S_OK, "ret %08x\n", hr );
4428
4429                 IXMLDOMElement_Release(pElement);
4430             }
4431
4432             /* UI4 */
4433             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
4434             ok(hr == S_OK, "ret %08x\n", hr );
4435             if(hr == S_OK)
4436             {
4437                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4438
4439                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
4440                 ok(hr == S_OK, "ret %08x\n", hr );
4441
4442                 IXMLDOMElement_Release(pElement);
4443             }
4444
4445             /* r4 */
4446             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
4447             ok(hr == S_OK, "ret %08x\n", hr );
4448             if(hr == S_OK)
4449             {
4450                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4451
4452                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
4453                 ok(hr == S_OK, "ret %08x\n", hr );
4454
4455                 IXMLDOMElement_Release(pElement);
4456             }
4457
4458             /* r8 */
4459             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
4460             ok(hr == S_OK, "ret %08x\n", hr );
4461             if(hr == S_OK)
4462             {
4463                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4464
4465                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
4466                 ok(hr == S_OK, "ret %08x\n", hr );
4467
4468                 IXMLDOMElement_Release(pElement);
4469             }
4470
4471             /* float */
4472             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
4473             ok(hr == S_OK, "ret %08x\n", hr );
4474             if(hr == S_OK)
4475             {
4476                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4477
4478                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
4479                 ok(hr == S_OK, "ret %08x\n", hr );
4480
4481                 IXMLDOMElement_Release(pElement);
4482             }
4483
4484             /* uuid */
4485             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
4486             ok(hr == S_OK, "ret %08x\n", hr );
4487             if(hr == S_OK)
4488             {
4489                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4490
4491                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
4492                 ok(hr == S_OK, "ret %08x\n", hr );
4493
4494                 IXMLDOMElement_Release(pElement);
4495             }
4496
4497             /* bin.hex */
4498             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
4499             ok(hr == S_OK, "ret %08x\n", hr );
4500             if(hr == S_OK)
4501             {
4502                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4503
4504                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
4505                 ok(hr == S_OK, "ret %08x\n", hr );
4506
4507                 IXMLDOMElement_Release(pElement);
4508             }
4509
4510             /* bin.base64 */
4511             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
4512             ok(hr == S_OK, "ret %08x\n", hr );
4513             if(hr == S_OK)
4514             {
4515                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4516
4517                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
4518                 ok(hr == S_OK, "ret %08x\n", hr );
4519
4520                 IXMLDOMElement_Release(pElement);
4521             }
4522
4523             /* Check changing types */
4524             hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
4525             ok(hr == S_OK, "ret %08x\n", hr );
4526             if(hr == S_OK)
4527             {
4528                 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4529
4530                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
4531                 ok(hr == S_OK, "ret %08x\n", hr );
4532
4533                 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
4534                 ok(hr == S_OK, "ret %08x\n", hr );
4535
4536                 IXMLDOMElement_Release(pElement);
4537             }
4538
4539             IXMLDOMElement_Release(pRoot);
4540         }
4541     }
4542
4543     IXMLDOMDocument_Release(doc);
4544
4545     free_bstrs();
4546 }
4547
4548 static void test_DocumentSaveToDocument(void)
4549 {
4550     IXMLDOMDocument *doc = NULL;
4551     IXMLDOMDocument *doc2 = NULL;
4552     IXMLDOMElement *pRoot;
4553
4554     HRESULT hr;
4555
4556     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4557     if( hr != S_OK )
4558         return;
4559
4560     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc2 );
4561     if( hr != S_OK )
4562     {
4563         IXMLDOMDocument_Release(doc);
4564         return;
4565     }
4566
4567     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
4568     ok(hr == S_OK, "ret %08x\n", hr );
4569     if(hr == S_OK)
4570     {
4571         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
4572         ok(hr == S_OK, "ret %08x\n", hr );
4573         if(hr == S_OK)
4574         {
4575             VARIANT vDoc;
4576             BSTR sOrig;
4577             BSTR sNew;
4578
4579             V_VT(&vDoc) = VT_UNKNOWN;
4580             V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
4581
4582             hr = IXMLDOMDocument_save(doc, vDoc);
4583             ok(hr == S_OK, "ret %08x\n", hr );
4584
4585             hr = IXMLDOMDocument_get_xml(doc, &sOrig);
4586             ok(hr == S_OK, "ret %08x\n", hr );
4587
4588             hr = IXMLDOMDocument_get_xml(doc2, &sNew);
4589             ok(hr == S_OK, "ret %08x\n", hr );
4590
4591             ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as origial\n");
4592
4593             SysFreeString(sOrig);
4594             SysFreeString(sNew);
4595         }
4596     }
4597
4598     IXMLDOMDocument_Release(doc2);
4599     IXMLDOMDocument_Release(doc);
4600 }
4601
4602 static void test_DocumentSaveToFile(void)
4603 {
4604     IXMLDOMDocument *doc = NULL;
4605     IXMLDOMElement *pRoot;
4606     HANDLE file;
4607     char buffer[100];
4608     DWORD read = 0;
4609     HRESULT hr;
4610
4611     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4612     if( hr != S_OK )
4613         return;
4614
4615     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
4616     ok(hr == S_OK, "ret %08x\n", hr );
4617     if(hr == S_OK)
4618     {
4619         hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
4620         ok(hr == S_OK, "ret %08x\n", hr );
4621         if(hr == S_OK)
4622         {
4623             VARIANT vFile;
4624
4625             V_VT(&vFile) = VT_BSTR;
4626             V_BSTR(&vFile) = _bstr_("test.xml");
4627
4628             hr = IXMLDOMDocument_save(doc, vFile);
4629             ok(hr == S_OK, "ret %08x\n", hr );
4630         }
4631     }
4632
4633     IXMLDOMElement_Release(pRoot);
4634     IXMLDOMDocument_Release(doc);
4635
4636     file = CreateFile("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
4637     ok(file != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
4638     if(file == INVALID_HANDLE_VALUE)
4639         return;
4640
4641     ReadFile(file, buffer, sizeof(buffer), &read, NULL);
4642     ok(read != 0, "could not read file\n");
4643     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
4644
4645     CloseHandle(file);
4646     DeleteFile("test.xml");
4647 }
4648
4649 static void test_testTransforms(void)
4650 {
4651     IXMLDOMDocument *doc = NULL;
4652     IXMLDOMDocument *docSS = NULL;
4653     IXMLDOMNode *pNode;
4654     VARIANT_BOOL bSucc;
4655
4656     HRESULT hr;
4657
4658     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4659     if( hr != S_OK )
4660         return;
4661
4662     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&docSS );
4663     if( hr != S_OK )
4664     {
4665         IXMLDOMDocument_Release(doc);
4666         return;
4667     }
4668
4669     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
4670     ok(hr == S_OK, "ret %08x\n", hr );
4671
4672     hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
4673     ok(hr == S_OK, "ret %08x\n", hr );
4674
4675     hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (LPVOID*)&pNode );
4676     ok(hr == S_OK, "ret %08x\n", hr );
4677     if(hr == S_OK)
4678     {
4679         BSTR bOut;
4680
4681         hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
4682         ok(hr == S_OK, "ret %08x\n", hr );
4683         ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
4684         SysFreeString(bOut);
4685
4686         IXMLDOMNode_Release(pNode);
4687     }
4688
4689     IXMLDOMDocument_Release(docSS);
4690     IXMLDOMDocument_Release(doc);
4691
4692     free_bstrs();
4693 }
4694
4695 static void test_Namespaces(void)
4696 {
4697     IXMLDOMDocument2 *doc = NULL;
4698     IXMLDOMNode *pNode;
4699     IXMLDOMNode *pNode2 = NULL;
4700     VARIANT_BOOL bSucc;
4701     HRESULT hr;
4702     BSTR str;
4703     static  const CHAR szNamespacesXML[] =
4704 "<?xml version=\"1.0\"?>\n"
4705 "<root xmlns:WEB='http://www.winehq.org'>\n"
4706 "<WEB:Site version=\"1.0\" />\n"
4707 "</root>";
4708
4709     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4710     if( hr != S_OK )
4711         return;
4712
4713     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNamespacesXML), &bSucc);
4714     ok(hr == S_OK, "ret %08x\n", hr );
4715     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
4716
4717     hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root"), &pNode );
4718     ok(hr == S_OK, "ret %08x\n", hr );
4719     if(hr == S_OK)
4720     {
4721         hr = IXMLDOMNode_get_firstChild( pNode, &pNode2 );
4722         ok( hr == S_OK, "ret %08x\n", hr );
4723         ok( pNode2 != NULL, "pNode2 == NULL\n");
4724
4725         /* Test get_prefix */
4726         hr = IXMLDOMNode_get_prefix(pNode2, NULL);
4727         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
4728         /* NOTE: Need to test that arg2 gets cleared on Error. */
4729
4730         hr = IXMLDOMNode_get_prefix(pNode2, &str);
4731         ok( hr == S_OK, "ret %08x\n", hr );
4732         ok( !lstrcmpW( str, _bstr_("WEB")), "incorrect prefix string\n");
4733         SysFreeString(str);
4734
4735         /* Test get_namespaceURI */
4736         hr = IXMLDOMNode_get_namespaceURI(pNode2, NULL);
4737         ok( hr == E_INVALIDARG, "ret %08x\n", hr );
4738         /* NOTE: Need to test that arg2 gets cleared on Error. */
4739
4740         hr = IXMLDOMNode_get_namespaceURI(pNode2, &str);
4741         ok( hr == S_OK, "ret %08x\n", hr );
4742         ok( !lstrcmpW( str, _bstr_("http://www.winehq.org")), "incorrect namespaceURI string\n");
4743         SysFreeString(str);
4744
4745         IXMLDOMNode_Release(pNode2);
4746         IXMLDOMNode_Release(pNode);
4747     }
4748
4749     IXMLDOMDocument2_Release(doc);
4750
4751     free_bstrs();
4752 }
4753
4754 static void test_FormattingXML(void)
4755 {
4756     IXMLDOMDocument2 *doc = NULL;
4757     IXMLDOMElement *pElement;
4758     VARIANT_BOOL bSucc;
4759     HRESULT hr;
4760     BSTR str;
4761     static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
4762     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
4763
4764     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4765     if( hr != S_OK )
4766         return;
4767
4768     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
4769     ok(hr == S_OK, "ret %08x\n", hr );
4770     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
4771
4772     if(bSucc == VARIANT_TRUE)
4773     {
4774         hr = IXMLDOMDocument2_get_documentElement(doc, &pElement);
4775         ok(hr == S_OK, "ret %08x\n", hr );
4776         if(hr == S_OK)
4777         {
4778             hr = IXMLDOMElement_get_xml(pElement, &str);
4779             ok(hr == S_OK, "ret %08x\n", hr );
4780             ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
4781             SysFreeString(str);
4782
4783             IXMLDOMElement_Release(pElement);
4784         }
4785     }
4786
4787     IXMLDOMDocument2_Release(doc);
4788
4789     free_bstrs();
4790 }
4791
4792 static void test_NodeTypeValue(void)
4793 {
4794     IXMLDOMDocument2 *doc = NULL;
4795     IXMLDOMNode *pNode;
4796     VARIANT_BOOL bSucc;
4797     HRESULT hr;
4798     VARIANT v;
4799
4800     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
4801     if( hr != S_OK )
4802         return;
4803
4804     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
4805     ok(hr == S_OK, "ret %08x\n", hr );
4806     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
4807     if(bSucc == VARIANT_TRUE)
4808     {
4809         hr = IXMLDOMDocument2_get_nodeValue(doc, NULL);
4810         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4811
4812         V_VT(&v) = VT_BSTR;
4813         V_BSTR(&v) = NULL;
4814         hr = IXMLDOMDocument2_get_nodeValue(doc, &v);
4815         ok(hr == S_FALSE, "ret %08x\n", hr );
4816         ok(V_VT(&v) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&v));
4817
4818         hr = IXMLDOMDocument2_get_nodeTypedValue(doc, NULL);
4819         ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4820
4821         hr = IXMLDOMDocument2_get_nodeTypedValue(doc, &v);
4822         ok(hr == S_FALSE, "ret %08x\n", hr );
4823
4824         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/string"), &pNode);
4825         ok(hr == S_OK, "ret %08x\n", hr );
4826         if(hr == S_OK)
4827         {
4828             V_VT(&v) = VT_BSTR;
4829             V_BSTR(&v) = NULL;
4830             hr = IXMLDOMNode_get_nodeValue(pNode, &v);
4831             ok(hr == S_FALSE, "ret %08x\n", hr );
4832             ok(V_VT(&v) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&v));
4833
4834             hr = IXMLDOMNode_get_nodeTypedValue(pNode, NULL);
4835             ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4836
4837             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4838             ok(hr == S_OK, "ret %08x\n", hr );
4839             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4840             ok(!lstrcmpW( V_BSTR(&v), _bstr_("Wine") ), "incorrect value\n");
4841             VariantClear( &v );
4842
4843             IXMLDOMNode_Release(pNode);
4844         }
4845
4846         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/string2"), &pNode);
4847         ok(hr == S_OK, "ret %08x\n", hr );
4848         if(hr == S_OK)
4849         {
4850             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4851             ok(hr == S_OK, "ret %08x\n", hr );
4852             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4853             ok(!lstrcmpW( V_BSTR(&v), _bstr_("String") ), "incorrect value\n");
4854             VariantClear( &v );
4855
4856             IXMLDOMNode_Release(pNode);
4857         }
4858
4859         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/number"), &pNode);
4860         ok(hr == S_OK, "ret %08x\n", hr );
4861         if(hr == S_OK)
4862         {
4863             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4864             ok(hr == S_OK, "ret %08x\n", hr );
4865             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4866             ok(!lstrcmpW( V_BSTR(&v), _bstr_("12.44") ), "incorrect value\n");
4867             VariantClear( &v );
4868
4869             IXMLDOMNode_Release(pNode);
4870         }
4871
4872         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/number2"), &pNode);
4873         ok(hr == S_OK, "ret %08x\n", hr );
4874         if(hr == S_OK)
4875         {
4876             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4877             ok(hr == S_OK, "ret %08x\n", hr );
4878             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
4879             ok(!lstrcmpW( V_BSTR(&v), _bstr_("-3.71e3") ), "incorrect value\n");
4880             VariantClear( &v );
4881
4882             IXMLDOMNode_Release(pNode);
4883         }
4884
4885         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/int"), &pNode);
4886         ok(hr == S_OK, "ret %08x\n", hr );
4887         if(hr == S_OK)
4888         {
4889             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4890             ok(hr == S_OK, "ret %08x\n", hr );
4891             ok(V_VT(&v) == VT_I4, "incorrect type\n");
4892             ok(V_I4(&v) == -13, "incorrect value\n");
4893             VariantClear( &v );
4894
4895             IXMLDOMNode_Release(pNode);
4896         }
4897
4898         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/fixed"), &pNode);
4899         ok(hr == S_OK, "ret %08x\n", hr );
4900         if(hr == S_OK)
4901         {
4902             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4903             ok(hr == S_OK, "ret %08x\n", hr );
4904             ok(V_VT(&v) == VT_CY, "incorrect type\n");
4905             VariantClear(&v);
4906
4907             IXMLDOMNode_Release(pNode);
4908         }
4909
4910         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/bool"), &pNode);
4911         ok(hr == S_OK, "ret %08x\n", hr );
4912         if(hr == S_OK)
4913         {
4914             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4915             ok(hr == S_OK, "ret %08x\n", hr );
4916             ok(V_VT(&v) == VT_BOOL, "incorrect type\n");
4917             ok(V_BOOL(&v) == VARIANT_TRUE, "incorrect value\n");
4918             VariantClear( &v );
4919
4920             IXMLDOMNode_Release(pNode);
4921         }
4922
4923         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetime"), &pNode);
4924         ok(hr == S_OK, "ret %08x\n", hr );
4925         if(hr == S_OK)
4926         {
4927             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4928             ok(hr == S_OK, "ret %08x\n", hr );
4929             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4930             double_eq(40135.13996527778, V_DATE(&v));
4931             VariantClear( &v );
4932
4933             IXMLDOMNode_Release(pNode);
4934         }
4935
4936         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetimetz"), &pNode);
4937         ok(hr == S_OK, "ret %08x\n", hr );
4938         if(hr == S_OK)
4939         {
4940             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4941             ok(hr == S_OK, "ret %08x\n", hr );
4942             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4943             double_eq(37813.59302083334, V_DATE(&v));
4944             VariantClear( &v );
4945
4946             IXMLDOMNode_Release(pNode);
4947         }
4948
4949         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/date"), &pNode);
4950         ok(hr == S_OK, "ret %08x\n", hr );
4951         if(hr == S_OK)
4952         {
4953             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4954             ok(hr == S_OK, "ret %08x\n", hr );
4955             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4956             double_eq(665413.0, V_DATE(&v));
4957             VariantClear( &v );
4958
4959             IXMLDOMNode_Release(pNode);
4960         }
4961
4962         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/time"), &pNode);
4963         ok(hr == S_OK, "ret %08x\n", hr );
4964         if(hr == S_OK)
4965         {
4966             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4967             ok(hr == S_OK, "ret %08x\n", hr );
4968             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4969             double_eq(0.5813888888888888, V_DATE(&v));
4970             VariantClear( &v );
4971
4972             IXMLDOMNode_Release(pNode);
4973         }
4974
4975         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/timetz"), &pNode);
4976         ok(hr == S_OK, "ret %08x\n", hr );
4977         if(hr == S_OK)
4978         {
4979             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4980             ok(hr == S_OK, "ret %08x\n", hr );
4981             ok(V_VT(&v) == VT_DATE, "incorrect type\n");
4982             double_eq(1.112511574074074, V_DATE(&v));
4983             VariantClear( &v );
4984
4985             IXMLDOMNode_Release(pNode);
4986         }
4987
4988         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i1"), &pNode);
4989         ok(hr == S_OK, "ret %08x\n", hr );
4990         if(hr == S_OK)
4991         {
4992             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
4993             ok(hr == S_OK, "ret %08x\n", hr );
4994             ok(V_VT(&v) == VT_I1, "incorrect type\n");
4995             ok(V_I1(&v) == -13, "incorrect value\n");
4996             VariantClear( &v );
4997
4998             IXMLDOMNode_Release(pNode);
4999         }
5000
5001         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i2"), &pNode);
5002         ok(hr == S_OK, "ret %08x\n", hr );
5003         if(hr == S_OK)
5004         {
5005             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5006             ok(hr == S_OK, "ret %08x\n", hr );
5007             ok(V_VT(&v) == VT_I2, "incorrect type\n");
5008             ok(V_I2(&v) == 31915, "incorrect value\n");
5009             VariantClear( &v );
5010
5011             IXMLDOMNode_Release(pNode);
5012         }
5013
5014         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/i4"), &pNode);
5015         ok(hr == S_OK, "ret %08x\n", hr );
5016         if(hr == S_OK)
5017         {
5018             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5019             ok(hr == S_OK, "ret %08x\n", hr );
5020             ok(V_VT(&v) == VT_I4, "incorrect type\n");
5021             ok(V_I4(&v) == -312232, "incorrect value\n");
5022             VariantClear(&v);
5023
5024             IXMLDOMNode_Release(pNode);
5025         }
5026
5027         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui1"), &pNode);
5028         ok(hr == S_OK, "ret %08x\n", hr );
5029         if(hr == S_OK)
5030         {
5031             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5032             ok(hr == S_OK, "ret %08x\n", hr );
5033             ok(V_VT(&v) == VT_UI1, "incorrect type\n");
5034             ok(V_UI1(&v) == 123, "incorrect value\n");
5035             VariantClear(&v);
5036
5037             IXMLDOMNode_Release(pNode);
5038         }
5039
5040         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui2"), &pNode);
5041         ok(hr == S_OK, "ret %08x\n", hr );
5042         if(hr == S_OK)
5043         {
5044             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5045             ok(hr == S_OK, "ret %08x\n", hr );
5046             ok(V_VT(&v) == VT_UI2, "incorrect type\n");
5047             ok(V_UI2(&v) == 48282, "incorrect value\n");
5048             VariantClear(&v);
5049
5050             IXMLDOMNode_Release(pNode);
5051         }
5052
5053         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/ui4"), &pNode);
5054         ok(hr == S_OK, "ret %08x\n", hr );
5055         if(hr == S_OK)
5056         {
5057             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5058             ok(hr == S_OK, "ret %08x\n", hr );
5059             ok(V_VT(&v) == VT_UI4, "incorrect type\n");
5060             ok(V_UI4(&v) == 949281, "incorrect value\n");
5061             VariantClear(&v);
5062
5063             IXMLDOMNode_Release(pNode);
5064         }
5065
5066         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/r4"), &pNode);
5067         ok(hr == S_OK, "ret %08x\n", hr );
5068         if(hr == S_OK)
5069         {
5070             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5071             ok(hr == S_OK, "ret %08x\n", hr );
5072             ok(V_VT(&v) == VT_R4, "incorrect type\n");
5073             double_eq(213124.0, V_R4(&v));
5074             VariantClear(&v);
5075
5076             IXMLDOMNode_Release(pNode);
5077         }
5078
5079         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/r8"), &pNode);
5080         ok(hr == S_OK, "ret %08x\n", hr );
5081         if(hr == S_OK)
5082         {
5083             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5084             ok(hr == S_OK, "ret %08x\n", hr );
5085             ok(V_VT(&v) == VT_R8, "incorrect type\n");
5086             double_eq(0.412, V_R8(&v));
5087             VariantClear(&v);
5088
5089             IXMLDOMNode_Release(pNode);
5090         }
5091
5092         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/float"), &pNode);
5093         ok(hr == S_OK, "ret %08x\n", hr );
5094         if(hr == S_OK)
5095         {
5096             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5097             ok(hr == S_OK, "ret %08x\n", hr );
5098             ok(V_VT(&v) == VT_R8, "incorrect type\n");
5099             double_eq(41221.421, V_R8(&v));
5100             VariantClear(&v);
5101
5102             IXMLDOMNode_Release(pNode);
5103         }
5104
5105         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/uuid"), &pNode);
5106         ok(hr == S_OK, "ret %08x\n", hr );
5107         if(hr == S_OK)
5108         {
5109             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5110             ok(hr == S_OK, "ret %08x\n", hr );
5111             ok(V_VT(&v) == VT_BSTR, "incorrect type\n");
5112             ok(!lstrcmpW(V_BSTR(&v), _bstr_("333C7BC4-460F-11D0-BC04-0080C7055a83")), "incorrect value\n");
5113             VariantClear(&v);
5114
5115             IXMLDOMNode_Release(pNode);
5116         }
5117
5118         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/binhex"), &pNode);
5119         ok(hr == S_OK, "ret %08x\n", hr );
5120         if(hr == S_OK)
5121         {
5122             BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
5123
5124             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5125             ok(hr == S_OK, "ret %08x\n", hr );
5126             ok(V_VT(&v) == (VT_ARRAY|VT_UI1), "incorrect type\n");
5127             ok(V_ARRAY(&v)->rgsabound[0].cElements == 6, "incorrect array size\n");
5128             if(V_ARRAY(&v)->rgsabound[0].cElements == 6)
5129                 ok(!memcmp(bytes, V_ARRAY(&v)->pvData, sizeof(bytes)), "incorrect value\n");
5130             VariantClear(&v);
5131
5132             IXMLDOMNode_Release(pNode);
5133         }
5134
5135         hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/binbase64"), &pNode);
5136         ok(hr == S_OK, "ret %08x\n", hr );
5137         if(hr == S_OK)
5138         {
5139             BYTE bytes[] = {0x62,0x61,0x73,0x65,0x36,0x34,0x20,0x74,0x65,0x73,0x74};
5140
5141             hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v);
5142             ok(hr == S_OK, "ret %08x\n", hr );
5143             ok(V_VT(&v) == (VT_ARRAY|VT_UI1), "incorrect type\n");
5144             ok(V_ARRAY(&v)->rgsabound[0].cElements == 11, "incorrect array size\n");
5145             if(V_ARRAY(&v)->rgsabound[0].cElements == 11)
5146                 ok(!memcmp(bytes, V_ARRAY(&v)->pvData, sizeof(bytes)), "incorrect value\n");
5147             VariantClear(&v);
5148
5149             IXMLDOMNode_Release(pNode);
5150         }
5151     }
5152
5153     IXMLDOMDocument2_Release(doc);
5154
5155     free_bstrs();
5156 }
5157
5158 static void test_TransformWithLoadingLocalFile(void)
5159 {
5160     IXMLDOMDocument2 *doc = NULL;
5161     IXMLDOMDocument2 *xsl = NULL;
5162     IXMLDOMNode *pNode;
5163     VARIANT_BOOL bSucc;
5164     HRESULT hr;
5165     HANDLE file;
5166     DWORD dwWritten;
5167     char lpPathBuffer[MAX_PATH];
5168     int i;
5169
5170     /* Create a Temp File. */
5171     GetTempPathA(MAX_PATH, lpPathBuffer);
5172     strcat(lpPathBuffer, "customers.xml" );
5173
5174     file = CreateFile(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
5175     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
5176     if(file == INVALID_HANDLE_VALUE)
5177         return;
5178
5179     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
5180     CloseHandle(file);
5181
5182     /* Correct path to not include a escape character. */
5183     for(i=0; i < strlen(lpPathBuffer); i++)
5184     {
5185         if(lpPathBuffer[i] == '\\')
5186             lpPathBuffer[i] = '/';
5187     }
5188
5189     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
5190     if( hr != S_OK )
5191         return;
5192
5193     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&xsl );
5194     if( hr != S_OK )
5195     {
5196         IXMLDOMDocument2_Release(doc);
5197         return;
5198     }
5199
5200     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
5201     ok(hr == S_OK, "ret %08x\n", hr );
5202     ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5203     if(bSucc == VARIANT_TRUE)
5204     {
5205         BSTR sXSL;
5206         BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
5207         BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
5208         BSTR sFileName = _bstr_(lpPathBuffer);
5209         int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
5210
5211         sXSL = SysAllocStringLen(NULL, nLegnth);
5212         lstrcpyW(sXSL, sPart1);
5213         lstrcatW(sXSL, sFileName);
5214         lstrcatW(sXSL, sPart2);
5215
5216         hr = IXMLDOMDocument2_loadXML(xsl, sXSL, &bSucc);
5217         ok(hr == S_OK, "ret %08x\n", hr );
5218         ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5219         if(bSucc == VARIANT_TRUE)
5220         {
5221             BSTR sResult;
5222
5223             hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (LPVOID*)&pNode );
5224             ok(hr == S_OK, "ret %08x\n", hr );
5225             if(hr == S_OK)
5226             {
5227                 /* This will load the temp file via the XSL */
5228                 hr = IXMLDOMDocument2_transformNode(doc, pNode, &sResult);
5229                 ok(hr == S_OK, "ret %08x\n", hr );
5230                 if(hr == S_OK)
5231                 {
5232                     ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
5233                     SysFreeString(sResult);
5234                 }
5235
5236                 IXMLDOMNode_Release(pNode);
5237             }
5238         }
5239
5240         SysFreeString(sXSL);
5241     }
5242
5243     IXMLDOMDocument2_Release(doc);
5244     IXMLDOMDocument2_Release(xsl);
5245
5246     DeleteFile(lpPathBuffer);
5247     free_bstrs();
5248 }
5249
5250 static void test_put_nodeValue(void)
5251 {
5252     IXMLDOMDocument *doc;
5253     IXMLDOMEntityReference *entityref;
5254     IXMLDOMNode *node;
5255     HRESULT hr;
5256     VARIANT data, type;
5257
5258     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
5259     if( hr != S_OK )
5260         return;
5261
5262     /* test for unsupported types */
5263     /* NODE_DOCUMENT */
5264     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
5265     ok(hr == S_OK, "ret %08x\n", hr );
5266     V_VT(&data) = VT_BSTR;
5267     V_BSTR(&data) = _bstr_("one two three");
5268     hr = IXMLDOMNode_put_nodeValue(node, data);
5269     ok(hr == E_FAIL, "ret %08x\n", hr );
5270     IXMLDOMNode_Release(node);
5271
5272     /* NODE_DOCUMENT_FRAGMENT */
5273     V_VT(&type) = VT_I1;
5274     V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
5275     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
5276     ok(hr == S_OK, "ret %08x\n", hr );
5277     V_VT(&data) = VT_BSTR;
5278     V_BSTR(&data) = _bstr_("one two three");
5279     hr = IXMLDOMNode_put_nodeValue(node, data);
5280     ok(hr == E_FAIL, "ret %08x\n", hr );
5281     IXMLDOMNode_Release(node);
5282
5283     /* NODE_ELEMENT */
5284     V_VT(&type) = VT_I1;
5285     V_I1(&type) = NODE_ELEMENT;
5286     hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
5287     ok(hr == S_OK, "ret %08x\n", hr );
5288     V_VT(&data) = VT_BSTR;
5289     V_BSTR(&data) = _bstr_("one two three");
5290     hr = IXMLDOMNode_put_nodeValue(node, data);
5291     ok(hr == E_FAIL, "ret %08x\n", hr );
5292     IXMLDOMNode_Release(node);
5293
5294     /* NODE_ENTITY_REFERENCE */
5295     hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
5296     ok(hr == S_OK, "ret %08x\n", hr );
5297
5298     V_VT(&data) = VT_BSTR;
5299     V_BSTR(&data) = _bstr_("one two three");
5300     hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
5301     ok(hr == E_FAIL, "ret %08x\n", hr );
5302
5303     hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
5304     ok(hr == S_OK, "ret %08x\n", hr );
5305     V_VT(&data) = VT_BSTR;
5306     V_BSTR(&data) = _bstr_("one two three");
5307     hr = IXMLDOMNode_put_nodeValue(node, data);
5308     ok(hr == E_FAIL, "ret %08x\n", hr );
5309     IXMLDOMNode_Release(node);
5310     IXMLDOMEntityReference_Release(entityref);
5311
5312     free_bstrs();
5313
5314     IXMLDOMDocument_Release(doc);
5315 }
5316
5317 static void test_IObjectSafety_set(IObjectSafety *safety, HRESULT result, HRESULT result2, DWORD set, DWORD mask, DWORD expected, DWORD expected2)
5318 {
5319     HRESULT hr;
5320     DWORD enabled, supported;
5321
5322     trace("testing IObjectSafety: enable=%08x, mask=%08x\n", set, mask);
5323
5324     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
5325     if (result == result2)
5326         ok(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
5327     else
5328         ok(broken(hr == result) || hr == result2,
5329            "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
5330
5331     supported = enabled = 0xCAFECAFE;
5332     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
5333     ok(hr == S_OK, "ret %08x\n", hr );
5334     if (expected == expected2)
5335         ok(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
5336     else
5337         ok(broken(enabled == expected) || enabled == expected2,
5338            "Expected %08x, got %08x\n", expected2, enabled);
5339
5340     /* reset the safety options */
5341
5342     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
5343             INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
5344             0);
5345     ok(hr == S_OK, "ret %08x\n", hr );
5346
5347     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
5348     ok(hr == S_OK, "ret %08x\n", hr );
5349     ok(enabled == 0, "Expected 0, got %08x\n", enabled);
5350 }
5351
5352 static void test_document_IObjectSafety(void)
5353 {
5354     IXMLDOMDocument *doc;
5355     IObjectSafety *safety;
5356     DWORD enabled = 0, supported = 0;
5357     HRESULT hr;
5358
5359     hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
5360     if( hr != S_OK )
5361         return;
5362
5363     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
5364     ok(hr == S_OK, "ret %08x\n", hr );
5365
5366     /* get */
5367     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
5368     ok(hr == E_POINTER, "ret %08x\n", hr );
5369     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
5370     ok(hr == E_POINTER, "ret %08x\n", hr );
5371
5372     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
5373     ok(hr == S_OK, "ret %08x\n", hr );
5374     ok(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
5375        supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
5376         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
5377              "got %08x\n", supported);
5378     ok(enabled == 0, "Expected 0, got %08x\n", enabled);
5379
5380     /* set -- individual flags */
5381
5382     test_IObjectSafety_set(safety, S_OK, S_OK,
5383         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
5384         INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
5385
5386     test_IObjectSafety_set(safety, S_OK, S_OK,
5387         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
5388         INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
5389
5390     test_IObjectSafety_set(safety, S_OK, S_OK,
5391         INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
5392         0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
5393
5394     /* set INTERFACE_USES_DISPEX  */
5395
5396     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
5397         INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
5398         0, 0);
5399
5400     test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
5401         INTERFACE_USES_DISPEX, 0,
5402         0, 0);
5403
5404     test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
5405         0, INTERFACE_USES_DISPEX,
5406         0, 0);
5407
5408     /* set option masking */
5409
5410     test_IObjectSafety_set(safety, S_OK, S_OK,
5411         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
5412         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
5413         INTERFACESAFE_FOR_UNTRUSTED_CALLER,
5414         INTERFACESAFE_FOR_UNTRUSTED_CALLER);
5415
5416     test_IObjectSafety_set(safety, S_OK, S_OK,
5417         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
5418         INTERFACESAFE_FOR_UNTRUSTED_DATA,
5419         INTERFACESAFE_FOR_UNTRUSTED_DATA,
5420         INTERFACESAFE_FOR_UNTRUSTED_DATA);
5421
5422     test_IObjectSafety_set(safety, S_OK, S_OK,
5423         INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
5424         INTERFACE_USES_SECURITY_MANAGER,
5425         0,
5426         0);
5427
5428     /* set -- inheriting previous settings */
5429
5430     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
5431                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER,
5432                                                          INTERFACESAFE_FOR_UNTRUSTED_CALLER);
5433     ok(hr == S_OK, "ret %08x\n", hr );
5434     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
5435     ok(hr == S_OK, "ret %08x\n", hr );
5436     todo_wine
5437     ok(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER) ||
5438        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
5439          "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER), "
5440          "got %08x\n", enabled);
5441
5442     hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
5443                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA,
5444                                                          INTERFACESAFE_FOR_UNTRUSTED_DATA);
5445     ok(hr == S_OK, "ret %08x\n", hr );
5446     hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
5447     ok(hr == S_OK, "ret %08x\n", hr );
5448     todo_wine
5449     ok(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
5450        enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) /* msxml3 SP8+ */,
5451         "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA), "
5452         "got %08x\n", enabled);
5453
5454     IObjectSafety_Release(safety);
5455
5456     IXMLDOMDocument_Release(doc);
5457 }
5458
5459 START_TEST(domdoc)
5460 {
5461     HRESULT r;
5462
5463     r = CoInitialize( NULL );
5464     ok( r == S_OK, "failed to init com\n");
5465
5466     test_domdoc();
5467     test_domnode();
5468     test_refs();
5469     test_create();
5470     test_getElementsByTagName();
5471     test_get_text();
5472     test_get_childNodes();
5473     test_removeChild();
5474     test_replaceChild();
5475     test_removeNamedItem();
5476     test_XMLHTTP();
5477     test_IXMLDOMDocument2();
5478     test_XPath();
5479     test_cloneNode();
5480     test_xmlTypes();
5481     test_nodeTypeTests();
5482     test_DocumentSaveToDocument();
5483     test_DocumentSaveToFile();
5484     test_testTransforms();
5485     test_Namespaces();
5486     test_FormattingXML();
5487     test_NodeTypeValue();
5488     test_TransformWithLoadingLocalFile();
5489     test_put_nodeValue();
5490     test_document_IObjectSafety();
5491
5492     CoUninitialize();
5493 }