[MSXML3_WINETEST]
[reactos.git] / rostests / winetests / msxml3 / 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
539 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
540 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
541 if( r != S_OK )
542 return;
543
544 test_disp((IUnknown*)doc);
545
546 /* try some stupid things */
547 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
548 ok( r == S_FALSE, "loadXML failed\n");
549
550 b = VARIANT_TRUE;
551 r = IXMLDOMDocument_loadXML( doc, NULL, &b );
552 ok( r == S_FALSE, "loadXML failed\n");
553 ok( b == VARIANT_FALSE, "failed to load XML string\n");
554
555 /* try to load a document from a nonexistent file */
556 b = VARIANT_TRUE;
557 str = SysAllocString( szNonExistentFile );
558 VariantInit(&var);
559 V_VT(&var) = VT_BSTR;
560 V_BSTR(&var) = str;
561
562 r = IXMLDOMDocument_load( doc, var, &b);
563 ok( r == S_FALSE, "load (from file) failed\n");
564 ok( b == VARIANT_FALSE, "failed to load XML file\n");
565 SysFreeString( str );
566
567 /* try load an empty document */
568 b = VARIANT_TRUE;
569 str = SysAllocString( szEmpty );
570 r = IXMLDOMDocument_loadXML( doc, str, &b );
571 ok( r == S_FALSE, "loadXML failed\n");
572 ok( b == VARIANT_FALSE, "failed to load XML string\n");
573 SysFreeString( str );
574
575 r = IXMLDOMDocument_get_async( doc, &b );
576 ok( r == S_OK, "get_async failed (%08x)\n", r);
577 ok( b == VARIANT_TRUE, "Wrong default value\n");
578
579 /* check that there's no document element */
580 element = NULL;
581 r = IXMLDOMDocument_get_documentElement( doc, &element );
582 ok( r == S_FALSE, "should be no document element\n");
583
584 /* try finding a node */
585 node = NULL;
586 str = SysAllocString( szstr1 );
587 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
588 ok( r == S_FALSE, "ret %08x\n", r );
589 SysFreeString( str );
590
591 b = VARIANT_TRUE;
592 str = SysAllocString( szIncomplete );
593 r = IXMLDOMDocument_loadXML( doc, str, &b );
594 ok( r == S_FALSE, "loadXML failed\n");
595 ok( b == VARIANT_FALSE, "failed to load XML string\n");
596 SysFreeString( str );
597
598 /* check that there's no document element */
599 element = (IXMLDOMElement*)1;
600 r = IXMLDOMDocument_get_documentElement( doc, &element );
601 ok( r == S_FALSE, "should be no document element\n");
602 ok( element == NULL, "Element should be NULL\n");
603
604 /* try to load something valid */
605 b = VARIANT_FALSE;
606 str = SysAllocString( szComplete1 );
607 r = IXMLDOMDocument_loadXML( doc, str, &b );
608 ok( r == S_OK, "loadXML failed\n");
609 ok( b == VARIANT_TRUE, "failed to load XML string\n");
610 SysFreeString( str );
611
612 /* check if nodename is correct */
613 r = IXMLDOMDocument_get_nodeName( doc, NULL );
614 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
615
616 /* content doesn't matter here */
617 str = NULL;
618 r = IXMLDOMDocument_get_nodeName( doc, &str );
619 ok ( r == S_OK, "get_nodeName wrong code\n");
620 ok ( str != NULL, "str is null\n");
621 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
622 SysFreeString( str );
623
624 /* test put_text */
625 r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
626 ok( r == E_FAIL, "ret %08x\n", r );
627
628 /* check that there's a document element */
629 element = NULL;
630 r = IXMLDOMDocument_get_documentElement( doc, &element );
631 ok( r == S_OK, "should be a document element\n");
632 if( element )
633 {
634 IObjectIdentity *ident;
635 BSTR tag = NULL;
636
637 test_disp((IUnknown*)element);
638
639 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (LPVOID*)&ident );
640 ok( r == E_NOINTERFACE, "ret %08x\n", r);
641
642 r = IXMLDOMElement_get_tagName( element, NULL );
643 ok( r == E_INVALIDARG, "ret %08x\n", r);
644
645 /* check if the tag is correct */
646 r = IXMLDOMElement_get_tagName( element, &tag );
647 ok( r == S_OK, "couldn't get tag name\n");
648 ok( tag != NULL, "tag was null\n");
649 ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
650 SysFreeString( tag );
651
652 /* figure out what happens if we try to reload the document */
653 str = SysAllocString( szComplete2 );
654 r = IXMLDOMDocument_loadXML( doc, str, &b );
655 ok( r == S_OK, "loadXML failed\n");
656 ok( b == VARIANT_TRUE, "failed to load XML string\n");
657 SysFreeString( str );
658
659 /* check if the tag is still correct */
660 tag = NULL;
661 r = IXMLDOMElement_get_tagName( element, &tag );
662 ok( r == S_OK, "couldn't get tag name\n");
663 ok( tag != NULL, "tag was null\n");
664 ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
665 SysFreeString( tag );
666
667 IXMLDOMElement_Release( element );
668 element = NULL;
669 }
670
671 /* as soon as we call loadXML again, the document element will disappear */
672 b = 2;
673 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
674 ok( r == S_FALSE, "loadXML failed\n");
675 ok( b == 2, "variant modified\n");
676 r = IXMLDOMDocument_get_documentElement( doc, &element );
677 ok( r == S_FALSE, "should be no document element\n");
678
679 /* try to load something else simple and valid */
680 b = VARIANT_FALSE;
681 str = SysAllocString( szComplete3 );
682 r = IXMLDOMDocument_loadXML( doc, str, &b );
683 ok( r == S_OK, "loadXML failed\n");
684 ok( b == VARIANT_TRUE, "failed to load XML string\n");
685 SysFreeString( str );
686
687 /* try something a little more complicated */
688 b = FALSE;
689 str = SysAllocString( szComplete4 );
690 r = IXMLDOMDocument_loadXML( doc, str, &b );
691 ok( r == S_OK, "loadXML failed\n");
692 ok( b == VARIANT_TRUE, "failed to load XML string\n");
693 SysFreeString( str );
694
695 r = IXMLDOMDocument_get_parseError( doc, &error );
696 ok( r == S_OK, "returns %08x\n", r );
697
698 r = IXMLDOMParseError_get_errorCode( error, &code );
699 ok( r == S_FALSE, "returns %08x\n", r );
700 ok( code == 0, "code %d\n", code );
701 IXMLDOMParseError_Release( error );
702
703 /* test createTextNode */
704 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
705 ok( r == S_OK, "returns %08x\n", r );
706 IXMLDOMText_Release(nodetext);
707
708 str = SysAllocString( szOpen );
709 r = IXMLDOMDocument_createTextNode(doc, str, NULL);
710 ok( r == E_INVALIDARG, "returns %08x\n", r );
711 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
712 ok( r == S_OK, "returns %08x\n", r );
713 SysFreeString( str );
714 if(nodetext)
715 {
716 IXMLDOMNamedNodeMap *pAttribs;
717
718 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (LPVOID*)&element);
719 ok(r == E_NOINTERFACE, "ret %08x\n", r );
720
721 /* Text Last Child Checks */
722 r = IXMLDOMText_get_lastChild(nodetext, NULL);
723 ok(r == E_INVALIDARG, "ret %08x\n", r );
724
725 nodeChild = (IXMLDOMNode*)0x1;
726 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
727 ok(r == S_FALSE, "ret %08x\n", r );
728 ok(nodeChild == NULL, "nodeChild not NULL\n");
729
730 /* test get_attributes */
731 r = IXMLDOMText_get_attributes( nodetext, NULL );
732 ok( r == E_INVALIDARG, "get_attributes returned wrong code\n");
733
734 pAttribs = (IXMLDOMNamedNodeMap*)0x1;
735 r = IXMLDOMText_get_attributes( nodetext, &pAttribs);
736 ok(r == S_FALSE, "ret %08x\n", r );
737 ok( pAttribs == NULL, "pAttribs not NULL\n");
738
739 /* test get_dataType */
740 r = IXMLDOMText_get_dataType(nodetext, &var);
741 ok(r == S_FALSE, "ret %08x\n", r );
742 ok( V_VT(&var) == VT_NULL, "incorrect dataType type\n");
743 VariantClear(&var);
744
745 /* test length property */
746 r = IXMLDOMText_get_length(nodetext, NULL);
747 ok(r == E_INVALIDARG, "ret %08x\n", r );
748
749 r = IXMLDOMText_get_length(nodetext, &nLength);
750 ok(r == S_OK, "ret %08x\n", r );
751 ok(nLength == 4, "expected 4 got %d\n", nLength);
752
753 /* test nodeTypeString */
754 r = IXMLDOMText_get_nodeTypeString(nodetext, &str);
755 ok(r == S_OK, "ret %08x\n", r );
756 ok( !lstrcmpW( str, _bstr_("text") ), "incorrect nodeTypeString string\n");
757 SysFreeString(str);
758
759 /* put data Tests */
760 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
761 ok(r == S_OK, "ret %08x\n", r );
762
763 /* get data Tests */
764 r = IXMLDOMText_get_data(nodetext, &str);
765 ok(r == S_OK, "ret %08x\n", r );
766 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
767 SysFreeString(str);
768
769 /* Confirm XML text is good */
770 r = IXMLDOMText_get_xml(nodetext, &str);
771 ok(r == S_OK, "ret %08x\n", r );
772 ok( !lstrcmpW( str, _bstr_("This &amp;is a ; test &lt;&gt;\\") ), "incorrect xml string\n");
773 SysFreeString(str);
774
775 /* Confirm we get the put_data Text back */
776 r = IXMLDOMText_get_text(nodetext, &str);
777 ok(r == S_OK, "ret %08x\n", r );
778 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
779 SysFreeString(str);
780
781 /* test substringData */
782 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
783 ok(r == E_INVALIDARG, "ret %08x\n", r );
784
785 /* test substringData - Invalid offset */
786 str = (BSTR)&szElement;
787 r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
788 ok(r == E_INVALIDARG, "ret %08x\n", r );
789 ok( str == NULL, "incorrect string\n");
790
791 /* test substringData - Invalid offset */
792 str = (BSTR)&szElement;
793 r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
794 ok(r == S_FALSE, "ret %08x\n", r );
795 ok( str == NULL, "incorrect string\n");
796
797 /* test substringData - Invalid size */
798 str = (BSTR)&szElement;
799 r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
800 ok(r == E_INVALIDARG, "ret %08x\n", r );
801 ok( str == NULL, "incorrect string\n");
802
803 /* test substringData - Invalid size */
804 str = (BSTR)&szElement;
805 r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
806 ok(r == S_FALSE, "ret %08x\n", r );
807 ok( str == NULL, "incorrect string\n");
808
809 /* test substringData - Start of string */
810 r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
811 ok(r == S_OK, "ret %08x\n", r );
812 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
813 SysFreeString(str);
814
815 /* test substringData - Middle of string */
816 r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
817 ok(r == S_OK, "ret %08x\n", r );
818 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
819 SysFreeString(str);
820
821 /* test substringData - End of string */
822 r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
823 ok(r == S_OK, "ret %08x\n", r );
824 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
825 SysFreeString(str);
826
827 /* test appendData */
828 r = IXMLDOMText_appendData(nodetext, NULL);
829 ok(r == S_OK, "ret %08x\n", r );
830
831 r = IXMLDOMText_appendData(nodetext, _bstr_(""));
832 ok(r == S_OK, "ret %08x\n", r );
833
834 r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
835 ok(r == S_OK, "ret %08x\n", r );
836
837 r = IXMLDOMText_get_text(nodetext, &str);
838 ok(r == S_OK, "ret %08x\n", r );
839 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string\n");
840 SysFreeString(str);
841
842 /* test insertData */
843 str = SysAllocStringLen(NULL, 0);
844 r = IXMLDOMText_insertData(nodetext, -1, str);
845 ok(r == S_OK, "ret %08x\n", r );
846
847 r = IXMLDOMText_insertData(nodetext, -1, NULL);
848 ok(r == S_OK, "ret %08x\n", r );
849
850 r = IXMLDOMText_insertData(nodetext, 1000, str);
851 ok(r == S_OK, "ret %08x\n", r );
852
853 r = IXMLDOMText_insertData(nodetext, 1000, NULL);
854 ok(r == S_OK, "ret %08x\n", r );
855
856 r = IXMLDOMText_insertData(nodetext, 0, NULL);
857 ok(r == S_OK, "ret %08x\n", r );
858
859 r = IXMLDOMText_insertData(nodetext, 0, str);
860 ok(r == S_OK, "ret %08x\n", r );
861 SysFreeString(str);
862
863 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
864 ok(r == E_INVALIDARG, "ret %08x\n", r );
865
866 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
867 ok(r == E_INVALIDARG, "ret %08x\n", r );
868
869 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
870 ok(r == S_OK, "ret %08x\n", r );
871
872 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
873 ok(r == S_OK, "ret %08x\n", r );
874
875 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
876 ok(r == S_OK, "ret %08x\n", r );
877
878 r = IXMLDOMText_get_text(nodetext, &str);
879 ok(r == S_OK, "ret %08x\n", r );
880 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
881 SysFreeString(str);
882
883 /* delete data */
884 /* invalid arguments */
885 r = IXMLDOMText_deleteData(nodetext, -1, 1);
886 ok(r == E_INVALIDARG, "ret %08x\n", r );
887
888 r = IXMLDOMText_deleteData(nodetext, 0, 0);
889 ok(r == S_OK, "ret %08x\n", r );
890
891 r = IXMLDOMText_deleteData(nodetext, 0, -1);
892 ok(r == E_INVALIDARG, "ret %08x\n", r );
893
894 r = IXMLDOMText_get_length(nodetext, &nLength);
895 ok(r == S_OK, "ret %08x\n", r );
896 ok(nLength == 43, "expected 43 got %d\n", nLength);
897
898 r = IXMLDOMText_deleteData(nodetext, nLength, 1);
899 ok(r == S_OK, "ret %08x\n", r );
900
901 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
902 ok(r == E_INVALIDARG, "ret %08x\n", r );
903
904 /* delete from start */
905 r = IXMLDOMText_deleteData(nodetext, 0, 5);
906 ok(r == S_OK, "ret %08x\n", r );
907
908 r = IXMLDOMText_get_length(nodetext, &nLength);
909 ok(r == S_OK, "ret %08x\n", r );
910 ok(nLength == 38, "expected 38 got %d\n", nLength);
911
912 r = IXMLDOMText_get_text(nodetext, &str);
913 ok(r == S_OK, "ret %08x\n", r );
914 /* whitespace preserving needs to be handled here */
915 todo_wine ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string\n");
916 SysFreeString(str);
917
918 /* delete from end */
919 r = IXMLDOMText_deleteData(nodetext, 35, 3);
920 ok(r == S_OK, "ret %08x\n", r );
921
922 r = IXMLDOMText_get_length(nodetext, &nLength);
923 ok(r == S_OK, "ret %08x\n", r );
924 ok(nLength == 35, "expected 35 got %d\n", nLength);
925
926 r = IXMLDOMText_get_text(nodetext, &str);
927 ok(r == S_OK, "ret %08x\n", r );
928 todo_wine ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string\n");
929 SysFreeString(str);
930
931 /* delete from inside */
932 r = IXMLDOMText_deleteData(nodetext, 1, 33);
933 ok(r == S_OK, "ret %08x\n", r );
934
935 r = IXMLDOMText_get_length(nodetext, &nLength);
936 ok(r == S_OK, "ret %08x\n", r );
937 ok(nLength == 2, "expected 2 got %d\n", nLength);
938
939 r = IXMLDOMText_get_text(nodetext, &str);
940 ok(r == S_OK, "ret %08x\n", r );
941 todo_wine ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string\n");
942 SysFreeString(str);
943
944 /* delete whole data ... */
945 r = IXMLDOMText_get_length(nodetext, &nLength);
946 ok(r == S_OK, "ret %08x\n", r );
947
948 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
949 ok(r == S_OK, "ret %08x\n", r );
950 /* ... and try again with empty string */
951 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
952 ok(r == S_OK, "ret %08x\n", r );
953
954 /* test put_data */
955 V_VT(&var) = VT_BSTR;
956 V_BSTR(&var) = SysAllocString(szstr1);
957 r = IXMLDOMText_put_nodeValue(nodetext, var);
958 ok(r == S_OK, "ret %08x\n", r );
959 VariantClear(&var);
960
961 r = IXMLDOMText_get_text(nodetext, &str);
962 ok(r == S_OK, "ret %08x\n", r );
963 ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string\n");
964 SysFreeString(str);
965
966 /* test put_data */
967 V_VT(&var) = VT_I4;
968 V_I4(&var) = 99;
969 r = IXMLDOMText_put_nodeValue(nodetext, var);
970 ok(r == S_OK, "ret %08x\n", r );
971 VariantClear(&var);
972
973 r = IXMLDOMText_get_text(nodetext, &str);
974 ok(r == S_OK, "ret %08x\n", r );
975 ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string\n");
976 SysFreeString(str);
977
978 /* ::replaceData() */
979 V_VT(&var) = VT_BSTR;
980 V_BSTR(&var) = SysAllocString(szstr1);
981 r = IXMLDOMText_put_nodeValue(nodetext, var);
982 ok(r == S_OK, "ret %08x\n", r );
983 VariantClear(&var);
984
985 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
986 ok(r == E_INVALIDARG, "ret %08x\n", r );
987 r = IXMLDOMText_get_text(nodetext, &str);
988 ok(r == S_OK, "ret %08x\n", r );
989 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
990 SysFreeString(str);
991
992 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
993 ok(r == S_OK, "ret %08x\n", r );
994 r = IXMLDOMText_get_text(nodetext, &str);
995 ok(r == S_OK, "ret %08x\n", r );
996 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string\n");
997 SysFreeString(str);
998
999 /* NULL pointer means delete */
1000 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1001 ok(r == S_OK, "ret %08x\n", r );
1002 r = IXMLDOMText_get_text(nodetext, &str);
1003 ok(r == S_OK, "ret %08x\n", r );
1004 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string\n");
1005 SysFreeString(str);
1006
1007 /* empty string means delete */
1008 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
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_("r1") ), "incorrect get_text string\n");
1013 SysFreeString(str);
1014
1015 /* zero count means insert */
1016 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
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_("ar1") ), "incorrect get_text string\n");
1021 SysFreeString(str);
1022
1023 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1024 ok(r == S_OK, "ret %08x\n", r );
1025
1026 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1027 ok(r == S_OK, "ret %08x\n", r );
1028 r = IXMLDOMText_get_text(nodetext, &str);
1029 ok(r == S_OK, "ret %08x\n", r );
1030 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string\n");
1031 SysFreeString(str);
1032
1033 /* nonempty string, count greater than its length */
1034 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1035 ok(r == S_OK, "ret %08x\n", r );
1036 r = IXMLDOMText_get_text(nodetext, &str);
1037 ok(r == S_OK, "ret %08x\n", r );
1038 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string\n");
1039 SysFreeString(str);
1040
1041 /* nonempty string, count less than its length */
1042 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
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_("wine1.2") ), "incorrect get_text string\n");
1047 SysFreeString(str);
1048
1049 IXMLDOMText_Release( nodetext );
1050 }
1051
1052 /* test Create Comment */
1053 r = IXMLDOMDocument_createComment(doc, NULL, NULL);
1054 ok( r == E_INVALIDARG, "returns %08x\n", r );
1055 node_comment = (IXMLDOMComment*)0x1;
1056
1057 /* empty comment */
1058 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
1059 ok( r == S_OK, "returns %08x\n", r );
1060 str = (BSTR)0x1;
1061 r = IXMLDOMComment_get_data(node_comment, &str);
1062 ok( r == S_OK, "returns %08x\n", r );
1063 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
1064 IXMLDOMComment_Release(node_comment);
1065 SysFreeString(str);
1066
1067 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
1068 ok( r == S_OK, "returns %08x\n", r );
1069 str = (BSTR)0x1;
1070 r = IXMLDOMComment_get_data(node_comment, &str);
1071 ok( r == S_OK, "returns %08x\n", r );
1072 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
1073 IXMLDOMComment_Release(node_comment);
1074 SysFreeString(str);
1075
1076 str = SysAllocString(szComment);
1077 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
1078 SysFreeString(str);
1079 ok( r == S_OK, "returns %08x\n", r );
1080 if(node_comment)
1081 {
1082 /* Last Child Checks */
1083 r = IXMLDOMComment_get_lastChild(node_comment, NULL);
1084 ok(r == E_INVALIDARG, "ret %08x\n", r );
1085
1086 nodeChild = (IXMLDOMNode*)0x1;
1087 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
1088 ok(r == S_FALSE, "ret %08x\n", r );
1089 ok(nodeChild == NULL, "pLastChild not NULL\n");
1090
1091 /* baseName */
1092 str = (BSTR)0xdeadbeef;
1093 IXMLDOMComment_get_baseName(node_comment, &str);
1094 ok(r == S_FALSE, "ret %08x\n", r );
1095 ok(str == NULL, "Expected NULL\n");
1096
1097 IXMLDOMComment_Release( node_comment );
1098 }
1099
1100 /* test Create Attribute */
1101 str = SysAllocString(szAttribute);
1102 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
1103 ok( r == E_INVALIDARG, "returns %08x\n", r );
1104 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
1105 ok( r == S_OK, "returns %08x\n", r );
1106 IXMLDOMText_Release( node_attr);
1107 SysFreeString(str);
1108
1109 /* test Processing Instruction */
1110 str = SysAllocStringLen(NULL, 0);
1111 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
1112 ok( r == E_INVALIDARG, "returns %08x\n", r );
1113 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
1114 ok( r == E_FAIL, "returns %08x\n", r );
1115 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
1116 ok( r == E_FAIL, "returns %08x\n", r );
1117 SysFreeString(str);
1118
1119 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
1120 ok( r == S_OK, "returns %08x\n", r );
1121 if(nodePI)
1122 {
1123 /* Last Child Checks */
1124 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
1125 ok(r == E_INVALIDARG, "ret %08x\n", r );
1126
1127 nodeChild = (IXMLDOMNode*)0x1;
1128 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
1129 ok(r == S_FALSE, "ret %08x\n", r );
1130 ok(nodeChild == NULL, "nodeChild not NULL\n");
1131
1132 r = IXMLDOMProcessingInstruction_get_dataType(nodePI, &var);
1133 ok(r == S_FALSE, "ret %08x\n", r );
1134 ok( V_VT(&var) == VT_NULL, "incorrect dataType type\n");
1135 VariantClear(&var);
1136
1137 /* test nodeName */
1138 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1139 ok(r == S_OK, "ret %08x\n", r );
1140 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1141 SysFreeString(str);
1142
1143 /* test baseName */
1144 str = (BSTR)0x1;
1145 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
1146 ok(r == S_OK, "ret %08x\n", r );
1147 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1148 SysFreeString(str);
1149
1150 /* test Target */
1151 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
1152 ok(r == S_OK, "ret %08x\n", r );
1153 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
1154 SysFreeString(str);
1155
1156 /* test nodeTypeString */
1157 r = IXMLDOMProcessingInstruction_get_nodeTypeString(nodePI, &str);
1158 ok(r == S_OK, "ret %08x\n", r );
1159 ok( !lstrcmpW( str, _bstr_("processinginstruction") ), "incorrect nodeTypeString string\n");
1160 SysFreeString(str);
1161
1162 /* test get_nodeValue */
1163 r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
1164 ok(r == S_OK, "ret %08x\n", r );
1165 ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1166 VariantClear(&var);
1167
1168 /* test get_data */
1169 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
1170 ok(r == S_OK, "ret %08x\n", r );
1171 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1172 SysFreeString(str);
1173
1174 /* test put_data */
1175 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
1176 ok(r == E_FAIL, "ret %08x\n", r );
1177
1178 /* test put_data */
1179 V_VT(&var) = VT_BSTR;
1180 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
1181 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
1182 ok(r == E_FAIL, "ret %08x\n", r );
1183 VariantClear(&var);
1184
1185 /* test get nodeName */
1186 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1187 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1188 ok(r == S_OK, "ret %08x\n", r );
1189 SysFreeString(str);
1190
1191 IXMLDOMProcessingInstruction_Release(nodePI);
1192 }
1193
1194 r = IXMLDOMDocument_QueryInterface( doc, &IID_ISupportErrorInfo, (LPVOID*)&support_error );
1195 ok( r == S_OK, "ret %08x\n", r );
1196 if(r == S_OK)
1197 {
1198 r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMDocument );
1199 todo_wine ok( r == S_OK, "ret %08x\n", r );
1200 ISupportErrorInfo_Release( support_error );
1201 }
1202
1203 r = IXMLDOMDocument_Release( doc );
1204 ok( r == 0, "document ref count incorrect\n");
1205
1206 free_bstrs();
1207 }
1208
1209 static void test_domnode( void )
1210 {
1211 HRESULT r;
1212 IXMLDOMDocument *doc = NULL, *owner = NULL;
1213 IXMLDOMElement *element = NULL;
1214 IXMLDOMNamedNodeMap *map = NULL;
1215 IXMLDOMNode *node = NULL, *next = NULL;
1216 IXMLDOMNodeList *list = NULL;
1217 IXMLDOMAttribute *attr = NULL;
1218 DOMNodeType type = NODE_INVALID;
1219 VARIANT_BOOL b;
1220 BSTR str;
1221 VARIANT var;
1222 LONG count;
1223
1224 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
1225 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1226 if( r != S_OK )
1227 return;
1228 if (!doc) {
1229 ok( FALSE, "no document\n");
1230 return;
1231 }
1232
1233 b = FALSE;
1234 str = SysAllocString( szComplete4 );
1235 r = IXMLDOMDocument_loadXML( doc, str, &b );
1236 ok( r == S_OK, "loadXML failed\n");
1237 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1238 SysFreeString( str );
1239
1240 b = 1;
1241 r = IXMLDOMNode_hasChildNodes( doc, &b );
1242 ok( r == S_OK, "hasChildNoes bad return\n");
1243 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1244
1245 r = IXMLDOMDocument_get_documentElement( doc, &element );
1246 ok( r == S_OK, "should be a document element\n");
1247 ok( element != NULL, "should be an element\n");
1248
1249 VariantInit(&var);
1250 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1251
1252 r = IXMLDOMNode_get_nodeValue( doc, NULL );
1253 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
1254
1255 r = IXMLDOMNode_get_nodeValue( doc, &var );
1256 ok( r == S_FALSE, "nextNode returned wrong code\n");
1257 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1258 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1259
1260 if (element)
1261 {
1262 owner = NULL;
1263 r = IXMLDOMNode_get_ownerDocument( element, &owner );
1264 ok( r == S_OK, "get_ownerDocument return code\n");
1265 ok( owner != doc, "get_ownerDocument return\n");
1266 IXMLDOMDocument_Release(owner);
1267
1268 type = NODE_INVALID;
1269 r = IXMLDOMNode_get_nodeType( element, &type);
1270 ok( r == S_OK, "getNamedItem returned wrong code\n");
1271 ok( type == NODE_ELEMENT, "node not an element\n");
1272
1273 str = NULL;
1274 r = IXMLDOMNode_get_baseName( element, &str );
1275 ok( r == S_OK, "get_baseName returned wrong code\n");
1276 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
1277 SysFreeString(str);
1278
1279 /* check if nodename is correct */
1280 r = IXMLDOMElement_get_nodeName( element, NULL );
1281 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1282
1283 /* content doesn't matter here */
1284 str = NULL;
1285 r = IXMLDOMElement_get_nodeName( element, &str );
1286 ok ( r == S_OK, "get_nodeName wrong code\n");
1287 ok ( str != NULL, "str is null\n");
1288 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
1289 SysFreeString( str );
1290
1291 str = SysAllocString( szNonExistentFile );
1292 V_VT(&var) = VT_I4;
1293 V_I4(&var) = 0x1234;
1294 r = IXMLDOMElement_getAttribute( element, str, &var );
1295 ok( r == E_FAIL, "getAttribute ret %08x\n", r );
1296 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
1297 VariantClear(&var);
1298
1299 r = IXMLDOMElement_getAttributeNode( element, str, NULL);
1300 ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1301
1302 attr = (IXMLDOMAttribute*)0xdeadbeef;
1303 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1304 ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1305 ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1306 SysFreeString( str );
1307
1308 attr = (IXMLDOMAttribute*)0xdeadbeef;
1309 str = SysAllocString( szNonExistentAttribute );
1310 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1311 ok( r == S_FALSE, "getAttributeNode ret %08x\n", r );
1312 ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1313 SysFreeString( str );
1314
1315 str = SysAllocString( szdl );
1316 V_VT(&var) = VT_I4;
1317 V_I4(&var) = 0x1234;
1318 r = IXMLDOMElement_getAttribute( element, str, &var );
1319 ok( r == S_OK, "getAttribute ret %08x\n", r );
1320 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
1321 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
1322 VariantClear( &var );
1323
1324 r = IXMLDOMElement_getAttribute( element, NULL, &var );
1325 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1326
1327 r = IXMLDOMElement_getAttribute( element, str, NULL );
1328 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1329
1330 attr = NULL;
1331 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1332 ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
1333 ok( attr != NULL, "getAttributeNode returned NULL\n" );
1334 if (attr)
1335 {
1336 r = IXMLDOMAttribute_get_parentNode( attr, NULL );
1337 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
1338
1339 /* attribute doesn't have a parent in msxml interpretation */
1340 node = (IXMLDOMNode*)0xdeadbeef;
1341 r = IXMLDOMAttribute_get_parentNode( attr, &node );
1342 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
1343 ok( node == NULL, "Expected NULL, got %p\n", node );
1344
1345 IXMLDOMAttribute_Release(attr);
1346 }
1347
1348 SysFreeString( str );
1349
1350 r = IXMLDOMElement_get_attributes( element, &map );
1351 ok( r == S_OK, "get_attributes returned wrong code\n");
1352 ok( map != NULL, "should be attributes\n");
1353
1354 b = 1;
1355 r = IXMLDOMNode_hasChildNodes( element, &b );
1356 ok( r == S_OK, "hasChildNoes bad return\n");
1357 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1358 }
1359 else
1360 ok( FALSE, "no element\n");
1361
1362 if (map)
1363 {
1364 ISupportErrorInfo *support_error;
1365 r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (LPVOID*)&support_error );
1366 ok( r == S_OK, "ret %08x\n", r );
1367
1368 r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
1369 todo_wine
1370 {
1371 ok( r == S_OK, "ret %08x\n", r );
1372 }
1373 ISupportErrorInfo_Release( support_error );
1374
1375 str = SysAllocString( szdl );
1376 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1377 ok( r == S_OK, "getNamedItem returned wrong code\n");
1378 ok( node != NULL, "should be attributes\n");
1379 IXMLDOMNode_Release(node);
1380 SysFreeString( str );
1381
1382 str = SysAllocString( szdl );
1383 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
1384 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
1385 SysFreeString( str );
1386
1387 /* something that isn't in szComplete4 */
1388 str = SysAllocString( szOpen );
1389 node = (IXMLDOMNode *) 1;
1390 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1391 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
1392 ok( node == NULL, "getNamedItem should have returned NULL\n");
1393 SysFreeString( str );
1394
1395 /* test indexed access of attributes */
1396 r = IXMLDOMNamedNodeMap_get_length( map, NULL );
1397 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
1398
1399 r = IXMLDOMNamedNodeMap_get_length( map, &count );
1400 ok ( r == S_OK, "get_length wrong code\n");
1401 ok ( count == 1, "get_length != 1\n");
1402
1403 node = NULL;
1404 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
1405 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
1406 ok ( node == NULL, "there is no node\n");
1407
1408 node = NULL;
1409 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
1410 ok ( r == S_FALSE, "get_item (1) wrong code\n");
1411 ok ( node == NULL, "there is no attribute\n");
1412
1413 node = NULL;
1414 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
1415 ok ( r == S_OK, "get_item (0) wrong code\n");
1416 ok ( node != NULL, "should be attribute\n");
1417
1418 r = IXMLDOMNode_get_nodeName( node, NULL );
1419 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1420
1421 /* content doesn't matter here */
1422 str = NULL;
1423 r = IXMLDOMNode_get_nodeName( node, &str );
1424 ok ( r == S_OK, "get_nodeName wrong code\n");
1425 ok ( str != NULL, "str is null\n");
1426 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
1427 SysFreeString( str );
1428
1429 /* test sequential access of attributes */
1430 node = NULL;
1431 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1432 ok ( r == S_OK, "nextNode (first time) wrong code\n");
1433 ok ( node != NULL, "nextNode, should be attribute\n");
1434
1435 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1436 ok ( r != S_OK, "nextNode (second time) wrong code\n");
1437 ok ( node == NULL, "nextNode, there is no attribute\n");
1438
1439 r = IXMLDOMNamedNodeMap_reset( map );
1440 ok ( r == S_OK, "reset should return S_OK\n");
1441
1442 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1443 ok ( r == S_OK, "nextNode (third time) wrong code\n");
1444 ok ( node != NULL, "nextNode, should be attribute\n");
1445 }
1446 else
1447 ok( FALSE, "no map\n");
1448
1449 if (node)
1450 {
1451 type = NODE_INVALID;
1452 r = IXMLDOMNode_get_nodeType( node, &type);
1453 ok( r == S_OK, "getNamedItem returned wrong code\n");
1454 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
1455
1456 str = NULL;
1457 r = IXMLDOMNode_get_baseName( node, NULL );
1458 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
1459
1460 str = NULL;
1461 r = IXMLDOMNode_get_baseName( node, &str );
1462 ok( r == S_OK, "get_baseName returned wrong code\n");
1463 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
1464 SysFreeString( str );
1465
1466 r = IXMLDOMNode_get_nodeValue( node, &var );
1467 ok( r == S_OK, "returns %08x\n", r );
1468 ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
1469 ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
1470 VariantClear(&var);
1471
1472 r = IXMLDOMNode_get_childNodes( node, NULL );
1473 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
1474
1475 r = IXMLDOMNode_get_childNodes( node, &list );
1476 ok( r == S_OK, "get_childNodes returned wrong code\n");
1477
1478 if (list)
1479 {
1480 r = IXMLDOMNodeList_nextNode( list, &next );
1481 ok( r == S_OK, "nextNode returned wrong code\n");
1482 }
1483 else
1484 ok( FALSE, "no childlist\n");
1485
1486 if (next)
1487 {
1488 b = 1;
1489 r = IXMLDOMNode_hasChildNodes( next, &b );
1490 ok( r == S_FALSE, "hasChildNoes bad return\n");
1491 ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
1492
1493 type = NODE_INVALID;
1494 r = IXMLDOMNode_get_nodeType( next, &type);
1495 ok( r == S_OK, "getNamedItem returned wrong code\n");
1496 ok( type == NODE_TEXT, "node not text\n");
1497
1498 str = (BSTR) 1;
1499 r = IXMLDOMNode_get_baseName( next, &str );
1500 ok( r == S_FALSE, "get_baseName returned wrong code\n");
1501 ok( str == NULL, "basename was wrong\n");
1502 SysFreeString(str);
1503 }
1504 else
1505 ok( FALSE, "no next\n");
1506
1507 if (next)
1508 IXMLDOMNode_Release( next );
1509 next = NULL;
1510 if (list)
1511 IXMLDOMNodeList_Release( list );
1512 list = NULL;
1513 if (node)
1514 IXMLDOMNode_Release( node );
1515 }
1516 else
1517 ok( FALSE, "no node\n");
1518 node = NULL;
1519
1520 if (map)
1521 IXMLDOMNamedNodeMap_Release( map );
1522
1523 /* now traverse the tree from the root element */
1524 if (element)
1525 {
1526 r = IXMLDOMNode_get_childNodes( element, &list );
1527 ok( r == S_OK, "get_childNodes returned wrong code\n");
1528
1529 /* using get_item for child list doesn't advance the position */
1530 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
1531 expect_node(node, "E2.E2.D1");
1532 IXMLDOMNode_Release(node);
1533 ole_check(IXMLDOMNodeList_nextNode(list, &node));
1534 expect_node(node, "E1.E2.D1");
1535 IXMLDOMNode_Release(node);
1536 ole_check(IXMLDOMNodeList_reset(list));
1537
1538 IXMLDOMNodeList_AddRef(list);
1539 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
1540 ole_check(IXMLDOMNodeList_reset(list));
1541
1542 node = (void*)0xdeadbeef;
1543 str = SysAllocString(szdl);
1544 r = IXMLDOMNode_selectSingleNode( element, str, &node );
1545 SysFreeString(str);
1546 ok( r == S_FALSE, "ret %08x\n", r );
1547 ok( node == NULL, "node %p\n", node );
1548
1549 str = SysAllocString(szbs);
1550 r = IXMLDOMNode_selectSingleNode( element, str, &node );
1551 SysFreeString(str);
1552 ok( r == S_OK, "ret %08x\n", r );
1553 r = IXMLDOMNode_Release( node );
1554 ok( r == 0, "ret %08x\n", r );
1555 }
1556 else
1557 ok( FALSE, "no element\n");
1558
1559 if (list)
1560 {
1561 r = IXMLDOMNodeList_QueryInterface(list, &IID_IDispatch, NULL);
1562 ok( r == E_INVALIDARG || r == E_POINTER, "ret %08x\n", r );
1563
1564 r = IXMLDOMNodeList_get_item(list, 0, NULL);
1565 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1566
1567 r = IXMLDOMNodeList_get_length(list, NULL);
1568 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1569
1570 r = IXMLDOMNodeList_get_length( list, &count );
1571 ok( r == S_OK, "get_length returns %08x\n", r );
1572 ok( count == 4, "get_length got %d\n", count );
1573
1574 r = IXMLDOMNodeList_nextNode(list, NULL);
1575 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1576
1577 r = IXMLDOMNodeList_nextNode( list, &node );
1578 ok( r == S_OK, "nextNode returned wrong code\n");
1579 }
1580 else
1581 ok( FALSE, "no list\n");
1582
1583 if (node)
1584 {
1585 type = NODE_INVALID;
1586 r = IXMLDOMNode_get_nodeType( node, &type);
1587 ok( r == S_OK, "getNamedItem returned wrong code\n");
1588 ok( type == NODE_ELEMENT, "node not text\n");
1589
1590 VariantInit(&var);
1591 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1592 r = IXMLDOMNode_get_nodeValue( node, &var );
1593 ok( r == S_FALSE, "nextNode returned wrong code\n");
1594 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1595 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1596
1597 r = IXMLDOMNode_hasChildNodes( node, NULL );
1598 ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
1599
1600 b = 1;
1601 r = IXMLDOMNode_hasChildNodes( node, &b );
1602 ok( r == S_OK, "hasChildNoes bad return\n");
1603 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1604
1605 str = NULL;
1606 r = IXMLDOMNode_get_baseName( node, &str );
1607 ok( r == S_OK, "get_baseName returned wrong code\n");
1608 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
1609 SysFreeString(str);
1610 }
1611 else
1612 ok( FALSE, "no node\n");
1613
1614 if (node)
1615 IXMLDOMNode_Release( node );
1616 if (list)
1617 IXMLDOMNodeList_Release( list );
1618 if (element)
1619 IXMLDOMElement_Release( element );
1620
1621 b = FALSE;
1622 str = SysAllocString( szComplete5 );
1623 r = IXMLDOMDocument_loadXML( doc, str, &b );
1624 ok( r == S_OK, "loadXML failed\n");
1625 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1626 SysFreeString( str );
1627
1628 b = 1;
1629 r = IXMLDOMNode_hasChildNodes( doc, &b );
1630 ok( r == S_OK, "hasChildNoes bad return\n");
1631 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
1632
1633 r = IXMLDOMDocument_get_documentElement( doc, &element );
1634 ok( r == S_OK, "should be a document element\n");
1635 ok( element != NULL, "should be an element\n");
1636
1637 if (element)
1638 {
1639 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
1640 BSTR tag = NULL;
1641
1642 /* check if the tag is correct */
1643 r = IXMLDOMElement_get_tagName( element, &tag );
1644 ok( r == S_OK, "couldn't get tag name\n");
1645 ok( tag != NULL, "tag was null\n");
1646 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
1647 SysFreeString( tag );
1648 }
1649
1650 if (element)
1651 IXMLDOMElement_Release( element );
1652 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
1653 }
1654
1655 static void test_refs(void)
1656 {
1657 HRESULT r;
1658 BSTR str;
1659 VARIANT_BOOL b;
1660 IXMLDOMDocument *doc = NULL;
1661 IXMLDOMElement *element = NULL;
1662 IXMLDOMNode *node = NULL, *node2;
1663 IXMLDOMNodeList *node_list = NULL;
1664 LONG ref;
1665 IUnknown *unk, *unk2;
1666
1667 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
1668 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1669 if( r != S_OK )
1670 return;
1671 ref = IXMLDOMDocument_Release(doc);
1672 ok( ref == 0, "ref %d\n", ref);
1673
1674 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
1675 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1676 if( r != S_OK )
1677 return;
1678
1679 str = SysAllocString( szComplete4 );
1680 r = IXMLDOMDocument_loadXML( doc, str, &b );
1681 ok( r == S_OK, "loadXML failed\n");
1682 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1683 SysFreeString( str );
1684
1685 ref = IXMLDOMDocument_AddRef( doc );
1686 ok( ref == 2, "ref %d\n", ref );
1687 ref = IXMLDOMDocument_AddRef( doc );
1688 ok( ref == 3, "ref %d\n", ref );
1689 IXMLDOMDocument_Release( doc );
1690 IXMLDOMDocument_Release( doc );
1691
1692 r = IXMLDOMDocument_get_documentElement( doc, &element );
1693 ok( r == S_OK, "should be a document element\n");
1694 ok( element != NULL, "should be an element\n");
1695
1696 ref = IXMLDOMDocument_AddRef( doc );
1697 ok( ref == 2, "ref %d\n", ref );
1698 IXMLDOMDocument_Release( doc );
1699
1700 r = IXMLDOMElement_get_childNodes( element, &node_list );
1701 ok( r == S_OK, "rets %08x\n", r);
1702
1703 ref = IXMLDOMNodeList_AddRef( node_list );
1704 ok( ref == 2, "ref %d\n", ref );
1705 IXMLDOMNodeList_Release( node_list );
1706
1707 IXMLDOMNodeList_get_item( node_list, 0, &node );
1708 ok( r == S_OK, "rets %08x\n", r);
1709
1710 IXMLDOMNodeList_get_item( node_list, 0, &node2 );
1711 ok( r == S_OK, "rets %08x\n", r);
1712
1713 ref = IXMLDOMNode_AddRef( node );
1714 ok( ref == 2, "ref %d\n", ref );
1715 IXMLDOMNode_Release( node );
1716
1717 ref = IXMLDOMNode_Release( node );
1718 ok( ref == 0, "ref %d\n", ref );
1719 ref = IXMLDOMNode_Release( node2 );
1720 ok( ref == 0, "ref %d\n", ref );
1721
1722 ref = IXMLDOMNodeList_Release( node_list );
1723 ok( ref == 0, "ref %d\n", ref );
1724
1725 ok( node != node2, "node %p node2 %p\n", node, node2 );
1726
1727 ref = IXMLDOMDocument_Release( doc );
1728 ok( ref == 0, "ref %d\n", ref );
1729
1730 ref = IXMLDOMElement_AddRef( element );
1731 todo_wine {
1732 ok( ref == 3, "ref %d\n", ref );
1733 }
1734 IXMLDOMElement_Release( element );
1735
1736 /* IUnknown must be unique however we obtain it */
1737 r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (LPVOID*)&unk );
1738 ok( r == S_OK, "rets %08x\n", r );
1739 r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (LPVOID*)&node );
1740 ok( r == S_OK, "rets %08x\n", r );
1741 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk2 );
1742 ok( r == S_OK, "rets %08x\n", r );
1743 ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
1744
1745 IUnknown_Release( unk2 );
1746 IUnknown_Release( unk );
1747 IXMLDOMNode_Release( node );
1748
1749 IXMLDOMElement_Release( element );
1750
1751 }
1752
1753 static void test_create(void)
1754 {
1755 static const WCHAR szOne[] = {'1',0};
1756 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
1757 HRESULT r;
1758 VARIANT var;
1759 BSTR str, name;
1760 IXMLDOMDocument *doc;
1761 IXMLDOMElement *element;
1762 IXMLDOMComment *comment;
1763 IXMLDOMText *text;
1764 IXMLDOMCDATASection *cdata;
1765 IXMLDOMNode *root, *node, *child;
1766 IXMLDOMNamedNodeMap *attr_map;
1767 IUnknown *unk;
1768 LONG ref;
1769 LONG num;
1770
1771 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
1772 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
1773 if( r != S_OK )
1774 return;
1775
1776 /* types not supported for creation */
1777 V_VT(&var) = VT_I1;
1778 V_I1(&var) = NODE_DOCUMENT;
1779 node = (IXMLDOMNode*)0x1;
1780 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1781 ok( r == E_INVALIDARG, "returns %08x\n", r );
1782 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1783
1784 V_VT(&var) = VT_I1;
1785 V_I1(&var) = NODE_DOCUMENT_TYPE;
1786 node = (IXMLDOMNode*)0x1;
1787 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1788 ok( r == E_INVALIDARG, "returns %08x\n", r );
1789 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1790
1791 V_VT(&var) = VT_I1;
1792 V_I1(&var) = NODE_ENTITY;
1793 node = (IXMLDOMNode*)0x1;
1794 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1795 ok( r == E_INVALIDARG, "returns %08x\n", r );
1796 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1797
1798 V_VT(&var) = VT_I1;
1799 V_I1(&var) = NODE_NOTATION;
1800 node = (IXMLDOMNode*)0x1;
1801 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1802 ok( r == E_INVALIDARG, "returns %08x\n", r );
1803 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1804
1805 /* NODE_COMMENT */
1806 V_VT(&var) = VT_I1;
1807 V_I1(&var) = NODE_COMMENT;
1808 node = NULL;
1809 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1810 ok( r == S_OK, "returns %08x\n", r );
1811 ok( node != NULL, "\n");
1812
1813 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
1814 ok( r == S_OK, "returns %08x\n", r );
1815 IXMLDOMNode_Release(node);
1816
1817 str = NULL;
1818 r = IXMLDOMComment_get_data(comment, &str);
1819 ok( r == S_OK, "returns %08x\n", r );
1820 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1821 IXMLDOMComment_Release(comment);
1822 SysFreeString(str);
1823
1824 node = (IXMLDOMNode*)0x1;
1825 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
1826 ok( r == S_OK, "returns %08x\n", r );
1827
1828 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
1829 ok( r == S_OK, "returns %08x\n", r );
1830 IXMLDOMNode_Release(node);
1831
1832 str = NULL;
1833 r = IXMLDOMComment_get_data(comment, &str);
1834 ok( r == S_OK, "returns %08x\n", r );
1835 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1836 IXMLDOMComment_Release(comment);
1837 SysFreeString(str);
1838
1839 node = (IXMLDOMNode*)0x1;
1840 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
1841 ok( r == S_OK, "returns %08x\n", r );
1842
1843 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
1844 ok( r == S_OK, "returns %08x\n", r );
1845 IXMLDOMNode_Release(node);
1846
1847 str = NULL;
1848 r = IXMLDOMComment_get_data(comment, &str);
1849 ok( r == S_OK, "returns %08x\n", r );
1850 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1851 IXMLDOMComment_Release(comment);
1852 SysFreeString(str);
1853
1854 /* NODE_TEXT */
1855 V_VT(&var) = VT_I1;
1856 V_I1(&var) = NODE_TEXT;
1857 node = NULL;
1858 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1859 ok( r == S_OK, "returns %08x\n", r );
1860 ok( node != NULL, "\n");
1861
1862 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
1863 ok( r == S_OK, "returns %08x\n", r );
1864 IXMLDOMNode_Release(node);
1865
1866 str = NULL;
1867 r = IXMLDOMText_get_data(text, &str);
1868 ok( r == S_OK, "returns %08x\n", r );
1869 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1870 IXMLDOMText_Release(text);
1871 SysFreeString(str);
1872
1873 node = (IXMLDOMNode*)0x1;
1874 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
1875 ok( r == S_OK, "returns %08x\n", r );
1876
1877 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
1878 ok( r == S_OK, "returns %08x\n", r );
1879 IXMLDOMNode_Release(node);
1880
1881 str = NULL;
1882 r = IXMLDOMText_get_data(text, &str);
1883 ok( r == S_OK, "returns %08x\n", r );
1884 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1885 IXMLDOMText_Release(text);
1886 SysFreeString(str);
1887
1888 node = (IXMLDOMNode*)0x1;
1889 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
1890 ok( r == S_OK, "returns %08x\n", r );
1891
1892 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
1893 ok( r == S_OK, "returns %08x\n", r );
1894 IXMLDOMNode_Release(node);
1895
1896 str = NULL;
1897 r = IXMLDOMText_get_data(text, &str);
1898 ok( r == S_OK, "returns %08x\n", r );
1899 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1900 IXMLDOMText_Release(text);
1901 SysFreeString(str);
1902
1903 /* NODE_CDATA_SECTION */
1904 V_VT(&var) = VT_I1;
1905 V_I1(&var) = NODE_CDATA_SECTION;
1906 node = NULL;
1907 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1908 ok( r == S_OK, "returns %08x\n", r );
1909 ok( node != NULL, "\n");
1910
1911 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
1912 ok( r == S_OK, "returns %08x\n", r );
1913 IXMLDOMNode_Release(node);
1914
1915 str = NULL;
1916 r = IXMLDOMCDATASection_get_data(cdata, &str);
1917 ok( r == S_OK, "returns %08x\n", r );
1918 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1919 IXMLDOMCDATASection_Release(cdata);
1920 SysFreeString(str);
1921
1922 node = (IXMLDOMNode*)0x1;
1923 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
1924 ok( r == S_OK, "returns %08x\n", r );
1925
1926 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
1927 ok( r == S_OK, "returns %08x\n", r );
1928 IXMLDOMNode_Release(node);
1929
1930 str = NULL;
1931 r = IXMLDOMCDATASection_get_data(cdata, &str);
1932 ok( r == S_OK, "returns %08x\n", r );
1933 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1934 IXMLDOMCDATASection_Release(cdata);
1935 SysFreeString(str);
1936
1937 node = (IXMLDOMNode*)0x1;
1938 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
1939 ok( r == S_OK, "returns %08x\n", r );
1940
1941 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
1942 ok( r == S_OK, "returns %08x\n", r );
1943 IXMLDOMNode_Release(node);
1944
1945 str = NULL;
1946 r = IXMLDOMCDATASection_get_data(cdata, &str);
1947 ok( r == S_OK, "returns %08x\n", r );
1948 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
1949 IXMLDOMCDATASection_Release(cdata);
1950 SysFreeString(str);
1951
1952 /* NODE_ATTRIBUTE */
1953 V_VT(&var) = VT_I1;
1954 V_I1(&var) = NODE_ATTRIBUTE;
1955 node = (IXMLDOMNode*)0x1;
1956 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
1957 ok( r == E_FAIL, "returns %08x\n", r );
1958 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1959
1960 V_VT(&var) = VT_I1;
1961 V_I1(&var) = NODE_ATTRIBUTE;
1962 node = (IXMLDOMNode*)0x1;
1963 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
1964 ok( r == E_FAIL, "returns %08x\n", r );
1965 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1966
1967 V_VT(&var) = VT_I1;
1968 V_I1(&var) = NODE_ATTRIBUTE;
1969 str = SysAllocString( szlc );
1970 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
1971 ok( r == S_OK, "returns %08x\n", r );
1972 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
1973 SysFreeString(str);
1974
1975 /* NODE_PROCESSING_INSTRUCTION */
1976 V_VT(&var) = VT_I1;
1977 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
1978 node = (IXMLDOMNode*)0x1;
1979 r = IXMLDOMDocument_createNode( doc, var, NULL, 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_PROCESSING_INSTRUCTION;
1985 node = (IXMLDOMNode*)0x1;
1986 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
1987 ok( r == E_FAIL, "returns %08x\n", r );
1988 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
1989
1990 V_VT(&var) = VT_I1;
1991 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
1992 r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
1993 ok( r == E_INVALIDARG, "returns %08x\n", r );
1994
1995 /* NODE_ENTITY_REFERENCE */
1996 V_VT(&var) = VT_I1;
1997 V_I1(&var) = NODE_ENTITY_REFERENCE;
1998 node = (IXMLDOMNode*)0x1;
1999 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2000 ok( r == E_FAIL, "returns %08x\n", r );
2001 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2002
2003 V_VT(&var) = VT_I1;
2004 V_I1(&var) = NODE_ENTITY_REFERENCE;
2005 node = (IXMLDOMNode*)0x1;
2006 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2007 ok( r == E_FAIL, "returns %08x\n", r );
2008 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2009
2010 /* NODE_ELEMENT */
2011 V_VT(&var) = VT_I1;
2012 V_I1(&var) = NODE_ELEMENT;
2013 node = (IXMLDOMNode*)0x1;
2014 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2015 ok( r == E_FAIL, "returns %08x\n", r );
2016 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2017
2018 V_VT(&var) = VT_I1;
2019 V_I1(&var) = NODE_ELEMENT;
2020 node = (IXMLDOMNode*)0x1;
2021 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2022 ok( r == E_FAIL, "returns %08x\n", r );
2023 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2024
2025 V_VT(&var) = VT_I1;
2026 V_I1(&var) = NODE_ELEMENT;
2027 str = SysAllocString( szlc );
2028 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2029 ok( r == S_OK, "returns %08x\n", r );
2030 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2031
2032 V_VT(&var) = VT_I1;
2033 V_I1(&var) = NODE_ELEMENT;
2034 r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
2035 ok( r == E_INVALIDARG, "returns %08x\n", r );
2036
2037 V_VT(&var) = VT_R4;
2038 V_R4(&var) = NODE_ELEMENT;
2039 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2040 ok( r == S_OK, "returns %08x\n", r );
2041 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2042
2043 V_VT(&var) = VT_BSTR;
2044 V_BSTR(&var) = SysAllocString( szOne );
2045 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2046 ok( r == S_OK, "returns %08x\n", r );
2047 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2048 VariantClear(&var);
2049
2050 V_VT(&var) = VT_BSTR;
2051 V_BSTR(&var) = SysAllocString( szOneGarbage );
2052 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2053 ok( r == E_INVALIDARG, "returns %08x\n", r );
2054 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2055 VariantClear(&var);
2056
2057 V_VT(&var) = VT_I4;
2058 V_I4(&var) = NODE_ELEMENT;
2059 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2060 ok( r == S_OK, "returns %08x\n", r );
2061 r = IXMLDOMDocument_appendChild( doc, node, &root );
2062 ok( r == S_OK, "returns %08x\n", r );
2063 ok( node == root, "%p %p\n", node, root );
2064
2065 ref = IXMLDOMNode_AddRef( node );
2066 ok(ref == 3, "ref %d\n", ref);
2067 IXMLDOMNode_Release( node );
2068
2069 ref = IXMLDOMNode_Release( node );
2070 ok(ref == 1, "ref %d\n", ref);
2071 SysFreeString( str );
2072
2073 V_VT(&var) = VT_I4;
2074 V_I4(&var) = NODE_ELEMENT;
2075 str = SysAllocString( szbs );
2076 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2077 ok( r == S_OK, "returns %08x\n", r );
2078 SysFreeString( str );
2079
2080 ref = IXMLDOMNode_AddRef( node );
2081 ok(ref == 2, "ref = %d\n", ref);
2082 IXMLDOMNode_Release( node );
2083
2084 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk );
2085 ok( r == S_OK, "returns %08x\n", r );
2086
2087 ref = IXMLDOMNode_AddRef( unk );
2088 ok(ref == 3, "ref = %d\n", ref);
2089 IXMLDOMNode_Release( unk );
2090
2091 V_VT(&var) = VT_EMPTY;
2092 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
2093 ok( r == S_OK, "returns %08x\n", r );
2094 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
2095 IXMLDOMNode_Release( child );
2096 IUnknown_Release( unk );
2097
2098
2099 V_VT(&var) = VT_NULL;
2100 V_DISPATCH(&var) = (IDispatch*)node;
2101 r = IXMLDOMNode_insertBefore( root, node, var, &child );
2102 ok( r == S_OK, "returns %08x\n", r );
2103 ok( node == child, "%p %p\n", node, child );
2104 IXMLDOMNode_Release( child );
2105
2106
2107 V_VT(&var) = VT_NULL;
2108 V_DISPATCH(&var) = (IDispatch*)node;
2109 r = IXMLDOMNode_insertBefore( root, node, var, NULL );
2110 ok( r == S_OK, "returns %08x\n", r );
2111 IXMLDOMNode_Release( node );
2112
2113 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (LPVOID*)&element );
2114 ok( r == S_OK, "returns %08x\n", r );
2115
2116 r = IXMLDOMElement_get_attributes( element, &attr_map );
2117 ok( r == S_OK, "returns %08x\n", r );
2118 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2119 ok( r == S_OK, "returns %08x\n", r );
2120 ok( num == 0, "num %d\n", num );
2121 IXMLDOMNamedNodeMap_Release( attr_map );
2122
2123 V_VT(&var) = VT_BSTR;
2124 V_BSTR(&var) = SysAllocString( szstr1 );
2125 name = SysAllocString( szdl );
2126 r = IXMLDOMElement_setAttribute( element, name, var );
2127 ok( r == S_OK, "returns %08x\n", r );
2128 r = IXMLDOMElement_get_attributes( element, &attr_map );
2129 ok( r == S_OK, "returns %08x\n", r );
2130 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2131 ok( r == S_OK, "returns %08x\n", r );
2132 ok( num == 1, "num %d\n", num );
2133 IXMLDOMNamedNodeMap_Release( attr_map );
2134 VariantClear(&var);
2135
2136 V_VT(&var) = VT_BSTR;
2137 V_BSTR(&var) = SysAllocString( szstr2 );
2138 r = IXMLDOMElement_setAttribute( element, name, var );
2139 ok( r == S_OK, "returns %08x\n", r );
2140 r = IXMLDOMElement_get_attributes( element, &attr_map );
2141 ok( r == S_OK, "returns %08x\n", r );
2142 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2143 ok( r == S_OK, "returns %08x\n", r );
2144 ok( num == 1, "num %d\n", num );
2145 IXMLDOMNamedNodeMap_Release( attr_map );
2146 VariantClear(&var);
2147 r = IXMLDOMElement_getAttribute( element, name, &var );
2148 ok( r == S_OK, "returns %08x\n", r );
2149 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
2150 VariantClear(&var);
2151 SysFreeString(name);
2152
2153 V_VT(&var) = VT_BSTR;
2154 V_BSTR(&var) = SysAllocString( szstr1 );
2155 name = SysAllocString( szlc );
2156 r = IXMLDOMElement_setAttribute( element, name, var );
2157 ok( r == S_OK, "returns %08x\n", r );
2158 r = IXMLDOMElement_get_attributes( element, &attr_map );
2159 ok( r == S_OK, "returns %08x\n", r );
2160 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2161 ok( r == S_OK, "returns %08x\n", r );
2162 ok( num == 2, "num %d\n", num );
2163 IXMLDOMNamedNodeMap_Release( attr_map );
2164 VariantClear(&var);
2165 SysFreeString(name);
2166
2167 V_VT(&var) = VT_I4;
2168 V_I4(&var) = 10;
2169 name = SysAllocString( szbs );
2170 r = IXMLDOMElement_setAttribute( element, name, var );
2171 ok( r == S_OK, "returns %08x\n", r );
2172 VariantClear(&var);
2173 r = IXMLDOMElement_getAttribute( element, name, &var );
2174 ok( r == S_OK, "returns %08x\n", r );
2175 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
2176 VariantClear(&var);
2177 SysFreeString(name);
2178
2179 /* Create an Attribute */
2180 V_VT(&var) = VT_I4;
2181 V_I4(&var) = NODE_ATTRIBUTE;
2182 str = SysAllocString( szAttribute );
2183 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2184 ok( r == S_OK, "returns %08x\n", r );
2185 ok( node != NULL, "node was null\n");
2186 SysFreeString(str);
2187
2188 if(r == S_OK)
2189 {
2190 r = IXMLDOMNode_get_nodeTypeString(node, &str);
2191 ok( r == S_OK, "returns %08x\n", r );
2192 ok( !lstrcmpW( str, _bstr_("attribute") ), "incorrect nodeTypeString string\n");
2193 SysFreeString(str);
2194 IXMLDOMNode_Release( node );
2195 }
2196
2197 IXMLDOMElement_Release( element );
2198 IXMLDOMNode_Release( root );
2199 IXMLDOMDocument_Release( doc );
2200 }
2201
2202 static void test_getElementsByTagName(void)
2203 {
2204 HRESULT r;
2205 BSTR str;
2206 VARIANT_BOOL b;
2207 IXMLDOMDocument *doc;
2208 IXMLDOMNodeList *node_list;
2209 LONG len;
2210
2211 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2212 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2213 if( r != S_OK )
2214 return;
2215
2216 str = SysAllocString( szComplete4 );
2217 r = IXMLDOMDocument_loadXML( doc, str, &b );
2218 ok( r == S_OK, "loadXML failed\n");
2219 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2220 SysFreeString( str );
2221
2222 str = SysAllocString( szstar );
2223 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2224 ok( r == S_OK, "ret %08x\n", r );
2225 r = IXMLDOMNodeList_get_length( node_list, &len );
2226 ok( r == S_OK, "ret %08x\n", r );
2227 ok( len == 6, "len %d\n", len );
2228
2229 test_disp((IUnknown*)node_list);
2230
2231 IXMLDOMNodeList_Release( node_list );
2232 SysFreeString( str );
2233
2234 str = SysAllocString( szbs );
2235 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2236 ok( r == S_OK, "ret %08x\n", r );
2237 r = IXMLDOMNodeList_get_length( node_list, &len );
2238 ok( r == S_OK, "ret %08x\n", r );
2239 ok( len == 1, "len %d\n", len );
2240 IXMLDOMNodeList_Release( node_list );
2241 SysFreeString( str );
2242
2243 str = SysAllocString( szdl );
2244 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2245 ok( r == S_OK, "ret %08x\n", r );
2246 r = IXMLDOMNodeList_get_length( node_list, &len );
2247 ok( r == S_OK, "ret %08x\n", r );
2248 ok( len == 0, "len %d\n", len );
2249 IXMLDOMNodeList_Release( node_list );
2250 SysFreeString( str );
2251
2252 str = SysAllocString( szstr1 );
2253 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2254 ok( r == S_OK, "ret %08x\n", r );
2255 r = IXMLDOMNodeList_get_length( node_list, &len );
2256 ok( r == S_OK, "ret %08x\n", r );
2257 ok( len == 0, "len %d\n", len );
2258 IXMLDOMNodeList_Release( node_list );
2259 SysFreeString( str );
2260
2261 IXMLDOMDocument_Release( doc );
2262 }
2263
2264 static void test_get_text(void)
2265 {
2266 HRESULT r;
2267 BSTR str;
2268 VARIANT_BOOL b;
2269 IXMLDOMDocument *doc;
2270 IXMLDOMNode *node, *node2, *node3;
2271 IXMLDOMNode *nodeRoot;
2272 IXMLDOMNodeList *node_list;
2273 IXMLDOMNamedNodeMap *node_map;
2274 LONG len;
2275
2276 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2277 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2278 if( r != S_OK )
2279 return;
2280
2281 str = SysAllocString( szComplete4 );
2282 r = IXMLDOMDocument_loadXML( doc, str, &b );
2283 ok( r == S_OK, "loadXML failed\n");
2284 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2285 SysFreeString( str );
2286
2287 str = SysAllocString( szbs );
2288 r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
2289 ok( r == S_OK, "ret %08x\n", r );
2290 SysFreeString(str);
2291
2292 /* Test to get all child node text. */
2293 r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (LPVOID*)&nodeRoot);
2294 ok( r == S_OK, "ret %08x\n", r );
2295 if(r == S_OK)
2296 {
2297 r = IXMLDOMNode_get_text( nodeRoot, &str );
2298 ok( r == S_OK, "ret %08x\n", r );
2299 ok( compareIgnoreReturnsWhitespace(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text\n");
2300 SysFreeString(str);
2301
2302 IXMLDOMNode_Release(nodeRoot);
2303 }
2304
2305 if (0) {
2306 /* this test crashes on win9x */
2307 r = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL);
2308 ok( r == E_INVALIDARG, "ret %08x\n", r );
2309 }
2310
2311 r = IXMLDOMNodeList_get_length( node_list, NULL );
2312 ok( r == E_INVALIDARG, "ret %08x\n", r );
2313
2314 r = IXMLDOMNodeList_get_length( node_list, &len );
2315 ok( r == S_OK, "ret %08x\n", r );
2316 ok( len == 1, "expect 1 got %d\n", len );
2317
2318 r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
2319 ok( r == E_INVALIDARG, "ret %08x\n", r );
2320
2321 r = IXMLDOMNodeList_nextNode( node_list, NULL );
2322 ok( r == E_INVALIDARG, "ret %08x\n", r );
2323
2324 r = IXMLDOMNodeList_get_item( node_list, 0, &node );
2325 ok( r == S_OK, "ret %08x\n", r );
2326 IXMLDOMNodeList_Release( node_list );
2327
2328 /* Invalid output parameter*/
2329 r = IXMLDOMNode_get_text( node, NULL );
2330 ok( r == E_INVALIDARG, "ret %08x\n", r );
2331
2332 r = IXMLDOMNode_get_text( node, &str );
2333 ok( r == S_OK, "ret %08x\n", r );
2334 ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
2335 SysFreeString(str);
2336
2337 r = IXMLDOMNode_get_attributes( node, &node_map );
2338 ok( r == S_OK, "ret %08x\n", r );
2339
2340 str = SysAllocString( szvr );
2341 r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
2342 ok( r == S_OK, "ret %08x\n", r );
2343 SysFreeString(str);
2344
2345 r = IXMLDOMNode_get_text( node2, &str );
2346 ok( r == S_OK, "ret %08x\n", r );
2347 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2348 SysFreeString(str);
2349
2350 r = IXMLDOMNode_get_firstChild( node2, &node3 );
2351 ok( r == S_OK, "ret %08x\n", r );
2352
2353 r = IXMLDOMNode_get_text( node3, &str );
2354 ok( r == S_OK, "ret %08x\n", r );
2355 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2356 SysFreeString(str);
2357
2358
2359 IXMLDOMNode_Release( node3 );
2360 IXMLDOMNode_Release( node2 );
2361 IXMLDOMNamedNodeMap_Release( node_map );
2362 IXMLDOMNode_Release( node );
2363 IXMLDOMDocument_Release( doc );
2364 }
2365
2366 static void test_get_childNodes(void)
2367 {
2368 HRESULT r;
2369 BSTR str;
2370 VARIANT_BOOL b;
2371 IXMLDOMDocument *doc;
2372 IXMLDOMElement *element;
2373 IXMLDOMNode *node, *node2;
2374 IXMLDOMNodeList *node_list, *node_list2;
2375 LONG len;
2376
2377 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2378 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2379 if( r != S_OK )
2380 return;
2381
2382 str = SysAllocString( szComplete4 );
2383 r = IXMLDOMDocument_loadXML( doc, str, &b );
2384 ok( r == S_OK, "loadXML failed\n");
2385 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2386 SysFreeString( str );
2387
2388 r = IXMLDOMDocument_get_documentElement( doc, &element );
2389 ok( r == S_OK, "ret %08x\n", r);
2390
2391 r = IXMLDOMElement_get_childNodes( element, &node_list );
2392 ok( r == S_OK, "ret %08x\n", r);
2393
2394 r = IXMLDOMNodeList_get_length( node_list, &len );
2395 ok( r == S_OK, "ret %08x\n", r);
2396 ok( len == 4, "len %d\n", len);
2397
2398 r = IXMLDOMNodeList_get_item( node_list, 2, &node );
2399 ok( r == S_OK, "ret %08x\n", r);
2400
2401 r = IXMLDOMNode_get_childNodes( node, &node_list2 );
2402 ok( r == S_OK, "ret %08x\n", r);
2403
2404 r = IXMLDOMNodeList_get_length( node_list2, &len );
2405 ok( r == S_OK, "ret %08x\n", r);
2406 ok( len == 0, "len %d\n", len);
2407
2408 r = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
2409 ok( r == S_FALSE, "ret %08x\n", r);
2410
2411 IXMLDOMNodeList_Release( node_list2 );
2412 IXMLDOMNode_Release( node );
2413 IXMLDOMNodeList_Release( node_list );
2414 IXMLDOMElement_Release( element );
2415 IXMLDOMDocument_Release( doc );
2416 }
2417
2418 static void test_removeChild(void)
2419 {
2420 HRESULT r;
2421 BSTR str;
2422 VARIANT_BOOL b;
2423 IXMLDOMDocument *doc;
2424 IXMLDOMElement *element, *lc_element;
2425 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
2426 IXMLDOMNodeList *root_list, *fo_list;
2427
2428 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2429 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2430 if( r != S_OK )
2431 return;
2432
2433 str = SysAllocString( szComplete4 );
2434 r = IXMLDOMDocument_loadXML( doc, str, &b );
2435 ok( r == S_OK, "loadXML failed\n");
2436 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2437 SysFreeString( str );
2438
2439 r = IXMLDOMDocument_get_documentElement( doc, &element );
2440 ok( r == S_OK, "ret %08x\n", r);
2441
2442 r = IXMLDOMElement_get_childNodes( element, &root_list );
2443 ok( r == S_OK, "ret %08x\n", r);
2444
2445 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
2446 ok( r == S_OK, "ret %08x\n", r);
2447
2448 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2449 ok( r == S_OK, "ret %08x\n", r);
2450
2451 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
2452 ok( r == S_OK, "ret %08x\n", r);
2453
2454 /* invalid parameter: NULL ptr */
2455 removed_node = (void*)0xdeadbeef;
2456 r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
2457 ok( r == E_INVALIDARG, "ret %08x\n", r );
2458 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2459
2460 /* ba_node is a descendant of element, but not a direct child. */
2461 removed_node = (void*)0xdeadbeef;
2462 r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
2463 ok( r == E_INVALIDARG, "ret %08x\n", r );
2464 ok( removed_node == NULL, "%p\n", removed_node );
2465
2466 r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
2467 ok( r == S_OK, "ret %08x\n", r);
2468 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
2469
2470 /* try removing already removed child */
2471 temp_node = (void*)0xdeadbeef;
2472 r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
2473 ok( r == E_INVALIDARG, "ret %08x\n", r);
2474 ok( temp_node == NULL, "%p\n", temp_node );
2475
2476 /* the removed node has no parent anymore */
2477 r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
2478 ok( r == S_FALSE, "ret %08x\n", r);
2479 ok( temp_node == NULL, "%p\n", temp_node );
2480
2481 IXMLDOMNode_Release( removed_node );
2482 IXMLDOMNode_Release( ba_node );
2483 IXMLDOMNodeList_Release( fo_list );
2484
2485 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2486 ok( r == S_OK, "ret %08x\n", r);
2487
2488 r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (LPVOID*)&lc_element );
2489 ok( r == S_OK, "ret %08x\n", r);
2490
2491 /* MS quirk: passing wrong interface pointer works, too */
2492 r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
2493 ok( r == S_OK, "ret %08x\n", r);
2494
2495 r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
2496 ok( r == S_FALSE, "ret %08x\n", r);
2497 ok( temp_node == NULL, "%p\n", temp_node );
2498
2499 IXMLDOMNode_Release( lc_node );
2500 IXMLDOMNodeList_Release( root_list );
2501 IXMLDOMElement_Release( element );
2502 IXMLDOMDocument_Release( doc );
2503 }
2504
2505 static void test_replaceChild(void)
2506 {
2507 HRESULT r;
2508 BSTR str;
2509 VARIANT_BOOL b;
2510 IXMLDOMDocument *doc;
2511 IXMLDOMElement *element, *ba_element;
2512 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
2513 IXMLDOMNodeList *root_list, *fo_list;
2514 IUnknown * unk1, *unk2;
2515 LONG len;
2516
2517 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
2518 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
2519 if( r != S_OK )
2520 return;
2521
2522 str = SysAllocString( szComplete4 );
2523 r = IXMLDOMDocument_loadXML( doc, str, &b );
2524 ok( r == S_OK, "loadXML failed\n");
2525 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2526 SysFreeString( str );
2527
2528 r = IXMLDOMDocument_get_documentElement( doc, &element );
2529 ok( r == S_OK, "ret %08x\n", r);
2530
2531 r = IXMLDOMElement_get_childNodes( element, &root_list );
2532 ok( r == S_OK, "ret %08x\n", r);
2533
2534 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2535 ok( r == S_OK, "ret %08x\n", r);
2536
2537 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
2538 ok( r == S_OK, "ret %08x\n", r);
2539
2540 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2541 ok( r == S_OK, "ret %08x\n", r);
2542
2543 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
2544 ok( r == S_OK, "ret %08x\n", r);
2545
2546 IXMLDOMNodeList_Release( fo_list );
2547
2548 /* invalid parameter: NULL ptr for element to remove */
2549 removed_node = (void*)0xdeadbeef;
2550 r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
2551 ok( r == E_INVALIDARG, "ret %08x\n", r );
2552 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2553
2554 /* invalid parameter: NULL for replacement element. (Sic!) */
2555 removed_node = (void*)0xdeadbeef;
2556 r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
2557 ok( r == E_INVALIDARG, "ret %08x\n", r );
2558 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2559
2560 /* invalid parameter: OldNode is not a child */
2561 removed_node = (void*)0xdeadbeef;
2562 r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
2563 ok( r == E_INVALIDARG, "ret %08x\n", r );
2564 ok( removed_node == NULL, "%p\n", removed_node );
2565
2566 /* invalid parameter: would create loop */
2567 removed_node = (void*)0xdeadbeef;
2568 r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
2569 ok( r == E_FAIL, "ret %08x\n", r );
2570 ok( removed_node == NULL, "%p\n", removed_node );
2571
2572 r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
2573 ok( r == S_OK, "ret %08x\n