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