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