[THEMES]
[reactos.git] / rostests / winetests / msxml3 / xmldoc.c
1 /*
2 * IXMLDocument tests
3 *
4 * Copyright 2007 James Hawkins
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define WIN32_NO_STATUS
22 #define _INC_WINDOWS
23 #define COM_NO_WINDOWS_H
24
25 #define COBJMACROS
26
27 #include <wine/test.h>
28
29 //#include <stdio.h>
30 //#include "windows.h"
31 #include <winnls.h>
32 #include <ole2.h>
33 #include <msxml2.h>
34 #include <msxml2did.h>
35 #include <ocidl.h>
36
37 #define EXPECT_HR(hr,hr_exp) \
38 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
39
40 /* Deprecated Error Code */
41 #define XML_E_INVALIDATROOTLEVEL 0xc00ce556
42
43 static void create_xml_file(LPCSTR filename)
44 {
45 DWORD dwNumberOfBytesWritten;
46 HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
47 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
48
49 static const char data[] =
50 "<?xml version=\"1.0\" ?>\n"
51 "<!DOCTYPE BankAccount>\n"
52 "<BankAccount>\n"
53 " <Number>1234</Number>\n"
54 " <Name>Captain Ahab</Name>\n"
55 "</BankAccount>";
56
57 WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
58 CloseHandle(hf);
59 }
60
61 static void create_stream_on_file(IStream **stream, LPCSTR path)
62 {
63 HANDLE hfile;
64 HGLOBAL hglobal;
65 LPVOID ptr;
66 HRESULT hr;
67 DWORD file_size, read;
68
69 hfile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL,
70 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
71 ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
72 file_size = GetFileSize(hfile, NULL);
73
74 hglobal = GlobalAlloc(GHND, file_size);
75 ptr = GlobalLock(hglobal);
76
77 ReadFile(hfile, ptr, file_size, &read, NULL);
78 ok(file_size == read, "Expected to read the whole file, read %d\n", read);
79
80 hr = CreateStreamOnHGlobal(hglobal, TRUE, stream);
81 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
82 ok(*stream != NULL, "Expected non-NULL stream\n");
83
84 CloseHandle(hfile);
85 GlobalUnlock(hglobal);
86 }
87
88 static void test_xmldoc(void)
89 {
90 IXMLElement *element = NULL, *child = NULL, *value = NULL;
91 IXMLElementCollection *collection = NULL, *inner = NULL;
92 IPersistStreamInit *psi = NULL;
93 IXMLDocument *doc = NULL;
94 IStream *stream = NULL;
95 VARIANT vIndex, vName;
96 LONG type, num_child;
97 CHAR path[MAX_PATH];
98 IDispatch *disp;
99 ITypeInfo *ti;
100 HRESULT hr;
101 BSTR name;
102
103 static const WCHAR szBankAccount[] = {'B','A','N','K','A','C','C','O','U','N','T',0};
104 static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
105 static const WCHAR szNumVal[] = {'1','2','3','4',0};
106 static const WCHAR szName[] = {'N','A','M','E',0};
107 static const WCHAR szNameVal[] = {'C','a','p','t','a','i','n',' ','A','h','a','b',0};
108 static const WCHAR szVersion[] = {'1','.','0',0};
109 static const WCHAR rootW[] = {'r','o','o','t',0};
110
111 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
112 &IID_IXMLDocument, (void**)&doc);
113 EXPECT_HR(hr, S_OK);
114
115 /* IDispatch */
116 hr = IXMLDocument_QueryInterface(doc, &IID_IDispatch, (void**)&disp);
117 EXPECT_HR(hr, S_OK);
118
119 /* just to make sure we're on right type data */
120 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
121 EXPECT_HR(hr, S_OK);
122 name = NULL;
123 hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLDOCUMENT_ROOT, &name, NULL, NULL, NULL);
124 EXPECT_HR(hr, S_OK);
125 ok(!lstrcmpW(name, rootW), "got name %s\n", wine_dbgstr_w(name));
126 SysFreeString(name);
127
128 ITypeInfo_Release(ti);
129 IDispatch_Release(disp);
130
131 hr = IXMLDocument_QueryInterface(doc, &IID_IXMLDOMDocument, (void**)&disp);
132 EXPECT_HR(hr, E_NOINTERFACE);
133
134 create_xml_file("bank.xml");
135 GetFullPathNameA("bank.xml", MAX_PATH, path, NULL);
136 create_stream_on_file(&stream, path);
137
138 hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&psi);
139 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
140 ok(psi != NULL, "Expected non-NULL psi\n");
141
142 hr = IXMLDocument_get_root(doc, &element);
143 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
144 ok(element == NULL, "Expected NULL element\n");
145
146 hr = IPersistStreamInit_Load(psi, stream);
147 ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr);
148 if(hr == XML_E_INVALIDATROOTLEVEL)
149 goto cleanup;
150
151 ok(stream != NULL, "Expected non-NULL stream\n");
152
153 /* version field */
154 hr = IXMLDocument_get_version(doc, NULL);
155 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
156
157 name = NULL;
158 hr = IXMLDocument_get_version(doc, &name);
159 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
160 ok(!lstrcmpW(name, szVersion), "Expected 1.0, got %s\n", wine_dbgstr_w(name));
161 SysFreeString(name);
162
163 /* doctype */
164 hr = IXMLDocument_get_doctype(doc, NULL);
165 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
166
167 hr = IXMLDocument_get_doctype(doc, &name);
168 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
169 ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT, got %s\n", wine_dbgstr_w(name));
170 SysFreeString(name);
171
172 hr = IXMLDocument_get_root(doc, &element);
173 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
174 ok(element != NULL, "Expected non-NULL element\n");
175
176 /* ::root() returns new instance each time */
177 hr = IXMLDocument_get_root(doc, &child);
178 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
179 ok(child != NULL, "Expected non-NULL element\n");
180 ok(child != element, "Expected new element instance\n");
181 IXMLElement_Release(child);
182
183 hr = IXMLElement_get_type(element, &type);
184 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
185 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
186
187 hr = IXMLElement_get_tagName(element, &name);
188 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
189 ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT\n");
190 SysFreeString(name);
191
192 hr = IXMLElement_get_children(element, &collection);
193 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
194 ok(collection != NULL, "Expected non-NULL collection\n");
195
196 hr = IXMLElementCollection_get_length(collection, &num_child);
197 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
198 ok(num_child == 2, "Expected 2, got %d\n", num_child);
199
200 V_VT(&vIndex) = VT_I4;
201 V_I4(&vIndex) = 0;
202 V_VT(&vName) = VT_ERROR;
203 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
204 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
205 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
206 ok(child != NULL, "Expected non-NULL child\n");
207
208 hr = IXMLElement_get_type(child, &type);
209 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
210 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
211
212 hr = IXMLElement_get_tagName(child, &name);
213 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
214 ok(!lstrcmpW(name, szNumber), "Expected NUMBER\n");
215 SysFreeString(name);
216
217 hr = IXMLElement_get_children(child, &inner);
218 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
219 ok(inner != NULL, "Expected non-NULL inner\n");
220
221 hr = IXMLElementCollection_get_length(inner, &num_child);
222 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
223 ok(num_child == 1, "Expected 1, got %d\n", num_child);
224
225 hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value);
226 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
227 ok(value != NULL, "Expected non-NULL value\n");
228
229 hr = IXMLElement_get_type(value, &type);
230 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
231 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
232
233 hr = IXMLElement_get_text(value, &name);
234 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
235 ok(!lstrcmpW(name, szNumVal), "Expected '1234'\n");
236 SysFreeString(name);
237
238 IXMLElementCollection_Release(inner);
239
240 inner = (IXMLElementCollection *)0xdeadbeef;
241 hr = IXMLElement_get_children(value, &inner);
242 ok(hr == 1, "Expected 1, got %08x\n", hr);
243 ok(inner == NULL, "Expected NULL inner, got %p\n", inner);
244
245 IXMLElement_Release(value);
246 IXMLElement_Release(child);
247 value = NULL;
248 child = NULL;
249
250 V_I4(&vIndex) = 1;
251 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
252 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
253 ok(child != NULL, "Expected non-NULL child\n");
254
255 hr = IXMLElement_get_type(child, &type);
256 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
257 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
258
259 hr = IXMLElement_get_tagName(child, &name);
260 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
261 ok(!lstrcmpW(name, szName), "Expected NAME\n");
262 SysFreeString(name);
263
264 hr = IXMLElement_get_children(child, &inner);
265 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
266 ok(inner != NULL, "Expected non-NULL inner\n");
267
268 hr = IXMLElementCollection_get_length(inner, &num_child);
269 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
270 ok(num_child == 1, "Expected 1, got %d\n", num_child);
271
272 V_I4(&vIndex) = 0;
273 hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value);
274 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
275 ok(value != NULL, "Expected non-NULL value\n");
276
277 hr = IXMLElement_get_type(value, &type);
278 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
279 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
280
281 hr = IXMLElement_get_text(value, &name);
282 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
283 ok(!lstrcmpW(name, szNameVal), "Expected 'Captain Ahab'\n");
284 SysFreeString(name);
285
286 IXMLElementCollection_Release(inner);
287
288 inner = (IXMLElementCollection *)0xdeadbeef;
289 hr = IXMLElement_get_children(value, &inner);
290 ok(hr == 1, "Expected 1, got %08x\n", hr);
291 ok(inner == NULL, "Expected NULL inner, got %p\n", inner);
292
293 IXMLElement_Release(value);
294 IXMLElement_Release(child);
295 IXMLElementCollection_Release(collection);
296 IXMLElement_Release(element);
297 cleanup:
298 IStream_Release(stream);
299 IPersistStreamInit_Release(psi);
300 IXMLDocument_Release(doc);
301
302 DeleteFileA("bank.xml");
303 }
304
305 static void test_createElement(void)
306 {
307 HRESULT hr;
308 IXMLDocument *doc = NULL;
309 IXMLElement *element = NULL, *root = NULL;
310 VARIANT vType, vName;
311 LONG type;
312
313 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
314 &IID_IXMLDocument, (LPVOID*)&doc);
315 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
316
317 /* invalid vType type */
318 V_VT(&vType) = VT_NULL;
319 V_VT(&vName) = VT_NULL;
320 element = (IXMLElement *)0xdeadbeef;
321 hr = IXMLDocument_createElement(doc, vType, vName, &element);
322 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
323 ok(element == NULL, "Expected NULL element\n");
324
325 /* invalid vType value */
326 V_VT(&vType) = VT_I4;
327 V_I4(&vType) = -1;
328 V_VT(&vName) = VT_NULL;
329 hr = IXMLDocument_createElement(doc, vType, vName, &element);
330 /* Up to and including SP7, createElement returns an element. */
331 if(hr == S_OK)
332 {
333 ok(element != NULL, "Expected element\n");
334 if (element != NULL)
335 {
336 hr = IXMLElement_get_type(element, &type);
337 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
338 /* SP7 returns an XMLELEMTYPE_ELEMENT */
339 ok(type == XMLELEMTYPE_OTHER || type == XMLELEMTYPE_ELEMENT,
340 "Expected XMLELEMTYPE_OTHER || XMLELEMTYPE_ELEMENT, got %d\n", type);
341
342 IXMLElement_Release(element);
343 }
344 }
345 else
346 {
347 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
348 ok(element == NULL, "Expected NULL element\n");
349 }
350
351 /* invalid vName type */
352 V_VT(&vType) = VT_I4;
353 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
354 V_VT(&vName) = VT_I4;
355 hr = IXMLDocument_createElement(doc, vType, vName, &element);
356 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
357 ok(element != NULL, "Expected non-NULL element\n");
358
359 hr = IXMLElement_get_type(element, &type);
360 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
361 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
362
363 IXMLElement_Release(element);
364
365 /* NULL element */
366 V_VT(&vType) = VT_I4;
367 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
368 V_VT(&vName) = VT_I4;
369 hr = IXMLDocument_createElement(doc, vType, vName, NULL);
370 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
371
372 root = (IXMLElement *)0xdeadbeef;
373 hr = IXMLDocument_get_root(doc, &root);
374 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
375 ok(root == NULL, "Expected NULL root\n");
376
377 V_VT(&vType) = VT_I4;
378 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
379 V_VT(&vName) = VT_NULL;
380 hr = IXMLDocument_createElement(doc, vType, vName, &element);
381 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
382 ok(element != NULL, "Expected non-NULL element\n");
383
384 /* createElement does not set the new element as root */
385 root = (IXMLElement *)0xdeadbeef;
386 hr = IXMLDocument_get_root(doc, &root);
387 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
388 ok(root == NULL, "Expected NULL root\n");
389
390 IXMLElement_Release(element);
391 IXMLDocument_Release(doc);
392 }
393
394 static void test_persiststreaminit(void)
395 {
396 IXMLDocument *doc = NULL;
397 IXMLElement *element = NULL;
398 IPersistStreamInit *psi = NULL;
399 IStream *stream = NULL;
400 STATSTG stat;
401 HRESULT hr;
402 ULARGE_INTEGER size;
403 CHAR path[MAX_PATH];
404 CLSID id;
405 BSTR str;
406 static const WCHAR testW[] = {'t','e','s','t',0};
407
408 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
409 &IID_IXMLDocument, (LPVOID*)&doc);
410 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
411
412 hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (LPVOID *)&psi);
413 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
414 ok(psi != NULL, "Expected non-NULL psi\n");
415
416 /* null arguments */
417 hr = IPersistStreamInit_GetSizeMax(psi, NULL);
418 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
419
420 hr = IPersistStreamInit_Load(psi, NULL);
421 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
422
423 hr = IPersistStreamInit_Save(psi, NULL, FALSE);
424 todo_wine ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
425
426 hr = IPersistStreamInit_GetClassID(psi, NULL);
427 ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr);
428
429 hr = IPersistStreamInit_IsDirty(psi);
430 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
431
432 create_xml_file("bank.xml");
433 GetFullPathNameA("bank.xml", MAX_PATH, path, NULL);
434 create_stream_on_file(&stream, path);
435
436 /* GetSizeMax not implemented */
437 size.QuadPart = 0;
438 hr = IPersistStreamInit_GetSizeMax(psi, &size);
439 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
440 ok(size.QuadPart == 0, "Expected 0\n");
441
442 hr = IPersistStreamInit_Load(psi, stream);
443 IStream_Release(stream);
444 ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr);
445 if(hr == XML_E_INVALIDATROOTLEVEL)
446 goto cleanup;
447
448 hr = IPersistStreamInit_IsDirty(psi);
449 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
450
451 /* try to save document */
452 stream = NULL;
453 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
454 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
455 hr = IPersistStreamInit_Save(psi, stream, FALSE);
456 todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
457
458 stat.cbSize.QuadPart = 0;
459 hr = IStream_Stat(stream, &stat, 0);
460 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
461 todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n");
462 IStream_Release(stream);
463
464 str = SysAllocString(testW);
465 hr = IXMLDocument_get_root(doc, &element);
466 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
467 hr = IXMLElement_put_text(element, str);
468 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
469 IXMLElement_Release(element);
470 SysFreeString(str);
471
472 hr = IPersistStreamInit_IsDirty(psi);
473 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
474
475 create_stream_on_file(&stream, path);
476 hr = IPersistStreamInit_Load(psi, stream);
477 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
478 IStream_Release(stream);
479
480 hr = IPersistStreamInit_IsDirty(psi);
481 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
482
483 /* reset internal stream */
484 hr = IPersistStreamInit_InitNew(psi);
485 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
486
487 hr = IPersistStreamInit_IsDirty(psi);
488 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
489
490 stream = NULL;
491 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
492 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
493
494 hr = IPersistStreamInit_Save(psi, stream, FALSE);
495 todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
496
497 stat.cbSize.QuadPart = 0;
498 hr = IStream_Stat(stream, &stat, 0);
499 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
500 todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n");
501 IStream_Release(stream);
502
503 memset(&id, 0, sizeof(id));
504 hr = IPersistStreamInit_GetClassID(psi, &id);
505 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
506 ok(IsEqualCLSID(&id, &CLSID_XMLDocument), "Expected CLSID_XMLDocument\n");
507
508 cleanup:
509 IPersistStreamInit_Release(psi);
510 IXMLDocument_Release(doc);
511 DeleteFileA("bank.xml");
512 }
513
514 static BOOL test_try_xmldoc(void)
515 {
516 IXMLDocument *doc = NULL;
517 HRESULT hr;
518
519 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
520 &IID_IXMLDocument, (LPVOID*)&doc);
521 if (FAILED(hr))
522 {
523 skip("Failed to create XMLDocument instance\n");
524 return FALSE;
525 }
526
527 IXMLDocument_Release(doc);
528 return TRUE;
529 }
530
531 static void test_xmlelem_children(void)
532 {
533 IXMLDocument *doc = NULL;
534 IXMLElement *element = NULL, *child = NULL, *child2 = NULL;
535 IXMLElementCollection *collection = NULL;
536 VARIANT vType, vName, vIndex;
537 LONG length;
538 HRESULT hr;
539
540 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
541 &IID_IXMLDocument, (LPVOID*)&doc);
542 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
543
544 V_VT(&vType) = VT_I4;
545 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
546 V_VT(&vName) = VT_NULL;
547 hr = IXMLDocument_createElement(doc, vType, vName, &element);
548 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
549 ok(element != NULL, "Expected non-NULL element\n");
550
551 V_VT(&vType) = VT_I4;
552 V_I4(&vType) = XMLELEMTYPE_TEXT;
553 V_VT(&vName) = VT_NULL;
554 hr = IXMLDocument_createElement(doc, vType, vName, &child);
555 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
556 ok(child != NULL, "Expected non-NULL child\n");
557
558 V_VT(&vType) = VT_I4;
559 V_I4(&vType) = XMLELEMTYPE_TEXT;
560 V_VT(&vName) = VT_NULL;
561 hr = IXMLDocument_createElement(doc, vType, vName, &child2);
562 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
563 ok(child2 != NULL, "Expected non-NULL child\n");
564
565 hr = IXMLElement_addChild(element, child, 0, -1);
566 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
567
568 hr = IXMLElement_get_children(element, &collection);
569 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
570 ok(collection != NULL, "Expected non-NULL collection\n");
571
572 length = 0;
573 hr = IXMLElementCollection_get_length(collection, &length);
574 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
575 ok(length == 1, "Expected 1, got %08x\n", length);
576
577 /* remove/add child and check what happens with collection */
578 hr = IXMLElement_removeChild(element, child);
579 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
580
581 length = -1;
582 hr = IXMLElementCollection_get_length(collection, &length);
583 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
584 ok(length == 0, "Expected 0, got %08x\n", length);
585 IXMLElementCollection_Release(collection);
586
587 hr = IXMLElement_AddRef(child);
588 ok(hr == 2, "Expected 2, got %08x\n", hr);
589 IXMLElement_Release(child);
590 hr = IXMLElement_addChild(element, child, 0, -1);
591 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
592 hr = IXMLElement_AddRef(child);
593 ok(hr == 2, "Expected 2, got %08x\n", hr);
594 IXMLElement_Release(child);
595 hr = IXMLElement_addChild(element, child2, 0, -1);
596 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
597
598 hr = IXMLElement_get_children(element, &collection);
599 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
600 ok(collection != NULL, "Expected non-NULL collection\n");
601
602 hr = IXMLElement_AddRef(child);
603 ok(hr == 2, "Expected 2, got %08x\n", hr);
604 IXMLElement_Release(child);
605
606 length = 0;
607 hr = IXMLElementCollection_get_length(collection, &length);
608 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
609 ok(length == 2, "Expected 2, got %08x\n", length);
610
611 IXMLElement_Release(child2);
612
613 length = 0;
614 hr = IXMLElementCollection_get_length(collection, &length);
615 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
616 ok(length == 2, "Expected 2, got %08x\n", length);
617
618 V_VT(&vIndex) = VT_I4;
619 V_I4(&vIndex) = 1;
620 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child2);
621 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
622 ok(child2 != NULL, "Expected not NULL child\n");
623 IXMLElementCollection_Release(collection);
624 IXMLElement_Release(child2);
625
626 /* add element->child->child2 structure, then remove child2 from node */
627 V_VT(&vType) = VT_I4;
628 V_I4(&vType) = XMLELEMTYPE_TEXT;
629 V_VT(&vName) = VT_NULL;
630 hr = IXMLDocument_createElement(doc, vType, vName, &child2);
631 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
632 ok(child2 != NULL, "Expected non-NULL child\n");
633
634 hr = IXMLElement_addChild(child, child2, 0, -1);
635 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
636
637 hr = IXMLElement_removeChild(element, child2);
638 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
639
640 hr = IXMLElement_removeChild(child, child2);
641 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
642
643 hr = IXMLElement_removeChild(child, NULL);
644 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
645
646 IXMLElement_Release(element);
647 IXMLElement_Release(child);
648 IXMLElement_Release(child2);
649 IXMLDocument_Release(doc);
650 }
651
652 static void test_xmlelem_collection(void)
653 {
654 HRESULT hr;
655 IUnknown *unk = NULL;
656 IXMLDocument *doc = NULL;
657 IXMLElement *element = NULL, *child;
658 IXMLElementCollection *collection = NULL;
659 IEnumVARIANT *enumVar = NULL;
660 CHAR pathA[MAX_PATH];
661 WCHAR path[MAX_PATH];
662 LONG length, type;
663 ULONG num_vars;
664 VARIANT var, vIndex, vName;
665 BSTR url, str;
666 static const CHAR szBankXML[] = "bank.xml";
667 static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
668 static const WCHAR szName[] = {'N','A','M','E',0};
669
670 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
671 &IID_IXMLDocument, (LPVOID*)&doc);
672 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
673
674 create_xml_file(szBankXML);
675 GetFullPathNameA(szBankXML, MAX_PATH, pathA, NULL);
676 MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
677
678 url = SysAllocString(path);
679 hr = IXMLDocument_put_URL(doc, url);
680 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
681 SysFreeString(url);
682
683 if(hr != S_OK)
684 goto cleanup;
685
686 hr = IXMLDocument_get_root(doc, &element);
687 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
688 ok(element != NULL, "Expected non-NULL element\n");
689
690 hr = IXMLElement_get_children(element, &collection);
691 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
692 ok(collection != NULL, "Expected non-NULL collection\n");
693
694 hr = IXMLElementCollection_get_length(collection, NULL);
695 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
696
697 hr = IXMLElementCollection_get_length(collection, &length);
698 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
699 ok(length == 2, "Expected 2, got %d\n", length);
700
701 /* IXMLElementCollection:put_length does nothing */
702 hr = IXMLElementCollection_put_length(collection, -1);
703 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
704
705 hr = IXMLElementCollection_put_length(collection, 0);
706 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
707
708 hr = IXMLElementCollection_put_length(collection, 1);
709 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
710
711 hr = IXMLElementCollection_put_length(collection, 2);
712 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
713
714 hr = IXMLElementCollection_put_length(collection, 3);
715 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
716
717 hr = IXMLElementCollection_put_length(collection, 50);
718 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
719
720 /* make sure the length hasn't changed */
721 hr = IXMLElementCollection_get_length(collection, &length);
722 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
723 ok(length == 2, "Expected 2, got %d\n", length);
724
725 /* IXMLElementCollection implements IEnumVARIANT */
726 hr = IXMLElementCollection_QueryInterface(collection, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
727 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
728 ok(enumVar != NULL, "Expected non-NULL enumVar\n");
729 IEnumVARIANT_Release(enumVar);
730
731 hr = IXMLElementCollection_get__newEnum(collection, &unk);
732 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
733 ok(unk != NULL, "Expected non-NULL unk\n");
734
735 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
736 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
737 ok(enumVar != NULL, "Expected non-NULL enumVar\n");
738 IUnknown_Release(unk);
739
740 /* <Number>1234</Number> */
741 hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
742 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
743 ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
744 ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
745
746 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
747 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
748 ok(child != NULL, "Expected non-NULL child\n");
749
750 VariantClear(&var);
751
752 hr = IXMLElement_get_type(child, &type);
753 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
754 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
755
756 hr = IXMLElement_get_tagName(child, &str);
757 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
758 ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
759 SysFreeString(str);
760 IXMLElement_Release(child);
761
762 /* <Name>Captain Ahab</Name> */
763 hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
764 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
765 ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
766 ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
767
768 /* try advance further, no children left */
769 hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
770 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
771 ok(V_VT(&var) == 0, "Expected 0, got %d\n", V_VT(&var));
772 ok(num_vars == 0, "Expected 0, got %d\n", num_vars);
773
774 hr = IEnumVARIANT_Next(enumVar, 1, &var, NULL);
775 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
776 ok(V_VT(&var) == 0, "Expected 0, got %d\n", V_VT(&var));
777
778 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
779 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
780 ok(child != NULL, "Expected non-NULL child\n");
781
782 VariantClear(&var);
783
784 hr = IXMLElement_get_type(child, &type);
785 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
786 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
787
788 hr = IXMLElement_get_tagName(child, &str);
789 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
790 ok(!lstrcmpW(str, szName), "Expected NAME\n");
791 SysFreeString(str);
792 IXMLElement_Release(child);
793
794 /* <Number>1234</Number> */
795 V_VT(&vIndex) = VT_I4;
796 V_I4(&vIndex) = 0;
797 V_VT(&vName) = VT_ERROR;
798 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
799 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
800 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
801 ok(child != NULL, "Expected non-NULL child\n");
802
803 hr = IXMLElement_get_type(child, &type);
804 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
805 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
806
807 hr = IXMLElement_get_tagName(child, &str);
808 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
809 ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
810 SysFreeString(str);
811 IXMLElement_Release(child);
812
813 /* <Name>Captain Ahab</Name> */
814 V_VT(&vIndex) = VT_I4;
815 V_I4(&vIndex) = 1;
816 V_VT(&vName) = VT_ERROR;
817 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
818 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
819 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
820 ok(child != NULL, "Expected non-NULL child\n");
821
822 hr = IXMLElement_get_type(child, &type);
823 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
824 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
825
826 hr = IXMLElement_get_tagName(child, &str);
827 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
828 ok(!lstrcmpW(str, szName), "Expected NAME\n");
829 SysFreeString(str);
830 IXMLElement_Release(child);
831
832 V_I4(&vIndex) = 100;
833 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
834 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
835 ok(child == NULL, "Expected NULL child\n");
836
837 V_I4(&vIndex) = -1;
838 child = (IXMLElement *)0xdeadbeef;
839 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
840 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
841 ok(child == NULL, "Expected NULL child\n");
842
843 IEnumVARIANT_Release(enumVar);
844 IXMLElement_Release(element);
845 IXMLElementCollection_Release(collection);
846 cleanup:
847 IXMLDocument_Release(doc);
848 DeleteFileA("bank.xml");
849 }
850
851 static void test_xmlelem(void)
852 {
853 HRESULT hr;
854 IXMLDocument *doc = NULL;
855 IXMLElement *element = NULL, *parent;
856 IXMLElement *child, *child2;
857 IXMLElementCollection *children;
858 VARIANT vType, vName;
859 VARIANT vIndex, vValue;
860 BSTR str, val, name;
861 LONG type, num_child;
862 IDispatch *disp;
863 ITypeInfo *ti;
864
865 static const WCHAR propName[] = {'p','r','o','p',0};
866 static const WCHAR propVal[] = {'v','a','l',0};
867 static const WCHAR nextVal[] = {'n','e','x','t',0};
868 static const WCHAR noexist[] = {'n','o','e','x','i','s','t',0};
869 static const WCHAR crazyCase1[] = {'C','R','a','z','Y','c','A','S','E',0};
870 static const WCHAR crazyCase2[] = {'C','R','A','Z','Y','C','A','S','E',0};
871
872 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
873 &IID_IXMLDocument, (LPVOID*)&doc);
874 EXPECT_HR(hr, S_OK);
875
876 V_VT(&vType) = VT_I4;
877 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
878 V_VT(&vName) = VT_NULL;
879 hr = IXMLDocument_createElement(doc, vType, vName, &element);
880 EXPECT_HR(hr, S_OK);
881 ok(element != NULL, "Expected non-NULL element\n");
882
883 /* test for IDispatch */
884 disp = NULL;
885 hr = IXMLElement_QueryInterface(element, &IID_IDispatch, (void**)&disp);
886 EXPECT_HR(hr, S_OK);
887
888 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
889 EXPECT_HR(hr, S_OK);
890
891 name = NULL;
892 hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLELEMENT_TAGNAME, &name, NULL, NULL, NULL);
893 EXPECT_HR(hr, S_OK);
894 SysFreeString(name);
895
896 ITypeInfo_Release(ti);
897 IDispatch_Release(disp);
898
899 hr = IXMLElement_get_tagName(element, &str);
900 EXPECT_HR(hr, S_OK);
901 ok(lstrlenW(str) == 0, "Expected empty tag name\n");
902 SysFreeString(str);
903
904 parent = (IXMLElement *)0xdeadbeef;
905 hr = IXMLElement_get_parent(element, &parent);
906 ok(hr == 1, "Expected 1, got %08x\n", hr);
907 ok(parent == NULL, "Expected NULL parent\n");
908
909 str = SysAllocString(noexist);
910 hr = IXMLElement_getAttribute(element, str, &vValue);
911 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
912 ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
913 ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
914 VariantClear(&vValue);
915 SysFreeString(str);
916
917 str = SysAllocString(crazyCase1);
918 val = SysAllocString(propVal);
919 V_VT(&vValue) = VT_BSTR;
920 V_BSTR(&vValue) = val;
921 hr = IXMLElement_setAttribute(element, str, vValue);
922 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
923 SysFreeString(str);
924 SysFreeString(val);
925
926 str = SysAllocString(crazyCase2);
927 hr = IXMLElement_getAttribute(element, str, &vValue);
928 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
929 ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
930 ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
931 VariantClear(&vValue);
932 SysFreeString(str);
933
934 str = SysAllocString(propName);
935 val = SysAllocString(propVal);
936 V_VT(&vValue) = VT_BSTR;
937 V_BSTR(&vValue) = val;
938 hr = IXMLElement_setAttribute(element, str, vValue);
939 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
940 SysFreeString(val);
941
942 hr = IXMLElement_getAttribute(element, str, &vValue);
943 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
944 ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
945 ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
946 VariantClear(&vValue);
947
948 hr = IXMLElement_removeAttribute(element, str);
949 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
950
951 /* remove now nonexistent attribute */
952 hr = IXMLElement_removeAttribute(element, str);
953 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
954
955 hr = IXMLElement_getAttribute(element, str, &vValue);
956 ok(hr == 1, "Expected 1, got %08x\n", hr);
957 ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
958 ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
959 SysFreeString(str);
960 VariantClear(&vValue);
961
962 children = (IXMLElementCollection *)0xdeadbeef;
963 hr = IXMLElement_get_children(element, &children);
964 ok(hr == 1, "Expected 1, got %08x\n", hr);
965 ok(children == NULL, "Expected NULL collection\n");
966
967 hr = IXMLElement_get_type(element, &type);
968 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
969 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
970
971 hr = IXMLElement_get_text(element, &str);
972 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
973 ok(lstrlenW(str) == 0, "Expected empty text\n");
974 SysFreeString(str);
975
976 /* put_text with an ELEMENT */
977 str = SysAllocString(propVal);
978 hr = IXMLElement_put_text(element, str);
979 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
980 SysFreeString(str);
981
982 V_VT(&vType) = VT_I4;
983 V_I4(&vType) = XMLELEMTYPE_TEXT;
984 V_VT(&vName) = VT_NULL;
985 hr = IXMLDocument_createElement(doc, vType, vName, &child);
986 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
987 ok(child != NULL, "Expected non-NULL child\n");
988
989 hr = IXMLElement_addChild(element, child, 0, -1);
990 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
991
992 str = SysAllocString(propVal);
993 hr = IXMLElement_put_text(child, str);
994 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
995 SysFreeString(str);
996
997 parent = (IXMLElement *)0xdeadbeef;
998 hr = IXMLElement_get_parent(child, &parent);
999 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1000 ok(parent != element, "Expected parent != element\n");
1001
1002 hr = IXMLElement_get_type(parent, &type);
1003 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1004 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
1005
1006 children = (IXMLElementCollection *)0xdeadbeef;
1007 hr = IXMLElement_get_children(element, &children);
1008 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1009 ok(children != NULL, "Expected non-NULL collection\n");
1010
1011 hr = IXMLElementCollection_get_length(children, &num_child);
1012 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1013 ok(num_child == 1, "Expected 1, got %d\n", num_child);
1014
1015 V_VT(&vIndex) = VT_I4;
1016 V_I4(&vIndex) = 0;
1017 V_VT(&vName) = VT_ERROR;
1018 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
1019 hr = IXMLElementCollection_item(children, vIndex, vName, (IDispatch **)&child2);
1020 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1021 ok(child2 != NULL, "Expected non-NULL child\n");
1022
1023 hr = IXMLElement_get_type(child2, &type);
1024 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1025 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
1026
1027 hr = IXMLElement_get_text(element, &str);
1028 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1029 ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
1030 SysFreeString(str);
1031
1032 hr = IXMLElement_get_text(child2, &str);
1033 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1034 ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
1035 SysFreeString(str);
1036
1037 /* try put_text on ELEMENT again, now that it has a text child */
1038 str = SysAllocString(nextVal);
1039 hr = IXMLElement_put_text(element, str);
1040 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
1041 SysFreeString(str);
1042
1043 str = SysAllocString(nextVal);
1044 hr = IXMLElement_put_text(child2, str);
1045 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1046 SysFreeString(str);
1047
1048 hr = IXMLElement_get_text(element, &str);
1049 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1050 ok(!lstrcmpW(str, nextVal), "Expected 'val'\n");
1051 SysFreeString(str);
1052
1053 IXMLElement_Release(child2);
1054 IXMLElementCollection_Release(children);
1055 IXMLElement_Release(parent);
1056 IXMLElement_Release(child);
1057 IXMLElement_Release(element);
1058 IXMLDocument_Release(doc);
1059 }
1060
1061 START_TEST(xmldoc)
1062 {
1063 HRESULT hr;
1064
1065 hr = CoInitialize(NULL);
1066 ok(hr == S_OK, "failed to init com\n");
1067
1068 if (!test_try_xmldoc())
1069 {
1070 CoUninitialize();
1071 return;
1072 }
1073
1074 test_xmldoc();
1075 test_createElement();
1076 test_persiststreaminit();
1077 test_xmlelem();
1078 test_xmlelem_collection();
1079 test_xmlelem_children();
1080
1081 CoUninitialize();
1082 }