1 /* 2 * XML test 3 * 4 * Copyright 2005 Mike McCormack for CodeWeavers 5 * Copyright 2007-2008 Alistair Leslie-Hughes 6 * Copyright 2010-2011 Adam Martinson for CodeWeavers 7 * Copyright 2010-2013 Nikolay Sivov for CodeWeavers 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 */ 23 24 25 #define COBJMACROS 26 #define CONST_VTABLE 27 28 #include <stdio.h> 29 #include <assert.h> 30 31 #include "windows.h" 32 33 #include "msxml.h" 34 #include "msxml2.h" 35 #include "msxml2did.h" 36 #include "ole2.h" 37 #include "dispex.h" 38 #include "objsafe.h" 39 #include "mshtml.h" 40 #include "initguid.h" 41 #include "asptlb.h" 42 43 #include "wine/heap.h" 44 #include "wine/test.h" 45 46 /* undef the #define in msxml2 so that we can access all versions */ 47 #undef CLSID_DOMDocument 48 49 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 50 DEFINE_GUID(IID_transformdest_unknown,0xf5078f3a,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21); 51 52 static int g_unexpectedcall, g_expectedcall; 53 54 struct msxmlsupported_data_t 55 { 56 const GUID *clsid; 57 const char *name; 58 const IID *ifaces[3]; 59 BOOL supported[3]; 60 }; 61 62 static struct msxmlsupported_data_t domdoc_support_data[] = 63 { 64 { &CLSID_DOMDocument, "DOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} }, 65 { &CLSID_DOMDocument2, "DOMDocument2", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} }, 66 { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} }, 67 { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} }, 68 { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} }, 69 { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} }, 70 { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} }, 71 { &CLSID_XSLTemplate, "XSLTemplate", {&IID_IXSLTemplate} }, 72 { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} }, 73 { NULL } 74 }; 75 76 static const char *debugstr_msxml_guid(REFIID riid) 77 { 78 if(!riid) 79 return "(null)"; 80 81 if (IsEqualIID(&IID_IXMLDOMDocument, riid)) 82 return "IXMLDOMDocument"; 83 else if (IsEqualIID(&IID_IXMLDOMDocument2, riid)) 84 return "IXMLDOMDocument2"; 85 else if (IsEqualIID(&IID_IXMLDOMDocument3, riid)) 86 return "IXMLDOMDocument3"; 87 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid)) 88 return "IXMLDOMSchemaCollection"; 89 else if (IsEqualIID(&IID_IXSLTemplate, riid)) 90 return "IXSLTemplate"; 91 else if (IsEqualIID(&IID_IMXNamespaceManager, riid)) 92 return "IMXNamespaceManager"; 93 else 94 return wine_dbgstr_guid(riid); 95 } 96 97 static void get_class_support_data(struct msxmlsupported_data_t *table) 98 { 99 while (table->clsid) 100 { 101 IUnknown *unk; 102 HRESULT hr; 103 int i; 104 105 for (i = 0; i < ARRAY_SIZE(table->ifaces) && table->ifaces[i] != NULL; i++) 106 { 107 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk); 108 if (hr == S_OK) IUnknown_Release(unk); 109 110 table->supported[i] = hr == S_OK; 111 if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i])); 112 } 113 114 table++; 115 } 116 } 117 118 static BOOL is_clsid_supported(const GUID *clsid, REFIID riid) 119 { 120 const struct msxmlsupported_data_t *table = domdoc_support_data; 121 while (table->clsid) 122 { 123 if (table->clsid == clsid) 124 { 125 int i; 126 127 for (i = 0; i < ARRAY_SIZE(table->ifaces) && table->ifaces[i] != NULL; i++) 128 if (table->ifaces[i] == riid) return table->supported[i]; 129 } 130 131 table++; 132 } 133 return FALSE; 134 } 135 136 typedef struct 137 { 138 IDispatch IDispatch_iface; 139 LONG ref; 140 } dispevent; 141 142 static inline dispevent *impl_from_IDispatch( IDispatch *iface ) 143 { 144 return CONTAINING_RECORD(iface, dispevent, IDispatch_iface); 145 } 146 147 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject) 148 { 149 *ppvObject = NULL; 150 151 if ( IsEqualGUID( riid, &IID_IDispatch) || 152 IsEqualGUID( riid, &IID_IUnknown) ) 153 { 154 *ppvObject = iface; 155 } 156 else 157 return E_NOINTERFACE; 158 159 IDispatch_AddRef( iface ); 160 161 return S_OK; 162 } 163 164 static ULONG WINAPI dispevent_AddRef(IDispatch *iface) 165 { 166 dispevent *This = impl_from_IDispatch( iface ); 167 return InterlockedIncrement( &This->ref ); 168 } 169 170 static ULONG WINAPI dispevent_Release(IDispatch *iface) 171 { 172 dispevent *This = impl_from_IDispatch( iface ); 173 ULONG ref = InterlockedDecrement( &This->ref ); 174 175 if (ref == 0) 176 heap_free(This); 177 178 return ref; 179 } 180 181 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) 182 { 183 g_unexpectedcall++; 184 *pctinfo = 0; 185 return S_OK; 186 } 187 188 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo, 189 LCID lcid, ITypeInfo **ppTInfo) 190 { 191 g_unexpectedcall++; 192 return S_OK; 193 } 194 195 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid, 196 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 197 { 198 g_unexpectedcall++; 199 return S_OK; 200 } 201 202 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid, 203 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, 204 EXCEPINFO *excepInfo, UINT *argErr) 205 { 206 ok(member == 0, "expected 0 member, got %d\n", member); 207 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid); 208 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags); 209 210 ok(params->cArgs == 0, "got %d\n", params->cArgs); 211 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs); 212 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg); 213 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs); 214 215 ok(result == NULL, "got %p\n", result); 216 ok(excepInfo == NULL, "got %p\n", excepInfo); 217 ok(argErr == NULL, "got %p\n", argErr); 218 219 g_expectedcall++; 220 return E_FAIL; 221 } 222 223 static const IDispatchVtbl dispeventVtbl = 224 { 225 dispevent_QueryInterface, 226 dispevent_AddRef, 227 dispevent_Release, 228 dispevent_GetTypeInfoCount, 229 dispevent_GetTypeInfo, 230 dispevent_GetIDsOfNames, 231 dispevent_Invoke 232 }; 233 234 static IDispatch* create_dispevent(void) 235 { 236 dispevent *event = heap_alloc(sizeof(*event)); 237 238 event->IDispatch_iface.lpVtbl = &dispeventVtbl; 239 event->ref = 1; 240 241 return (IDispatch*)&event->IDispatch_iface; 242 } 243 244 /* IStream */ 245 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject) 246 { 247 *ppvObject = NULL; 248 249 if (IsEqualGUID(riid, &IID_IStream) || 250 IsEqualGUID(riid, &IID_IUnknown)) 251 *ppvObject = iface; 252 else 253 return E_NOINTERFACE; 254 255 return S_OK; 256 } 257 258 static ULONG WINAPI istream_AddRef(IStream *iface) 259 { 260 return 2; 261 } 262 263 static ULONG WINAPI istream_Release(IStream *iface) 264 { 265 return 1; 266 } 267 268 static HRESULT WINAPI istream_Read(IStream *iface, void *ptr, ULONG len, ULONG *pread) 269 { 270 ok(0, "unexpected call\n"); 271 return E_NOTIMPL; 272 } 273 274 static HRESULT WINAPI istream_Write(IStream *iface, const void *ptr, ULONG len, ULONG *written) 275 { 276 *written = len/2; 277 return S_OK; 278 } 279 280 static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *new_pos) 281 { 282 ok(0, "unexpected call\n"); 283 return E_NOTIMPL; 284 } 285 286 static HRESULT WINAPI istream_SetSize(IStream *iface, ULARGE_INTEGER size) 287 { 288 ok(0, "unexpected call\n"); 289 return E_NOTIMPL; 290 } 291 292 static HRESULT WINAPI istream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len, 293 ULARGE_INTEGER *pread, ULARGE_INTEGER *written) 294 { 295 ok(0, "unexpected call\n"); 296 return E_NOTIMPL; 297 } 298 299 static HRESULT WINAPI istream_Commit(IStream *iface, DWORD flags) 300 { 301 ok(0, "unexpected call\n"); 302 return E_NOTIMPL; 303 } 304 305 static HRESULT WINAPI istream_Revert(IStream *iface) 306 { 307 ok(0, "unexpected call\n"); 308 return E_NOTIMPL; 309 } 310 311 static HRESULT WINAPI istream_LockRegion(IStream *iface, ULARGE_INTEGER offset, 312 ULARGE_INTEGER len, DWORD locktype) 313 { 314 ok(0, "unexpected call\n"); 315 return E_NOTIMPL; 316 } 317 318 static HRESULT WINAPI istream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset, 319 ULARGE_INTEGER len, DWORD locktype) 320 { 321 ok(0, "unexpected call\n"); 322 return E_NOTIMPL; 323 } 324 325 static HRESULT WINAPI istream_Stat(IStream *iface, STATSTG *pstatstg, DWORD flag) 326 { 327 ok(0, "unexpected call\n"); 328 return E_NOTIMPL; 329 } 330 331 static HRESULT WINAPI istream_Clone(IStream *iface, IStream **stream) 332 { 333 ok(0, "unexpected call\n"); 334 return E_NOTIMPL; 335 } 336 337 static const IStreamVtbl StreamVtbl = { 338 istream_QueryInterface, 339 istream_AddRef, 340 istream_Release, 341 istream_Read, 342 istream_Write, 343 istream_Seek, 344 istream_SetSize, 345 istream_CopyTo, 346 istream_Commit, 347 istream_Revert, 348 istream_LockRegion, 349 istream_UnlockRegion, 350 istream_Stat, 351 istream_Clone 352 }; 353 354 static IStream savestream = { &StreamVtbl }; 355 356 static HRESULT WINAPI response_QI(IResponse *iface, REFIID riid, void **obj) 357 { 358 if (IsEqualIID(&IID_IResponse, riid) || 359 IsEqualIID(&IID_IDispatch, riid) || 360 IsEqualIID(&IID_IUnknown, riid)) 361 { 362 *obj = iface; 363 return S_OK; 364 } 365 366 if (!IsEqualIID(&IID_IStream, riid) && !IsEqualIID(&IID_ISequentialStream, riid)) 367 ok(0, "unexpected call\n"); 368 return E_NOINTERFACE; 369 } 370 371 static ULONG WINAPI response_AddRef(IResponse *iface) 372 { 373 return 2; 374 } 375 376 static ULONG WINAPI response_Release(IResponse *iface) 377 { 378 return 1; 379 } 380 381 static HRESULT WINAPI response_GetTypeInfoCount(IResponse *iface, UINT *count) 382 { 383 ok(0, "unexpected call\n"); 384 return E_NOTIMPL; 385 } 386 387 static HRESULT WINAPI response_GetTypeInfo(IResponse *iface, UINT ti, LCID lcid, ITypeInfo **tinfo) 388 { 389 ok(0, "unexpected call\n"); 390 return E_NOTIMPL; 391 } 392 393 static HRESULT WINAPI response_GetIDsOfNames(IResponse *iface, REFIID riid, LPOLESTR *names, 394 UINT cnames, LCID lcid, DISPID *rgDispId) 395 { 396 ok(0, "unexpected call\n"); 397 return E_NOTIMPL; 398 } 399 400 static HRESULT WINAPI response_Invoke(IResponse *iface, DISPID dispid, REFIID riid, LCID lcid, 401 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *ei, UINT *argerr) 402 { 403 ok(0, "unexpected call\n"); 404 return E_NOTIMPL; 405 } 406 407 static HRESULT WINAPI response_get_Buffer(IResponse *iface, VARIANT_BOOL *fIsBuffering) 408 { 409 ok(0, "unexpected call\n"); 410 return E_NOTIMPL; 411 } 412 413 static HRESULT WINAPI response_put_Buffer(IResponse *iface, VARIANT_BOOL fIsBuffering) 414 { 415 ok(0, "unexpected call\n"); 416 return E_NOTIMPL; 417 } 418 419 static HRESULT WINAPI response_get_ContentType(IResponse *iface, BSTR *pbstrContentTypeRet) 420 { 421 ok(0, "unexpected call\n"); 422 return E_NOTIMPL; 423 } 424 425 static HRESULT WINAPI response_put_ContentType(IResponse *iface, BSTR bstrContentType) 426 { 427 ok(0, "unexpected call\n"); 428 return E_NOTIMPL; 429 } 430 431 static HRESULT WINAPI response_get_Expires(IResponse *iface, VARIANT *pvarExpiresMinutesRet) 432 { 433 ok(0, "unexpected call\n"); 434 return E_NOTIMPL; 435 } 436 437 static HRESULT WINAPI response_put_Expires(IResponse *iface, LONG lExpiresMinutes) 438 { 439 ok(0, "unexpected call\n"); 440 return E_NOTIMPL; 441 } 442 443 static HRESULT WINAPI response_get_ExpiresAbsolute(IResponse *iface, VARIANT *pvarExpiresRet) 444 { 445 ok(0, "unexpected call\n"); 446 return E_NOTIMPL; 447 } 448 449 static HRESULT WINAPI response_put_ExpiresAbsolute(IResponse *iface, DATE dtExpires) 450 { 451 ok(0, "unexpected call\n"); 452 return E_NOTIMPL; 453 } 454 455 static HRESULT WINAPI response_get_Cookies(IResponse *iface, IRequestDictionary **ppCookies) 456 { 457 ok(0, "unexpected call\n"); 458 return E_NOTIMPL; 459 } 460 461 static HRESULT WINAPI response_get_Status(IResponse *iface, BSTR *pbstrStatusRet) 462 { 463 ok(0, "unexpected call\n"); 464 return E_NOTIMPL; 465 } 466 467 static HRESULT WINAPI response_put_Status(IResponse *iface, BSTR bstrStatus) 468 { 469 ok(0, "unexpected call\n"); 470 return E_NOTIMPL; 471 } 472 473 static HRESULT WINAPI response_Add(IResponse *iface, BSTR bstrHeaderValue, BSTR bstrHeaderName) 474 { 475 ok(0, "unexpected call\n"); 476 return E_NOTIMPL; 477 } 478 479 static HRESULT WINAPI response_AddHeader(IResponse *iface, BSTR bstrHeaderName, BSTR bstrHeaderValue) 480 { 481 ok(0, "unexpected call\n"); 482 return E_NOTIMPL; 483 } 484 485 static HRESULT WINAPI response_AppendToLog(IResponse *iface, BSTR bstrLogEntry) 486 { 487 ok(0, "unexpected call\n"); 488 return E_NOTIMPL; 489 } 490 491 static HRESULT WINAPI response_BinaryWrite(IResponse *iface, VARIANT input) 492 { 493 HRESULT hr; 494 LONG bound; 495 UINT dim; 496 497 ok(V_VT(&input) == (VT_ARRAY | VT_UI1), "got wrong input type %x\n", V_VT(&input)); 498 499 dim = SafeArrayGetDim(V_ARRAY(&input)); 500 ok(dim == 1, "got wrong array dimensions %u\n", dim); 501 502 bound = 1; 503 hr = SafeArrayGetLBound(V_ARRAY(&input), 1, &bound); 504 ok(hr == S_OK, "got %#x\n", hr); 505 ok(bound == 0, "wrong array low bound %d\n", bound); 506 507 bound = 0; 508 hr = SafeArrayGetUBound(V_ARRAY(&input), 1, &bound); 509 ok(hr == S_OK, "got %#x\n", hr); 510 ok(bound > 0, "wrong array high bound %d\n", bound); 511 512 return E_NOTIMPL; 513 } 514 515 static HRESULT WINAPI response_Clear(IResponse *iface) 516 { 517 ok(0, "unexpected call\n"); 518 return E_NOTIMPL; 519 } 520 521 static HRESULT WINAPI response_End(IResponse *iface) 522 { 523 ok(0, "unexpected call\n"); 524 return E_NOTIMPL; 525 } 526 527 static HRESULT WINAPI response_Flush(IResponse *iface) 528 { 529 ok(0, "unexpected call\n"); 530 return E_NOTIMPL; 531 } 532 533 static HRESULT WINAPI response_Redirect(IResponse *iface, BSTR bstrURL) 534 { 535 ok(0, "unexpected call\n"); 536 return E_NOTIMPL; 537 } 538 539 static HRESULT WINAPI response_Write(IResponse *iface, VARIANT varText) 540 { 541 ok(0, "unexpected call\n"); 542 return E_NOTIMPL; 543 } 544 545 static HRESULT WINAPI response_WriteBlock(IResponse *iface, short iBlockNumber) 546 { 547 ok(0, "unexpected call\n"); 548 return E_NOTIMPL; 549 } 550 551 static HRESULT WINAPI response_IsClientConnected(IResponse *iface, VARIANT_BOOL *pfIsClientConnected) 552 { 553 ok(0, "unexpected call\n"); 554 return E_NOTIMPL; 555 } 556 557 static HRESULT WINAPI response_get_CharSet(IResponse *iface, BSTR *pbstrCharSetRet) 558 { 559 ok(0, "unexpected call\n"); 560 return E_NOTIMPL; 561 } 562 563 static HRESULT WINAPI response_put_CharSet(IResponse *iface, BSTR bstrCharSet) 564 { 565 ok(0, "unexpected call\n"); 566 return E_NOTIMPL; 567 } 568 569 static HRESULT WINAPI response_Pics(IResponse *iface, BSTR bstrHeaderValue) 570 { 571 ok(0, "unexpected call\n"); 572 return E_NOTIMPL; 573 } 574 575 static HRESULT WINAPI response_get_CacheControl(IResponse *iface, BSTR *pbstrCacheControl) 576 { 577 ok(0, "unexpected call\n"); 578 return E_NOTIMPL; 579 } 580 581 static HRESULT WINAPI response_put_CacheControl(IResponse *iface, BSTR bstrCacheControl) 582 { 583 ok(0, "unexpected call\n"); 584 return E_NOTIMPL; 585 } 586 587 static HRESULT WINAPI response_get_CodePage(IResponse *iface, LONG *plvar) 588 { 589 ok(0, "unexpected call\n"); 590 return E_NOTIMPL; 591 } 592 593 static HRESULT WINAPI response_put_CodePage(IResponse *iface, LONG codepage) 594 { 595 ok(0, "unexpected call\n"); 596 return E_NOTIMPL; 597 } 598 599 static HRESULT WINAPI response_get_LCID(IResponse *iface, LONG *lcid) 600 { 601 ok(0, "unexpected call\n"); 602 return E_NOTIMPL; 603 } 604 605 static HRESULT WINAPI response_put_LCID(IResponse *iface, LONG lcid) 606 { 607 ok(0, "unexpected call\n"); 608 return E_NOTIMPL; 609 } 610 611 static const IResponseVtbl testresponsevtbl = 612 { 613 response_QI, 614 response_AddRef, 615 response_Release, 616 response_GetTypeInfoCount, 617 response_GetTypeInfo, 618 response_GetIDsOfNames, 619 response_Invoke, 620 response_get_Buffer, 621 response_put_Buffer, 622 response_get_ContentType, 623 response_put_ContentType, 624 response_get_Expires, 625 response_put_Expires, 626 response_get_ExpiresAbsolute, 627 response_put_ExpiresAbsolute, 628 response_get_Cookies, 629 response_get_Status, 630 response_put_Status, 631 response_Add, 632 response_AddHeader, 633 response_AppendToLog, 634 response_BinaryWrite, 635 response_Clear, 636 response_End, 637 response_Flush, 638 response_Redirect, 639 response_Write, 640 response_WriteBlock, 641 response_IsClientConnected, 642 response_get_CharSet, 643 response_put_CharSet, 644 response_Pics, 645 response_get_CacheControl, 646 response_put_CacheControl, 647 response_get_CodePage, 648 response_put_CodePage, 649 response_get_LCID, 650 response_put_LCID, 651 }; 652 653 static IResponse testresponse = { &testresponsevtbl }; 654 655 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__) 656 static void _expect_children(IXMLDOMNode *node, int line) 657 { 658 VARIANT_BOOL b; 659 HRESULT hr; 660 661 b = VARIANT_FALSE; 662 hr = IXMLDOMNode_hasChildNodes(node, &b); 663 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr); 664 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b); 665 } 666 667 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__) 668 static void _expect_no_children(IXMLDOMNode *node, int line) 669 { 670 VARIANT_BOOL b; 671 HRESULT hr; 672 673 b = VARIANT_TRUE; 674 hr = IXMLDOMNode_hasChildNodes(node, &b); 675 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr); 676 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b); 677 } 678 679 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__) 680 static void _expect_ref(IUnknown* obj, ULONG ref, int line) 681 { 682 ULONG rc; 683 IUnknown_AddRef(obj); 684 rc = IUnknown_Release(obj); 685 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); 686 } 687 688 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__) 689 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line) 690 { 691 LONG length; 692 HRESULT hr; 693 694 length = 0; 695 hr = IXMLDOMNodeList_get_length(list, &length); 696 ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr); 697 ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len); 698 } 699 700 #define EXPECT_HR(hr,hr_exp) \ 701 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) 702 703 #ifdef __REACTOS__ 704 #define EXPECT_NOT_HR(hr,hr_exp) \ 705 ok(hr != hr_exp, "got 0x%08x, expected not 0x%08x\n", hr, hr_exp) 706 #endif 707 708 static const WCHAR szEmpty[] = { 0 }; 709 static const WCHAR szIncomplete[] = { 710 '<','?','x','m','l',' ', 711 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0 712 }; 713 static const WCHAR szComplete1[] = { 714 '<','?','x','m','l',' ', 715 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n', 716 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0 717 }; 718 static const WCHAR szComplete2[] = { 719 '<','?','x','m','l',' ', 720 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n', 721 '<','a','>','<','/','a','>','\n',0 722 }; 723 static const char complete4A[] = 724 "<?xml version=\'1.0\'?>\n" 725 "<lc dl=\'str1\'>\n" 726 "<bs vr=\'str2\' sz=\'1234\'>" 727 "fn1.txt\n" 728 "</bs>\n" 729 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n" 730 "fn2.txt\n" 731 "</pr>\n" 732 "<empty></empty>\n" 733 "<fo>\n" 734 "<ba>\n" 735 "f1\n" 736 "</ba>\n" 737 "</fo>\n" 738 "</lc>\n"; 739 740 static const WCHAR szComplete5[] = { 741 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ', 742 'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"', 743 ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>', 744 '<','S',':','s','c','o','p','e','>', 745 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>', 746 '<','/','S',':','s','c','o','p','e','>', 747 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>', 748 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>', 749 'c','o','m','p','u','t','e','r', 750 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>', 751 '<','/','S',':','s','e','a','r','c','h','>',0 752 }; 753 754 static const WCHAR szComplete6[] = { 755 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ', 756 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n', 757 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0 758 }; 759 760 static const char complete7[] = { 761 "<?xml version=\"1.0\"?>\n\t" 762 "<root>\n" 763 "\t<a/>\n" 764 "\t<b/>\n" 765 "\t<c/>\n" 766 "</root>" 767 }; 768 769 #define DECL_WIN_1252 \ 770 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>" 771 772 static const char win1252xml[] = 773 DECL_WIN_1252 774 "<open></open>"; 775 776 static const char win1252decl[] = 777 DECL_WIN_1252 778 ; 779 780 static const char nocontent[] = "no xml content here"; 781 782 static const char szExampleXML[] = 783 "<?xml version='1.0' encoding='utf-8'?>\n" 784 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n" 785 " <elem>\n" 786 " <a>A1 field</a>\n" 787 " <b>B1 field</b>\n" 788 " <c>C1 field</c>\n" 789 " <d>D1 field</d>\n" 790 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n" 791 " <html xmlns='http://www.w3.org/1999/xhtml'>\n" 792 " <![CDATA[]]> This is<strong> a</strong> <i>description</i><dot>. </dot><bar:x/>\n" 793 " </html>\n" 794 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n" 795 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n" 796 " </html>\n" 797 " </description>\n" 798 " </elem>\n" 799 "\n" 800 " <elem a='a'>\n" 801 " <a>A2 field</a>\n" 802 " <b>B2 field</b>\n" 803 " <c type=\"old\">C2 field</c>\n" 804 " <d>D2 field</d>\n" 805 " </elem>\n" 806 "\n" 807 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n" 808 " <a>A3 field</a>\n" 809 " <b>B3 field</b>\n" 810 " <c>C3 field</c>\n" 811 " </elem>\n" 812 "\n" 813 " <elem>\n" 814 " <a>A4 field</a>\n" 815 " <b>B4 field</b>\n" 816 " <foo:c>C4 field</foo:c>\n" 817 " <d>D4 field</d>\n" 818 " </elem>\n" 819 "</root>\n"; 820 821 static const char charrefsxml[] = 822 "<?xml version='1.0'?>" 823 "<a>" 824 "<b1> Text A end </b1>" 825 "<b2>AB C </b2>" 826 "</a>"; 827 828 static const CHAR szNodeTypesXML[] = 829 "<?xml version='1.0'?>" 830 "<!-- comment node 0 -->" 831 "<root id='0' depth='0'>" 832 " <!-- comment node 1 -->" 833 " text node 0" 834 " <x id='1' depth='1'>" 835 " <?foo value='PI for x'?>" 836 " <!-- comment node 2 -->" 837 " text node 1" 838 " <a id='3' depth='2'/>" 839 " <b id='4' depth='2'/>" 840 " <c id='5' depth='2'/>" 841 " </x>" 842 " <y id='2' depth='1'>" 843 " <?bar value='PI for y'?>" 844 " <!-- comment node 3 -->" 845 " text node 2" 846 " <a id='6' depth='2'/>" 847 " <b id='7' depth='2'/>" 848 " <c id='8' depth='2'/>" 849 " </y>" 850 "</root>"; 851 852 static const CHAR szTransformXML[] = 853 "<?xml version=\"1.0\"?>\n" 854 "<greeting>\n" 855 "Hello World\n" 856 "</greeting>"; 857 858 static const CHAR szTransformSSXML[] = 859 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n" 860 " <xsl:output method=\"html\"/>\n" 861 " <xsl:template match=\"/\">\n" 862 " <xsl:apply-templates select=\"greeting\"/>\n" 863 " </xsl:template>\n" 864 " <xsl:template match=\"greeting\">\n" 865 " <html>\n" 866 " <body>\n" 867 " <h1>\n" 868 " <xsl:value-of select=\".\"/>\n" 869 " </h1>\n" 870 " </body>\n" 871 " </html>\n" 872 " </xsl:template>\n" 873 "</xsl:stylesheet>"; 874 875 static const CHAR szTransformOutput[] = 876 "<html><body><h1>" 877 "Hello World" 878 "</h1></body></html>"; 879 880 static const CHAR szTypeValueXML[] = 881 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 882 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n" 883 " <string>Wine</string>\n" 884 " <string2 dt:dt=\"string\">String</string2>\n" 885 " <number dt:dt=\"number\">12.44</number>\n" 886 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n" 887 " <int dt:dt=\"int\">-13</int>\n" 888 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n" 889 " <bool dt:dt=\"boolean\">1</bool>\n" 890 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n" 891 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n" 892 " <date dt:dt=\"date\">3721-11-01</date>\n" 893 " <time dt:dt=\"time\">13:57:12.31321</time>\n" 894 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n" 895 " <i1 dt:dt=\"i1\">-13</i1>\n" 896 " <i2 dt:dt=\"i2\">31915</i2>\n" 897 " <i4 dt:dt=\"i4\">-312232</i4>\n" 898 " <ui1 dt:dt=\"ui1\">123</ui1>\n" 899 " <ui2 dt:dt=\"ui2\">48282</ui2>\n" 900 " <ui4 dt:dt=\"ui4\">949281</ui4>\n" 901 " <r4 dt:dt=\"r4\">213124.0</r4>\n" 902 " <r8 dt:dt=\"r8\">0.412</r8>\n" 903 " <float dt:dt=\"float\">41221.421</float>\n" 904 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n" 905 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n" 906 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n" 907 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n" 908 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n" 909 "</root>"; 910 911 static const CHAR szBasicTransformSSXMLPart1[] = 912 "<?xml version=\"1.0\"?>" 913 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >" 914 "<xsl:output method=\"html\"/>\n" 915 "<xsl:template match=\"/\">" 916 "<HTML><BODY><TABLE>" 917 " <xsl:apply-templates select='document(\""; 918 919 static const CHAR szBasicTransformSSXMLPart2[] = 920 "\")/bottle/wine'>" 921 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>" 922 " </xsl:apply-templates>" 923 "</TABLE></BODY></HTML>" 924 "</xsl:template>" 925 "<xsl:template match=\"bottle\">" 926 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>" 927 "</xsl:template>" 928 "<xsl:template match=\"name\">" 929 " <TD><xsl:apply-templates /></TD>" 930 "</xsl:template>" 931 "<xsl:template match=\"cost\">" 932 " <TD><xsl:apply-templates /></TD>" 933 "</xsl:template>" 934 "</xsl:stylesheet>"; 935 936 static const CHAR szBasicTransformXML[] = 937 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>"; 938 939 static const CHAR szBasicTransformOutput[] = 940 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>"; 941 942 #define SZ_EMAIL_DTD \ 943 "<!DOCTYPE email ["\ 944 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\ 945 " <!ATTLIST email attachments IDREFS #REQUIRED>"\ 946 " <!ATTLIST email sent (yes|no) \"no\">"\ 947 " <!ELEMENT recipients (to+,cc*)>"\ 948 " <!ELEMENT to (#PCDATA)>"\ 949 " <!ATTLIST to name CDATA #IMPLIED>"\ 950 " <!ELEMENT cc (#PCDATA)>"\ 951 " <!ATTLIST cc name CDATA #IMPLIED>"\ 952 " <!ELEMENT from (#PCDATA)>"\ 953 " <!ATTLIST from name CDATA #IMPLIED>"\ 954 " <!ELEMENT reply-to (#PCDATA)>"\ 955 " <!ATTLIST reply-to name CDATA #IMPLIED>"\ 956 " <!ELEMENT subject ANY>"\ 957 " <!ELEMENT body ANY>"\ 958 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\ 959 " <!ELEMENT attachment (#PCDATA)>"\ 960 " <!ATTLIST attachment id ID #REQUIRED>"\ 961 "]>" 962 963 static const CHAR szEmailXML[] = 964 "<?xml version=\"1.0\"?>" 965 SZ_EMAIL_DTD 966 "<email attachments=\"patch1\">" 967 " <recipients>" 968 " <to>wine-patches@winehq.org</to>" 969 " </recipients>" 970 " <from name=\"Anonymous\">user@localhost</from>" 971 " <subject>msxml3/tests: DTD validation (try 87)</subject>" 972 " <body>" 973 " It no longer causes spontaneous combustion..." 974 " </body>" 975 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 976 "</email>"; 977 978 static const CHAR szEmailXML_0D[] = 979 "<?xml version=\"1.0\"?>" 980 SZ_EMAIL_DTD 981 "<email attachments=\"patch1\">" 982 " <recipients>" 983 " <to>wine-patches@winehq.org</to>" 984 " </recipients>" 985 " <from name=\"Anonymous\">user@localhost</from>" 986 " <subject>msxml3/tests: DTD validation (try 88)</subject>" 987 " <body>" 988 " <undecl />" 989 " XML_ELEMENT_UNDECLARED 0xC00CE00D" 990 " </body>" 991 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 992 "</email>"; 993 994 static const CHAR szEmailXML_0E[] = 995 "<?xml version=\"1.0\"?>" 996 SZ_EMAIL_DTD 997 "<email attachments=\"patch1\">" 998 " <recipients>" 999 " <to>wine-patches@winehq.org</to>" 1000 " </recipients>" 1001 " <from name=\"Anonymous\">user@localhost</from>" 1002 " <subject>msxml3/tests: DTD validation (try 89)</subject>" 1003 " <body>" 1004 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E" 1005 " </body>" 1006 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1007 "</email>"; 1008 1009 static const CHAR szEmailXML_11[] = 1010 "<?xml version=\"1.0\"?>" 1011 SZ_EMAIL_DTD 1012 "<email attachments=\"patch1\">" 1013 " <recipients>" 1014 " </recipients>" 1015 " <from name=\"Anonymous\">user@localhost</from>" 1016 " <subject>msxml3/tests: DTD validation (try 90)</subject>" 1017 " <body>" 1018 " XML_EMPTY_NOT_ALLOWED 0xC00CE011" 1019 " </body>" 1020 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1021 "</email>"; 1022 1023 static const CHAR szEmailXML_13[] = 1024 "<?xml version=\"1.0\"?>" 1025 SZ_EMAIL_DTD 1026 "<msg attachments=\"patch1\">" 1027 " <recipients>" 1028 " <to>wine-patches@winehq.org</to>" 1029 " </recipients>" 1030 " <from name=\"Anonymous\">user@localhost</from>" 1031 " <subject>msxml3/tests: DTD validation (try 91)</subject>" 1032 " <body>" 1033 " XML_ROOT_NAME_MISMATCH 0xC00CE013" 1034 " </body>" 1035 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1036 "</msg>"; 1037 1038 static const CHAR szEmailXML_14[] = 1039 "<?xml version=\"1.0\"?>" 1040 SZ_EMAIL_DTD 1041 "<email attachments=\"patch1\">" 1042 " <to>wine-patches@winehq.org</to>" 1043 " <from name=\"Anonymous\">user@localhost</from>" 1044 " <subject>msxml3/tests: DTD validation (try 92)</subject>" 1045 " <body>" 1046 " XML_INVALID_CONTENT 0xC00CE014" 1047 " </body>" 1048 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1049 "</email>"; 1050 1051 static const CHAR szEmailXML_15[] = 1052 "<?xml version=\"1.0\"?>" 1053 SZ_EMAIL_DTD 1054 "<email attachments=\"patch1\" ip=\"127.0.0.1\">" 1055 " <recipients>" 1056 " <to>wine-patches@winehq.org</to>" 1057 " </recipients>" 1058 " <from name=\"Anonymous\">user@localhost</from>" 1059 " <subject>msxml3/tests: DTD validation (try 93)</subject>" 1060 " <body>" 1061 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015" 1062 " </body>" 1063 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1064 "</email>"; 1065 1066 static const CHAR szEmailXML_16[] = 1067 "<?xml version=\"1.0\"?>" 1068 SZ_EMAIL_DTD 1069 "<email attachments=\"patch1\">" 1070 " <recipients>" 1071 " <to>wine-patches@winehq.org</to>" 1072 " </recipients>" 1073 " <from name=\"Anonymous\">user@localhost</from>" 1074 " <subject>msxml3/tests: DTD validation (try 94)</subject>" 1075 " <body enc=\"ASCII\">" 1076 " XML_ATTRIBUTE_FIXED 0xC00CE016" 1077 " </body>" 1078 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1079 "</email>"; 1080 1081 static const CHAR szEmailXML_17[] = 1082 "<?xml version=\"1.0\"?>" 1083 SZ_EMAIL_DTD 1084 "<email attachments=\"patch1\" sent=\"true\">" 1085 " <recipients>" 1086 " <to>wine-patches@winehq.org</to>" 1087 " </recipients>" 1088 " <from name=\"Anonymous\">user@localhost</from>" 1089 " <subject>msxml3/tests: DTD validation (try 95)</subject>" 1090 " <body>" 1091 " XML_ATTRIBUTE_VALUE 0xC00CE017" 1092 " </body>" 1093 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1094 "</email>"; 1095 1096 static const CHAR szEmailXML_18[] = 1097 "<?xml version=\"1.0\"?>" 1098 SZ_EMAIL_DTD 1099 "<email attachments=\"patch1\">" 1100 " oops" 1101 " <recipients>" 1102 " <to>wine-patches@winehq.org</to>" 1103 " </recipients>" 1104 " <from name=\"Anonymous\">user@localhost</from>" 1105 " <subject>msxml3/tests: DTD validation (try 96)</subject>" 1106 " <body>" 1107 " XML_ILLEGAL_TEXT 0xC00CE018" 1108 " </body>" 1109 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1110 "</email>"; 1111 1112 static const CHAR szEmailXML_20[] = 1113 "<?xml version=\"1.0\"?>" 1114 SZ_EMAIL_DTD 1115 "<email>" 1116 " <recipients>" 1117 " <to>wine-patches@winehq.org</to>" 1118 " </recipients>" 1119 " <from name=\"Anonymous\">user@localhost</from>" 1120 " <subject>msxml3/tests: DTD validation (try 97)</subject>" 1121 " <body>" 1122 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020" 1123 " </body>" 1124 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>" 1125 "</email>"; 1126 1127 static const char xpath_simple_list[] = 1128 "<?xml version=\"1.0\"?>" 1129 "<root>" 1130 " <a attr1=\"1\" attr2=\"2\" />" 1131 " <b/>" 1132 " <c/>" 1133 " <d/>" 1134 "</root>"; 1135 1136 static const char default_ns_doc[] = { 1137 "<?xml version=\"1.0\"?>" 1138 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" " 1139 " d=\"d attr\" />" 1140 }; 1141 1142 static const char attributes_map[] = { 1143 "<?xml version=\"1.0\"?>" 1144 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />" 1145 }; 1146 1147 static const WCHAR nonexistent_fileW[] = { 1148 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0 1149 }; 1150 static const WCHAR nonexistent_attrW[] = { 1151 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0 1152 }; 1153 static const WCHAR szDocument[] = { 1154 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0 1155 }; 1156 1157 static const WCHAR szOpen[] = { 'o','p','e','n',0 }; 1158 static const WCHAR szdl[] = { 'd','l',0 }; 1159 static const WCHAR szvr[] = { 'v','r',0 }; 1160 static const WCHAR szlc[] = { 'l','c',0 }; 1161 static const WCHAR szbs[] = { 'b','s',0 }; 1162 static const WCHAR szstr1[] = { 's','t','r','1',0 }; 1163 static const WCHAR szstr2[] = { 's','t','r','2',0 }; 1164 static const WCHAR szstar[] = { '*',0 }; 1165 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0}; 1166 1167 static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 }; 1168 static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 }; 1169 static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 }; 1170 1171 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 }; 1172 static const WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 }; 1173 static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 }; 1174 static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>', 1175 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 }; 1176 static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>', 1177 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 }; 1178 1179 static const WCHAR szAttribute[] = {'A','t','t','r',0 }; 1180 static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 }; 1181 1182 static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s', 1183 ' ','n','o','t',' ','r','i','g','h','t','!', 0}; 1184 static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&', 1185 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t', 1186 '!',']',']','>',0}; 1187 static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 }; 1188 static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 }; 1189 1190 static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 }; 1191 static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 }; 1192 static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0}; 1193 1194 #define expect_bstr_eq_and_free(bstr, expect) { \ 1195 BSTR bstrExp = alloc_str_from_narrow(expect); \ 1196 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \ 1197 SysFreeString(bstr); \ 1198 SysFreeString(bstrExp); \ 1199 } 1200 1201 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); } 1202 1203 #define ole_check(expr) { \ 1204 HRESULT r = expr; \ 1205 ok(r == S_OK, #expr " returned %x\n", r); \ 1206 } 1207 1208 #define ole_expect(expr, expect) { \ 1209 HRESULT r = expr; \ 1210 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \ 1211 } 1212 1213 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y) 1214 1215 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line) 1216 { 1217 void *obj = NULL; 1218 HRESULT hr; 1219 1220 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj); 1221 ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr); 1222 1223 return obj; 1224 } 1225 1226 #define _create(cls) cls, #cls 1227 1228 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__) 1229 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__) 1230 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__) 1231 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__) 1232 1233 static BSTR alloc_str_from_narrow(const char *str) 1234 { 1235 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 1236 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */ 1237 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); 1238 return ret; 1239 } 1240 1241 static BSTR alloced_bstrs[256]; 1242 static int alloced_bstrs_count; 1243 1244 static BSTR _bstr_(const char *str) 1245 { 1246 assert(alloced_bstrs_count < ARRAY_SIZE(alloced_bstrs)); 1247 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str); 1248 return alloced_bstrs[alloced_bstrs_count++]; 1249 } 1250 1251 static void free_bstrs(void) 1252 { 1253 int i; 1254 for (i = 0; i < alloced_bstrs_count; i++) 1255 SysFreeString(alloced_bstrs[i]); 1256 alloced_bstrs_count = 0; 1257 } 1258 1259 static VARIANT _variantbstr_(const char *str) 1260 { 1261 VARIANT v; 1262 V_VT(&v) = VT_BSTR; 1263 V_BSTR(&v) = _bstr_(str); 1264 return v; 1265 } 1266 1267 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight) 1268 { 1269 for (;;) 1270 { 1271 while (*sLeft == '\r' || *sLeft == '\n') sLeft++; 1272 while (*sRight == '\r' || *sRight == '\n') sRight++; 1273 if (*sLeft != *sRight) return FALSE; 1274 if (!*sLeft) return TRUE; 1275 sLeft++; 1276 sRight++; 1277 } 1278 } 1279 1280 static void get_str_for_type(DOMNodeType type, char *buf) 1281 { 1282 switch (type) 1283 { 1284 case NODE_ATTRIBUTE: 1285 strcpy(buf, "A"); 1286 break; 1287 case NODE_ELEMENT: 1288 strcpy(buf, "E"); 1289 break; 1290 case NODE_DOCUMENT: 1291 strcpy(buf, "D"); 1292 break; 1293 case NODE_TEXT: 1294 strcpy(buf, "T"); 1295 break; 1296 case NODE_COMMENT: 1297 strcpy(buf, "C"); 1298 break; 1299 case NODE_PROCESSING_INSTRUCTION: 1300 strcpy(buf, "P"); 1301 break; 1302 default: 1303 wsprintfA(buf, "[%d]", type); 1304 } 1305 } 1306 1307 static int get_node_position(IXMLDOMNode *node) 1308 { 1309 HRESULT r; 1310 int pos = 0; 1311 1312 IXMLDOMNode_AddRef(node); 1313 do 1314 { 1315 IXMLDOMNode *new_node; 1316 1317 pos++; 1318 r = IXMLDOMNode_get_previousSibling(node, &new_node); 1319 ok(SUCCEEDED(r), "get_previousSibling failed\n"); 1320 IXMLDOMNode_Release(node); 1321 node = new_node; 1322 } while (r == S_OK); 1323 return pos; 1324 } 1325 1326 static void node_to_string(IXMLDOMNode *node, char *buf) 1327 { 1328 HRESULT r = S_OK; 1329 DOMNodeType type; 1330 1331 if (node == NULL) 1332 { 1333 lstrcpyA(buf, "(null)"); 1334 return; 1335 } 1336 1337 IXMLDOMNode_AddRef(node); 1338 while (r == S_OK) 1339 { 1340 IXMLDOMNode *new_node; 1341 1342 ole_check(IXMLDOMNode_get_nodeType(node, &type)); 1343 get_str_for_type(type, buf); 1344 buf+=strlen(buf); 1345 1346 if (type == NODE_ATTRIBUTE) 1347 { 1348 BSTR bstr; 1349 ole_check(IXMLDOMNode_get_nodeName(node, &bstr)); 1350 *(buf++) = '\''; 1351 wsprintfA(buf, "%ws", bstr); 1352 buf += strlen(buf); 1353 *(buf++) = '\''; 1354 SysFreeString(bstr); 1355 1356 r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node); 1357 } 1358 else 1359 { 1360 r = IXMLDOMNode_get_parentNode(node, &new_node); 1361 sprintf(buf, "%d", get_node_position(node)); 1362 buf += strlen(buf); 1363 } 1364 1365 ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r); 1366 IXMLDOMNode_Release(node); 1367 node = new_node; 1368 if (r == S_OK) 1369 *(buf++) = '.'; 1370 } 1371 1372 *buf = 0; 1373 } 1374 1375 static char *list_to_string(IXMLDOMNodeList *list) 1376 { 1377 static char buf[4096]; 1378 char *pos = buf; 1379 LONG len = 0; 1380 HRESULT hr; 1381 int i; 1382 1383 if (list == NULL) 1384 { 1385 strcpy(buf, "(null)"); 1386 return buf; 1387 } 1388 hr = IXMLDOMNodeList_get_length(list, &len); 1389 ok(hr == S_OK, "got 0x%08x\n", hr); 1390 for (i = 0; i < len; i++) 1391 { 1392 IXMLDOMNode *node; 1393 if (i > 0) 1394 *(pos++) = ' '; 1395 ole_check(IXMLDOMNodeList_nextNode(list, &node)); 1396 node_to_string(node, pos); 1397 pos += strlen(pos); 1398 IXMLDOMNode_Release(node); 1399 } 1400 *pos = 0; 1401 return buf; 1402 } 1403 1404 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); } 1405 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); } 1406 1407 struct docload_ret_t { 1408 VARIANT_BOOL b; 1409 HRESULT hr; 1410 }; 1411 1412 struct leading_spaces_t { 1413 const CLSID *clsid; 1414 const char *name; 1415 struct docload_ret_t ret[2]; /* 0 - ::load(), 1 - ::loadXML() */ 1416 }; 1417 1418 static const struct leading_spaces_t leading_spaces_classdata[] = { 1419 { &CLSID_DOMDocument, "CLSID_DOMDocument", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }}, 1420 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }}, 1421 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", {{VARIANT_FALSE, S_FALSE }, {VARIANT_TRUE, S_OK } }}, 1422 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }}, 1423 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }}, 1424 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", {{VARIANT_FALSE, S_FALSE }, {VARIANT_FALSE, S_FALSE } }}, 1425 { NULL } 1426 }; 1427 1428 static const char* leading_spaces_xmldata[] = { 1429 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>", 1430 " <?xml version=\"1.0\"?><root/>", 1431 "\n<?xml version=\"1.0\"?><root/>", 1432 "\t<?xml version=\"1.0\"?><root/>", 1433 "\r\n<?xml version=\"1.0\"?><root/>", 1434 "\r<?xml version=\"1.0\"?><root/>", 1435 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>", 1436 0 1437 }; 1438 1439 static void test_domdoc( void ) 1440 { 1441 HRESULT r, hr; 1442 IXMLDOMDocument *doc; 1443 IXMLDOMParseError *error; 1444 IXMLDOMElement *element = NULL; 1445 IXMLDOMNode *node; 1446 IXMLDOMText *nodetext = NULL; 1447 IXMLDOMComment *node_comment = NULL; 1448 IXMLDOMAttribute *node_attr = NULL; 1449 IXMLDOMNode *nodeChild = NULL; 1450 IXMLDOMProcessingInstruction *nodePI = NULL; 1451 const struct leading_spaces_t *class_ptr; 1452 const char **data_ptr; 1453 VARIANT_BOOL b; 1454 VARIANT var; 1455 BSTR str; 1456 LONG code, ref; 1457 LONG nLength = 0; 1458 WCHAR buff[100]; 1459 char path[MAX_PATH]; 1460 int index; 1461 1462 GetTempPathA(MAX_PATH, path); 1463 strcat(path, "leading_spaces.xml"); 1464 1465 /* Load document with leading spaces 1466 * 1467 * Test all CLSIDs with all test data XML strings 1468 */ 1469 class_ptr = leading_spaces_classdata; 1470 index = 0; 1471 while (class_ptr->clsid) 1472 { 1473 HRESULT hr; 1474 int i; 1475 1476 if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument)) 1477 { 1478 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc); 1479 } 1480 else 1481 { 1482 class_ptr++; 1483 index++; 1484 continue; 1485 } 1486 1487 data_ptr = leading_spaces_xmldata; 1488 i = 0; 1489 while (*data_ptr) { 1490 BSTR data = _bstr_(*data_ptr); 1491 DWORD written; 1492 HANDLE file; 1493 1494 file = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 1495 ok(file != INVALID_HANDLE_VALUE, "can't create file %s: %u\n", path, GetLastError()); 1496 1497 WriteFile(file, data, lstrlenW(data)*sizeof(WCHAR), &written, NULL); 1498 CloseHandle(file); 1499 1500 b = 0xc; 1501 V_VT(&var) = VT_BSTR; 1502 V_BSTR(&var) = _bstr_(path); 1503 hr = IXMLDOMDocument_load(doc, var, &b); 1504 EXPECT_HR(hr, class_ptr->ret[0].hr); 1505 ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b); 1506 1507 DeleteFileA(path); 1508 1509 b = 0xc; 1510 hr = IXMLDOMDocument_loadXML(doc, data, &b); 1511 EXPECT_HR(hr, class_ptr->ret[1].hr); 1512 ok(b == class_ptr->ret[1].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[1].b); 1513 1514 data_ptr++; 1515 i++; 1516 } 1517 1518 class_ptr++; 1519 index++; 1520 free_bstrs(); 1521 } 1522 1523 doc = create_document(&IID_IXMLDOMDocument); 1524 if (!doc) return; 1525 1526 if (0) 1527 { 1528 /* crashes on native */ 1529 IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL ); 1530 } 1531 1532 /* try some stupid things */ 1533 hr = IXMLDOMDocument_loadXML( doc, NULL, NULL ); 1534 EXPECT_HR(hr, S_FALSE); 1535 1536 b = VARIANT_TRUE; 1537 hr = IXMLDOMDocument_loadXML( doc, NULL, &b ); 1538 EXPECT_HR(hr, S_FALSE); 1539 ok( b == VARIANT_FALSE, "failed to load XML string\n"); 1540 1541 /* try to load a document from a nonexistent file */ 1542 b = VARIANT_TRUE; 1543 str = SysAllocString( nonexistent_fileW ); 1544 VariantInit(&var); 1545 V_VT(&var) = VT_BSTR; 1546 V_BSTR(&var) = str; 1547 1548 r = IXMLDOMDocument_load( doc, var, &b); 1549 ok( r == S_FALSE, "loadXML succeeded\n"); 1550 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n"); 1551 SysFreeString( str ); 1552 1553 str = (void *)0xdeadbeef; 1554 hr = IXMLDOMDocument_get_url(doc, &str); 1555 ok(hr == S_FALSE, "got 0x%08x\n", hr); 1556 ok(str == NULL, "got %p\n", str); 1557 1558 /* try load an empty document */ 1559 b = VARIANT_TRUE; 1560 str = SysAllocString( szEmpty ); 1561 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1562 ok( r == S_FALSE, "loadXML succeeded\n"); 1563 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n"); 1564 SysFreeString( str ); 1565 1566 r = IXMLDOMDocument_get_async( doc, &b ); 1567 ok( r == S_OK, "get_async failed (%08x)\n", r); 1568 ok( b == VARIANT_TRUE, "Wrong default value\n"); 1569 1570 /* check that there's no document element */ 1571 element = NULL; 1572 r = IXMLDOMDocument_get_documentElement( doc, &element ); 1573 ok( r == S_FALSE, "should be no document element\n"); 1574 1575 /* try finding a node */ 1576 node = NULL; 1577 str = SysAllocString( szstr1 ); 1578 r = IXMLDOMDocument_selectSingleNode( doc, str, &node ); 1579 ok( r == S_FALSE, "ret %08x\n", r ); 1580 SysFreeString( str ); 1581 1582 b = VARIANT_TRUE; 1583 str = SysAllocString( szIncomplete ); 1584 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1585 ok( r == S_FALSE, "loadXML succeeded\n"); 1586 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n"); 1587 SysFreeString( str ); 1588 1589 /* check that there's no document element */ 1590 element = (IXMLDOMElement*)1; 1591 r = IXMLDOMDocument_get_documentElement( doc, &element ); 1592 ok( r == S_FALSE, "should be no document element\n"); 1593 ok( element == NULL, "Element should be NULL\n"); 1594 1595 /* test for BSTR handling, pass broken BSTR */ 1596 memcpy(&buff[2], szComplete1, sizeof(szComplete1)); 1597 /* just a big length */ 1598 *(DWORD*)buff = 0xf0f0; 1599 b = VARIANT_FALSE; 1600 r = IXMLDOMDocument_loadXML( doc, &buff[2], &b ); 1601 ok( r == S_OK, "loadXML failed\n"); 1602 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 1603 1604 /* loadXML ignores the encoding attribute and always expects Unicode */ 1605 b = VARIANT_FALSE; 1606 str = SysAllocString( szComplete6 ); 1607 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1608 ok( r == S_OK, "loadXML failed\n"); 1609 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 1610 SysFreeString( str ); 1611 1612 /* try a BSTR containing a Windows-1252 document */ 1613 b = VARIANT_TRUE; 1614 str = SysAllocStringByteLen( win1252xml, strlen(win1252xml) ); 1615 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1616 ok( r == S_FALSE, "loadXML succeeded\n"); 1617 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n"); 1618 SysFreeString( str ); 1619 1620 /* try to load something valid */ 1621 b = VARIANT_FALSE; 1622 str = SysAllocString( szComplete1 ); 1623 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1624 ok( r == S_OK, "loadXML failed\n"); 1625 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 1626 SysFreeString( str ); 1627 1628 /* check if nodename is correct */ 1629 r = IXMLDOMDocument_get_nodeName( doc, NULL ); 1630 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n"); 1631 1632 str = (void *)0xdeadbeef; 1633 r = IXMLDOMDocument_get_baseName( doc, &str ); 1634 ok ( r == S_FALSE, "got 0x%08x\n", r); 1635 ok (str == NULL, "got %p\n", str); 1636 1637 /* content doesn't matter here */ 1638 str = NULL; 1639 r = IXMLDOMDocument_get_nodeName( doc, &str ); 1640 ok ( r == S_OK, "get_nodeName wrong code\n"); 1641 ok ( str != NULL, "str is null\n"); 1642 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n"); 1643 SysFreeString( str ); 1644 1645 /* test put_text */ 1646 r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") ); 1647 ok( r == E_FAIL, "ret %08x\n", r ); 1648 1649 /* check that there's a document element */ 1650 element = NULL; 1651 r = IXMLDOMDocument_get_documentElement( doc, &element ); 1652 ok( r == S_OK, "should be a document element\n"); 1653 if( element ) 1654 { 1655 IObjectIdentity *ident; 1656 1657 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident ); 1658 ok( r == E_NOINTERFACE, "ret %08x\n", r); 1659 1660 IXMLDOMElement_Release( element ); 1661 element = NULL; 1662 } 1663 1664 /* as soon as we call loadXML again, the document element will disappear */ 1665 b = 2; 1666 r = IXMLDOMDocument_loadXML( doc, NULL, NULL ); 1667 ok( r == S_FALSE, "loadXML failed\n"); 1668 ok( b == 2, "variant modified\n"); 1669 r = IXMLDOMDocument_get_documentElement( doc, &element ); 1670 ok( r == S_FALSE, "should be no document element\n"); 1671 1672 /* try to load something else simple and valid */ 1673 b = VARIANT_FALSE; 1674 str = SysAllocString( szComplete2 ); 1675 r = IXMLDOMDocument_loadXML( doc, str, &b ); 1676 ok( r == S_OK, "loadXML failed\n"); 1677 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 1678 SysFreeString( str ); 1679 1680 /* try something a little more complicated */ 1681 b = FALSE; 1682 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 1683 ok( r == S_OK, "loadXML failed\n"); 1684 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 1685 1686 r = IXMLDOMDocument_get_parseError( doc, &error ); 1687 ok( r == S_OK, "returns %08x\n", r ); 1688 1689 r = IXMLDOMParseError_get_errorCode( error, &code ); 1690 ok( r == S_FALSE, "returns %08x\n", r ); 1691 ok( code == 0, "code %d\n", code ); 1692 IXMLDOMParseError_Release( error ); 1693 1694 /* test createTextNode */ 1695 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext); 1696 ok( r == S_OK, "returns %08x\n", r ); 1697 IXMLDOMText_Release(nodetext); 1698 1699 str = SysAllocString( szOpen ); 1700 r = IXMLDOMDocument_createTextNode(doc, str, NULL); 1701 ok( r == E_INVALIDARG, "returns %08x\n", r ); 1702 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext); 1703 ok( r == S_OK, "returns %08x\n", r ); 1704 SysFreeString( str ); 1705 if(nodetext) 1706 { 1707 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element); 1708 ok(r == E_NOINTERFACE, "ret %08x\n", r ); 1709 1710 /* Text Last Child Checks */ 1711 r = IXMLDOMText_get_lastChild(nodetext, NULL); 1712 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1713 1714 nodeChild = (IXMLDOMNode*)0x1; 1715 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild); 1716 ok(r == S_FALSE, "ret %08x\n", r ); 1717 ok(nodeChild == NULL, "nodeChild not NULL\n"); 1718 1719 /* test length property */ 1720 r = IXMLDOMText_get_length(nodetext, NULL); 1721 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1722 1723 r = IXMLDOMText_get_length(nodetext, &nLength); 1724 ok(r == S_OK, "ret %08x\n", r ); 1725 ok(nLength == 4, "expected 4 got %d\n", nLength); 1726 1727 /* put data Tests */ 1728 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\")); 1729 ok(r == S_OK, "ret %08x\n", r ); 1730 1731 /* get data Tests */ 1732 r = IXMLDOMText_get_data(nodetext, &str); 1733 ok(r == S_OK, "ret %08x\n", r ); 1734 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n"); 1735 SysFreeString(str); 1736 1737 /* Confirm XML text is good */ 1738 r = IXMLDOMText_get_xml(nodetext, &str); 1739 ok(r == S_OK, "ret %08x\n", r ); 1740 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n"); 1741 SysFreeString(str); 1742 1743 /* Confirm we get the put_data Text back */ 1744 r = IXMLDOMText_get_text(nodetext, &str); 1745 ok(r == S_OK, "ret %08x\n", r ); 1746 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n"); 1747 SysFreeString(str); 1748 1749 /* test substringData */ 1750 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL); 1751 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1752 1753 /* test substringData - Invalid offset */ 1754 str = (void *)0xdeadbeef; 1755 r = IXMLDOMText_substringData(nodetext, -1, 4, &str); 1756 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1757 ok( str == NULL, "incorrect string\n"); 1758 1759 /* test substringData - Invalid offset */ 1760 str = (void *)0xdeadbeef; 1761 r = IXMLDOMText_substringData(nodetext, 30, 0, &str); 1762 ok(r == S_FALSE, "ret %08x\n", r ); 1763 ok( str == NULL, "incorrect string\n"); 1764 1765 /* test substringData - Invalid size */ 1766 str = (void *)0xdeadbeef; 1767 r = IXMLDOMText_substringData(nodetext, 0, -1, &str); 1768 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1769 ok( str == NULL, "incorrect string\n"); 1770 1771 /* test substringData - Invalid size */ 1772 str = (void *)0xdeadbeef; 1773 r = IXMLDOMText_substringData(nodetext, 2, 0, &str); 1774 ok(r == S_FALSE, "ret %08x\n", r ); 1775 ok( str == NULL, "incorrect string\n"); 1776 1777 /* test substringData - Start of string */ 1778 r = IXMLDOMText_substringData(nodetext, 0, 4, &str); 1779 ok(r == S_OK, "ret %08x\n", r ); 1780 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n"); 1781 SysFreeString(str); 1782 1783 /* test substringData - Middle of string */ 1784 r = IXMLDOMText_substringData(nodetext, 13, 4, &str); 1785 ok(r == S_OK, "ret %08x\n", r ); 1786 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n"); 1787 SysFreeString(str); 1788 1789 /* test substringData - End of string */ 1790 r = IXMLDOMText_substringData(nodetext, 20, 4, &str); 1791 ok(r == S_OK, "ret %08x\n", r ); 1792 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n"); 1793 SysFreeString(str); 1794 1795 /* test appendData */ 1796 r = IXMLDOMText_appendData(nodetext, NULL); 1797 ok(r == S_OK, "ret %08x\n", r ); 1798 1799 r = IXMLDOMText_appendData(nodetext, _bstr_("")); 1800 ok(r == S_OK, "ret %08x\n", r ); 1801 1802 r = IXMLDOMText_appendData(nodetext, _bstr_("Append")); 1803 ok(r == S_OK, "ret %08x\n", r ); 1804 1805 r = IXMLDOMText_get_text(nodetext, &str); 1806 ok(r == S_OK, "ret %08x\n", r ); 1807 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1808 SysFreeString(str); 1809 1810 /* test insertData */ 1811 str = SysAllocStringLen(NULL, 0); 1812 r = IXMLDOMText_insertData(nodetext, -1, str); 1813 ok(r == S_OK, "ret %08x\n", r ); 1814 1815 r = IXMLDOMText_insertData(nodetext, -1, NULL); 1816 ok(r == S_OK, "ret %08x\n", r ); 1817 1818 r = IXMLDOMText_insertData(nodetext, 1000, str); 1819 ok(r == S_OK, "ret %08x\n", r ); 1820 1821 r = IXMLDOMText_insertData(nodetext, 1000, NULL); 1822 ok(r == S_OK, "ret %08x\n", r ); 1823 1824 r = IXMLDOMText_insertData(nodetext, 0, NULL); 1825 ok(r == S_OK, "ret %08x\n", r ); 1826 1827 r = IXMLDOMText_insertData(nodetext, 0, str); 1828 ok(r == S_OK, "ret %08x\n", r ); 1829 SysFreeString(str); 1830 1831 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting")); 1832 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1833 1834 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting")); 1835 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1836 1837 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin ")); 1838 ok(r == S_OK, "ret %08x\n", r ); 1839 1840 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle")); 1841 ok(r == S_OK, "ret %08x\n", r ); 1842 1843 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End")); 1844 ok(r == S_OK, "ret %08x\n", r ); 1845 1846 r = IXMLDOMText_get_text(nodetext, &str); 1847 ok(r == S_OK, "ret %08x\n", r ); 1848 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1849 SysFreeString(str); 1850 1851 /* delete data */ 1852 /* invalid arguments */ 1853 r = IXMLDOMText_deleteData(nodetext, -1, 1); 1854 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1855 1856 r = IXMLDOMText_deleteData(nodetext, 0, 0); 1857 ok(r == S_OK, "ret %08x\n", r ); 1858 1859 r = IXMLDOMText_deleteData(nodetext, 0, -1); 1860 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1861 1862 r = IXMLDOMText_get_length(nodetext, &nLength); 1863 ok(r == S_OK, "ret %08x\n", r ); 1864 ok(nLength == 43, "expected 43 got %d\n", nLength); 1865 1866 r = IXMLDOMText_deleteData(nodetext, nLength, 1); 1867 ok(r == S_OK, "ret %08x\n", r ); 1868 1869 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1); 1870 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1871 1872 /* delete from start */ 1873 r = IXMLDOMText_deleteData(nodetext, 0, 5); 1874 ok(r == S_OK, "ret %08x\n", r ); 1875 1876 r = IXMLDOMText_get_length(nodetext, &nLength); 1877 ok(r == S_OK, "ret %08x\n", r ); 1878 ok(nLength == 38, "expected 38 got %d\n", nLength); 1879 1880 r = IXMLDOMText_get_text(nodetext, &str); 1881 ok(r == S_OK, "ret %08x\n", r ); 1882 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1883 SysFreeString(str); 1884 1885 /* delete from end */ 1886 r = IXMLDOMText_deleteData(nodetext, 35, 3); 1887 ok(r == S_OK, "ret %08x\n", r ); 1888 1889 r = IXMLDOMText_get_length(nodetext, &nLength); 1890 ok(r == S_OK, "ret %08x\n", r ); 1891 ok(nLength == 35, "expected 35 got %d\n", nLength); 1892 1893 r = IXMLDOMText_get_text(nodetext, &str); 1894 ok(r == S_OK, "ret %08x\n", r ); 1895 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1896 SysFreeString(str); 1897 1898 /* delete from inside */ 1899 r = IXMLDOMText_deleteData(nodetext, 1, 33); 1900 ok(r == S_OK, "ret %08x\n", r ); 1901 1902 r = IXMLDOMText_get_length(nodetext, &nLength); 1903 ok(r == S_OK, "ret %08x\n", r ); 1904 ok(nLength == 2, "expected 2 got %d\n", nLength); 1905 1906 r = IXMLDOMText_get_text(nodetext, &str); 1907 ok(r == S_OK, "ret %08x\n", r ); 1908 ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1909 SysFreeString(str); 1910 1911 /* delete whole data ... */ 1912 r = IXMLDOMText_get_length(nodetext, &nLength); 1913 ok(r == S_OK, "ret %08x\n", r ); 1914 1915 r = IXMLDOMText_deleteData(nodetext, 0, nLength); 1916 ok(r == S_OK, "ret %08x\n", r ); 1917 /* ... and try again with empty string */ 1918 r = IXMLDOMText_deleteData(nodetext, 0, nLength); 1919 ok(r == S_OK, "ret %08x\n", r ); 1920 1921 /* test put_data */ 1922 V_VT(&var) = VT_BSTR; 1923 V_BSTR(&var) = SysAllocString(szstr1); 1924 r = IXMLDOMText_put_nodeValue(nodetext, var); 1925 ok(r == S_OK, "ret %08x\n", r ); 1926 VariantClear(&var); 1927 1928 r = IXMLDOMText_get_text(nodetext, &str); 1929 ok(r == S_OK, "ret %08x\n", r ); 1930 ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1931 SysFreeString(str); 1932 1933 /* test put_data */ 1934 V_VT(&var) = VT_I4; 1935 V_I4(&var) = 99; 1936 r = IXMLDOMText_put_nodeValue(nodetext, var); 1937 ok(r == S_OK, "ret %08x\n", r ); 1938 VariantClear(&var); 1939 1940 r = IXMLDOMText_get_text(nodetext, &str); 1941 ok(r == S_OK, "ret %08x\n", r ); 1942 ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1943 SysFreeString(str); 1944 1945 /* ::replaceData() */ 1946 V_VT(&var) = VT_BSTR; 1947 V_BSTR(&var) = SysAllocString(szstr1); 1948 r = IXMLDOMText_put_nodeValue(nodetext, var); 1949 ok(r == S_OK, "ret %08x\n", r ); 1950 VariantClear(&var); 1951 1952 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL); 1953 ok(r == E_INVALIDARG, "ret %08x\n", r ); 1954 r = IXMLDOMText_get_text(nodetext, &str); 1955 ok(r == S_OK, "ret %08x\n", r ); 1956 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1957 SysFreeString(str); 1958 1959 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL); 1960 ok(r == S_OK, "ret %08x\n", r ); 1961 r = IXMLDOMText_get_text(nodetext, &str); 1962 ok(r == S_OK, "ret %08x\n", r ); 1963 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1964 SysFreeString(str); 1965 1966 /* NULL pointer means delete */ 1967 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL); 1968 ok(r == S_OK, "ret %08x\n", r ); 1969 r = IXMLDOMText_get_text(nodetext, &str); 1970 ok(r == S_OK, "ret %08x\n", r ); 1971 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1972 SysFreeString(str); 1973 1974 /* empty string means delete */ 1975 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("")); 1976 ok(r == S_OK, "ret %08x\n", r ); 1977 r = IXMLDOMText_get_text(nodetext, &str); 1978 ok(r == S_OK, "ret %08x\n", r ); 1979 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1980 SysFreeString(str); 1981 1982 /* zero count means insert */ 1983 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a")); 1984 ok(r == S_OK, "ret %08x\n", r ); 1985 r = IXMLDOMText_get_text(nodetext, &str); 1986 ok(r == S_OK, "ret %08x\n", r ); 1987 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1988 SysFreeString(str); 1989 1990 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL); 1991 ok(r == S_OK, "ret %08x\n", r ); 1992 1993 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m")); 1994 ok(r == S_OK, "ret %08x\n", r ); 1995 r = IXMLDOMText_get_text(nodetext, &str); 1996 ok(r == S_OK, "ret %08x\n", r ); 1997 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 1998 SysFreeString(str); 1999 2000 /* nonempty string, count greater than its length */ 2001 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2")); 2002 ok(r == S_OK, "ret %08x\n", r ); 2003 r = IXMLDOMText_get_text(nodetext, &str); 2004 ok(r == S_OK, "ret %08x\n", r ); 2005 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 2006 SysFreeString(str); 2007 2008 /* nonempty string, count less than its length */ 2009 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine")); 2010 ok(r == S_OK, "ret %08x\n", r ); 2011 r = IXMLDOMText_get_text(nodetext, &str); 2012 ok(r == S_OK, "ret %08x\n", r ); 2013 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 2014 SysFreeString(str); 2015 2016 IXMLDOMText_Release( nodetext ); 2017 } 2018 2019 /* test Create Comment */ 2020 r = IXMLDOMDocument_createComment(doc, NULL, NULL); 2021 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2022 node_comment = (IXMLDOMComment*)0x1; 2023 2024 /* empty comment */ 2025 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment); 2026 ok( r == S_OK, "returns %08x\n", r ); 2027 str = NULL; 2028 r = IXMLDOMComment_get_data(node_comment, &str); 2029 ok( r == S_OK, "returns %08x\n", r ); 2030 ok( str && SysStringLen(str) == 0, "expected empty string data\n"); 2031 IXMLDOMComment_Release(node_comment); 2032 SysFreeString(str); 2033 2034 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment); 2035 ok( r == S_OK, "returns %08x\n", r ); 2036 str = NULL; 2037 r = IXMLDOMComment_get_data(node_comment, &str); 2038 ok( r == S_OK, "returns %08x\n", r ); 2039 ok( str && (SysStringLen(str) == 0), "expected empty string data\n"); 2040 IXMLDOMComment_Release(node_comment); 2041 SysFreeString(str); 2042 2043 str = SysAllocString(szComment); 2044 r = IXMLDOMDocument_createComment(doc, str, &node_comment); 2045 SysFreeString(str); 2046 ok( r == S_OK, "returns %08x\n", r ); 2047 if(node_comment) 2048 { 2049 /* Last Child Checks */ 2050 r = IXMLDOMComment_get_lastChild(node_comment, NULL); 2051 ok(r == E_INVALIDARG, "ret %08x\n", r ); 2052 2053 nodeChild = (IXMLDOMNode*)0x1; 2054 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild); 2055 ok(r == S_FALSE, "ret %08x\n", r ); 2056 ok(nodeChild == NULL, "pLastChild not NULL\n"); 2057 2058 /* baseName */ 2059 str = (void *)0xdeadbeef; 2060 r = IXMLDOMComment_get_baseName(node_comment, &str); 2061 ok(r == S_FALSE, "ret %08x\n", r ); 2062 ok(str == NULL, "Expected NULL\n"); 2063 2064 IXMLDOMComment_Release( node_comment ); 2065 } 2066 2067 /* test Create Attribute */ 2068 str = SysAllocString(szAttribute); 2069 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL); 2070 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2071 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr); 2072 ok( r == S_OK, "returns %08x\n", r ); 2073 IXMLDOMAttribute_Release( node_attr); 2074 SysFreeString(str); 2075 2076 /* test Processing Instruction */ 2077 str = SysAllocStringLen(NULL, 0); 2078 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL); 2079 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2080 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI); 2081 ok( r == E_FAIL, "returns %08x\n", r ); 2082 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI); 2083 ok( r == E_FAIL, "returns %08x\n", r ); 2084 SysFreeString(str); 2085 2086 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI); 2087 ok( r == S_OK, "returns %08x\n", r ); 2088 if(nodePI) 2089 { 2090 /* Last Child Checks */ 2091 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL); 2092 ok(r == E_INVALIDARG, "ret %08x\n", r ); 2093 2094 nodeChild = (IXMLDOMNode*)0x1; 2095 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild); 2096 ok(r == S_FALSE, "ret %08x\n", r ); 2097 ok(nodeChild == NULL, "nodeChild not NULL\n"); 2098 2099 /* test nodeName */ 2100 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str); 2101 ok(r == S_OK, "ret %08x\n", r ); 2102 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n"); 2103 SysFreeString(str); 2104 2105 /* test baseName */ 2106 str = NULL; 2107 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str); 2108 ok(r == S_OK, "ret %08x\n", r ); 2109 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n"); 2110 SysFreeString(str); 2111 2112 /* test Target */ 2113 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str); 2114 ok(r == S_OK, "ret %08x\n", r ); 2115 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n"); 2116 SysFreeString(str); 2117 2118 /* test get_data */ 2119 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str); 2120 ok(r == S_OK, "ret %08x\n", r ); 2121 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n"); 2122 SysFreeString(str); 2123 2124 /* test put_data */ 2125 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\"")); 2126 ok(r == E_FAIL, "ret %08x\n", r ); 2127 2128 /* test put_data */ 2129 V_VT(&var) = VT_BSTR; 2130 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */ 2131 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var); 2132 ok(r == E_FAIL, "ret %08x\n", r ); 2133 VariantClear(&var); 2134 2135 /* test get nodeName */ 2136 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str); 2137 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n"); 2138 ok(r == S_OK, "ret %08x\n", r ); 2139 SysFreeString(str); 2140 2141 IXMLDOMProcessingInstruction_Release(nodePI); 2142 } 2143 2144 ref = IXMLDOMDocument_Release( doc ); 2145 ok( ref == 0, "got %d\n", ref); 2146 2147 free_bstrs(); 2148 } 2149 2150 static void test_persiststream(void) 2151 { 2152 IPersistStreamInit *streaminit; 2153 IPersistStream *stream; 2154 IXMLDOMDocument *doc; 2155 ULARGE_INTEGER size; 2156 IPersist *persist; 2157 HRESULT hr; 2158 CLSID clsid; 2159 2160 doc = create_document(&IID_IXMLDOMDocument); 2161 2162 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit); 2163 ok(hr == S_OK, "got 0x%08x\n", hr); 2164 2165 hr = IPersistStreamInit_InitNew(streaminit); 2166 ok(hr == S_OK, "got 0x%08x\n", hr); 2167 2168 hr = IPersistStreamInit_GetSizeMax(streaminit, &size); 2169 ok(hr == E_NOTIMPL, "got 0x%08x\n", hr); 2170 2171 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStream, (void **)&stream); 2172 ok(hr == S_OK, "got 0x%08x\n", hr); 2173 ok((IUnknown *)stream == (IUnknown *)streaminit, "got %p, %p\n", stream, streaminit); 2174 2175 hr = IPersistStream_QueryInterface(stream, &IID_IPersist, (void **)&persist); 2176 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); 2177 2178 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersist, (void **)&persist); 2179 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); 2180 2181 hr = IPersistStreamInit_GetClassID(streaminit, NULL); 2182 ok(hr == E_POINTER, "got 0x%08x\n", hr); 2183 2184 memset(&clsid, 0, sizeof(clsid)); 2185 hr = IPersistStreamInit_GetClassID(streaminit, &clsid); 2186 ok(hr == S_OK, "got 0x%08x\n", hr); 2187 ok(IsEqualGUID(&clsid, &CLSID_DOMDocument2), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); 2188 2189 IPersistStream_Release(stream); 2190 IPersistStreamInit_Release(streaminit); 2191 IXMLDOMDocument_Release(doc); 2192 } 2193 2194 static void test_domnode( void ) 2195 { 2196 HRESULT r; 2197 IXMLDOMDocument *doc, *owner = NULL; 2198 IXMLDOMElement *element = NULL; 2199 IXMLDOMNamedNodeMap *map = NULL; 2200 IXMLDOMNode *node = NULL, *next = NULL; 2201 IXMLDOMNodeList *list = NULL; 2202 IXMLDOMAttribute *attr = NULL; 2203 DOMNodeType type = NODE_INVALID; 2204 VARIANT_BOOL b; 2205 BSTR str; 2206 VARIANT var; 2207 LONG count; 2208 2209 doc = create_document(&IID_IXMLDOMDocument); 2210 2211 b = FALSE; 2212 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 2213 ok( r == S_OK, "loadXML failed\n"); 2214 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 2215 2216 EXPECT_CHILDREN(doc); 2217 2218 r = IXMLDOMDocument_get_documentElement( doc, &element ); 2219 ok( r == S_OK, "should be a document element\n"); 2220 ok( element != NULL, "should be an element\n"); 2221 2222 VariantInit(&var); 2223 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n"); 2224 2225 r = IXMLDOMDocument_get_nodeValue( doc, NULL ); 2226 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r ); 2227 2228 r = IXMLDOMDocument_get_nodeValue( doc, &var ); 2229 ok( r == S_FALSE, "nextNode returned wrong code\n"); 2230 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n"); 2231 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n"); 2232 2233 if (element) 2234 { 2235 owner = NULL; 2236 r = IXMLDOMElement_get_ownerDocument( element, &owner ); 2237 ok( r == S_OK, "get_ownerDocument return code\n"); 2238 ok( owner != doc, "get_ownerDocument return\n"); 2239 IXMLDOMDocument_Release(owner); 2240 2241 type = NODE_INVALID; 2242 r = IXMLDOMElement_get_nodeType( element, &type); 2243 ok( r == S_OK, "got %08x\n", r); 2244 ok( type == NODE_ELEMENT, "node not an element\n"); 2245 2246 str = NULL; 2247 r = IXMLDOMElement_get_baseName( element, &str ); 2248 ok( r == S_OK, "get_baseName returned wrong code\n"); 2249 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n"); 2250 SysFreeString(str); 2251 2252 /* check if nodename is correct */ 2253 r = IXMLDOMElement_get_nodeName( element, NULL ); 2254 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n"); 2255 2256 /* content doesn't matter here */ 2257 str = NULL; 2258 r = IXMLDOMElement_get_nodeName( element, &str ); 2259 ok ( r == S_OK, "get_nodeName wrong code\n"); 2260 ok ( str != NULL, "str is null\n"); 2261 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n"); 2262 SysFreeString( str ); 2263 2264 str = SysAllocString( nonexistent_fileW ); 2265 V_VT(&var) = VT_I4; 2266 V_I4(&var) = 0x1234; 2267 r = IXMLDOMElement_getAttribute( element, str, &var ); 2268 ok( r == E_FAIL, "getAttribute ret %08x\n", r ); 2269 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var)); 2270 VariantClear(&var); 2271 SysFreeString(str); 2272 2273 str = SysAllocString( szdl ); 2274 V_VT(&var) = VT_I4; 2275 V_I4(&var) = 0x1234; 2276 r = IXMLDOMElement_getAttribute( element, str, &var ); 2277 ok( r == S_OK, "getAttribute ret %08x\n", r ); 2278 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); 2279 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n"); 2280 VariantClear( &var ); 2281 2282 r = IXMLDOMElement_getAttribute( element, NULL, &var ); 2283 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r ); 2284 2285 r = IXMLDOMElement_getAttribute( element, str, NULL ); 2286 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r ); 2287 2288 attr = NULL; 2289 r = IXMLDOMElement_getAttributeNode( element, str, &attr); 2290 ok( r == S_OK, "GetAttributeNode ret %08x\n", r ); 2291 ok( attr != NULL, "getAttributeNode returned NULL\n" ); 2292 if (attr) 2293 { 2294 r = IXMLDOMAttribute_get_parentNode( attr, NULL ); 2295 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r ); 2296 2297 /* attribute doesn't have a parent in msxml interpretation */ 2298 node = (IXMLDOMNode*)0xdeadbeef; 2299 r = IXMLDOMAttribute_get_parentNode( attr, &node ); 2300 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r ); 2301 ok( node == NULL, "Expected NULL, got %p\n", node ); 2302 2303 IXMLDOMAttribute_Release(attr); 2304 } 2305 2306 SysFreeString( str ); 2307 2308 r = IXMLDOMElement_get_attributes( element, &map ); 2309 ok( r == S_OK, "get_attributes returned wrong code\n"); 2310 ok( map != NULL, "should be attributes\n"); 2311 2312 EXPECT_CHILDREN(element); 2313 } 2314 else 2315 ok( FALSE, "no element\n"); 2316 2317 if (map) 2318 { 2319 str = SysAllocString( szdl ); 2320 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node ); 2321 ok( r == S_OK, "getNamedItem returned wrong code\n"); 2322 ok( node != NULL, "should be attributes\n"); 2323 IXMLDOMNode_Release(node); 2324 SysFreeString( str ); 2325 2326 str = SysAllocString( szdl ); 2327 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL ); 2328 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n"); 2329 SysFreeString( str ); 2330 2331 /* something that isn't in complete4A */ 2332 str = SysAllocString( szOpen ); 2333 node = (IXMLDOMNode *) 1; 2334 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node ); 2335 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n"); 2336 ok( node == NULL, "getNamedItem should have returned NULL\n"); 2337 SysFreeString( str ); 2338 2339 /* test indexed access of attributes */ 2340 r = IXMLDOMNamedNodeMap_get_length( map, NULL ); 2341 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n"); 2342 2343 r = IXMLDOMNamedNodeMap_get_length( map, &count ); 2344 ok ( r == S_OK, "get_length wrong code\n"); 2345 ok ( count == 1, "get_length != 1\n"); 2346 2347 node = NULL; 2348 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node); 2349 ok ( r == S_FALSE, "get_item (-1) wrong code\n"); 2350 ok ( node == NULL, "there is no node\n"); 2351 2352 node = NULL; 2353 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node); 2354 ok ( r == S_FALSE, "get_item (1) wrong code\n"); 2355 ok ( node == NULL, "there is no attribute\n"); 2356 2357 node = NULL; 2358 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node); 2359 ok ( r == S_OK, "get_item (0) wrong code\n"); 2360 ok ( node != NULL, "should be attribute\n"); 2361 2362 r = IXMLDOMNode_get_nodeName( node, NULL ); 2363 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n"); 2364 2365 /* content doesn't matter here */ 2366 str = NULL; 2367 r = IXMLDOMNode_get_nodeName( node, &str ); 2368 ok ( r == S_OK, "get_nodeName wrong code\n"); 2369 ok ( str != NULL, "str is null\n"); 2370 ok( !lstrcmpW( str, szdl ), "incorrect node name\n"); 2371 SysFreeString( str ); 2372 IXMLDOMNode_Release( node ); 2373 2374 /* test sequential access of attributes */ 2375 node = NULL; 2376 r = IXMLDOMNamedNodeMap_nextNode( map, &node ); 2377 ok ( r == S_OK, "nextNode (first time) wrong code\n"); 2378 ok ( node != NULL, "nextNode, should be attribute\n"); 2379 IXMLDOMNode_Release( node ); 2380 2381 r = IXMLDOMNamedNodeMap_nextNode( map, &node ); 2382 ok ( r != S_OK, "nextNode (second time) wrong code\n"); 2383 ok ( node == NULL, "nextNode, there is no attribute\n"); 2384 2385 r = IXMLDOMNamedNodeMap_reset( map ); 2386 ok ( r == S_OK, "reset should return S_OK\n"); 2387 2388 r = IXMLDOMNamedNodeMap_nextNode( map, &node ); 2389 ok ( r == S_OK, "nextNode (third time) wrong code\n"); 2390 ok ( node != NULL, "nextNode, should be attribute\n"); 2391 } 2392 else 2393 ok( FALSE, "no map\n"); 2394 2395 if (node) 2396 { 2397 type = NODE_INVALID; 2398 r = IXMLDOMNode_get_nodeType( node, &type); 2399 ok( r == S_OK, "getNamedItem returned wrong code\n"); 2400 ok( type == NODE_ATTRIBUTE, "node not an attribute\n"); 2401 2402 str = NULL; 2403 r = IXMLDOMNode_get_baseName( node, NULL ); 2404 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n"); 2405 2406 str = NULL; 2407 r = IXMLDOMNode_get_baseName( node, &str ); 2408 ok( r == S_OK, "get_baseName returned wrong code\n"); 2409 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n"); 2410 SysFreeString( str ); 2411 2412 r = IXMLDOMNode_get_childNodes( node, NULL ); 2413 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n"); 2414 2415 r = IXMLDOMNode_get_childNodes( node, &list ); 2416 ok( r == S_OK, "get_childNodes returned wrong code\n"); 2417 2418 if (list) 2419 { 2420 r = IXMLDOMNodeList_nextNode( list, &next ); 2421 ok( r == S_OK, "nextNode returned wrong code\n"); 2422 } 2423 else 2424 ok( FALSE, "no childlist\n"); 2425 2426 if (next) 2427 { 2428 EXPECT_NO_CHILDREN(next); 2429 2430 type = NODE_INVALID; 2431 r = IXMLDOMNode_get_nodeType( next, &type); 2432 ok( r == S_OK, "getNamedItem returned wrong code\n"); 2433 ok( type == NODE_TEXT, "node not text\n"); 2434 2435 str = (void *)0xdeadbeef; 2436 r = IXMLDOMNode_get_baseName( next, &str ); 2437 ok( r == S_FALSE, "get_baseName returned wrong code\n"); 2438 ok( str == NULL, "basename was wrong\n"); 2439 SysFreeString(str); 2440 } 2441 else 2442 ok( FALSE, "no next\n"); 2443 2444 if (next) 2445 IXMLDOMNode_Release( next ); 2446 next = NULL; 2447 if (list) 2448 IXMLDOMNodeList_Release( list ); 2449 list = NULL; 2450 if (node) 2451 IXMLDOMNode_Release( node ); 2452 } 2453 else 2454 ok( FALSE, "no node\n"); 2455 node = NULL; 2456 2457 if (map) 2458 IXMLDOMNamedNodeMap_Release( map ); 2459 2460 /* now traverse the tree from the root element */ 2461 if (element) 2462 { 2463 r = IXMLDOMElement_get_childNodes( element, &list ); 2464 ok( r == S_OK, "get_childNodes returned wrong code\n"); 2465 2466 /* using get_item for child list doesn't advance the position */ 2467 ole_check(IXMLDOMNodeList_get_item(list, 1, &node)); 2468 expect_node(node, "E2.E2.D1"); 2469 IXMLDOMNode_Release(node); 2470 ole_check(IXMLDOMNodeList_nextNode(list, &node)); 2471 expect_node(node, "E1.E2.D1"); 2472 IXMLDOMNode_Release(node); 2473 ole_check(IXMLDOMNodeList_reset(list)); 2474 2475 IXMLDOMNodeList_AddRef(list); 2476 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1"); 2477 ole_check(IXMLDOMNodeList_reset(list)); 2478 2479 node = (void*)0xdeadbeef; 2480 str = SysAllocString(szdl); 2481 r = IXMLDOMElement_selectSingleNode( element, str, &node ); 2482 SysFreeString(str); 2483 ok( r == S_FALSE, "ret %08x\n", r ); 2484 ok( node == NULL, "node %p\n", node ); 2485 2486 str = SysAllocString(szbs); 2487 r = IXMLDOMElement_selectSingleNode( element, str, &node ); 2488 SysFreeString(str); 2489 ok( r == S_OK, "ret %08x\n", r ); 2490 r = IXMLDOMNode_Release( node ); 2491 ok( r == 0, "ret %08x\n", r ); 2492 } 2493 else 2494 ok( FALSE, "no element\n"); 2495 2496 if (list) 2497 { 2498 r = IXMLDOMNodeList_get_item(list, 0, NULL); 2499 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r); 2500 2501 r = IXMLDOMNodeList_get_length(list, NULL); 2502 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r); 2503 2504 r = IXMLDOMNodeList_get_length( list, &count ); 2505 ok( r == S_OK, "get_length returns %08x\n", r ); 2506 ok( count == 4, "get_length got %d\n", count ); 2507 2508 r = IXMLDOMNodeList_nextNode(list, NULL); 2509 ok(r == E_INVALIDARG, "Expected E_INVALIDARG got %08x\n", r); 2510 2511 r = IXMLDOMNodeList_nextNode( list, &node ); 2512 ok( r == S_OK, "nextNode returned wrong code\n"); 2513 } 2514 else 2515 ok( FALSE, "no list\n"); 2516 2517 if (node) 2518 { 2519 type = NODE_INVALID; 2520 r = IXMLDOMNode_get_nodeType( node, &type); 2521 ok( r == S_OK, "getNamedItem returned wrong code\n"); 2522 ok( type == NODE_ELEMENT, "node not text\n"); 2523 2524 r = IXMLDOMNode_hasChildNodes( node, NULL ); 2525 ok( r == E_INVALIDARG, "hasChildNodes bad return\n"); 2526 2527 EXPECT_CHILDREN(node); 2528 2529 str = NULL; 2530 r = IXMLDOMNode_get_baseName( node, &str ); 2531 ok( r == S_OK, "get_baseName returned wrong code\n"); 2532 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n"); 2533 SysFreeString(str); 2534 } 2535 else 2536 ok( FALSE, "no node\n"); 2537 2538 if (node) 2539 IXMLDOMNode_Release( node ); 2540 if (list) 2541 IXMLDOMNodeList_Release( list ); 2542 if (element) 2543 IXMLDOMElement_Release( element ); 2544 2545 b = FALSE; 2546 str = SysAllocString( szComplete5 ); 2547 r = IXMLDOMDocument_loadXML( doc, str, &b ); 2548 ok( r == S_OK, "loadXML failed\n"); 2549 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 2550 SysFreeString( str ); 2551 2552 EXPECT_CHILDREN(doc); 2553 2554 r = IXMLDOMDocument_get_documentElement( doc, &element ); 2555 ok( r == S_OK, "should be a document element\n"); 2556 ok( element != NULL, "should be an element\n"); 2557 2558 if (element) 2559 { 2560 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0}; 2561 BSTR tag = NULL; 2562 2563 /* check if the tag is correct */ 2564 r = IXMLDOMElement_get_tagName( element, &tag ); 2565 ok( r == S_OK, "couldn't get tag name\n"); 2566 ok( tag != NULL, "tag was null\n"); 2567 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n"); 2568 SysFreeString( tag ); 2569 2570 IXMLDOMElement_Release( element ); 2571 } 2572 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n"); 2573 2574 free_bstrs(); 2575 } 2576 2577 typedef struct { 2578 DOMNodeType type; 2579 REFIID iid; 2580 } refcount_test_t; 2581 2582 static const refcount_test_t refcount_test[] = { 2583 { NODE_ELEMENT, &IID_IXMLDOMElement }, 2584 { NODE_ATTRIBUTE, &IID_IXMLDOMAttribute }, 2585 { NODE_TEXT, &IID_IXMLDOMText }, 2586 { NODE_CDATA_SECTION, &IID_IXMLDOMCDATASection }, 2587 { NODE_ENTITY_REFERENCE, &IID_IXMLDOMEntityReference }, 2588 { NODE_PROCESSING_INSTRUCTION, &IID_IXMLDOMProcessingInstruction }, 2589 { NODE_COMMENT, &IID_IXMLDOMComment }, 2590 { NODE_DOCUMENT_FRAGMENT, &IID_IXMLDOMDocumentFragment }, 2591 { NODE_INVALID, &IID_NULL } 2592 }; 2593 2594 static void test_refs(void) 2595 { 2596 IXMLDOMImplementation *impl, *impl2; 2597 IXMLDOMElement *element, *elem2; 2598 IXMLDOMNodeList *node_list = NULL; 2599 IXMLDOMNode *node, *node2, *node3; 2600 const refcount_test_t *ptr; 2601 IXMLDOMDocument *doc; 2602 IUnknown *unk, *unk2; 2603 VARIANT_BOOL b; 2604 HRESULT hr; 2605 LONG ref; 2606 2607 doc = create_document(&IID_IXMLDOMDocument); 2608 2609 ptr = refcount_test; 2610 while (ptr->type != NODE_INVALID) 2611 { 2612 IUnknown *node_typed, *node_typed2; 2613 IDispatchEx *dispex, *dispex2; 2614 IDispatch *disp, *disp2; 2615 VARIANT type; 2616 2617 V_VT(&type) = VT_I1; 2618 V_I1(&type) = ptr->type; 2619 2620 EXPECT_REF(doc, 1); 2621 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("name"), NULL, &node); 2622 EXPECT_HR(hr, S_OK); 2623 EXPECT_REF(doc, 1); 2624 EXPECT_REF(node, 1); 2625 2626 /* try IDispatch and IUnknown from IXMLDOMNode */ 2627 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk); 2628 EXPECT_HR(hr, S_OK); 2629 EXPECT_REF(unk, 2); 2630 todo_wine { 2631 EXPECT_REF(node, 1); 2632 ok(unk != (IUnknown*)node, "%d: got %p and %p\n", ptr->type, unk, node); 2633 } 2634 EXPECT_REF(unk, 2); 2635 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp); 2636 EXPECT_HR(hr, S_OK); 2637 todo_wine ok(unk != (IUnknown*)disp, "%d: got %p and %p\n", ptr->type, unk, disp); 2638 EXPECT_REF(unk, 3); 2639 todo_wine EXPECT_REF(disp, 1); 2640 2641 EXPECT_REF(unk, 3); 2642 hr = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp2); 2643 EXPECT_HR(hr, S_OK); 2644 todo_wine ok(disp != disp2, "%d: got %p and %p\n", ptr->type, disp, disp2); 2645 EXPECT_REF(unk, 4); 2646 todo_wine EXPECT_REF(disp2, 1); 2647 2648 IDispatch_Release(disp); 2649 IDispatch_Release(disp2); 2650 2651 /* get IXMLDOMNode from this IUnknown */ 2652 EXPECT_REF(unk, 2); 2653 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node2); 2654 EXPECT_HR(hr, S_OK); 2655 todo_wine ok(unk != (IUnknown*)node2, "%d: got %p and %p\n", ptr->type, unk, node2); 2656 EXPECT_REF(unk, 3); 2657 todo_wine EXPECT_REF(node2, 1); 2658 2659 EXPECT_REF(unk, 3); 2660 hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMNode, (void**)&node3); 2661 EXPECT_HR(hr, S_OK); 2662 todo_wine ok(node2 != node3, "%d: got %p and %p\n", ptr->type, node2, node3); 2663 EXPECT_REF(unk, 4); 2664 todo_wine EXPECT_REF(node3, 1); 2665 2666 IXMLDOMNode_Release(node2); 2667 IXMLDOMNode_Release(node3); 2668 2669 /* try IDispatchEx from IUnknown */ 2670 EXPECT_REF(unk, 2); 2671 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex); 2672 EXPECT_HR(hr, S_OK); 2673 ok(unk != (IUnknown*)dispex, "%d: got %p and %p\n", ptr->type, unk, dispex); 2674 EXPECT_REF(unk, 3); 2675 todo_wine EXPECT_REF(dispex, 1); 2676 2677 EXPECT_REF(unk, 3); 2678 hr = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex2); 2679 EXPECT_HR(hr, S_OK); 2680 todo_wine ok(dispex != dispex2, "%d: got %p and %p\n", ptr->type, dispex, dispex2); 2681 EXPECT_REF(unk, 4); 2682 todo_wine EXPECT_REF(dispex2, 1); 2683 2684 IDispatchEx_Release(dispex); 2685 IDispatchEx_Release(dispex2); 2686 2687 /* try corresponding IXMLDOM* */ 2688 EXPECT_REF(unk, 2); 2689 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed); 2690 EXPECT_HR(hr, S_OK); 2691 EXPECT_REF(unk, 3); 2692 hr = IUnknown_QueryInterface(unk, ptr->iid, (void**)&node_typed2); 2693 EXPECT_HR(hr, S_OK); 2694 EXPECT_REF(unk, 4); 2695 todo_wine ok(node_typed != node_typed2, "%d: got %p and %p\n", ptr->type, node_typed, node_typed2); 2696 IUnknown_Release(node_typed); 2697 IUnknown_Release(node_typed2); 2698 2699 /* try invalid IXMLDOM* */ 2700 hr = IUnknown_QueryInterface(unk, (ptr+1)->iid, (void**)&node_typed); 2701 EXPECT_HR(hr, E_NOINTERFACE); 2702 2703 IUnknown_Release(unk); 2704 2705 EXPECT_REF(node, 1); 2706 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMNode, (void**)&node2); 2707 EXPECT_HR(hr, S_OK); 2708 EXPECT_REF(node, 2); 2709 ok(node == node2, "%d: got %p and %p\n", ptr->type, node, node2); 2710 2711 EXPECT_REF(node, 2); 2712 hr = IXMLDOMNode_QueryInterface(node, ptr->iid, (void**)&node_typed); 2713 EXPECT_HR(hr, S_OK); 2714 EXPECT_REF(node, 3); 2715 todo_wine { 2716 EXPECT_REF(node_typed, 2); 2717 ok((IUnknown*)node != node_typed, "%d: got %p and %p\n", ptr->type, node, node_typed); 2718 } 2719 IUnknown_Release(node_typed); 2720 2721 IXMLDOMNode_Release(node2); 2722 IXMLDOMNode_Release(node); 2723 2724 ptr++; 2725 } 2726 2727 EXPECT_REF(doc, 1); 2728 ref = IXMLDOMDocument_Release(doc); 2729 ok( ref == 0, "ref %d\n", ref); 2730 2731 /* check IUnknown after releasing DOM iface */ 2732 doc = create_document(&IID_IXMLDOMDocument); 2733 EXPECT_REF(doc, 1); 2734 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk); 2735 EXPECT_HR(hr, S_OK); 2736 todo_wine { 2737 EXPECT_REF(unk, 3); 2738 EXPECT_REF(doc, 1); 2739 } 2740 IXMLDOMDocument_Release(doc); 2741 EXPECT_REF(unk, 1); 2742 IUnknown_Release(unk); 2743 2744 doc = create_document(&IID_IXMLDOMDocument); 2745 2746 EXPECT_REF(doc, 1); 2747 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk); 2748 EXPECT_HR(hr, S_OK); 2749 todo_wine { 2750 EXPECT_REF(unk, 3); 2751 EXPECT_REF(doc, 1); 2752 } 2753 IUnknown_Release(unk); 2754 2755 /* IXMLDOMImplementation */ 2756 EXPECT_REF(doc, 1); 2757 hr = IXMLDOMDocument_get_implementation(doc, &impl); 2758 EXPECT_HR(hr, S_OK); 2759 EXPECT_REF(doc, 1); 2760 EXPECT_REF(impl, 1); 2761 hr = IXMLDOMDocument_get_implementation(doc, &impl2); 2762 EXPECT_HR(hr, S_OK); 2763 EXPECT_REF(doc, 1); 2764 EXPECT_REF(impl2, 1); 2765 ok(impl != impl2, "got %p, %p\n", impl, impl2); 2766 IXMLDOMImplementation_Release(impl); 2767 IXMLDOMImplementation_Release(impl2); 2768 2769 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 2770 EXPECT_HR(hr, S_OK); 2771 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 2772 2773 EXPECT_REF(doc, 1); 2774 IXMLDOMDocument_AddRef( doc ); 2775 EXPECT_REF(doc, 2); 2776 IXMLDOMDocument_AddRef( doc ); 2777 EXPECT_REF(doc, 3); 2778 2779 IXMLDOMDocument_Release( doc ); 2780 IXMLDOMDocument_Release( doc ); 2781 2782 EXPECT_REF(doc, 1); 2783 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk); 2784 EXPECT_HR(hr, S_OK); 2785 todo_wine { 2786 EXPECT_REF(unk, 3); 2787 EXPECT_REF(doc, 1); 2788 } 2789 hr = IXMLDOMDocument_get_documentElement(doc, &element); 2790 EXPECT_HR(hr, S_OK); 2791 todo_wine { 2792 EXPECT_REF(doc, 1); 2793 EXPECT_REF(element, 2); 2794 } 2795 hr = IXMLDOMDocument_get_documentElement(doc, &elem2); 2796 EXPECT_HR(hr, S_OK); 2797 2798 todo_wine { 2799 EXPECT_REF(doc, 1); 2800 EXPECT_REF(element, 2); 2801 EXPECT_REF(elem2, 2); 2802 } 2803 IXMLDOMElement_AddRef(element); 2804 todo_wine EXPECT_REF(element, 3); 2805 IXMLDOMElement_Release(element); 2806 2807 /* get IUnknown from a node doesn't touch node instance refcount */ 2808 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk); 2809 EXPECT_HR(hr, S_OK); 2810 EXPECT_REF(element, 2); 2811 todo_wine { 2812 EXPECT_REF(unk, 4); 2813 EXPECT_REF(elem2, 2); 2814 } 2815 hr = IXMLDOMElement_QueryInterface(elem2, &IID_IUnknown, (void**)&unk2); 2816 EXPECT_HR(hr, S_OK); 2817 todo_wine { 2818 EXPECT_REF(unk, 5); 2819 EXPECT_REF(unk2, 5); 2820 } 2821 EXPECT_REF(element, 2); 2822 EXPECT_REF(elem2, 2); 2823 2824 todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2); 2825 IUnknown_Release(unk); 2826 2827 /* IUnknown refcount is not affected by node refcount */ 2828 todo_wine EXPECT_REF(unk2, 4); 2829 IXMLDOMElement_AddRef(elem2); 2830 todo_wine EXPECT_REF(unk2, 4); 2831 IXMLDOMElement_Release(elem2); 2832 2833 IXMLDOMElement_Release(elem2); 2834 todo_wine EXPECT_REF(unk2, 3); 2835 2836 IUnknown_Release(unk2); 2837 2838 hr = IXMLDOMElement_get_childNodes( element, &node_list ); 2839 EXPECT_HR(hr, S_OK); 2840 2841 todo_wine EXPECT_REF(element, 2); 2842 EXPECT_REF(node_list, 1); 2843 2844 hr = IXMLDOMNodeList_get_item( node_list, 0, &node ); 2845 EXPECT_HR(hr, S_OK); 2846 EXPECT_REF(node_list, 1); 2847 EXPECT_REF(node, 1); 2848 2849 hr = IXMLDOMNodeList_get_item( node_list, 0, &node2 ); 2850 EXPECT_HR(hr, S_OK); 2851 EXPECT_REF(node_list, 1); 2852 EXPECT_REF(node2, 1); 2853 2854 ref = IXMLDOMNode_Release( node ); 2855 ok( ref == 0, "ref %d\n", ref ); 2856 ref = IXMLDOMNode_Release( node2 ); 2857 ok( ref == 0, "ref %d\n", ref ); 2858 2859 ref = IXMLDOMNodeList_Release( node_list ); 2860 ok( ref == 0, "ref %d\n", ref ); 2861 2862 ok( node != node2, "node %p node2 %p\n", node, node2 ); 2863 2864 ref = IXMLDOMDocument_Release( doc ); 2865 todo_wine ok( ref == 0, "ref %d\n", ref ); 2866 2867 todo_wine EXPECT_REF(element, 2); 2868 2869 /* IUnknown must be unique however we obtain it */ 2870 hr = IXMLDOMElement_QueryInterface(element, &IID_IUnknown, (void**)&unk); 2871 EXPECT_HR(hr, S_OK); 2872 EXPECT_REF(element, 2); 2873 hr = IXMLDOMElement_QueryInterface(element, &IID_IXMLDOMNode, (void**)&node); 2874 EXPECT_HR(hr, S_OK); 2875 todo_wine EXPECT_REF(element, 2); 2876 hr = IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk2); 2877 EXPECT_HR(hr, S_OK); 2878 todo_wine EXPECT_REF(element, 2); 2879 ok(unk == unk2, "unk %p unk2 %p\n", unk, unk2); 2880 todo_wine ok(element != (void*)node, "node %p element %p\n", node, element); 2881 2882 IUnknown_Release( unk2 ); 2883 IUnknown_Release( unk ); 2884 IXMLDOMNode_Release( node ); 2885 todo_wine EXPECT_REF(element, 2); 2886 2887 IXMLDOMElement_Release( element ); 2888 2889 free_bstrs(); 2890 } 2891 2892 static void test_create(void) 2893 { 2894 static const WCHAR szOne[] = {'1',0}; 2895 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0}; 2896 HRESULT r; 2897 VARIANT var; 2898 BSTR str, name; 2899 IXMLDOMDocument *doc; 2900 IXMLDOMElement *element; 2901 IXMLDOMComment *comment; 2902 IXMLDOMText *text; 2903 IXMLDOMCDATASection *cdata; 2904 IXMLDOMNode *root, *node, *child; 2905 IXMLDOMNamedNodeMap *attr_map; 2906 IUnknown *unk; 2907 LONG ref; 2908 LONG num; 2909 2910 doc = create_document(&IID_IXMLDOMDocument); 2911 2912 EXPECT_REF(doc, 1); 2913 2914 /* types not supported for creation */ 2915 V_VT(&var) = VT_I1; 2916 V_I1(&var) = NODE_DOCUMENT; 2917 node = (IXMLDOMNode*)0x1; 2918 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2919 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2920 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 2921 2922 V_VT(&var) = VT_I1; 2923 V_I1(&var) = NODE_DOCUMENT_TYPE; 2924 node = (IXMLDOMNode*)0x1; 2925 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2926 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2927 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 2928 2929 V_VT(&var) = VT_I1; 2930 V_I1(&var) = NODE_ENTITY; 2931 node = (IXMLDOMNode*)0x1; 2932 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2933 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2934 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 2935 2936 V_VT(&var) = VT_I1; 2937 V_I1(&var) = NODE_NOTATION; 2938 node = (IXMLDOMNode*)0x1; 2939 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2940 ok( r == E_INVALIDARG, "returns %08x\n", r ); 2941 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 2942 2943 /* NODE_COMMENT */ 2944 V_VT(&var) = VT_I1; 2945 V_I1(&var) = NODE_COMMENT; 2946 node = NULL; 2947 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2948 ok( r == S_OK, "returns %08x\n", r ); 2949 ok( node != NULL, "\n"); 2950 2951 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment); 2952 ok( r == S_OK, "returns %08x\n", r ); 2953 IXMLDOMNode_Release(node); 2954 2955 str = NULL; 2956 r = IXMLDOMComment_get_data(comment, &str); 2957 ok( r == S_OK, "returns %08x\n", r ); 2958 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 2959 IXMLDOMComment_Release(comment); 2960 SysFreeString(str); 2961 2962 node = (IXMLDOMNode*)0x1; 2963 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 2964 ok( r == S_OK, "returns %08x\n", r ); 2965 2966 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment); 2967 ok( r == S_OK, "returns %08x\n", r ); 2968 IXMLDOMNode_Release(node); 2969 2970 str = NULL; 2971 r = IXMLDOMComment_get_data(comment, &str); 2972 ok( r == S_OK, "returns %08x\n", r ); 2973 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 2974 IXMLDOMComment_Release(comment); 2975 SysFreeString(str); 2976 2977 node = (IXMLDOMNode*)0x1; 2978 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node ); 2979 ok( r == S_OK, "returns %08x\n", r ); 2980 2981 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment); 2982 ok( r == S_OK, "returns %08x\n", r ); 2983 IXMLDOMNode_Release(node); 2984 2985 str = NULL; 2986 r = IXMLDOMComment_get_data(comment, &str); 2987 ok( r == S_OK, "returns %08x\n", r ); 2988 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 2989 IXMLDOMComment_Release(comment); 2990 SysFreeString(str); 2991 2992 /* NODE_TEXT */ 2993 V_VT(&var) = VT_I1; 2994 V_I1(&var) = NODE_TEXT; 2995 node = NULL; 2996 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 2997 ok( r == S_OK, "returns %08x\n", r ); 2998 ok( node != NULL, "\n"); 2999 3000 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text); 3001 ok( r == S_OK, "returns %08x\n", r ); 3002 IXMLDOMNode_Release(node); 3003 3004 str = NULL; 3005 r = IXMLDOMText_get_data(text, &str); 3006 ok( r == S_OK, "returns %08x\n", r ); 3007 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3008 IXMLDOMText_Release(text); 3009 SysFreeString(str); 3010 3011 node = (IXMLDOMNode*)0x1; 3012 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3013 ok( r == S_OK, "returns %08x\n", r ); 3014 3015 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text); 3016 ok( r == S_OK, "returns %08x\n", r ); 3017 IXMLDOMNode_Release(node); 3018 3019 str = NULL; 3020 r = IXMLDOMText_get_data(text, &str); 3021 ok( r == S_OK, "returns %08x\n", r ); 3022 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3023 IXMLDOMText_Release(text); 3024 SysFreeString(str); 3025 3026 node = (IXMLDOMNode*)0x1; 3027 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node ); 3028 ok( r == S_OK, "returns %08x\n", r ); 3029 3030 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text); 3031 ok( r == S_OK, "returns %08x\n", r ); 3032 IXMLDOMNode_Release(node); 3033 3034 str = NULL; 3035 r = IXMLDOMText_get_data(text, &str); 3036 ok( r == S_OK, "returns %08x\n", r ); 3037 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3038 IXMLDOMText_Release(text); 3039 SysFreeString(str); 3040 3041 /* NODE_CDATA_SECTION */ 3042 V_VT(&var) = VT_I1; 3043 V_I1(&var) = NODE_CDATA_SECTION; 3044 node = NULL; 3045 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 3046 ok( r == S_OK, "returns %08x\n", r ); 3047 ok( node != NULL, "\n"); 3048 3049 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata); 3050 ok( r == S_OK, "returns %08x\n", r ); 3051 IXMLDOMNode_Release(node); 3052 3053 str = NULL; 3054 r = IXMLDOMCDATASection_get_data(cdata, &str); 3055 ok( r == S_OK, "returns %08x\n", r ); 3056 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3057 IXMLDOMCDATASection_Release(cdata); 3058 SysFreeString(str); 3059 3060 node = (IXMLDOMNode*)0x1; 3061 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3062 ok( r == S_OK, "returns %08x\n", r ); 3063 3064 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata); 3065 ok( r == S_OK, "returns %08x\n", r ); 3066 IXMLDOMNode_Release(node); 3067 3068 str = NULL; 3069 r = IXMLDOMCDATASection_get_data(cdata, &str); 3070 ok( r == S_OK, "returns %08x\n", r ); 3071 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3072 IXMLDOMCDATASection_Release(cdata); 3073 SysFreeString(str); 3074 3075 node = (IXMLDOMNode*)0x1; 3076 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node ); 3077 ok( r == S_OK, "returns %08x\n", r ); 3078 3079 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata); 3080 ok( r == S_OK, "returns %08x\n", r ); 3081 IXMLDOMNode_Release(node); 3082 3083 str = NULL; 3084 r = IXMLDOMCDATASection_get_data(cdata, &str); 3085 ok( r == S_OK, "returns %08x\n", r ); 3086 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str); 3087 IXMLDOMCDATASection_Release(cdata); 3088 SysFreeString(str); 3089 3090 /* NODE_ATTRIBUTE */ 3091 V_VT(&var) = VT_I1; 3092 V_I1(&var) = NODE_ATTRIBUTE; 3093 node = (IXMLDOMNode*)0x1; 3094 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 3095 ok( r == E_FAIL, "returns %08x\n", r ); 3096 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3097 3098 V_VT(&var) = VT_I1; 3099 V_I1(&var) = NODE_ATTRIBUTE; 3100 node = (IXMLDOMNode*)0x1; 3101 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3102 ok( r == E_FAIL, "returns %08x\n", r ); 3103 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3104 3105 V_VT(&var) = VT_I1; 3106 V_I1(&var) = NODE_ATTRIBUTE; 3107 str = SysAllocString( szlc ); 3108 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3109 ok( r == S_OK, "returns %08x\n", r ); 3110 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node ); 3111 SysFreeString(str); 3112 3113 /* a name is required for attribute, try a BSTR with first null wchar */ 3114 V_VT(&var) = VT_I1; 3115 V_I1(&var) = NODE_ATTRIBUTE; 3116 str = SysAllocString( szstr1 ); 3117 str[0] = 0; 3118 node = (IXMLDOMNode*)0x1; 3119 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3120 ok( r == E_FAIL, "returns %08x\n", r ); 3121 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3122 SysFreeString(str); 3123 3124 /* NODE_PROCESSING_INSTRUCTION */ 3125 V_VT(&var) = VT_I1; 3126 V_I1(&var) = NODE_PROCESSING_INSTRUCTION; 3127 node = (IXMLDOMNode*)0x1; 3128 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 3129 ok( r == E_FAIL, "returns %08x\n", r ); 3130 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3131 3132 V_VT(&var) = VT_I1; 3133 V_I1(&var) = NODE_PROCESSING_INSTRUCTION; 3134 node = (IXMLDOMNode*)0x1; 3135 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3136 ok( r == E_FAIL, "returns %08x\n", r ); 3137 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3138 3139 V_VT(&var) = VT_I1; 3140 V_I1(&var) = NODE_PROCESSING_INSTRUCTION; 3141 r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL ); 3142 ok( r == E_INVALIDARG, "returns %08x\n", r ); 3143 3144 /* NODE_ENTITY_REFERENCE */ 3145 V_VT(&var) = VT_I1; 3146 V_I1(&var) = NODE_ENTITY_REFERENCE; 3147 node = (IXMLDOMNode*)0x1; 3148 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 3149 ok( r == E_FAIL, "returns %08x\n", r ); 3150 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3151 3152 V_VT(&var) = VT_I1; 3153 V_I1(&var) = NODE_ENTITY_REFERENCE; 3154 node = (IXMLDOMNode*)0x1; 3155 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3156 ok( r == E_FAIL, "returns %08x\n", r ); 3157 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3158 3159 /* NODE_ELEMENT */ 3160 V_VT(&var) = VT_I1; 3161 V_I1(&var) = NODE_ELEMENT; 3162 node = (IXMLDOMNode*)0x1; 3163 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node ); 3164 ok( r == E_FAIL, "returns %08x\n", r ); 3165 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3166 3167 V_VT(&var) = VT_I1; 3168 V_I1(&var) = NODE_ELEMENT; 3169 node = (IXMLDOMNode*)0x1; 3170 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node ); 3171 ok( r == E_FAIL, "returns %08x\n", r ); 3172 ok( node == (void*)0x1, "expected same ptr, got %p\n", node); 3173 3174 V_VT(&var) = VT_I1; 3175 V_I1(&var) = NODE_ELEMENT; 3176 str = SysAllocString( szlc ); 3177 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3178 ok( r == S_OK, "returns %08x\n", r ); 3179 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node ); 3180 3181 V_VT(&var) = VT_I1; 3182 V_I1(&var) = NODE_ELEMENT; 3183 r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL ); 3184 ok( r == E_INVALIDARG, "returns %08x\n", r ); 3185 3186 V_VT(&var) = VT_R4; 3187 V_R4(&var) = NODE_ELEMENT; 3188 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3189 ok( r == S_OK, "returns %08x\n", r ); 3190 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node ); 3191 3192 V_VT(&var) = VT_BSTR; 3193 V_BSTR(&var) = SysAllocString( szOne ); 3194 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3195 ok( r == S_OK, "returns %08x\n", r ); 3196 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node ); 3197 VariantClear(&var); 3198 3199 V_VT(&var) = VT_BSTR; 3200 V_BSTR(&var) = SysAllocString( szOneGarbage ); 3201 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3202 ok( r == E_INVALIDARG, "returns %08x\n", r ); 3203 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node ); 3204 VariantClear(&var); 3205 3206 V_VT(&var) = VT_I4; 3207 V_I4(&var) = NODE_ELEMENT; 3208 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3209 ok( r == S_OK, "returns %08x\n", r ); 3210 3211 EXPECT_REF(doc, 1); 3212 r = IXMLDOMDocument_appendChild( doc, node, &root ); 3213 ok( r == S_OK, "returns %08x\n", r ); 3214 ok( node == root, "%p %p\n", node, root ); 3215 EXPECT_REF(doc, 1); 3216 3217 EXPECT_REF(node, 2); 3218 3219 ref = IXMLDOMNode_Release( node ); 3220 ok(ref == 1, "ref %d\n", ref); 3221 SysFreeString( str ); 3222 3223 V_VT(&var) = VT_I4; 3224 V_I4(&var) = NODE_ELEMENT; 3225 str = SysAllocString( szbs ); 3226 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3227 ok( r == S_OK, "returns %08x\n", r ); 3228 SysFreeString( str ); 3229 3230 EXPECT_REF(node, 1); 3231 3232 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk ); 3233 ok( r == S_OK, "returns %08x\n", r ); 3234 3235 EXPECT_REF(unk, 2); 3236 3237 V_VT(&var) = VT_EMPTY; 3238 child = NULL; 3239 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child ); 3240 ok( r == S_OK, "returns %08x\n", r ); 3241 ok( unk == (IUnknown*)child, "%p %p\n", unk, child ); 3242 3243 todo_wine EXPECT_REF(unk, 4); 3244 3245 IXMLDOMNode_Release( child ); 3246 IUnknown_Release( unk ); 3247 3248 V_VT(&var) = VT_NULL; 3249 V_DISPATCH(&var) = (IDispatch*)node; 3250 r = IXMLDOMNode_insertBefore( root, node, var, &child ); 3251 ok( r == S_OK, "returns %08x\n", r ); 3252 ok( node == child, "%p %p\n", node, child ); 3253 IXMLDOMNode_Release( child ); 3254 3255 V_VT(&var) = VT_NULL; 3256 V_DISPATCH(&var) = (IDispatch*)node; 3257 r = IXMLDOMNode_insertBefore( root, node, var, NULL ); 3258 ok( r == S_OK, "returns %08x\n", r ); 3259 IXMLDOMNode_Release( node ); 3260 3261 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element ); 3262 ok( r == S_OK, "returns %08x\n", r ); 3263 3264 r = IXMLDOMElement_get_attributes( element, &attr_map ); 3265 ok( r == S_OK, "returns %08x\n", r ); 3266 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num ); 3267 ok( r == S_OK, "returns %08x\n", r ); 3268 ok( num == 0, "num %d\n", num ); 3269 IXMLDOMNamedNodeMap_Release( attr_map ); 3270 3271 V_VT(&var) = VT_BSTR; 3272 V_BSTR(&var) = SysAllocString( szstr1 ); 3273 name = SysAllocString( szdl ); 3274 r = IXMLDOMElement_setAttribute( element, name, var ); 3275 ok( r == S_OK, "returns %08x\n", r ); 3276 r = IXMLDOMElement_get_attributes( element, &attr_map ); 3277 ok( r == S_OK, "returns %08x\n", r ); 3278 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num ); 3279 ok( r == S_OK, "returns %08x\n", r ); 3280 ok( num == 1, "num %d\n", num ); 3281 IXMLDOMNamedNodeMap_Release( attr_map ); 3282 VariantClear(&var); 3283 3284 V_VT(&var) = VT_BSTR; 3285 V_BSTR(&var) = SysAllocString( szstr2 ); 3286 r = IXMLDOMElement_setAttribute( element, name, var ); 3287 ok( r == S_OK, "returns %08x\n", r ); 3288 r = IXMLDOMElement_get_attributes( element, &attr_map ); 3289 ok( r == S_OK, "returns %08x\n", r ); 3290 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num ); 3291 ok( r == S_OK, "returns %08x\n", r ); 3292 ok( num == 1, "num %d\n", num ); 3293 IXMLDOMNamedNodeMap_Release( attr_map ); 3294 VariantClear(&var); 3295 r = IXMLDOMElement_getAttribute( element, name, &var ); 3296 ok( r == S_OK, "returns %08x\n", r ); 3297 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n"); 3298 VariantClear(&var); 3299 SysFreeString(name); 3300 3301 V_VT(&var) = VT_BSTR; 3302 V_BSTR(&var) = SysAllocString( szstr1 ); 3303 name = SysAllocString( szlc ); 3304 r = IXMLDOMElement_setAttribute( element, name, var ); 3305 ok( r == S_OK, "returns %08x\n", r ); 3306 r = IXMLDOMElement_get_attributes( element, &attr_map ); 3307 ok( r == S_OK, "returns %08x\n", r ); 3308 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num ); 3309 ok( r == S_OK, "returns %08x\n", r ); 3310 ok( num == 2, "num %d\n", num ); 3311 IXMLDOMNamedNodeMap_Release( attr_map ); 3312 VariantClear(&var); 3313 SysFreeString(name); 3314 3315 V_VT(&var) = VT_I4; 3316 V_I4(&var) = 10; 3317 name = SysAllocString( szbs ); 3318 r = IXMLDOMElement_setAttribute( element, name, var ); 3319 ok( r == S_OK, "returns %08x\n", r ); 3320 VariantClear(&var); 3321 r = IXMLDOMElement_getAttribute( element, name, &var ); 3322 ok( r == S_OK, "returns %08x\n", r ); 3323 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var)); 3324 VariantClear(&var); 3325 SysFreeString(name); 3326 3327 /* Create an Attribute */ 3328 V_VT(&var) = VT_I4; 3329 V_I4(&var) = NODE_ATTRIBUTE; 3330 str = SysAllocString( szAttribute ); 3331 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node ); 3332 ok( r == S_OK, "returns %08x\n", r ); 3333 ok( node != NULL, "node was null\n"); 3334 SysFreeString(str); 3335 3336 IXMLDOMElement_Release( element ); 3337 IXMLDOMNode_Release( root ); 3338 IXMLDOMDocument_Release( doc ); 3339 } 3340 3341 struct queryresult_t { 3342 const char *query; 3343 const char *result; 3344 int len; 3345 }; 3346 3347 static const struct queryresult_t elementsbytagname[] = { 3348 { "", "P1.D1 E2.D1 E1.E2.D1 T1.E1.E2.D1 E2.E2.D1 T1.E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1 T1.E1.E4.E2.D1", 10 }, 3349 { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 }, 3350 { "bs", "E1.E2.D1", 1 }, 3351 { "dl", "", 0 }, 3352 { "str1","", 0 }, 3353 { NULL } 3354 }; 3355 3356 static void test_getElementsByTagName(void) 3357 { 3358 const struct queryresult_t *ptr = elementsbytagname; 3359 IXMLDOMNodeList *node_list; 3360 IXMLDOMDocument *doc; 3361 IXMLDOMElement *elem; 3362 WCHAR buff[100]; 3363 VARIANT_BOOL b; 3364 HRESULT r; 3365 LONG len; 3366 BSTR str; 3367 3368 doc = create_document(&IID_IXMLDOMDocument); 3369 3370 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3371 ok( r == S_OK, "loadXML failed\n"); 3372 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3373 3374 /* null arguments cases */ 3375 r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list); 3376 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3377 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL); 3378 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3379 3380 while (ptr->query) 3381 { 3382 r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list); 3383 ok(r == S_OK, "ret %08x\n", r); 3384 r = IXMLDOMNodeList_get_length(node_list, &len); 3385 ok(r == S_OK, "ret %08x\n", r); 3386 ok(len == ptr->len, "%s: got len %d, expected %d\n", ptr->query, len, ptr->len); 3387 expect_list_and_release(node_list, ptr->result); 3388 3389 free_bstrs(); 3390 ptr++; 3391 } 3392 3393 /* broken query BSTR */ 3394 memcpy(&buff[2], szstar, sizeof(szstar)); 3395 /* just a big length */ 3396 *(DWORD*)buff = 0xf0f0; 3397 r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list); 3398 ok( r == S_OK, "ret %08x\n", r ); 3399 r = IXMLDOMNodeList_get_length( node_list, &len ); 3400 ok( r == S_OK, "ret %08x\n", r ); 3401 ok( len == 6, "len %d\n", len ); 3402 IXMLDOMNodeList_Release( node_list ); 3403 3404 /* test for element */ 3405 r = IXMLDOMDocument_get_documentElement(doc, &elem); 3406 ok( r == S_OK, "ret %08x\n", r ); 3407 3408 str = SysAllocString( szstar ); 3409 3410 /* null arguments cases */ 3411 r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list); 3412 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3413 r = IXMLDOMElement_getElementsByTagName(elem, str, NULL); 3414 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3415 3416 r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list); 3417 ok( r == S_OK, "ret %08x\n", r ); 3418 r = IXMLDOMNodeList_get_length( node_list, &len ); 3419 ok( r == S_OK, "ret %08x\n", r ); 3420 ok( len == 5, "len %d\n", len ); 3421 expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1"); 3422 SysFreeString( str ); 3423 3424 /* broken query BSTR */ 3425 memcpy(&buff[2], szstar, sizeof(szstar)); 3426 /* just a big length */ 3427 *(DWORD*)buff = 0xf0f0; 3428 r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list); 3429 ok( r == S_OK, "ret %08x\n", r ); 3430 r = IXMLDOMNodeList_get_length( node_list, &len ); 3431 ok( r == S_OK, "ret %08x\n", r ); 3432 ok( len == 5, "len %d\n", len ); 3433 IXMLDOMNodeList_Release( node_list ); 3434 3435 IXMLDOMElement_Release(elem); 3436 3437 IXMLDOMDocument_Release( doc ); 3438 3439 free_bstrs(); 3440 } 3441 3442 static void test_get_text(void) 3443 { 3444 HRESULT r; 3445 BSTR str; 3446 VARIANT_BOOL b; 3447 IXMLDOMDocument *doc; 3448 IXMLDOMNode *node, *node2, *node3; 3449 IXMLDOMNode *nodeRoot; 3450 IXMLDOMNodeList *node_list; 3451 IXMLDOMNamedNodeMap *node_map; 3452 LONG len; 3453 3454 doc = create_document(&IID_IXMLDOMDocument); 3455 3456 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3457 ok( r == S_OK, "loadXML failed\n"); 3458 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3459 3460 str = SysAllocString( szbs ); 3461 r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list ); 3462 ok( r == S_OK, "ret %08x\n", r ); 3463 SysFreeString(str); 3464 3465 /* Test to get all child node text. */ 3466 r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot); 3467 ok( r == S_OK, "ret %08x\n", r ); 3468 if(r == S_OK) 3469 { 3470 r = IXMLDOMNode_get_text( nodeRoot, &str ); 3471 ok( r == S_OK, "ret %08x\n", r ); 3472 expect_bstr_eq_and_free(str, "fn1.txt\n \nfn2.txt\n \nf1"); 3473 3474 IXMLDOMNode_Release(nodeRoot); 3475 } 3476 3477 r = IXMLDOMNodeList_get_length( node_list, NULL ); 3478 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3479 3480 r = IXMLDOMNodeList_get_length( node_list, &len ); 3481 ok( r == S_OK, "ret %08x\n", r ); 3482 ok( len == 1, "expect 1 got %d\n", len ); 3483 3484 r = IXMLDOMNodeList_get_item( node_list, 0, NULL ); 3485 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3486 3487 r = IXMLDOMNodeList_nextNode( node_list, NULL ); 3488 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3489 3490 r = IXMLDOMNodeList_get_item( node_list, 0, &node ); 3491 ok( r == S_OK, "ret %08x\n", r ); 3492 IXMLDOMNodeList_Release( node_list ); 3493 3494 /* Invalid output parameter*/ 3495 r = IXMLDOMNode_get_text( node, NULL ); 3496 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3497 3498 r = IXMLDOMNode_get_text( node, &str ); 3499 ok( r == S_OK, "ret %08x\n", r ); 3500 ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" ); 3501 SysFreeString(str); 3502 3503 r = IXMLDOMNode_get_attributes( node, &node_map ); 3504 ok( r == S_OK, "ret %08x\n", r ); 3505 3506 str = SysAllocString( szvr ); 3507 r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 ); 3508 ok( r == S_OK, "ret %08x\n", r ); 3509 SysFreeString(str); 3510 3511 r = IXMLDOMNode_get_text( node2, &str ); 3512 ok( r == S_OK, "ret %08x\n", r ); 3513 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" ); 3514 SysFreeString(str); 3515 3516 r = IXMLDOMNode_get_firstChild( node2, &node3 ); 3517 ok( r == S_OK, "ret %08x\n", r ); 3518 3519 r = IXMLDOMNode_get_text( node3, &str ); 3520 ok( r == S_OK, "ret %08x\n", r ); 3521 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" ); 3522 SysFreeString(str); 3523 3524 3525 IXMLDOMNode_Release( node3 ); 3526 IXMLDOMNode_Release( node2 ); 3527 IXMLDOMNamedNodeMap_Release( node_map ); 3528 IXMLDOMNode_Release( node ); 3529 IXMLDOMDocument_Release( doc ); 3530 3531 free_bstrs(); 3532 } 3533 3534 #ifdef __REACTOS__ 3535 /* 3536 * This function is to display that xmlnodelist_QueryInterface 3537 * generates SEGV for these conditions, and once fixed make sure 3538 * it never does it again. 3539 */ 3540 static void verify_nodelist_query_interface(IXMLDOMNodeList *node_list) 3541 { 3542 HRESULT hr; 3543 /* 3544 * NOTE: The following calls are supposed to test wine's 3545 * xmlnodelist_QueryInterface behaving properly. 3546 * While we should be able to expect E_POINTER (due to the NULL pointer), 3547 * it seems MS' own implementation(s) violate the spec and return 3548 * E_INVALIDARG. To not get cought be a potentially correct implementation 3549 * in the future, we check for NOT S_OK. 3550 */ 3551 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, NULL); 3552 EXPECT_NOT_HR(hr, S_OK); 3553 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatch, NULL); 3554 EXPECT_NOT_HR(hr, S_OK); 3555 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IXMLDOMNodeList, NULL); 3556 EXPECT_NOT_HR(hr, S_OK); 3557 } 3558 #endif 3559 3560 static void test_get_childNodes(void) 3561 { 3562 IXMLDOMNodeList *node_list, *node_list2; 3563 IEnumVARIANT *enum1, *enum2, *enum3; 3564 VARIANT_BOOL b; 3565 IXMLDOMDocument *doc; 3566 IXMLDOMNode *node, *node2; 3567 IXMLDOMElement *element; 3568 IUnknown *unk1, *unk2; 3569 HRESULT hr; 3570 VARIANT v; 3571 BSTR str; 3572 LONG len; 3573 3574 doc = create_document(&IID_IXMLDOMDocument); 3575 3576 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3577 EXPECT_HR(hr, S_OK); 3578 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3579 3580 hr = IXMLDOMDocument_get_documentElement( doc, &element ); 3581 EXPECT_HR(hr, S_OK); 3582 3583 hr = IXMLDOMElement_get_childNodes( element, &node_list ); 3584 EXPECT_HR(hr, S_OK); 3585 3586 #ifdef __REACTOS__ 3587 verify_nodelist_query_interface(node_list); 3588 #endif 3589 3590 hr = IXMLDOMNodeList_get_length( node_list, &len ); 3591 EXPECT_HR(hr, S_OK); 3592 ok( len == 4, "len %d\n", len); 3593 3594 /* refcount tests for IEnumVARIANT support */ 3595 EXPECT_REF(node_list, 1); 3596 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1); 3597 EXPECT_HR(hr, S_OK); 3598 EXPECT_REF(node_list, 1); 3599 EXPECT_REF(enum1, 2); 3600 3601 EXPECT_REF(node_list, 1); 3602 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2); 3603 EXPECT_HR(hr, S_OK); 3604 EXPECT_REF(node_list, 1); 3605 ok(enum2 == enum1, "got %p, %p\n", enum2, enum1); 3606 IEnumVARIANT_Release(enum2); 3607 3608 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1); 3609 EXPECT_HR(hr, S_OK); 3610 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2); 3611 EXPECT_HR(hr, S_OK); 3612 EXPECT_REF(node_list, 3); 3613 EXPECT_REF(enum1, 2); 3614 ok(unk1 == unk2, "got %p, %p\n", unk1, unk2); 3615 IUnknown_Release(unk1); 3616 IUnknown_Release(unk2); 3617 3618 EXPECT_REF(node_list, 1); 3619 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2); 3620 EXPECT_HR(hr, S_OK); 3621 EXPECT_REF(node_list, 2); 3622 EXPECT_REF(enum2, 1); 3623 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1); 3624 3625 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */ 3626 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1); 3627 EXPECT_HR(hr, S_OK); 3628 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2); 3629 EXPECT_HR(hr, S_OK); 3630 EXPECT_REF(node_list, 3); 3631 EXPECT_REF(enum2, 2); 3632 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2); 3633 IUnknown_Release(unk1); 3634 IUnknown_Release(unk2); 3635 3636 hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3); 3637 EXPECT_HR(hr, S_OK); 3638 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3); 3639 IEnumVARIANT_Release(enum3); 3640 IEnumVARIANT_Release(enum2); 3641 3642 /* iteration tests */ 3643 hr = IXMLDOMNodeList_get_item(node_list, 0, &node); 3644 EXPECT_HR(hr, S_OK); 3645 hr = IXMLDOMNode_get_nodeName(node, &str); 3646 EXPECT_HR(hr, S_OK); 3647 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str)); 3648 SysFreeString(str); 3649 IXMLDOMNode_Release(node); 3650 3651 hr = IXMLDOMNodeList_nextNode(node_list, &node); 3652 EXPECT_HR(hr, S_OK); 3653 hr = IXMLDOMNode_get_nodeName(node, &str); 3654 EXPECT_HR(hr, S_OK); 3655 ok(!lstrcmpW(str, _bstr_("bs")), "got %s\n", wine_dbgstr_w(str)); 3656 SysFreeString(str); 3657 IXMLDOMNode_Release(node); 3658 3659 V_VT(&v) = VT_EMPTY; 3660 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); 3661 EXPECT_HR(hr, S_OK); 3662 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); 3663 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); 3664 EXPECT_HR(hr, S_OK); 3665 hr = IXMLDOMNode_get_nodeName(node, &str); 3666 EXPECT_HR(hr, S_OK); 3667 ok(!lstrcmpW(str, _bstr_("bs")), "got node name %s\n", wine_dbgstr_w(str)); 3668 SysFreeString(str); 3669 IXMLDOMNode_Release(node); 3670 VariantClear(&v); 3671 3672 hr = IXMLDOMNodeList_nextNode(node_list, &node); 3673 EXPECT_HR(hr, S_OK); 3674 hr = IXMLDOMNode_get_nodeName(node, &str); 3675 EXPECT_HR(hr, S_OK); 3676 ok(!lstrcmpW(str, _bstr_("pr")), "got %s\n", wine_dbgstr_w(str)); 3677 SysFreeString(str); 3678 IXMLDOMNode_Release(node); 3679 3680 IEnumVARIANT_Release(enum1); 3681 3682 hr = IXMLDOMNodeList_get_item( node_list, 2, &node ); 3683 EXPECT_HR(hr, S_OK); 3684 3685 hr = IXMLDOMNode_get_childNodes( node, &node_list2 ); 3686 EXPECT_HR(hr, S_OK); 3687 3688 hr = IXMLDOMNodeList_get_length( node_list2, &len ); 3689 EXPECT_HR(hr, S_OK); 3690 ok( len == 0, "len %d\n", len); 3691 3692 hr = IXMLDOMNodeList_get_item( node_list2, 0, &node2); 3693 EXPECT_HR(hr, S_FALSE); 3694 3695 IXMLDOMNodeList_Release( node_list2 ); 3696 IXMLDOMNode_Release( node ); 3697 IXMLDOMNodeList_Release( node_list ); 3698 IXMLDOMElement_Release( element ); 3699 3700 /* test for children of <?xml ..?> node */ 3701 hr = IXMLDOMDocument_get_firstChild(doc, &node); 3702 EXPECT_HR(hr, S_OK); 3703 3704 str = NULL; 3705 hr = IXMLDOMNode_get_nodeName(node, &str); 3706 EXPECT_HR(hr, S_OK); 3707 ok(!lstrcmpW(str, _bstr_("xml")), "got %s\n", wine_dbgstr_w(str)); 3708 SysFreeString(str); 3709 3710 /* it returns empty but valid node list */ 3711 node_list = (void*)0xdeadbeef; 3712 hr = IXMLDOMNode_get_childNodes(node, &node_list); 3713 EXPECT_HR(hr, S_OK); 3714 3715 len = -1; 3716 hr = IXMLDOMNodeList_get_length(node_list, &len); 3717 EXPECT_HR(hr, S_OK); 3718 ok(len == 0, "got %d\n", len); 3719 3720 IXMLDOMNodeList_Release( node_list ); 3721 IXMLDOMNode_Release(node); 3722 3723 IXMLDOMDocument_Release( doc ); 3724 free_bstrs(); 3725 } 3726 3727 static void test_get_firstChild(void) 3728 { 3729 static const WCHAR xmlW[] = {'x','m','l',0}; 3730 IXMLDOMDocument *doc; 3731 IXMLDOMNode *node; 3732 VARIANT_BOOL b; 3733 HRESULT r; 3734 BSTR str; 3735 3736 doc = create_document(&IID_IXMLDOMDocument); 3737 3738 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3739 ok( r == S_OK, "loadXML failed\n"); 3740 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3741 3742 r = IXMLDOMDocument_get_firstChild( doc, &node ); 3743 ok( r == S_OK, "ret %08x\n", r); 3744 3745 r = IXMLDOMNode_get_nodeName( node, &str ); 3746 ok( r == S_OK, "ret %08x\n", r); 3747 3748 ok(!lstrcmpW(str, xmlW), "expected \"xml\" node name, got %s\n", wine_dbgstr_w(str)); 3749 3750 SysFreeString(str); 3751 IXMLDOMNode_Release( node ); 3752 IXMLDOMDocument_Release( doc ); 3753 3754 free_bstrs(); 3755 } 3756 3757 static void test_get_lastChild(void) 3758 { 3759 static const WCHAR lcW[] = {'l','c',0}; 3760 static const WCHAR foW[] = {'f','o',0}; 3761 IXMLDOMDocument *doc; 3762 IXMLDOMNode *node, *child; 3763 VARIANT_BOOL b; 3764 HRESULT r; 3765 BSTR str; 3766 3767 doc = create_document(&IID_IXMLDOMDocument); 3768 3769 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3770 ok( r == S_OK, "loadXML failed\n"); 3771 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3772 3773 r = IXMLDOMDocument_get_lastChild( doc, &node ); 3774 ok( r == S_OK, "ret %08x\n", r); 3775 3776 r = IXMLDOMNode_get_nodeName( node, &str ); 3777 ok( r == S_OK, "ret %08x\n", r); 3778 3779 ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n"); 3780 SysFreeString(str); 3781 3782 r = IXMLDOMNode_get_lastChild( node, &child ); 3783 ok( r == S_OK, "ret %08x\n", r); 3784 3785 r = IXMLDOMNode_get_nodeName( child, &str ); 3786 ok( r == S_OK, "ret %08x\n", r); 3787 3788 ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n"); 3789 SysFreeString(str); 3790 3791 IXMLDOMNode_Release( child ); 3792 IXMLDOMNode_Release( node ); 3793 IXMLDOMDocument_Release( doc ); 3794 3795 free_bstrs(); 3796 } 3797 3798 static void test_removeChild(void) 3799 { 3800 HRESULT r; 3801 VARIANT_BOOL b; 3802 IXMLDOMDocument *doc; 3803 IXMLDOMElement *element, *lc_element; 3804 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node; 3805 IXMLDOMNodeList *root_list, *fo_list; 3806 3807 doc = create_document(&IID_IXMLDOMDocument); 3808 3809 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3810 ok( r == S_OK, "loadXML failed\n"); 3811 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3812 3813 r = IXMLDOMDocument_get_documentElement( doc, &element ); 3814 ok( r == S_OK, "ret %08x\n", r); 3815 todo_wine EXPECT_REF(element, 2); 3816 3817 r = IXMLDOMElement_get_childNodes( element, &root_list ); 3818 ok( r == S_OK, "ret %08x\n", r); 3819 EXPECT_REF(root_list, 1); 3820 3821 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node ); 3822 ok( r == S_OK, "ret %08x\n", r); 3823 EXPECT_REF(fo_node, 1); 3824 3825 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list ); 3826 ok( r == S_OK, "ret %08x\n", r); 3827 EXPECT_REF(fo_list, 1); 3828 3829 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node ); 3830 ok( r == S_OK, "ret %08x\n", r); 3831 EXPECT_REF(ba_node, 1); 3832 3833 /* invalid parameter: NULL ptr */ 3834 removed_node = (void*)0xdeadbeef; 3835 r = IXMLDOMElement_removeChild( element, NULL, &removed_node ); 3836 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3837 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node ); 3838 3839 /* ba_node is a descendant of element, but not a direct child. */ 3840 removed_node = (void*)0xdeadbeef; 3841 EXPECT_REF(ba_node, 1); 3842 EXPECT_CHILDREN(fo_node); 3843 r = IXMLDOMElement_removeChild( element, ba_node, &removed_node ); 3844 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3845 ok( removed_node == NULL, "%p\n", removed_node ); 3846 EXPECT_REF(ba_node, 1); 3847 EXPECT_CHILDREN(fo_node); 3848 3849 EXPECT_REF(ba_node, 1); 3850 EXPECT_REF(fo_node, 1); 3851 r = IXMLDOMElement_removeChild( element, fo_node, &removed_node ); 3852 ok( r == S_OK, "ret %08x\n", r); 3853 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node ); 3854 EXPECT_REF(fo_node, 2); 3855 EXPECT_REF(ba_node, 1); 3856 3857 /* try removing already removed child */ 3858 temp_node = (void*)0xdeadbeef; 3859 r = IXMLDOMElement_removeChild( element, fo_node, &temp_node ); 3860 ok( r == E_INVALIDARG, "ret %08x\n", r); 3861 ok( temp_node == NULL, "%p\n", temp_node ); 3862 IXMLDOMNode_Release( fo_node ); 3863 3864 /* the removed node has no parent anymore */ 3865 r = IXMLDOMNode_get_parentNode( removed_node, &temp_node ); 3866 ok( r == S_FALSE, "ret %08x\n", r); 3867 ok( temp_node == NULL, "%p\n", temp_node ); 3868 3869 IXMLDOMNode_Release( removed_node ); 3870 IXMLDOMNode_Release( ba_node ); 3871 IXMLDOMNodeList_Release( fo_list ); 3872 3873 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node ); 3874 ok( r == S_OK, "ret %08x\n", r); 3875 3876 r = IXMLDOMNode_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element ); 3877 ok( r == S_OK, "ret %08x\n", r); 3878 3879 /* MS quirk: passing wrong interface pointer works, too */ 3880 r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL ); 3881 ok( r == S_OK, "ret %08x\n", r); 3882 IXMLDOMElement_Release( lc_element ); 3883 3884 temp_node = (void*)0xdeadbeef; 3885 r = IXMLDOMNode_get_parentNode( lc_node, &temp_node ); 3886 ok( r == S_FALSE, "ret %08x\n", r); 3887 ok( temp_node == NULL, "%p\n", temp_node ); 3888 3889 IXMLDOMNode_Release( lc_node ); 3890 IXMLDOMNodeList_Release( root_list ); 3891 IXMLDOMElement_Release( element ); 3892 IXMLDOMDocument_Release( doc ); 3893 3894 free_bstrs(); 3895 } 3896 3897 static void test_replaceChild(void) 3898 { 3899 HRESULT r; 3900 VARIANT_BOOL b; 3901 IXMLDOMDocument *doc; 3902 IXMLDOMElement *element, *ba_element; 3903 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node; 3904 IXMLDOMNodeList *root_list, *fo_list; 3905 IUnknown * unk1, *unk2; 3906 LONG len; 3907 3908 doc = create_document(&IID_IXMLDOMDocument); 3909 3910 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 3911 ok( r == S_OK, "loadXML failed\n"); 3912 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 3913 3914 r = IXMLDOMDocument_get_documentElement( doc, &element ); 3915 ok( r == S_OK, "ret %08x\n", r); 3916 3917 r = IXMLDOMElement_get_childNodes( element, &root_list ); 3918 ok( r == S_OK, "ret %08x\n", r); 3919 3920 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node ); 3921 ok( r == S_OK, "ret %08x\n", r); 3922 3923 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node ); 3924 ok( r == S_OK, "ret %08x\n", r); 3925 3926 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list ); 3927 ok( r == S_OK, "ret %08x\n", r); 3928 3929 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node ); 3930 ok( r == S_OK, "ret %08x\n", r); 3931 3932 IXMLDOMNodeList_Release( fo_list ); 3933 3934 /* invalid parameter: NULL ptr for element to remove */ 3935 removed_node = (void*)0xdeadbeef; 3936 r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node ); 3937 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3938 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node ); 3939 3940 /* invalid parameter: NULL for replacement element. (Sic!) */ 3941 removed_node = (void*)0xdeadbeef; 3942 r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node ); 3943 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3944 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node ); 3945 3946 /* invalid parameter: OldNode is not a child */ 3947 removed_node = (void*)0xdeadbeef; 3948 r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node ); 3949 ok( r == E_INVALIDARG, "ret %08x\n", r ); 3950 ok( removed_node == NULL, "%p\n", removed_node ); 3951 IXMLDOMNode_Release( lc_node ); 3952 3953 /* invalid parameter: would create loop */ 3954 removed_node = (void*)0xdeadbeef; 3955 r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node ); 3956 ok( r == E_FAIL, "ret %08x\n", r ); 3957 ok( removed_node == NULL, "%p\n", removed_node ); 3958 3959 r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL ); 3960 ok( r == S_OK, "ret %08x\n", r ); 3961 3962 r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node ); 3963 ok( r == S_OK, "ret %08x\n", r ); 3964 3965 /* ba_node and temp_node refer to the same node, yet they 3966 are different interface pointers */ 3967 ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node); 3968 r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1); 3969 ok( r == S_OK, "ret %08x\n", r ); 3970 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2); 3971 ok( r == S_OK, "ret %08x\n", r ); 3972 todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2); 3973 3974 IUnknown_Release( unk1 ); 3975 IUnknown_Release( unk2 ); 3976 3977 /* ba_node should have been removed from below fo_node */ 3978 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list ); 3979 ok( r == S_OK, "ret %08x\n", r ); 3980 3981 /* MS quirk: replaceChild also accepts elements instead of nodes */ 3982 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element); 3983 ok( r == S_OK, "ret %08x\n", r ); 3984 EXPECT_REF(ba_element, 2); 3985 3986 removed_node = NULL; 3987 r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node ); 3988 ok( r == S_OK, "ret %08x\n", r ); 3989 ok( removed_node != NULL, "got %p\n", removed_node); 3990 EXPECT_REF(ba_element, 3); 3991 IXMLDOMElement_Release( ba_element ); 3992 3993 r = IXMLDOMNodeList_get_length( fo_list, &len); 3994 ok( r == S_OK, "ret %08x\n", r ); 3995 ok( len == 0, "len %d\n", len); 3996 3997 IXMLDOMNodeList_Release( fo_list ); 3998 3999 IXMLDOMNode_Release(ba_node); 4000 IXMLDOMNode_Release(fo_node); 4001 IXMLDOMNode_Release(temp_node); 4002 IXMLDOMNodeList_Release( root_list ); 4003 IXMLDOMElement_Release( element ); 4004 IXMLDOMDocument_Release( doc ); 4005 4006 free_bstrs(); 4007 } 4008 4009 static void test_removeNamedItem(void) 4010 { 4011 IXMLDOMDocument *doc; 4012 IXMLDOMElement *element; 4013 IXMLDOMNode *pr_node, *removed_node, *removed_node2; 4014 IXMLDOMNodeList *root_list; 4015 IXMLDOMNamedNodeMap * pr_attrs; 4016 VARIANT_BOOL b; 4017 BSTR str; 4018 LONG len; 4019 HRESULT r; 4020 4021 doc = create_document(&IID_IXMLDOMDocument); 4022 4023 r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 4024 ok( r == S_OK, "loadXML failed\n"); 4025 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4026 4027 r = IXMLDOMDocument_get_documentElement( doc, &element ); 4028 ok( r == S_OK, "ret %08x\n", r); 4029 4030 r = IXMLDOMElement_get_childNodes( element, &root_list ); 4031 ok( r == S_OK, "ret %08x\n", r); 4032 4033 r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node ); 4034 ok( r == S_OK, "ret %08x\n", r); 4035 4036 r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs ); 4037 ok( r == S_OK, "ret %08x\n", r); 4038 4039 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len ); 4040 ok( r == S_OK, "ret %08x\n", r); 4041 ok( len == 3, "length %d\n", len); 4042 4043 removed_node = (void*)0xdeadbeef; 4044 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node); 4045 ok ( r == E_INVALIDARG, "ret %08x\n", r); 4046 ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node); 4047 4048 removed_node = (void*)0xdeadbeef; 4049 str = SysAllocString(szvr); 4050 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node); 4051 ok ( r == S_OK, "ret %08x\n", r); 4052 4053 removed_node2 = (void*)0xdeadbeef; 4054 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2); 4055 ok ( r == S_FALSE, "ret %08x\n", r); 4056 ok ( removed_node2 == NULL, "got %p\n", removed_node2 ); 4057 4058 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len ); 4059 ok( r == S_OK, "ret %08x\n", r); 4060 ok( len == 2, "length %d\n", len); 4061 4062 r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL); 4063 ok ( r == S_OK, "ret %08x\n", r); 4064 IXMLDOMNode_Release(removed_node); 4065 4066 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len ); 4067 ok( r == S_OK, "ret %08x\n", r); 4068 ok( len == 3, "length %d\n", len); 4069 4070 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL); 4071 ok ( r == S_OK, "ret %08x\n", r); 4072 4073 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len ); 4074 ok( r == S_OK, "ret %08x\n", r); 4075 ok( len == 2, "length %d\n", len); 4076 4077 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL); 4078 ok ( r == S_FALSE, "ret %08x\n", r); 4079 4080 SysFreeString(str); 4081 4082 IXMLDOMNamedNodeMap_Release( pr_attrs ); 4083 IXMLDOMNode_Release( pr_node ); 4084 IXMLDOMNodeList_Release( root_list ); 4085 IXMLDOMElement_Release( element ); 4086 IXMLDOMDocument_Release( doc ); 4087 4088 free_bstrs(); 4089 } 4090 4091 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2) 4092 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result, 4093 HRESULT result2, DWORD set, DWORD mask, DWORD expected, 4094 DWORD expected2) 4095 { 4096 DWORD enabled, supported; 4097 HRESULT hr; 4098 4099 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask); 4100 if (result == result2) 4101 ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr ); 4102 else 4103 ok_(__FILE__,line)(broken(hr == result) || hr == result2, 4104 "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr ); 4105 4106 supported = enabled = 0xCAFECAFE; 4107 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); 4108 ok(hr == S_OK, "ret %08x\n", hr ); 4109 if (expected == expected2) 4110 ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled); 4111 else 4112 ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2, 4113 "Expected %08x, got %08x\n", expected2, enabled); 4114 4115 /* reset the safety options */ 4116 4117 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, 4118 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER, 4119 0); 4120 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4121 4122 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); 4123 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4124 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled); 4125 } 4126 4127 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s) 4128 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety) 4129 { 4130 DWORD enabled = 0, supported = 0; 4131 HRESULT hr; 4132 4133 /* get */ 4134 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled); 4135 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr ); 4136 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL); 4137 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr ); 4138 4139 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); 4140 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4141 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) || 4142 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */, 4143 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), " 4144 "got %08x\n", supported); 4145 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled); 4146 4147 /* set -- individual flags */ 4148 4149 test_IObjectSafety_set(safety, S_OK, S_OK, 4150 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER, 4151 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER); 4152 4153 test_IObjectSafety_set(safety, S_OK, S_OK, 4154 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA, 4155 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA); 4156 4157 test_IObjectSafety_set(safety, S_OK, S_OK, 4158 INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER, 4159 0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */); 4160 4161 /* set INTERFACE_USES_DISPEX */ 4162 4163 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */, 4164 INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX, 4165 0, 0); 4166 4167 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */, 4168 INTERFACE_USES_DISPEX, 0, 4169 0, 0); 4170 4171 test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */, 4172 0, INTERFACE_USES_DISPEX, 4173 0, 0); 4174 4175 /* set option masking */ 4176 4177 test_IObjectSafety_set(safety, S_OK, S_OK, 4178 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA, 4179 INTERFACESAFE_FOR_UNTRUSTED_CALLER, 4180 INTERFACESAFE_FOR_UNTRUSTED_CALLER, 4181 INTERFACESAFE_FOR_UNTRUSTED_CALLER); 4182 4183 test_IObjectSafety_set(safety, S_OK, S_OK, 4184 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA, 4185 INTERFACESAFE_FOR_UNTRUSTED_DATA, 4186 INTERFACESAFE_FOR_UNTRUSTED_DATA, 4187 INTERFACESAFE_FOR_UNTRUSTED_DATA); 4188 4189 test_IObjectSafety_set(safety, S_OK, S_OK, 4190 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA, 4191 INTERFACE_USES_SECURITY_MANAGER, 4192 0, 4193 0); 4194 4195 /* set -- inheriting previous settings */ 4196 4197 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, 4198 INTERFACESAFE_FOR_UNTRUSTED_CALLER, 4199 INTERFACESAFE_FOR_UNTRUSTED_CALLER); 4200 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4201 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); 4202 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4203 ok_(__FILE__,line)(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER, "Expected INTERFACESAFE_FOR_UNTRUSTED_CALLER got %08x\n", enabled); 4204 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) || 4205 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */, 4206 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), " 4207 "got %08x\n", supported); 4208 4209 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, 4210 INTERFACESAFE_FOR_UNTRUSTED_DATA, 4211 INTERFACESAFE_FOR_UNTRUSTED_DATA); 4212 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4213 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); 4214 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr ); 4215 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) || 4216 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA), 4217 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) got %08x\n", enabled); 4218 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) || 4219 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */, 4220 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), " 4221 "got %08x\n", supported); 4222 } 4223 4224 static void test_IXMLDOMDocument2(void) 4225 { 4226 static const WCHAR emptyW[] = {0}; 4227 IXMLDOMDocument2 *doc2, *dtddoc2; 4228 IXMLDOMDocument *doc; 4229 IXMLDOMParseError* err; 4230 IDispatchEx *dispex; 4231 VARIANT_BOOL b; 4232 VARIANT var; 4233 HRESULT r; 4234 LONG res; 4235 4236 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return; 4237 4238 doc = create_document(&IID_IXMLDOMDocument); 4239 dtddoc2 = create_document(&IID_IXMLDOMDocument2); 4240 4241 r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 ); 4242 ok( r == S_OK, "ret %08x\n", r ); 4243 ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n"); 4244 4245 ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG); 4246 ole_check(IXMLDOMDocument2_get_readyState(doc2, &res)); 4247 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res); 4248 4249 err = NULL; 4250 ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE); 4251 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE); 4252 ok(err != NULL, "expected a pointer\n"); 4253 if (err) 4254 { 4255 res = 0; 4256 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4257 /* XML_E_NOTWF */ 4258 ok(res == E_XML_NOTWF, "got %08x\n", res); 4259 IXMLDOMParseError_Release(err); 4260 } 4261 4262 r = IXMLDOMDocument2_loadXML( doc2, _bstr_(complete4A), &b ); 4263 ok( r == S_OK, "loadXML failed\n"); 4264 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4265 4266 ole_check(IXMLDOMDocument_get_readyState(doc, &res)); 4267 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res); 4268 4269 err = NULL; 4270 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE); 4271 ok(err != NULL, "expected a pointer\n"); 4272 if (err) 4273 { 4274 res = 0; 4275 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4276 /* XML_E_NODTD */ 4277 ok(res == E_XML_NODTD, "got %08x\n", res); 4278 IXMLDOMParseError_Release(err); 4279 } 4280 4281 r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex ); 4282 ok( r == S_OK, "ret %08x\n", r ); 4283 if(r == S_OK) 4284 { 4285 IDispatchEx_Release(dispex); 4286 } 4287 4288 /* we will check if the variant got cleared */ 4289 IXMLDOMDocument2_AddRef(doc2); 4290 EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/ 4291 4292 V_VT(&var) = VT_UNKNOWN; 4293 V_UNKNOWN(&var) = (IUnknown *)doc2; 4294 4295 /* invalid calls */ 4296 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL); 4297 expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x"); 4298 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG); 4299 4300 /* valid call */ 4301 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var)); 4302 expect_eq(V_VT(&var), VT_BSTR, int, "%x"); 4303 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern"); 4304 V_VT(&var) = VT_R4; 4305 4306 /* the variant didn't get cleared*/ 4307 expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d"); 4308 4309 /* setProperty tests */ 4310 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL); 4311 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL); 4312 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL); 4313 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"))); 4314 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); 4315 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"))); 4316 4317 V_VT(&var) = VT_BSTR; 4318 V_BSTR(&var) = SysAllocString(emptyW); 4319 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var); 4320 ok(r == S_OK, "got 0x%08x\n", r); 4321 VariantClear(&var); 4322 4323 V_VT(&var) = VT_I2; 4324 V_I2(&var) = 0; 4325 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var); 4326 ok(r == E_FAIL, "got 0x%08x\n", r); 4327 4328 /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */ 4329 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var)); 4330 expect_eq(V_VT(&var), VT_BSTR, int, "%x"); 4331 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern"); 4332 4333 IXMLDOMDocument2_Release( doc2 ); 4334 IXMLDOMDocument_Release( doc ); 4335 4336 /* DTD validation */ 4337 ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE)); 4338 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b)); 4339 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4340 err = NULL; 4341 ole_check(IXMLDOMDocument2_validate(dtddoc2, &err)); 4342 ok(err != NULL, "expected pointer\n"); 4343 if (err) 4344 { 4345 res = 0; 4346 ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE); 4347 ok(res == 0, "got %08x\n", res); 4348 IXMLDOMParseError_Release(err); 4349 } 4350 4351 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b)); 4352 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4353 err = NULL; 4354 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4355 ok(err != NULL, "expected pointer\n"); 4356 if (err) 4357 { 4358 res = 0; 4359 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4360 /* XML_ELEMENT_UNDECLARED */ 4361 todo_wine ok(res == 0xC00CE00D, "got %08x\n", res); 4362 IXMLDOMParseError_Release(err); 4363 } 4364 4365 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b)); 4366 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4367 err = NULL; 4368 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4369 ok(err != NULL, "expected pointer\n"); 4370 if (err) 4371 { 4372 res = 0; 4373 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4374 /* XML_ELEMENT_ID_NOT_FOUND */ 4375 todo_wine ok(res == 0xC00CE00E, "got %08x\n", res); 4376 IXMLDOMParseError_Release(err); 4377 } 4378 4379 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b)); 4380 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4381 err = NULL; 4382 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4383 ok(err != NULL, "expected pointer\n"); 4384 if (err) 4385 { 4386 res = 0; 4387 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4388 /* XML_EMPTY_NOT_ALLOWED */ 4389 todo_wine ok(res == 0xC00CE011, "got %08x\n", res); 4390 IXMLDOMParseError_Release(err); 4391 } 4392 4393 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b)); 4394 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4395 err = NULL; 4396 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4397 ok(err != NULL, "expected pointer\n"); 4398 if (err) 4399 { 4400 res = 0; 4401 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4402 /* XML_ROOT_NAME_MISMATCH */ 4403 todo_wine ok(res == 0xC00CE013, "got %08x\n", res); 4404 IXMLDOMParseError_Release(err); 4405 } 4406 4407 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b)); 4408 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4409 err = NULL; 4410 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4411 ok(err != NULL, "expected pointer\n"); 4412 if (err) 4413 { 4414 res = 0; 4415 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4416 /* XML_INVALID_CONTENT */ 4417 todo_wine ok(res == 0xC00CE014, "got %08x\n", res); 4418 IXMLDOMParseError_Release(err); 4419 } 4420 4421 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b)); 4422 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4423 err = NULL; 4424 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4425 ok(err != NULL, "expected pointer\n"); 4426 if (err) 4427 { 4428 res = 0; 4429 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4430 /* XML_ATTRIBUTE_NOT_DEFINED */ 4431 todo_wine ok(res == 0xC00CE015, "got %08x\n", res); 4432 IXMLDOMParseError_Release(err); 4433 } 4434 4435 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b)); 4436 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4437 err = NULL; 4438 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4439 ok(err != NULL, "expected pointer\n"); 4440 if (err) 4441 { 4442 res = 0; 4443 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4444 /* XML_ATTRIBUTE_FIXED */ 4445 todo_wine ok(res == 0xC00CE016, "got %08x\n", res); 4446 IXMLDOMParseError_Release(err); 4447 } 4448 4449 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b)); 4450 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4451 err = NULL; 4452 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4453 ok(err != NULL, "expected pointer\n"); 4454 if (err) 4455 { 4456 res = 0; 4457 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4458 /* XML_ATTRIBUTE_VALUE */ 4459 todo_wine ok(res == 0xC00CE017, "got %08x\n", res); 4460 IXMLDOMParseError_Release(err); 4461 } 4462 4463 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b)); 4464 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4465 err = NULL; 4466 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4467 ok(err != NULL, "expected pointer\n"); 4468 if (err) 4469 { 4470 res = 0; 4471 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4472 /* XML_ILLEGAL_TEXT */ 4473 todo_wine ok(res == 0xC00CE018, "got %08x\n", res); 4474 IXMLDOMParseError_Release(err); 4475 } 4476 4477 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b)); 4478 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 4479 err = NULL; 4480 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE); 4481 ok(err != NULL, "expected pointer\n"); 4482 if (err) 4483 { 4484 res = 0; 4485 ole_check(IXMLDOMParseError_get_errorCode(err, &res)); 4486 /* XML_REQUIRED_ATTRIBUTE_MISSING */ 4487 todo_wine ok(res == 0xC00CE020, "got %08x\n", res); 4488 IXMLDOMParseError_Release(err); 4489 } 4490 4491 IXMLDOMDocument2_Release( dtddoc2 ); 4492 free_bstrs(); 4493 } 4494 4495 #define helper_ole_check(expr) { \ 4496 HRESULT r = expr; \ 4497 ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \ 4498 } 4499 4500 #define helper_ole_check_ver(expr) { \ 4501 HRESULT r = expr; \ 4502 ok_(__FILE__, line)(r == S_OK, "-> %i (%s): " #expr " returned %08x\n", __LINE__, ver, r); \ 4503 } 4504 4505 #define helper_expect_list_and_release(list, expstr) { \ 4506 char *str = list_to_string(list); \ 4507 ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i (%s): Invalid node list: %s, expected %s\n", __LINE__, ver, str, expstr); \ 4508 if (list) IXMLDOMNodeList_Release(list); \ 4509 } 4510 4511 #define helper_expect_bstr_and_release(bstr, str) { \ 4512 ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \ 4513 "=> %i (%s): got %s\n", __LINE__, ver, wine_dbgstr_w(bstr)); \ 4514 SysFreeString(bstr); \ 4515 } 4516 4517 #define check_ws_ignored(ver, doc, str) _check_ws_ignored(__LINE__, ver, doc, str) 4518 static inline void _check_ws_ignored(int line, const char *ver, IXMLDOMDocument2* doc, char const* str) 4519 { 4520 IXMLDOMNode *node1, *node2; 4521 IXMLDOMNodeList *list; 4522 BSTR bstr; 4523 4524 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list)); 4525 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1)); 4526 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2)); 4527 helper_ole_check_ver(IXMLDOMNodeList_reset(list)); 4528 helper_expect_list_and_release(list, "E1.E5.E1.E2.D1 E2.E5.E1.E2.D1"); 4529 4530 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list)); 4531 helper_expect_list_and_release(list, 4532 "[4]1.E1.E5.E1.E2.D1 T2.E1.E5.E1.E2.D1 E3.E1.E5.E1.E2.D1 " 4533 "E4.E1.E5.E1.E2.D1 E5.E1.E5.E1.E2.D1 E6.E1.E5.E1.E2.D1"); 4534 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr)); 4535 if (str) 4536 { 4537 helper_expect_bstr_and_release(bstr, str); 4538 } 4539 else 4540 { 4541 helper_expect_bstr_and_release(bstr, " This is a description."); 4542 } 4543 IXMLDOMNode_Release(node1); 4544 4545 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list)); 4546 helper_expect_list_and_release(list, 4547 "T1.E2.E5.E1.E2.D1 E2.E2.E5.E1.E2.D1 T3.E2.E5.E1.E2.D1 " 4548 "E4.E2.E5.E1.E2.D1 T5.E2.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1 T7.E2.E5.E1.E2.D1"); 4549 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr)); 4550 helper_expect_bstr_and_release(bstr, 4551 "\n This is a description with preserved whitespace. \n "); 4552 IXMLDOMNode_Release(node2); 4553 } 4554 4555 #define check_ws_preserved(ver, doc, str) _check_ws_preserved(__LINE__, ver, doc, str) 4556 static inline void _check_ws_preserved(int line, const char *ver, IXMLDOMDocument2* doc, char const* str) 4557 { 4558 IXMLDOMNode *node1, *node2; 4559 IXMLDOMNodeList *list; 4560 BSTR bstr; 4561 4562 helper_ole_check_ver(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list)); 4563 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 0, &node1)); 4564 helper_ole_check_ver(IXMLDOMNodeList_get_item(list, 1, &node2)); 4565 helper_ole_check_ver(IXMLDOMNodeList_reset(list)); 4566 helper_expect_list_and_release(list, "E2.E10.E2.E2.D1 E4.E10.E2.E2.D1"); 4567 4568 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node1, &list)); 4569 helper_expect_list_and_release(list, 4570 "T1.E2.E10.E2.E2.D1 [4]2.E2.E10.E2.E2.D1 T3.E2.E10.E2.E2.D1 " 4571 "E4.E2.E10.E2.E2.D1 T5.E2.E10.E2.E2.D1 E6.E2.E10.E2.E2.D1 " 4572 "E7.E2.E10.E2.E2.D1 E8.E2.E10.E2.E2.D1 T9.E2.E10.E2.E2.D1"); 4573 helper_ole_check_ver(IXMLDOMNode_get_text(node1, &bstr)); 4574 if (str) 4575 { 4576 helper_expect_bstr_and_release(bstr, str); 4577 } 4578 else 4579 { 4580 helper_expect_bstr_and_release(bstr, "\n This is a description. \n "); 4581 } 4582 IXMLDOMNode_Release(node1); 4583 4584 helper_ole_check_ver(IXMLDOMNode_get_childNodes(node2, &list)); 4585 helper_expect_list_and_release(list, 4586 "T1.E4.E10.E2.E2.D1 E2.E4.E10.E2.E2.D1 T3.E4.E10.E2.E2.D1 " 4587 "E4.E4.E10.E2.E2.D1 T5.E4.E10.E2.E2.D1 E6.E4.E10.E2.E2.D1 T7.E4.E10.E2.E2.D1"); 4588 helper_ole_check_ver(IXMLDOMNode_get_text(node2, &bstr)); 4589 helper_expect_bstr_and_release(bstr, 4590 "\n This is a description with preserved whitespace. \n "); 4591 IXMLDOMNode_Release(node2); 4592 } 4593 4594 static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve) 4595 { 4596 static const WCHAR b1_p[] = {' ','T','e','x','t',' ','A',' ','e','n','d',' ',0}; 4597 static const WCHAR b1_i[] = {'T','e','x','t',' ','A',' ','e','n','d',0}; 4598 static const WCHAR b2_p[] = {'A','B',' ','C',' ',0}; 4599 static const WCHAR b2_i[] = {'A','B',' ','C',0}; 4600 IXMLDOMNodeList *list; 4601 IXMLDOMElement *root; 4602 IXMLDOMNode *node; 4603 const WCHAR *text; 4604 VARIANT_BOOL b; 4605 HRESULT hr; 4606 BSTR s; 4607 4608 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, preserve); 4609 ok(hr == S_OK, "got 0x%08x\n", hr); 4610 4611 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(charrefsxml), &b); 4612 ok(hr == S_OK, "got 0x%08x\n", hr); 4613 4614 hr = IXMLDOMDocument2_get_documentElement(doc, &root); 4615 ok(hr == S_OK, "got 0x%08x\n", hr); 4616 4617 hr = IXMLDOMElement_get_childNodes(root, &list); 4618 ok(hr == S_OK, "got 0x%08x\n", hr); 4619 IXMLDOMElement_Release(root); 4620 4621 text = preserve == VARIANT_TRUE ? b1_p : b1_i; 4622 hr = IXMLDOMNodeList_get_item(list, 0, &node); 4623 ok(hr == S_OK, "got 0x%08x\n", hr); 4624 hr = IXMLDOMNode_get_text(node, &s); 4625 ok(hr == S_OK, "got 0x%08x\n", hr); 4626 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s)); 4627 SysFreeString(s); 4628 IXMLDOMNode_Release(node); 4629 4630 text = preserve == VARIANT_TRUE ? b2_p : b2_i; 4631 hr = IXMLDOMNodeList_get_item(list, 1, &node); 4632 ok(hr == S_OK, "got 0x%08x\n", hr); 4633 hr = IXMLDOMNode_get_text(node, &s); 4634 ok(hr == S_OK, "got 0x%08x\n", hr); 4635 ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s)); 4636 SysFreeString(s); 4637 IXMLDOMNode_Release(node); 4638 4639 IXMLDOMNodeList_Release(list); 4640 } 4641 4642 struct whitespace_t { 4643 const CLSID *clsid; 4644 const char *name; 4645 }; 4646 4647 static const struct whitespace_t whitespace_test_data[] = { 4648 { &CLSID_DOMDocument, "CLSID_DOMDocument" }, 4649 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" }, 4650 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" }, 4651 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" }, 4652 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" }, 4653 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" }, 4654 { 0 } 4655 }; 4656 4657 static void test_whitespace(void) 4658 { 4659 const struct whitespace_t *class_ptr = whitespace_test_data; 4660 4661 while (class_ptr->clsid) 4662 { 4663 IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4; 4664 IXMLDOMNodeList *list; 4665 IXMLDOMElement *root; 4666 VARIANT_BOOL b; 4667 HRESULT hr; 4668 LONG len; 4669 4670 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument2)) 4671 { 4672 class_ptr++; 4673 continue; 4674 } 4675 4676 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, 4677 &IID_IXMLDOMDocument2, (void**)&doc1); 4678 ok(hr == S_OK, "got 0x%08x\n", hr); 4679 4680 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, 4681 &IID_IXMLDOMDocument2, (void**)&doc2); 4682 ok(hr == S_OK, "got 0x%08x\n", hr); 4683 4684 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE)); 4685 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b)); 4686 ok(b == VARIANT_FALSE, "expected false\n"); 4687 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b)); 4688 ok(b == VARIANT_TRUE, "expected true\n"); 4689 4690 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b)); 4691 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 4692 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b)); 4693 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 4694 4695 /* switch to XPath */ 4696 ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); 4697 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); 4698 4699 check_ws_ignored(class_ptr->name, doc1, NULL); 4700 check_ws_preserved(class_ptr->name, doc2, NULL); 4701 4702 /* new instances copy the property */ 4703 ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3)); 4704 ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4)); 4705 4706 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b)); 4707 ok(b == VARIANT_FALSE, "expected false\n"); 4708 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b)); 4709 ok(b == VARIANT_TRUE, "expected true\n"); 4710 4711 check_ws_ignored(class_ptr->name, doc3, NULL); 4712 check_ws_preserved(class_ptr->name, doc4, NULL); 4713 4714 /* setting after loading xml affects trimming of leading/trailing ws only */ 4715 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE)); 4716 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE)); 4717 4718 /* the trailing "\n " isn't there, because it was ws-only node */ 4719 check_ws_ignored(class_ptr->name, doc1, " This is a description. "); 4720 check_ws_preserved(class_ptr->name, doc2, " This is a description."); 4721 4722 /* it takes effect on reload */ 4723 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b)); 4724 ok(b == VARIANT_TRUE, "expected true\n"); 4725 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b)); 4726 ok(b == VARIANT_FALSE, "expected false\n"); 4727 4728 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b)); 4729 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 4730 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b)); 4731 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 4732 4733 check_ws_preserved(class_ptr->name, doc1, NULL); 4734 check_ws_ignored(class_ptr->name, doc2, NULL); 4735 4736 /* other instances follow suit */ 4737 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b)); 4738 ok(b == VARIANT_TRUE, "expected true\n"); 4739 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b)); 4740 ok(b == VARIANT_FALSE, "expected false\n"); 4741 4742 check_ws_preserved(class_ptr->name, doc3, NULL); 4743 check_ws_ignored(class_ptr->name, doc4, NULL); 4744 4745 IXMLDOMDocument2_Release(doc2); 4746 IXMLDOMDocument2_Release(doc3); 4747 IXMLDOMDocument2_Release(doc4); 4748 4749 /* text with char references */ 4750 test_preserve_charref(doc1, VARIANT_TRUE); 4751 test_preserve_charref(doc1, VARIANT_FALSE); 4752 4753 /* formatting whitespaces */ 4754 hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE); 4755 ok(hr == S_OK, "got 0x%08x\n", hr); 4756 4757 hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b); 4758 ok(hr == S_OK, "got 0x%08x\n", hr); 4759 ok(b == VARIANT_TRUE, "for %x\n", b); 4760 4761 hr = IXMLDOMDocument2_get_documentElement(doc1, &root); 4762 ok(hr == S_OK, "got 0x%08x\n", hr); 4763 hr = IXMLDOMElement_get_childNodes(root, &list); 4764 ok(hr == S_OK, "got 0x%08x\n", hr); 4765 len = 0; 4766 hr = IXMLDOMNodeList_get_length(list, &len); 4767 ok(hr == S_OK, "got 0x%08x\n", hr); 4768 ok(len == 3, "got %d\n", len); 4769 IXMLDOMNodeList_Release(list); 4770 IXMLDOMElement_Release(root); 4771 4772 IXMLDOMDocument2_Release(doc1); 4773 4774 free_bstrs(); 4775 4776 class_ptr++; 4777 } 4778 } 4779 4780 typedef struct { 4781 const GUID *clsid; 4782 const char *name; 4783 const char *ns; 4784 HRESULT hr; 4785 } selection_ns_t; 4786 4787 /* supposed to be tested with szExampleXML */ 4788 static const selection_ns_t selection_ns_data[] = { 4789 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4790 { &CLSID_DOMDocument, "CLSID_DOMDocument", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4791 { &CLSID_DOMDocument, "CLSID_DOMDocument", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4792 { &CLSID_DOMDocument, "CLSID_DOMDocument", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK }, 4793 4794 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4795 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4796 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4797 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK }, 4798 4799 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4800 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4801 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4802 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK }, 4803 4804 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4805 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4806 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4807 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK }, 4808 4809 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\txmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4810 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "\n\rxmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4811 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", " xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'", S_OK }, 4812 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' ", S_OK }, 4813 4814 { NULL } 4815 }; 4816 4817 typedef struct { 4818 const char *query; 4819 const char *list; 4820 } xpath_test_t; 4821 4822 static const xpath_test_t xpath_test[] = { 4823 { "*/a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" }, 4824 { "*/b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" }, 4825 { "*/c", "E3.E1.E2.D1 E3.E2.E2.D1" }, 4826 { "*/d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" }, 4827 { "//a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" }, 4828 { "//b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" }, 4829 { "//c", "E3.E1.E2.D1 E3.E2.E2.D1" }, 4830 { "//d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" }, 4831 { "//c[@type]", "E3.E2.E2.D1" }, 4832 { "//c[@type]/ancestor::node()[1]", "E2.E2.D1" }, 4833 { "//c[@type]/ancestor-or-self::node()[1]", "E3.E2.E2.D1" }, 4834 { "//c[@type]/attribute::node()[1]", "A'type'.E3.E2.E2.D1" }, 4835 { "//c[@type]/child::node()[1]", "T1.E3.E2.E2.D1" }, 4836 { "//c[@type]/descendant::node()[1]", "T1.E3.E2.E2.D1" }, 4837 { "//c[@type]/descendant-or-self::node()[1]", "E3.E2.E2.D1" }, 4838 { "//c[@type]/following::node()[1]", "E4.E2.E2.D1" }, 4839 { "//c[@type]/following-sibling::node()[1]", "E4.E2.E2.D1" }, 4840 { "//c[@type]/parent::node()[1]", "E2.E2.D1" }, 4841 { "//c[@type]/preceding::node()[1]", "T1.E2.E2.E2.D1" }, 4842 { "//c[@type]/self::node()[1]", "E3.E2.E2.D1" }, 4843 { "child::*", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 4844 { "child::node()", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 4845 { "child::text()", "" }, 4846 { "child::*/..", "E2.D1" }, 4847 { "child::*//@*/..", "E2.E5.E1.E2.D1 E2.E2.D1 E3.E2.E2.D1" }, 4848 { "self::node()", "E2.D1" }, 4849 { "ancestor::node()", "D1" }, 4850 { "elem[c][last()]/a", "E1.E2.E2.D1"}, 4851 { "ancestor-or-self::node()[1]", "E2.D1" }, 4852 { "((//a)[1])[last()]", "E1.E1.E2.D1" }, 4853 { "//elem[@*]", "E2.E2.D1" }, 4854 { NULL } 4855 }; 4856 4857 static void test_XPath(void) 4858 { 4859 const selection_ns_t *ptr = selection_ns_data; 4860 const xpath_test_t *xptest = xpath_test; 4861 VARIANT var; 4862 VARIANT_BOOL b; 4863 IXMLDOMDocument2 *doc; 4864 IXMLDOMDocument *doc2; 4865 IXMLDOMNode *rootNode; 4866 IXMLDOMNode *elem1Node; 4867 IXMLDOMNode *node; 4868 IXMLDOMNodeList *list; 4869 IXMLDOMElement *elem; 4870 IXMLDOMAttribute *attr; 4871 DOMNodeType type; 4872 HRESULT hr; 4873 LONG len; 4874 BSTR str; 4875 4876 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return; 4877 doc = create_document(&IID_IXMLDOMDocument2); 4878 4879 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b); 4880 EXPECT_HR(hr, S_OK); 4881 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 4882 4883 /* switch to XPath */ 4884 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); 4885 4886 /* some simple queries*/ 4887 EXPECT_REF(doc, 1); 4888 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list); 4889 EXPECT_HR(hr, S_OK); 4890 EXPECT_REF(doc, 1); 4891 EXPECT_LIST_LEN(list, 1); 4892 4893 EXPECT_REF(list, 1); 4894 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode); 4895 EXPECT_HR(hr, S_OK); 4896 EXPECT_REF(list, 1); 4897 EXPECT_REF(rootNode, 1); 4898 4899 hr = IXMLDOMNodeList_reset(list); 4900 EXPECT_HR(hr, S_OK); 4901 expect_list_and_release(list, "E2.D1"); 4902 4903 /* peform xpath tests */ 4904 for ( ; xptest->query ; xptest++ ) 4905 { 4906 char *str; 4907 4908 hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(xptest->query), &list); 4909 ok(hr == S_OK, "query evaluation failed for query=%s\n", xptest->query); 4910 4911 if (hr != S_OK) 4912 continue; 4913 4914 str = list_to_string(list); 4915 4916 ok(!strcmp(str, xptest->list), "query=%s, invalid node list: \"%s\", expected \"%s\"\n", 4917 xptest->query, str, xptest->list); 4918 4919 if (list) 4920 IXMLDOMNodeList_Release(list); 4921 } 4922 4923 if (0) 4924 { 4925 /* namespace:: axis test is disabled until namespace definitions 4926 are supported as attribute nodes, currently it's another node type */ 4927 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("/root/namespace::*"), &list); 4928 EXPECT_HR(hr, S_OK); 4929 len = -1; 4930 hr = IXMLDOMNodeList_get_length(list, &len); 4931 EXPECT_HR(hr, S_OK); 4932 ok(len == 2, "got %d\n", len); 4933 4934 hr = IXMLDOMNodeList_nextNode(list, &node); 4935 EXPECT_HR(hr, S_OK); 4936 type = NODE_INVALID; 4937 hr = IXMLDOMNode_get_nodeType(node, &type); 4938 EXPECT_HR(hr, S_OK); 4939 ok(type == NODE_ATTRIBUTE, "got %d\n", type); 4940 IXMLDOMNode_Release(node); 4941 4942 IXMLDOMNodeList_Release(list); 4943 } 4944 4945 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list)); 4946 expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1"); 4947 4948 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list)); 4949 expect_list_and_release(list, "E3.E2.E2.D1"); 4950 4951 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list)); 4952 /* using get_item for query results advances the position */ 4953 ole_check(IXMLDOMNodeList_get_item(list, 1, &node)); 4954 expect_node(node, "E2.E2.D1"); 4955 IXMLDOMNode_Release(node); 4956 ole_check(IXMLDOMNodeList_nextNode(list, &node)); 4957 expect_node(node, "E4.E2.D1"); 4958 IXMLDOMNode_Release(node); 4959 ole_check(IXMLDOMNodeList_reset(list)); 4960 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1"); 4961 4962 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list)); 4963 expect_list_and_release(list, "E2.D1"); 4964 4965 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list)); 4966 ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node)); 4967 ole_check(IXMLDOMNodeList_reset(list)); 4968 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1"); 4969 4970 /* select an attribute */ 4971 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list)); 4972 expect_list_and_release(list, "A'type'.E3.E2.E2.D1"); 4973 4974 /* would evaluate to a number */ 4975 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL); 4976 /* would evaluate to a boolean */ 4977 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL); 4978 /* would evaluate to a string */ 4979 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL); 4980 4981 /* no results */ 4982 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list)); 4983 expect_list_and_release(list, ""); 4984 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("elem//c"), &list)); 4985 expect_list_and_release(list, ""); 4986 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem[4]"), &list)); 4987 expect_list_and_release(list, ""); 4988 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list)); 4989 expect_list_and_release(list, ""); 4990 4991 /* foo undeclared in document node */ 4992 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL); 4993 /* undeclared in <root> node */ 4994 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL); 4995 /* undeclared in <elem> node */ 4996 ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL); 4997 /* but this trick can be used */ 4998 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list)); 4999 expect_list_and_release(list, "E3.E4.E2.D1"); 5000 5001 /* it has to be declared in SelectionNamespaces */ 5002 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), 5003 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'"))); 5004 5005 /* now the namespace can be used */ 5006 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list)); 5007 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); 5008 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list)); 5009 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); 5010 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list)); 5011 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); 5012 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list)); 5013 expect_list_and_release(list, "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1"); 5014 5015 /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */ 5016 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), 5017 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL); 5018 5019 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL); 5020 5021 VariantInit(&var); 5022 ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var)); 5023 expect_eq(V_VT(&var), VT_BSTR, int, "%x"); 5024 if (V_VT(&var) == VT_BSTR) 5025 expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###"); 5026 5027 /* extra attributes - same thing*/ 5028 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), 5029 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL); 5030 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL); 5031 5032 IXMLDOMNode_Release(rootNode); 5033 IXMLDOMNode_Release(elem1Node); 5034 5035 /* alter document with already built list */ 5036 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list); 5037 EXPECT_HR(hr, S_OK); 5038 EXPECT_LIST_LEN(list, 1); 5039 5040 hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode); 5041 EXPECT_HR(hr, S_OK); 5042 EXPECT_REF(rootNode, 1); 5043 EXPECT_REF(doc, 1); 5044 5045 hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL); 5046 EXPECT_HR(hr, S_OK); 5047 IXMLDOMNode_Release(rootNode); 5048 5049 EXPECT_LIST_LEN(list, 1); 5050 5051 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode); 5052 EXPECT_HR(hr, S_OK); 5053 EXPECT_REF(rootNode, 1); 5054 5055 IXMLDOMNodeList_Release(list); 5056 5057 hr = IXMLDOMNode_get_nodeName(rootNode, &str); 5058 EXPECT_HR(hr, S_OK); 5059 ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str)); 5060 SysFreeString(str); 5061 IXMLDOMNode_Release(rootNode); 5062 5063 /* alter node from list and get it another time */ 5064 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b); 5065 EXPECT_HR(hr, S_OK); 5066 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 5067 5068 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list); 5069 EXPECT_HR(hr, S_OK); 5070 EXPECT_LIST_LEN(list, 1); 5071 5072 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode); 5073 EXPECT_HR(hr, S_OK); 5074 5075 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem); 5076 EXPECT_HR(hr, S_OK); 5077 5078 V_VT(&var) = VT_I2; 5079 V_I2(&var) = 1; 5080 hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var); 5081 EXPECT_HR(hr, S_OK); 5082 IXMLDOMElement_Release(elem); 5083 IXMLDOMNode_Release(rootNode); 5084 5085 /* now check attribute to be present */ 5086 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode); 5087 EXPECT_HR(hr, S_OK); 5088 5089 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem); 5090 EXPECT_HR(hr, S_OK); 5091 5092 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr); 5093 EXPECT_HR(hr, S_OK); 5094 IXMLDOMAttribute_Release(attr); 5095 5096 IXMLDOMElement_Release(elem); 5097 IXMLDOMNode_Release(rootNode); 5098 5099 /* and now check for attribute in original document */ 5100 hr = IXMLDOMDocument2_get_documentElement(doc, &elem); 5101 EXPECT_HR(hr, S_OK); 5102 5103 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr); 5104 EXPECT_HR(hr, S_OK); 5105 IXMLDOMAttribute_Release(attr); 5106 5107 IXMLDOMElement_Release(elem); 5108 5109 /* attach node from list to another document */ 5110 doc2 = create_document(&IID_IXMLDOMDocument); 5111 5112 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b); 5113 EXPECT_HR(hr, S_OK); 5114 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 5115 5116 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list); 5117 EXPECT_HR(hr, S_OK); 5118 EXPECT_LIST_LEN(list, 1); 5119 5120 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode); 5121 EXPECT_HR(hr, S_OK); 5122 EXPECT_REF(rootNode, 1); 5123 5124 hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL); 5125 EXPECT_HR(hr, S_OK); 5126 EXPECT_REF(rootNode, 1); 5127 EXPECT_REF(doc2, 1); 5128 EXPECT_REF(list, 1); 5129 5130 EXPECT_LIST_LEN(list, 1); 5131 5132 IXMLDOMNode_Release(rootNode); 5133 IXMLDOMNodeList_Release(list); 5134 IXMLDOMDocument_Release(doc2); 5135 IXMLDOMDocument2_Release(doc); 5136 5137 while (ptr->clsid) 5138 { 5139 if (is_clsid_supported(ptr->clsid, &IID_IXMLDOMDocument2)) 5140 { 5141 hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc); 5142 ok(hr == S_OK, "got 0x%08x\n", hr); 5143 } 5144 else 5145 { 5146 ptr++; 5147 continue; 5148 } 5149 5150 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b); 5151 EXPECT_HR(hr, S_OK); 5152 ok(b == VARIANT_TRUE, "failed to load, %s\n", ptr->name); 5153 5154 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")); 5155 EXPECT_HR(hr, S_OK); 5156 5157 V_VT(&var) = VT_BSTR; 5158 V_BSTR(&var) = _bstr_(ptr->ns); 5159 5160 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), var); 5161 ok(hr == ptr->hr, "got 0x%08x, for %s, %s\n", hr, ptr->name, ptr->ns); 5162 5163 V_VT(&var) = VT_EMPTY; 5164 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var); 5165 EXPECT_HR(hr, S_OK); 5166 ok(V_VT(&var) == VT_BSTR, "got wrong property type %d\n", V_VT(&var)); 5167 ok(!lstrcmpW(V_BSTR(&var), _bstr_(ptr->ns)), "got wrong value %s\n", wine_dbgstr_w(V_BSTR(&var))); 5168 VariantClear(&var); 5169 5170 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list); 5171 EXPECT_HR(hr, S_OK); 5172 if (hr == S_OK) 5173 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); 5174 5175 IXMLDOMDocument2_Release(doc); 5176 ptr++; 5177 free_bstrs(); 5178 } 5179 5180 free_bstrs(); 5181 } 5182 5183 static void test_cloneNode(void ) 5184 { 5185 IXMLDOMDocument2 *doc, *doc_clone; 5186 IXMLDOMDocument *doc2; 5187 VARIANT_BOOL b; 5188 IXMLDOMNodeList *pList; 5189 IXMLDOMNamedNodeMap *mapAttr; 5190 LONG length, length1; 5191 LONG attr_cnt, attr_cnt1; 5192 IXMLDOMNode *node, *attr; 5193 IXMLDOMNode *node_clone; 5194 IXMLDOMNode *node_first; 5195 VARIANT v; 5196 HRESULT hr; 5197 5198 doc = create_document(&IID_IXMLDOMDocument2); 5199 5200 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b); 5201 ok(hr == S_OK, "got 0x%08x\n", hr); 5202 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 5203 5204 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v); 5205 ok(hr == S_OK, "got 0x%08x\n", hr); 5206 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XSLPattern")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); 5207 VariantClear(&v); 5208 5209 V_BSTR(&v) = _bstr_("XPath"); 5210 V_VT(&v) = VT_BSTR; 5211 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v); 5212 ok(hr == S_OK, "got 0x%08x\n", hr); 5213 VariantClear(&v); 5214 5215 /* clone document node */ 5216 hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node); 5217 ok( hr == S_OK, "ret %08x\n", hr ); 5218 ok( node != NULL, "node %p\n", node ); 5219 5220 hr = IXMLDOMNode_get_childNodes(node, &pList); 5221 ok( hr == S_OK, "ret %08x\n", hr ); 5222 length = 0; 5223 hr = IXMLDOMNodeList_get_length(pList, &length); 5224 ok( hr == S_OK, "ret %08x\n", hr ); 5225 ok(length == 2, "got %d\n", length); 5226 IXMLDOMNodeList_Release(pList); 5227 5228 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone); 5229 ok(hr == S_OK, "got 0x%08x\n", hr); 5230 5231 /* cloned document inherits properties */ 5232 hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v); 5233 ok(hr == S_OK, "got 0x%08x\n", hr); 5234 ok(!lstrcmpW(V_BSTR(&v), _bstr_("XPath")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); 5235 VariantClear(&v); 5236 5237 IXMLDOMDocument2_Release(doc_clone); 5238 IXMLDOMNode_Release(node); 5239 5240 hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node); 5241 ok( hr == S_OK, "ret %08x\n", hr ); 5242 ok( node != NULL, "node %p\n", node ); 5243 5244 /* Check invalid parameter */ 5245 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL); 5246 ok( hr == E_INVALIDARG, "ret %08x\n", hr ); 5247 5248 /* All Children */ 5249 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone); 5250 ok( hr == S_OK, "ret %08x\n", hr ); 5251 ok( node_clone != NULL, "node %p\n", node ); 5252 5253 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first); 5254 ok( hr == S_OK, "ret %08x\n", hr ); 5255 hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2); 5256 ok( hr == S_OK, "ret %08x\n", hr ); 5257 IXMLDOMDocument_Release(doc2); 5258 IXMLDOMNode_Release(node_first); 5259 5260 hr = IXMLDOMNode_get_childNodes(node, &pList); 5261 ok( hr == S_OK, "ret %08x\n", hr ); 5262 length = 0; 5263 hr = IXMLDOMNodeList_get_length(pList, &length); 5264 ok( hr == S_OK, "ret %08x\n", hr ); 5265 ok(length == 1, "got %d\n", length); 5266 IXMLDOMNodeList_Release(pList); 5267 5268 hr = IXMLDOMNode_get_attributes(node, &mapAttr); 5269 ok( hr == S_OK, "ret %08x\n", hr ); 5270 attr_cnt = 0; 5271 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt); 5272 ok( hr == S_OK, "ret %08x\n", hr ); 5273 ok(attr_cnt == 3, "got %d\n", attr_cnt); 5274 IXMLDOMNamedNodeMap_Release(mapAttr); 5275 5276 hr = IXMLDOMNode_get_childNodes(node_clone, &pList); 5277 ok( hr == S_OK, "ret %08x\n", hr ); 5278 length1 = 0; 5279 hr = IXMLDOMNodeList_get_length(pList, &length1); 5280 ok(length1 == 1, "got %d\n", length1); 5281 ok( hr == S_OK, "ret %08x\n", hr ); 5282 IXMLDOMNodeList_Release(pList); 5283 5284 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr); 5285 ok( hr == S_OK, "ret %08x\n", hr ); 5286 attr_cnt1 = 0; 5287 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1); 5288 ok( hr == S_OK, "ret %08x\n", hr ); 5289 ok(attr_cnt1 == 3, "got %d\n", attr_cnt1); 5290 /* now really get some attributes from cloned element */ 5291 attr = NULL; 5292 hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr); 5293 ok(hr == S_OK, "ret %08x\n", hr); 5294 IXMLDOMNode_Release(attr); 5295 IXMLDOMNamedNodeMap_Release(mapAttr); 5296 5297 ok(length == length1, "wrong Child count (%d, %d)\n", length, length1); 5298 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1); 5299 IXMLDOMNode_Release(node_clone); 5300 5301 /* No Children */ 5302 hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone); 5303 ok( hr == S_OK, "ret %08x\n", hr ); 5304 ok( node_clone != NULL, "node %p\n", node ); 5305 5306 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first); 5307 ok(hr == S_FALSE, "ret %08x\n", hr ); 5308 5309 hr = IXMLDOMNode_get_childNodes(node_clone, &pList); 5310 ok(hr == S_OK, "ret %08x\n", hr ); 5311 hr = IXMLDOMNodeList_get_length(pList, &length1); 5312 ok(hr == S_OK, "ret %08x\n", hr ); 5313 ok( length1 == 0, "Length should be 0 (%d)\n", length1); 5314 IXMLDOMNodeList_Release(pList); 5315 5316 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr); 5317 ok(hr == S_OK, "ret %08x\n", hr ); 5318 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1); 5319 ok(hr == S_OK, "ret %08x\n", hr ); 5320 ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1); 5321 IXMLDOMNamedNodeMap_Release(mapAttr); 5322 5323 ok(length != length1, "wrong Child count (%d, %d)\n", length, length1); 5324 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1); 5325 IXMLDOMNode_Release(node_clone); 5326 5327 IXMLDOMNode_Release(node); 5328 IXMLDOMDocument2_Release(doc); 5329 free_bstrs(); 5330 } 5331 5332 static void test_xmlTypes(void) 5333 { 5334 IXMLDOMDocument *doc; 5335 IXMLDOMElement *pRoot; 5336 HRESULT hr; 5337 IXMLDOMComment *pComment; 5338 IXMLDOMElement *pElement; 5339 IXMLDOMAttribute *pAttribute; 5340 IXMLDOMNamedNodeMap *pAttribs; 5341 IXMLDOMCDATASection *pCDataSec; 5342 IXMLDOMImplementation *pIXMLDOMImplementation = NULL; 5343 IXMLDOMDocumentFragment *pDocFrag = NULL; 5344 IXMLDOMEntityReference *pEntityRef = NULL; 5345 BSTR str; 5346 IXMLDOMNode *pNextChild; 5347 VARIANT v; 5348 LONG len = 0; 5349 5350 doc = create_document(&IID_IXMLDOMDocument); 5351 5352 hr = IXMLDOMDocument_get_nextSibling(doc, NULL); 5353 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5354 5355 pNextChild = (void*)0xdeadbeef; 5356 hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild); 5357 ok(hr == S_FALSE, "ret %08x\n", hr ); 5358 ok(pNextChild == NULL, "pDocChild not NULL\n"); 5359 5360 /* test previous Sibling */ 5361 hr = IXMLDOMDocument_get_previousSibling(doc, NULL); 5362 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5363 5364 pNextChild = (void*)0xdeadbeef; 5365 hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild); 5366 ok(hr == S_FALSE, "ret %08x\n", hr ); 5367 ok(pNextChild == NULL, "pNextChild not NULL\n"); 5368 5369 /* test get_dataType */ 5370 V_VT(&v) = VT_EMPTY; 5371 hr = IXMLDOMDocument_get_dataType(doc, &v); 5372 ok(hr == S_FALSE, "ret %08x\n", hr ); 5373 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n"); 5374 VariantClear(&v); 5375 5376 /* test implementation */ 5377 hr = IXMLDOMDocument_get_implementation(doc, NULL); 5378 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5379 5380 hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation); 5381 ok(hr == S_OK, "ret %08x\n", hr ); 5382 if(hr == S_OK) 5383 { 5384 VARIANT_BOOL hasFeature = VARIANT_TRUE; 5385 BSTR sEmpty = SysAllocStringLen(NULL, 0); 5386 5387 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature); 5388 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5389 5390 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL); 5391 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5392 5393 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature); 5394 ok(hr == S_OK, "ret %08x\n", hr ); 5395 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n"); 5396 5397 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature); 5398 ok(hr == S_OK, "ret %08x\n", hr ); 5399 ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n"); 5400 5401 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature); 5402 ok(hr == S_OK, "ret %08x\n", hr ); 5403 ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n"); 5404 5405 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature); 5406 ok(hr == S_OK, "ret %08x\n", hr ); 5407 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n"); 5408 5409 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature); 5410 ok(hr == S_OK, "ret %08x\n", hr ); 5411 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n"); 5412 5413 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature); 5414 ok(hr == S_OK, "ret %08x\n", hr ); 5415 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n"); 5416 5417 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature); 5418 ok(hr == S_OK, "ret %08x\n", hr ); 5419 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n"); 5420 5421 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature); 5422 ok(hr == S_OK, "ret %08x\n", hr ); 5423 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n"); 5424 5425 SysFreeString(sEmpty); 5426 IXMLDOMImplementation_Release(pIXMLDOMImplementation); 5427 } 5428 5429 pRoot = (IXMLDOMElement*)0x1; 5430 hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot); 5431 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5432 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot); 5433 5434 pRoot = (IXMLDOMElement*)0x1; 5435 hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot); 5436 ok(hr == E_FAIL, "ret %08x\n", hr ); 5437 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot); 5438 5439 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot); 5440 ok(hr == S_OK, "ret %08x\n", hr ); 5441 if(hr == S_OK) 5442 { 5443 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL); 5444 ok(hr == S_OK, "ret %08x\n", hr ); 5445 if(hr == S_OK) 5446 { 5447 /* Comment */ 5448 str = SysAllocString(szComment); 5449 hr = IXMLDOMDocument_createComment(doc, str, &pComment); 5450 SysFreeString(str); 5451 ok(hr == S_OK, "ret %08x\n", hr ); 5452 if(hr == S_OK) 5453 { 5454 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL); 5455 ok(hr == S_OK, "ret %08x\n", hr ); 5456 5457 hr = IXMLDOMComment_get_nodeName(pComment, &str); 5458 ok(hr == S_OK, "ret %08x\n", hr ); 5459 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n"); 5460 SysFreeString(str); 5461 5462 hr = IXMLDOMComment_get_xml(pComment, &str); 5463 ok(hr == S_OK, "ret %08x\n", hr ); 5464 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n"); 5465 SysFreeString(str); 5466 5467 /* put data Tests */ 5468 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\")); 5469 ok(hr == S_OK, "ret %08x\n", hr ); 5470 5471 /* get data Tests */ 5472 hr = IXMLDOMComment_get_data(pComment, &str); 5473 ok(hr == S_OK, "ret %08x\n", hr ); 5474 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n"); 5475 SysFreeString(str); 5476 5477 /* Confirm XML text is good */ 5478 hr = IXMLDOMComment_get_xml(pComment, &str); 5479 ok(hr == S_OK, "ret %08x\n", hr ); 5480 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n"); 5481 SysFreeString(str); 5482 5483 /* Confirm we get the put_data Text back */ 5484 hr = IXMLDOMComment_get_text(pComment, &str); 5485 ok(hr == S_OK, "ret %08x\n", hr ); 5486 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n"); 5487 SysFreeString(str); 5488 5489 /* test length property */ 5490 hr = IXMLDOMComment_get_length(pComment, &len); 5491 ok(hr == S_OK, "ret %08x\n", hr ); 5492 ok(len == 21, "expected 21 got %d\n", len); 5493 5494 /* test substringData */ 5495 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL); 5496 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5497 5498 /* test substringData - Invalid offset */ 5499 str = (void *)0xdeadbeef; 5500 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str); 5501 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5502 ok( str == NULL, "incorrect string\n"); 5503 5504 /* test substringData - Invalid offset */ 5505 str = (void *)0xdeadbeef; 5506 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str); 5507 ok(hr == S_FALSE, "ret %08x\n", hr ); 5508 ok( str == NULL, "incorrect string\n"); 5509 5510 /* test substringData - Invalid size */ 5511 str = (void *)0xdeadbeef; 5512 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str); 5513 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5514 ok( str == NULL, "incorrect string\n"); 5515 5516 /* test substringData - Invalid size */ 5517 str = (void *)0xdeadbeef; 5518 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str); 5519 ok(hr == S_FALSE, "ret %08x\n", hr ); 5520 ok( str == NULL, "incorrect string\n"); 5521 5522 /* test substringData - Start of string */ 5523 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str); 5524 ok(hr == S_OK, "ret %08x\n", hr ); 5525 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n"); 5526 SysFreeString(str); 5527 5528 /* test substringData - Middle of string */ 5529 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str); 5530 ok(hr == S_OK, "ret %08x\n", hr ); 5531 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n"); 5532 SysFreeString(str); 5533 5534 /* test substringData - End of string */ 5535 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str); 5536 ok(hr == S_OK, "ret %08x\n", hr ); 5537 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n"); 5538 SysFreeString(str); 5539 5540 /* test appendData */ 5541 hr = IXMLDOMComment_appendData(pComment, NULL); 5542 ok(hr == S_OK, "ret %08x\n", hr ); 5543 5544 hr = IXMLDOMComment_appendData(pComment, _bstr_("")); 5545 ok(hr == S_OK, "ret %08x\n", hr ); 5546 5547 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append")); 5548 ok(hr == S_OK, "ret %08x\n", hr ); 5549 5550 hr = IXMLDOMComment_get_text(pComment, &str); 5551 ok(hr == S_OK, "ret %08x\n", hr ); 5552 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5553 SysFreeString(str); 5554 5555 /* test insertData */ 5556 str = SysAllocStringLen(NULL, 0); 5557 hr = IXMLDOMComment_insertData(pComment, -1, str); 5558 ok(hr == S_OK, "ret %08x\n", hr ); 5559 5560 hr = IXMLDOMComment_insertData(pComment, -1, NULL); 5561 ok(hr == S_OK, "ret %08x\n", hr ); 5562 5563 hr = IXMLDOMComment_insertData(pComment, 1000, str); 5564 ok(hr == S_OK, "ret %08x\n", hr ); 5565 5566 hr = IXMLDOMComment_insertData(pComment, 1000, NULL); 5567 ok(hr == S_OK, "ret %08x\n", hr ); 5568 5569 hr = IXMLDOMComment_insertData(pComment, 0, NULL); 5570 ok(hr == S_OK, "ret %08x\n", hr ); 5571 5572 hr = IXMLDOMComment_insertData(pComment, 0, str); 5573 ok(hr == S_OK, "ret %08x\n", hr ); 5574 SysFreeString(str); 5575 5576 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting")); 5577 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5578 5579 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting")); 5580 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5581 5582 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin ")); 5583 ok(hr == S_OK, "ret %08x\n", hr ); 5584 5585 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle")); 5586 ok(hr == S_OK, "ret %08x\n", hr ); 5587 5588 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End")); 5589 ok(hr == S_OK, "ret %08x\n", hr ); 5590 5591 hr = IXMLDOMComment_get_text(pComment, &str); 5592 ok(hr == S_OK, "ret %08x\n", hr ); 5593 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5594 SysFreeString(str); 5595 5596 /* delete data */ 5597 /* invalid arguments */ 5598 hr = IXMLDOMComment_deleteData(pComment, -1, 1); 5599 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5600 5601 hr = IXMLDOMComment_deleteData(pComment, 0, 0); 5602 ok(hr == S_OK, "ret %08x\n", hr ); 5603 5604 hr = IXMLDOMComment_deleteData(pComment, 0, -1); 5605 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5606 5607 hr = IXMLDOMComment_get_length(pComment, &len); 5608 ok(hr == S_OK, "ret %08x\n", hr ); 5609 ok(len == 43, "expected 43 got %d\n", len); 5610 5611 hr = IXMLDOMComment_deleteData(pComment, len, 1); 5612 ok(hr == S_OK, "ret %08x\n", hr ); 5613 5614 hr = IXMLDOMComment_deleteData(pComment, len+1, 1); 5615 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5616 5617 /* delete from start */ 5618 hr = IXMLDOMComment_deleteData(pComment, 0, 5); 5619 ok(hr == S_OK, "ret %08x\n", hr ); 5620 5621 hr = IXMLDOMComment_get_length(pComment, &len); 5622 ok(hr == S_OK, "ret %08x\n", hr ); 5623 ok(len == 38, "expected 38 got %d\n", len); 5624 5625 hr = IXMLDOMComment_get_text(pComment, &str); 5626 ok(hr == S_OK, "ret %08x\n", hr ); 5627 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5628 SysFreeString(str); 5629 5630 /* delete from end */ 5631 hr = IXMLDOMComment_deleteData(pComment, 35, 3); 5632 ok(hr == S_OK, "ret %08x\n", hr ); 5633 5634 hr = IXMLDOMComment_get_length(pComment, &len); 5635 ok(hr == S_OK, "ret %08x\n", hr ); 5636 ok(len == 35, "expected 35 got %d\n", len); 5637 5638 hr = IXMLDOMComment_get_text(pComment, &str); 5639 ok(hr == S_OK, "ret %08x\n", hr ); 5640 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5641 SysFreeString(str); 5642 5643 /* delete from inside */ 5644 hr = IXMLDOMComment_deleteData(pComment, 1, 33); 5645 ok(hr == S_OK, "ret %08x\n", hr ); 5646 5647 hr = IXMLDOMComment_get_length(pComment, &len); 5648 ok(hr == S_OK, "ret %08x\n", hr ); 5649 ok(len == 2, "expected 2 got %d\n", len); 5650 5651 hr = IXMLDOMComment_get_text(pComment, &str); 5652 ok(hr == S_OK, "ret %08x\n", hr ); 5653 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5654 SysFreeString(str); 5655 5656 /* delete whole data ... */ 5657 hr = IXMLDOMComment_get_length(pComment, &len); 5658 ok(hr == S_OK, "ret %08x\n", hr ); 5659 5660 hr = IXMLDOMComment_deleteData(pComment, 0, len); 5661 ok(hr == S_OK, "ret %08x\n", hr ); 5662 /* ... and try again with empty string */ 5663 hr = IXMLDOMComment_deleteData(pComment, 0, len); 5664 ok(hr == S_OK, "ret %08x\n", hr ); 5665 5666 /* ::replaceData() */ 5667 V_VT(&v) = VT_BSTR; 5668 V_BSTR(&v) = SysAllocString(szstr1); 5669 hr = IXMLDOMComment_put_nodeValue(pComment, v); 5670 ok(hr == S_OK, "ret %08x\n", hr ); 5671 VariantClear(&v); 5672 5673 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL); 5674 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5675 hr = IXMLDOMComment_get_text(pComment, &str); 5676 ok(hr == S_OK, "ret %08x\n", hr ); 5677 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5678 SysFreeString(str); 5679 5680 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL); 5681 ok(hr == S_OK, "ret %08x\n", hr ); 5682 hr = IXMLDOMComment_get_text(pComment, &str); 5683 ok(hr == S_OK, "ret %08x\n", hr ); 5684 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5685 SysFreeString(str); 5686 5687 /* NULL pointer means delete */ 5688 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL); 5689 ok(hr == S_OK, "ret %08x\n", hr ); 5690 hr = IXMLDOMComment_get_text(pComment, &str); 5691 ok(hr == S_OK, "ret %08x\n", hr ); 5692 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5693 SysFreeString(str); 5694 5695 /* empty string means delete */ 5696 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("")); 5697 ok(hr == S_OK, "ret %08x\n", hr ); 5698 hr = IXMLDOMComment_get_text(pComment, &str); 5699 ok(hr == S_OK, "ret %08x\n", hr ); 5700 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5701 SysFreeString(str); 5702 5703 /* zero count means insert */ 5704 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a")); 5705 ok(hr == S_OK, "ret %08x\n", hr ); 5706 hr = IXMLDOMComment_get_text(pComment, &str); 5707 ok(hr == S_OK, "ret %08x\n", hr ); 5708 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5709 SysFreeString(str); 5710 5711 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL); 5712 ok(hr == S_OK, "ret %08x\n", hr ); 5713 5714 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m")); 5715 ok(hr == S_OK, "ret %08x\n", hr ); 5716 hr = IXMLDOMComment_get_text(pComment, &str); 5717 ok(hr == S_OK, "ret %08x\n", hr ); 5718 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5719 SysFreeString(str); 5720 5721 /* nonempty string, count greater than its length */ 5722 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2")); 5723 ok(hr == S_OK, "ret %08x\n", hr ); 5724 hr = IXMLDOMComment_get_text(pComment, &str); 5725 ok(hr == S_OK, "ret %08x\n", hr ); 5726 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5727 SysFreeString(str); 5728 5729 /* nonempty string, count less than its length */ 5730 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine")); 5731 ok(hr == S_OK, "ret %08x\n", hr ); 5732 hr = IXMLDOMComment_get_text(pComment, &str); 5733 ok(hr == S_OK, "ret %08x\n", hr ); 5734 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5735 SysFreeString(str); 5736 5737 IXMLDOMComment_Release(pComment); 5738 } 5739 5740 /* Element */ 5741 str = SysAllocString(szElement); 5742 hr = IXMLDOMDocument_createElement(doc, str, &pElement); 5743 SysFreeString(str); 5744 ok(hr == S_OK, "ret %08x\n", hr ); 5745 if(hr == S_OK) 5746 { 5747 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL); 5748 ok(hr == S_OK, "ret %08x\n", hr ); 5749 5750 hr = IXMLDOMElement_get_nodeName(pElement, &str); 5751 ok(hr == S_OK, "ret %08x\n", hr ); 5752 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n"); 5753 SysFreeString(str); 5754 5755 hr = IXMLDOMElement_get_xml(pElement, &str); 5756 ok(hr == S_OK, "ret %08x\n", hr ); 5757 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n"); 5758 SysFreeString(str); 5759 5760 /* Attribute */ 5761 pAttribute = (IXMLDOMAttribute*)0x1; 5762 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute); 5763 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5764 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute); 5765 5766 pAttribute = (IXMLDOMAttribute*)0x1; 5767 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute); 5768 ok(hr == E_FAIL, "ret %08x\n", hr ); 5769 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute); 5770 5771 str = SysAllocString(szAttribute); 5772 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute); 5773 SysFreeString(str); 5774 ok(hr == S_OK, "ret %08x\n", hr ); 5775 if(hr == S_OK) 5776 { 5777 IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1; 5778 5779 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL); 5780 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5781 5782 pNextChild = (IXMLDOMNode *)0x1; 5783 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild); 5784 ok(hr == S_FALSE, "ret %08x\n", hr ); 5785 ok(pNextChild == NULL, "pNextChild not NULL\n"); 5786 5787 /* test Previous Sibling*/ 5788 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL); 5789 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5790 5791 pNextChild = (IXMLDOMNode *)0x1; 5792 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild); 5793 ok(hr == S_FALSE, "ret %08x\n", hr ); 5794 ok(pNextChild == NULL, "pNextChild not NULL\n"); 5795 5796 hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild); 5797 ok(hr == E_FAIL, "ret %08x\n", hr ); 5798 ok(pNewChild == NULL, "pNewChild not NULL\n"); 5799 5800 hr = IXMLDOMElement_get_attributes(pElement, &pAttribs); 5801 ok(hr == S_OK, "ret %08x\n", hr ); 5802 if ( hr == S_OK ) 5803 { 5804 hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL ); 5805 ok(hr == S_OK, "ret %08x\n", hr ); 5806 5807 IXMLDOMNamedNodeMap_Release(pAttribs); 5808 } 5809 5810 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str); 5811 ok(hr == S_OK, "ret %08x\n", hr ); 5812 ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n"); 5813 SysFreeString(str); 5814 5815 /* test nodeName */ 5816 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str); 5817 ok(hr == S_OK, "ret %08x\n", hr ); 5818 ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n"); 5819 SysFreeString(str); 5820 5821 /* test name property */ 5822 hr = IXMLDOMAttribute_get_name(pAttribute, &str); 5823 ok(hr == S_OK, "ret %08x\n", hr ); 5824 ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n"); 5825 SysFreeString(str); 5826 5827 hr = IXMLDOMAttribute_get_xml(pAttribute, &str); 5828 ok(hr == S_OK, "ret %08x\n", hr ); 5829 ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n"); 5830 SysFreeString(str); 5831 5832 IXMLDOMAttribute_Release(pAttribute); 5833 5834 /* Check Element again with the Add Attribute*/ 5835 hr = IXMLDOMElement_get_xml(pElement, &str); 5836 ok(hr == S_OK, "ret %08x\n", hr ); 5837 ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n"); 5838 SysFreeString(str); 5839 } 5840 5841 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode")); 5842 ok(hr == S_OK, "ret %08x\n", hr ); 5843 5844 hr = IXMLDOMElement_get_xml(pElement, &str); 5845 ok(hr == S_OK, "ret %08x\n", hr ); 5846 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n"); 5847 SysFreeString(str); 5848 5849 /* Test for reversible escaping */ 5850 str = SysAllocString( szStrangeChars ); 5851 hr = IXMLDOMElement_put_text(pElement, str); 5852 ok(hr == S_OK, "ret %08x\n", hr ); 5853 SysFreeString( str ); 5854 5855 hr = IXMLDOMElement_get_xml(pElement, &str); 5856 ok(hr == S_OK, "ret %08x\n", hr ); 5857 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n"); 5858 SysFreeString(str); 5859 5860 hr = IXMLDOMElement_get_text(pElement, &str); 5861 ok(hr == S_OK, "ret %08x\n", hr ); 5862 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n"); 5863 SysFreeString(str); 5864 5865 IXMLDOMElement_Release(pElement); 5866 } 5867 5868 /* CData Section */ 5869 str = SysAllocString(szCData); 5870 hr = IXMLDOMDocument_createCDATASection(doc, str, NULL); 5871 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5872 5873 hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec); 5874 SysFreeString(str); 5875 ok(hr == S_OK, "ret %08x\n", hr ); 5876 if(hr == S_OK) 5877 { 5878 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1; 5879 VARIANT var; 5880 5881 VariantInit(&var); 5882 5883 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement); 5884 ok(hr == E_NOINTERFACE, "ret %08x\n", hr); 5885 5886 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL); 5887 ok(hr == S_OK, "ret %08x\n", hr ); 5888 5889 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str); 5890 ok(hr == S_OK, "ret %08x\n", hr ); 5891 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n"); 5892 SysFreeString(str); 5893 5894 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str); 5895 ok(hr == S_OK, "ret %08x\n", hr ); 5896 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n"); 5897 SysFreeString(str); 5898 5899 /* test lastChild */ 5900 pNextChild = (IXMLDOMNode*)0x1; 5901 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild); 5902 ok(hr == S_FALSE, "ret %08x\n", hr ); 5903 ok(pNextChild == NULL, "pNextChild not NULL\n"); 5904 5905 /* put data Tests */ 5906 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\")); 5907 ok(hr == S_OK, "ret %08x\n", hr ); 5908 5909 /* Confirm XML text is good */ 5910 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str); 5911 ok(hr == S_OK, "ret %08x\n", hr ); 5912 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n"); 5913 SysFreeString(str); 5914 5915 /* Confirm we get the put_data Text back */ 5916 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 5917 ok(hr == S_OK, "ret %08x\n", hr ); 5918 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); 5919 SysFreeString(str); 5920 5921 /* test length property */ 5922 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 5923 ok(hr == S_OK, "ret %08x\n", hr ); 5924 ok(len == 21, "expected 21 got %d\n", len); 5925 5926 /* test get data */ 5927 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str); 5928 ok(hr == S_OK, "ret %08x\n", hr ); 5929 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n"); 5930 SysFreeString(str); 5931 5932 /* test substringData */ 5933 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL); 5934 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5935 5936 /* test substringData - Invalid offset */ 5937 str = (void *)0xdeadbeef; 5938 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str); 5939 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5940 ok( str == NULL, "incorrect string\n"); 5941 5942 /* test substringData - Invalid offset */ 5943 str = (void *)0xdeadbeef; 5944 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str); 5945 ok(hr == S_FALSE, "ret %08x\n", hr ); 5946 ok( str == NULL, "incorrect string\n"); 5947 5948 /* test substringData - Invalid size */ 5949 str = (void *)0xdeadbeef; 5950 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str); 5951 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 5952 ok( str == NULL, "incorrect string\n"); 5953 5954 /* test substringData - Invalid size */ 5955 str = (void *)0xdeadbeef; 5956 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str); 5957 ok(hr == S_FALSE, "ret %08x\n", hr ); 5958 ok( str == NULL, "incorrect string\n"); 5959 5960 /* test substringData - Start of string */ 5961 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str); 5962 ok(hr == S_OK, "ret %08x\n", hr ); 5963 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n"); 5964 SysFreeString(str); 5965 5966 /* test substringData - Middle of string */ 5967 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str); 5968 ok(hr == S_OK, "ret %08x\n", hr ); 5969 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n"); 5970 SysFreeString(str); 5971 5972 /* test substringData - End of string */ 5973 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str); 5974 ok(hr == S_OK, "ret %08x\n", hr ); 5975 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n"); 5976 SysFreeString(str); 5977 5978 /* test appendData */ 5979 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL); 5980 ok(hr == S_OK, "ret %08x\n", hr ); 5981 5982 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("")); 5983 ok(hr == S_OK, "ret %08x\n", hr ); 5984 5985 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append")); 5986 ok(hr == S_OK, "ret %08x\n", hr ); 5987 5988 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 5989 ok(hr == S_OK, "ret %08x\n", hr ); 5990 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 5991 SysFreeString(str); 5992 5993 /* test insertData */ 5994 str = SysAllocStringLen(NULL, 0); 5995 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str); 5996 ok(hr == S_OK, "ret %08x\n", hr ); 5997 5998 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL); 5999 ok(hr == S_OK, "ret %08x\n", hr ); 6000 6001 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str); 6002 ok(hr == S_OK, "ret %08x\n", hr ); 6003 6004 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL); 6005 ok(hr == S_OK, "ret %08x\n", hr ); 6006 6007 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL); 6008 ok(hr == S_OK, "ret %08x\n", hr ); 6009 6010 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str); 6011 ok(hr == S_OK, "ret %08x\n", hr ); 6012 SysFreeString(str); 6013 6014 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting")); 6015 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6016 6017 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting")); 6018 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6019 6020 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin ")); 6021 ok(hr == S_OK, "ret %08x\n", hr ); 6022 6023 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle")); 6024 ok(hr == S_OK, "ret %08x\n", hr ); 6025 6026 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End")); 6027 ok(hr == S_OK, "ret %08x\n", hr ); 6028 6029 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6030 ok(hr == S_OK, "ret %08x\n", hr ); 6031 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6032 SysFreeString(str); 6033 6034 /* delete data */ 6035 /* invalid arguments */ 6036 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1); 6037 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6038 6039 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0); 6040 ok(hr == S_OK, "ret %08x\n", hr ); 6041 6042 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1); 6043 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6044 6045 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 6046 ok(hr == S_OK, "ret %08x\n", hr ); 6047 ok(len == 43, "expected 43 got %d\n", len); 6048 6049 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1); 6050 ok(hr == S_OK, "ret %08x\n", hr ); 6051 6052 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1); 6053 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6054 6055 /* delete from start */ 6056 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5); 6057 ok(hr == S_OK, "ret %08x\n", hr ); 6058 6059 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 6060 ok(hr == S_OK, "ret %08x\n", hr ); 6061 ok(len == 38, "expected 38 got %d\n", len); 6062 6063 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6064 ok(hr == S_OK, "ret %08x\n", hr ); 6065 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6066 SysFreeString(str); 6067 6068 /* delete from end */ 6069 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3); 6070 ok(hr == S_OK, "ret %08x\n", hr ); 6071 6072 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 6073 ok(hr == S_OK, "ret %08x\n", hr ); 6074 ok(len == 35, "expected 35 got %d\n", len); 6075 6076 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6077 ok(hr == S_OK, "ret %08x\n", hr ); 6078 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6079 SysFreeString(str); 6080 6081 /* delete from inside */ 6082 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33); 6083 ok(hr == S_OK, "ret %08x\n", hr ); 6084 6085 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 6086 ok(hr == S_OK, "ret %08x\n", hr ); 6087 ok(len == 2, "expected 2 got %d\n", len); 6088 6089 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6090 ok(hr == S_OK, "ret %08x\n", hr ); 6091 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6092 SysFreeString(str); 6093 6094 /* delete whole data ... */ 6095 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len); 6096 ok(hr == S_OK, "ret %08x\n", hr ); 6097 6098 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len); 6099 ok(hr == S_OK, "ret %08x\n", hr ); 6100 6101 /* ... and try again with empty string */ 6102 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len); 6103 ok(hr == S_OK, "ret %08x\n", hr ); 6104 6105 /* ::replaceData() */ 6106 V_VT(&v) = VT_BSTR; 6107 V_BSTR(&v) = SysAllocString(szstr1); 6108 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v); 6109 ok(hr == S_OK, "ret %08x\n", hr ); 6110 VariantClear(&v); 6111 6112 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL); 6113 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6114 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6115 ok(hr == S_OK, "ret %08x\n", hr ); 6116 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6117 SysFreeString(str); 6118 6119 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL); 6120 ok(hr == S_OK, "ret %08x\n", hr ); 6121 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6122 ok(hr == S_OK, "ret %08x\n", hr ); 6123 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6124 SysFreeString(str); 6125 6126 /* NULL pointer means delete */ 6127 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL); 6128 ok(hr == S_OK, "ret %08x\n", hr ); 6129 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6130 ok(hr == S_OK, "ret %08x\n", hr ); 6131 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6132 SysFreeString(str); 6133 6134 /* empty string means delete */ 6135 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("")); 6136 ok(hr == S_OK, "ret %08x\n", hr ); 6137 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6138 ok(hr == S_OK, "ret %08x\n", hr ); 6139 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6140 SysFreeString(str); 6141 6142 /* zero count means insert */ 6143 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a")); 6144 ok(hr == S_OK, "ret %08x\n", hr ); 6145 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6146 ok(hr == S_OK, "ret %08x\n", hr ); 6147 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6148 SysFreeString(str); 6149 6150 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL); 6151 ok(hr == S_OK, "ret %08x\n", hr ); 6152 6153 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m")); 6154 ok(hr == S_OK, "ret %08x\n", hr ); 6155 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6156 ok(hr == S_OK, "ret %08x\n", hr ); 6157 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6158 SysFreeString(str); 6159 6160 /* nonempty string, count greater than its length */ 6161 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2")); 6162 ok(hr == S_OK, "ret %08x\n", hr ); 6163 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6164 ok(hr == S_OK, "ret %08x\n", hr ); 6165 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6166 SysFreeString(str); 6167 6168 /* nonempty string, count less than its length */ 6169 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine")); 6170 ok(hr == S_OK, "ret %08x\n", hr ); 6171 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str); 6172 ok(hr == S_OK, "ret %08x\n", hr ); 6173 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) ); 6174 SysFreeString(str); 6175 6176 IXMLDOMCDATASection_Release(pCDataSec); 6177 } 6178 6179 /* Document Fragments */ 6180 hr = IXMLDOMDocument_createDocumentFragment(doc, NULL); 6181 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6182 6183 hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag); 6184 ok(hr == S_OK, "ret %08x\n", hr ); 6185 if(hr == S_OK) 6186 { 6187 IXMLDOMNode *node; 6188 6189 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL); 6190 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6191 6192 node = (IXMLDOMNode *)0x1; 6193 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node); 6194 ok(hr == S_FALSE, "ret %08x\n", hr ); 6195 ok(node == NULL, "expected NULL, got %p\n", node); 6196 6197 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL); 6198 ok(hr == S_OK, "ret %08x\n", hr ); 6199 6200 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str); 6201 ok(hr == S_OK, "ret %08x\n", hr ); 6202 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n"); 6203 SysFreeString(str); 6204 6205 /* test next Sibling*/ 6206 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL); 6207 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6208 6209 node = (IXMLDOMNode *)0x1; 6210 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node); 6211 ok(hr == S_FALSE, "ret %08x\n", hr ); 6212 ok(node == NULL, "next sibling not NULL\n"); 6213 6214 /* test Previous Sibling*/ 6215 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL); 6216 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6217 6218 node = (IXMLDOMNode *)0x1; 6219 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node); 6220 ok(hr == S_FALSE, "ret %08x\n", hr ); 6221 ok(node == NULL, "previous sibling not NULL\n"); 6222 6223 IXMLDOMDocumentFragment_Release(pDocFrag); 6224 } 6225 6226 /* Entity References */ 6227 hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef); 6228 ok(hr == E_FAIL, "ret %08x\n", hr ); 6229 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef); 6230 ok(hr == E_FAIL, "ret %08x\n", hr ); 6231 6232 str = SysAllocString(szEntityRef); 6233 hr = IXMLDOMDocument_createEntityReference(doc, str, NULL); 6234 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6235 6236 hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef); 6237 SysFreeString(str); 6238 ok(hr == S_OK, "ret %08x\n", hr ); 6239 if(hr == S_OK) 6240 { 6241 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL); 6242 ok(hr == S_OK, "ret %08x\n", hr ); 6243 6244 /* test get_xml*/ 6245 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str); 6246 ok(hr == S_OK, "ret %08x\n", hr ); 6247 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n"); 6248 SysFreeString(str); 6249 6250 IXMLDOMEntityReference_Release(pEntityRef); 6251 } 6252 6253 IXMLDOMElement_Release( pRoot ); 6254 } 6255 } 6256 6257 IXMLDOMDocument_Release(doc); 6258 6259 free_bstrs(); 6260 } 6261 6262 typedef struct { 6263 const char *name; 6264 const char *type; 6265 HRESULT hr; 6266 } put_datatype_t; 6267 6268 /* Type test for elements only. Name passed into put_dataType is case-insensitive. 6269 So many of the names have been changed to reflect this. */ 6270 static put_datatype_t put_datatype_data[] = { 6271 { "test_inval", "abcdefg", E_FAIL }, 6272 { "test_bool", "Boolean", S_OK }, 6273 { "test_string", "String", S_OK }, 6274 { "test_number", "number", S_OK }, 6275 { "test_int", "InT", S_OK }, 6276 { "test_fixed", "fixed.14.4", S_OK }, 6277 { "test_datetime", "DateTime", S_OK }, 6278 { "test_datetimetz", "DateTime.tz", S_OK }, 6279 { "test_date", "Date", S_OK }, 6280 { "test_time", "Time", S_OK }, 6281 { "test_timetz", "Time.tz", S_OK }, 6282 { "test_I1", "I1", S_OK }, 6283 { "test_I2", "I2", S_OK }, 6284 { "test_I4", "I4", S_OK }, 6285 { "test_UI1", "UI1", S_OK }, 6286 { "test_UI2", "UI2", S_OK }, 6287 { "test_UI4", "UI4", S_OK }, 6288 { "test_r4", "r4", S_OK }, 6289 { "test_r8", "r8", S_OK }, 6290 { "test_float", "float", S_OK }, 6291 { "test_uuid", "UuId", S_OK }, 6292 { "test_binhex", "bin.hex", S_OK }, 6293 { "test_binbase64", "bin.base64", S_OK }, 6294 { NULL } 6295 }; 6296 6297 typedef struct { 6298 DOMNodeType type; 6299 HRESULT hr; 6300 } put_datatype_notype_t; 6301 6302 static put_datatype_notype_t put_dt_notype[] = { 6303 { NODE_PROCESSING_INSTRUCTION, E_FAIL }, 6304 { NODE_DOCUMENT_FRAGMENT, E_FAIL }, 6305 { NODE_ENTITY_REFERENCE, E_FAIL }, 6306 { NODE_CDATA_SECTION, E_FAIL }, 6307 { NODE_COMMENT, E_FAIL }, 6308 { NODE_INVALID } 6309 }; 6310 6311 static void test_put_dataType( void ) 6312 { 6313 const put_datatype_notype_t *ptr2 = put_dt_notype; 6314 const put_datatype_t *ptr = put_datatype_data; 6315 IXMLDOMElement *root, *element; 6316 BSTR nameW, type1W, type2W; 6317 IXMLDOMDocument *doc; 6318 HRESULT hr; 6319 6320 doc = create_document(&IID_IXMLDOMDocument); 6321 6322 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL); 6323 EXPECT_HR(hr, E_INVALIDARG); 6324 6325 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root); 6326 EXPECT_HR(hr, S_OK); 6327 6328 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL); 6329 EXPECT_HR(hr, S_OK); 6330 6331 hr = IXMLDOMElement_put_dataType(root, NULL); 6332 EXPECT_HR(hr, E_INVALIDARG); 6333 6334 while (ptr->name) 6335 { 6336 hr = IXMLDOMDocument_createElement(doc, _bstr_(ptr->name), &element); 6337 EXPECT_HR(hr, S_OK); 6338 if(hr == S_OK) 6339 { 6340 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL); 6341 EXPECT_HR(hr, S_OK); 6342 6343 hr = IXMLDOMElement_put_dataType(element, _bstr_(ptr->type)); 6344 ok(hr == ptr->hr, "failed for %s:%s, 0x%08x\n", ptr->name, ptr->type, ptr->hr); 6345 6346 IXMLDOMElement_Release(element); 6347 } 6348 ptr++; 6349 } 6350 6351 /* check changing types */ 6352 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &element); 6353 EXPECT_HR(hr, S_OK); 6354 6355 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)element, NULL); 6356 EXPECT_HR(hr, S_OK); 6357 6358 hr = IXMLDOMElement_put_dataType(element, _bstr_("DateTime.tz")); 6359 EXPECT_HR(hr, S_OK); 6360 6361 hr = IXMLDOMElement_put_dataType(element, _bstr_("string")); 6362 EXPECT_HR(hr, S_OK); 6363 6364 IXMLDOMElement_Release(element); 6365 6366 /* try to set type for node without a type */ 6367 nameW = _bstr_("testname"); 6368 type1W = _bstr_("string"); 6369 type2W = _bstr_("number"); 6370 while (ptr2->type != NODE_INVALID) 6371 { 6372 IXMLDOMNode *node; 6373 VARIANT type; 6374 6375 V_VT(&type) = VT_I2; 6376 V_I2(&type) = ptr2->type; 6377 6378 hr = IXMLDOMDocument_createNode(doc, type, nameW, NULL, &node); 6379 EXPECT_HR(hr, S_OK); 6380 if(hr == S_OK) 6381 { 6382 hr = IXMLDOMElement_appendChild(root, node, NULL); 6383 EXPECT_HR(hr, S_OK); 6384 6385 hr = IXMLDOMNode_put_dataType(node, NULL); 6386 EXPECT_HR(hr, E_INVALIDARG); 6387 6388 hr = IXMLDOMNode_put_dataType(node, type1W); 6389 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr); 6390 hr = IXMLDOMNode_put_dataType(node, type2W); 6391 ok(hr == ptr2->hr, "failed for type %d, 0x%08x\n", ptr2->type, ptr->hr); 6392 6393 IXMLDOMNode_Release(node); 6394 } 6395 ptr2++; 6396 } 6397 6398 IXMLDOMElement_Release(root); 6399 IXMLDOMDocument_Release(doc); 6400 free_bstrs(); 6401 } 6402 6403 static void test_save(void) 6404 { 6405 IXMLDOMDocument *doc, *doc2; 6406 IXMLDOMElement *root; 6407 BSTR sOrig, sNew, filename; 6408 char buffer[100]; 6409 IStream *stream; 6410 HGLOBAL global; 6411 VARIANT_BOOL b; 6412 DWORD read = 0; 6413 VARIANT dest; 6414 HANDLE hfile; 6415 HRESULT hr; 6416 char *ptr; 6417 6418 doc = create_document(&IID_IXMLDOMDocument); 6419 doc2 = create_document(&IID_IXMLDOMDocument); 6420 6421 /* save to IXMLDOMDocument */ 6422 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root); 6423 EXPECT_HR(hr, S_OK); 6424 6425 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL); 6426 EXPECT_HR(hr, S_OK); 6427 6428 V_VT(&dest) = VT_UNKNOWN; 6429 V_UNKNOWN(&dest) = (IUnknown*)doc2; 6430 6431 hr = IXMLDOMDocument_save(doc, dest); 6432 EXPECT_HR(hr, S_OK); 6433 6434 hr = IXMLDOMDocument_get_xml(doc, &sOrig); 6435 EXPECT_HR(hr, S_OK); 6436 6437 hr = IXMLDOMDocument_get_xml(doc2, &sNew); 6438 EXPECT_HR(hr, S_OK); 6439 6440 ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as original\n"); 6441 6442 SysFreeString(sOrig); 6443 SysFreeString(sNew); 6444 6445 IXMLDOMElement_Release(root); 6446 IXMLDOMDocument_Release(doc2); 6447 6448 /* save to path */ 6449 V_VT(&dest) = VT_BSTR; 6450 V_BSTR(&dest) = _bstr_("test.xml"); 6451 6452 hr = IXMLDOMDocument_save(doc, dest); 6453 EXPECT_HR(hr, S_OK); 6454 6455 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 6456 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError()); 6457 if(hfile == INVALID_HANDLE_VALUE) return; 6458 6459 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL); 6460 ok(read != 0, "could not read file\n"); 6461 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n"); 6462 6463 CloseHandle(hfile); 6464 DeleteFileA("test.xml"); 6465 6466 /* save to path VT_BSTR | VT_BYREF */ 6467 filename = _bstr_("test.xml"); 6468 V_VT(&dest) = VT_BSTR | VT_BYREF; 6469 V_BSTRREF(&dest) = &filename; 6470 6471 hr = IXMLDOMDocument_save(doc, dest); 6472 EXPECT_HR(hr, S_OK); 6473 6474 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 6475 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError()); 6476 if(hfile == INVALID_HANDLE_VALUE) return; 6477 6478 if (hfile != INVALID_HANDLE_VALUE) 6479 { 6480 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL); 6481 ok(read != 0, "could not read file\n"); 6482 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n"); 6483 6484 CloseHandle(hfile); 6485 DeleteFileA("test.xml"); 6486 } 6487 6488 /* save to stream */ 6489 V_VT(&dest) = VT_UNKNOWN; 6490 V_UNKNOWN(&dest) = (IUnknown*)&savestream; 6491 6492 hr = IXMLDOMDocument_save(doc, dest); 6493 EXPECT_HR(hr, S_OK); 6494 6495 /* loaded data contains xml declaration */ 6496 hr = IXMLDOMDocument_loadXML(doc, _bstr_(win1252xml), &b); 6497 EXPECT_HR(hr, S_OK); 6498 6499 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); 6500 ok(hr == S_OK, "got 0x%08x\n", hr); 6501 V_VT(&dest) = VT_UNKNOWN; 6502 V_UNKNOWN(&dest) = (IUnknown*)stream; 6503 hr = IXMLDOMDocument_save(doc, dest); 6504 EXPECT_HR(hr, S_OK); 6505 6506 hr = GetHGlobalFromStream(stream, &global); 6507 EXPECT_HR(hr, S_OK); 6508 ptr = GlobalLock(global); 6509 ok(!memcmp(ptr, win1252decl, strlen(win1252decl)), "got wrong xml declaration\n"); 6510 GlobalUnlock(global); 6511 IStream_Release(stream); 6512 6513 /* loaded data without xml declaration */ 6514 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b); 6515 EXPECT_HR(hr, S_OK); 6516 6517 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); 6518 ok(hr == S_OK, "got 0x%08x\n", hr); 6519 V_VT(&dest) = VT_UNKNOWN; 6520 V_UNKNOWN(&dest) = (IUnknown*)stream; 6521 hr = IXMLDOMDocument_save(doc, dest); 6522 EXPECT_HR(hr, S_OK); 6523 6524 hr = GetHGlobalFromStream(stream, &global); 6525 EXPECT_HR(hr, S_OK); 6526 ptr = GlobalLock(global); 6527 ok(ptr[0] == '<' && ptr[1] != '?', "got wrong start tag %c%c\n", ptr[0], ptr[1]); 6528 GlobalUnlock(global); 6529 IStream_Release(stream); 6530 6531 IXMLDOMDocument_Release(doc); 6532 free_bstrs(); 6533 } 6534 6535 static void test_testTransforms(void) 6536 { 6537 IXMLDOMDocument *doc, *docSS; 6538 IXMLDOMNode *pNode; 6539 VARIANT_BOOL bSucc; 6540 HRESULT hr; 6541 6542 doc = create_document(&IID_IXMLDOMDocument); 6543 docSS = create_document(&IID_IXMLDOMDocument); 6544 6545 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc); 6546 ok(hr == S_OK, "ret %08x\n", hr ); 6547 6548 hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc); 6549 ok(hr == S_OK, "ret %08x\n", hr ); 6550 6551 hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode ); 6552 ok(hr == S_OK, "ret %08x\n", hr ); 6553 if(hr == S_OK) 6554 { 6555 BSTR bOut; 6556 6557 hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut); 6558 ok(hr == S_OK, "ret %08x\n", hr ); 6559 if(hr == S_OK) 6560 { 6561 ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(bOut)); 6562 SysFreeString(bOut); 6563 } 6564 6565 IXMLDOMNode_Release(pNode); 6566 } 6567 6568 IXMLDOMDocument_Release(docSS); 6569 IXMLDOMDocument_Release(doc); 6570 6571 free_bstrs(); 6572 } 6573 6574 struct namespaces_change_t { 6575 const CLSID *clsid; 6576 const char *name; 6577 }; 6578 6579 static const struct namespaces_change_t namespaces_change_test_data[] = { 6580 { &CLSID_DOMDocument, "CLSID_DOMDocument" }, 6581 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" }, 6582 { &CLSID_DOMDocument26, "CLSID_DOMDocument26" }, 6583 { &CLSID_DOMDocument30, "CLSID_DOMDocument30" }, 6584 { &CLSID_DOMDocument40, "CLSID_DOMDocument40" }, 6585 { &CLSID_DOMDocument60, "CLSID_DOMDocument60" }, 6586 { 0 } 6587 }; 6588 6589 static void test_namespaces_change(void) 6590 { 6591 const struct namespaces_change_t *class_ptr = namespaces_change_test_data; 6592 6593 while (class_ptr->clsid) 6594 { 6595 IXMLDOMDocument *doc = NULL; 6596 IXMLDOMElement *elem = NULL; 6597 IXMLDOMNode *node = NULL; 6598 6599 VARIANT var; 6600 HRESULT hr; 6601 BSTR str; 6602 6603 if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument)) 6604 { 6605 class_ptr++; 6606 continue; 6607 } 6608 6609 hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, 6610 &IID_IXMLDOMDocument, (void**)&doc); 6611 ok(hr == S_OK, "got 0x%08x\n", hr); 6612 6613 V_VT(&var) = VT_I2; 6614 V_I2(&var) = NODE_ELEMENT; 6615 6616 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("ns:elem"), _bstr_("ns/uri"), &node); 6617 EXPECT_HR(hr, S_OK); 6618 6619 hr = IXMLDOMDocument_appendChild(doc, node, NULL); 6620 EXPECT_HR(hr, S_OK); 6621 6622 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 6623 EXPECT_HR(hr, S_OK); 6624 6625 /* try same prefix, different uri */ 6626 V_VT(&var) = VT_BSTR; 6627 V_BSTR(&var) = _bstr_("ns/uri2"); 6628 6629 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); 6630 EXPECT_HR(hr, E_INVALIDARG); 6631 6632 /* try same prefix and uri */ 6633 V_VT(&var) = VT_BSTR; 6634 V_BSTR(&var) = _bstr_("ns/uri"); 6635 6636 hr = IXMLDOMElement_setAttribute(elem, _bstr_("xmlns:ns"), var); 6637 EXPECT_HR(hr, S_OK); 6638 6639 hr = IXMLDOMElement_get_xml(elem, &str); 6640 EXPECT_HR(hr, S_OK); 6641 ok(!lstrcmpW(str, _bstr_("<ns:elem xmlns:ns=\"ns/uri\"/>")), "got element %s for %s\n", 6642 wine_dbgstr_w(str), class_ptr->name); 6643 SysFreeString(str); 6644 6645 IXMLDOMElement_Release(elem); 6646 IXMLDOMDocument_Release(doc); 6647 6648 free_bstrs(); 6649 6650 class_ptr++; 6651 } 6652 } 6653 6654 static void test_namespaces_basic(void) 6655 { 6656 static const CHAR namespaces_xmlA[] = 6657 "<?xml version=\"1.0\"?>\n" 6658 "<XMI xmi.version=\"1.1\" xmlns:Model=\"http://omg.org/mof.Model/1.3\">" 6659 " <XMI.content>" 6660 " <Model:Package name=\"WinePackage\" Model:name2=\"name2 attr\" />" 6661 " </XMI.content>" 6662 "</XMI>"; 6663 6664 IXMLDOMDocument *doc; 6665 IXMLDOMElement *elem; 6666 IXMLDOMNode *node; 6667 6668 VARIANT_BOOL b; 6669 HRESULT hr; 6670 BSTR str; 6671 6672 doc = create_document(&IID_IXMLDOMDocument); 6673 6674 hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b); 6675 EXPECT_HR(hr, S_OK); 6676 ok(b == VARIANT_TRUE, "got %d\n", b); 6677 6678 str = (void *)0xdeadbeef; 6679 hr = IXMLDOMDocument_get_namespaceURI(doc, &str); 6680 EXPECT_HR(hr, S_FALSE); 6681 ok(str == NULL, "got %p\n", str); 6682 6683 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("//XMI.content"), &node ); 6684 EXPECT_HR(hr, S_OK); 6685 if(hr == S_OK) 6686 { 6687 IXMLDOMAttribute *attr; 6688 IXMLDOMNode *node2; 6689 6690 hr = IXMLDOMNode_get_firstChild(node, &node2); 6691 EXPECT_HR(hr, S_OK); 6692 ok(node2 != NULL, "got %p\n", node2); 6693 6694 /* Test get_prefix */ 6695 hr = IXMLDOMNode_get_prefix(node2, NULL); 6696 EXPECT_HR(hr, E_INVALIDARG); 6697 /* NOTE: Need to test that arg2 gets cleared on Error. */ 6698 6699 hr = IXMLDOMNode_get_prefix(node2, &str); 6700 EXPECT_HR(hr, S_OK); 6701 ok( !lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str)); 6702 SysFreeString(str); 6703 6704 hr = IXMLDOMNode_get_nodeName(node2, &str); 6705 EXPECT_HR(hr, S_OK); 6706 ok(!lstrcmpW( str, _bstr_("Model:Package")), "got %s\n", wine_dbgstr_w(str)); 6707 SysFreeString(str); 6708 6709 /* Test get_namespaceURI */ 6710 hr = IXMLDOMNode_get_namespaceURI(node2, NULL); 6711 EXPECT_HR(hr, E_INVALIDARG); 6712 /* NOTE: Need to test that arg2 gets cleared on Error. */ 6713 6714 hr = IXMLDOMNode_get_namespaceURI(node2, &str); 6715 EXPECT_HR(hr, S_OK); 6716 ok(!lstrcmpW( str, _bstr_("http://omg.org/mof.Model/1.3")), "got %s\n", wine_dbgstr_w(str)); 6717 SysFreeString(str); 6718 6719 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&elem); 6720 EXPECT_HR(hr, S_OK); 6721 6722 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("Model:name2"), &attr); 6723 EXPECT_HR(hr, S_OK); 6724 6725 hr = IXMLDOMAttribute_get_nodeName(attr, &str); 6726 EXPECT_HR(hr, S_OK); 6727 ok(!lstrcmpW( str, _bstr_("Model:name2")), "got %s\n", wine_dbgstr_w(str)); 6728 SysFreeString(str); 6729 6730 hr = IXMLDOMAttribute_get_prefix(attr, &str); 6731 EXPECT_HR(hr, S_OK); 6732 ok(!lstrcmpW( str, _bstr_("Model")), "got %s\n", wine_dbgstr_w(str)); 6733 SysFreeString(str); 6734 6735 IXMLDOMAttribute_Release(attr); 6736 IXMLDOMElement_Release(elem); 6737 6738 IXMLDOMNode_Release(node2); 6739 IXMLDOMNode_Release(node); 6740 } 6741 6742 IXMLDOMDocument_Release(doc); 6743 6744 free_bstrs(); 6745 } 6746 6747 static void test_FormattingXML(void) 6748 { 6749 IXMLDOMDocument *doc; 6750 IXMLDOMElement *pElement; 6751 VARIANT_BOOL bSucc; 6752 HRESULT hr; 6753 BSTR str; 6754 static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>"; 6755 static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>"; 6756 6757 doc = create_document(&IID_IXMLDOMDocument); 6758 6759 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc); 6760 ok(hr == S_OK, "ret %08x\n", hr ); 6761 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n"); 6762 6763 if(bSucc == VARIANT_TRUE) 6764 { 6765 hr = IXMLDOMDocument_get_documentElement(doc, &pElement); 6766 ok(hr == S_OK, "ret %08x\n", hr ); 6767 if(hr == S_OK) 6768 { 6769 hr = IXMLDOMElement_get_xml(pElement, &str); 6770 ok(hr == S_OK, "ret %08x\n", hr ); 6771 ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n"); 6772 SysFreeString(str); 6773 6774 IXMLDOMElement_Release(pElement); 6775 } 6776 } 6777 6778 IXMLDOMDocument_Release(doc); 6779 6780 free_bstrs(); 6781 } 6782 6783 typedef struct _nodetypedvalue_t { 6784 const char *name; 6785 VARTYPE type; 6786 const char *value; /* value in string format */ 6787 } nodetypedvalue_t; 6788 6789 static const nodetypedvalue_t get_nodetypedvalue[] = { 6790 { "root/string", VT_BSTR, "Wine" }, 6791 { "root/string2", VT_BSTR, "String" }, 6792 { "root/number", VT_BSTR, "12.44" }, 6793 { "root/number2", VT_BSTR, "-3.71e3" }, 6794 { "root/int", VT_I4, "-13" }, 6795 { "root/fixed", VT_CY, "7322.9371" }, 6796 { "root/bool", VT_BOOL, "-1" }, 6797 { "root/datetime", VT_DATE, "40135.14" }, 6798 { "root/datetimetz",VT_DATE, "37813.59" }, 6799 { "root/date", VT_DATE, "665413" }, 6800 { "root/time", VT_DATE, "0.5813889" }, 6801 { "root/timetz", VT_DATE, "1.112512" }, 6802 { "root/i1", VT_I1, "-13" }, 6803 { "root/i2", VT_I2, "31915" }, 6804 { "root/i4", VT_I4, "-312232" }, 6805 { "root/ui1", VT_UI1, "123" }, 6806 { "root/ui2", VT_UI2, "48282" }, 6807 { "root/ui4", VT_UI4, "949281" }, 6808 { "root/r4", VT_R4, "213124" }, 6809 { "root/r8", VT_R8, "0.412" }, 6810 { "root/float", VT_R8, "41221.421" }, 6811 { "root/uuid", VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" }, 6812 { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" }, 6813 { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" }, 6814 { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" }, 6815 { 0 } 6816 }; 6817 6818 static void test_nodeTypedValue(void) 6819 { 6820 const nodetypedvalue_t *entry = get_nodetypedvalue; 6821 IXMLDOMDocumentType *doctype, *doctype2; 6822 IXMLDOMProcessingInstruction *pi; 6823 IXMLDOMDocumentFragment *frag; 6824 IXMLDOMDocument *doc, *doc2; 6825 IXMLDOMCDATASection *cdata; 6826 IXMLDOMComment *comment; 6827 IXMLDOMNode *node; 6828 VARIANT_BOOL b; 6829 VARIANT value; 6830 HRESULT hr; 6831 6832 doc = create_document(&IID_IXMLDOMDocument); 6833 6834 b = VARIANT_FALSE; 6835 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b); 6836 ok(hr == S_OK, "ret %08x\n", hr ); 6837 ok(b == VARIANT_TRUE, "got %d\n", b); 6838 6839 hr = IXMLDOMDocument_get_nodeValue(doc, NULL); 6840 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6841 6842 V_VT(&value) = VT_BSTR; 6843 V_BSTR(&value) = NULL; 6844 hr = IXMLDOMDocument_get_nodeValue(doc, &value); 6845 ok(hr == S_FALSE, "ret %08x\n", hr ); 6846 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value)); 6847 6848 hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL); 6849 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6850 6851 V_VT(&value) = VT_EMPTY; 6852 hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value); 6853 ok(hr == S_FALSE, "ret %08x\n", hr ); 6854 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value)); 6855 6856 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node); 6857 ok(hr == S_OK, "ret %08x\n", hr ); 6858 6859 V_VT(&value) = VT_BSTR; 6860 V_BSTR(&value) = NULL; 6861 hr = IXMLDOMNode_get_nodeValue(node, &value); 6862 ok(hr == S_FALSE, "ret %08x\n", hr ); 6863 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value)); 6864 6865 hr = IXMLDOMNode_get_nodeTypedValue(node, NULL); 6866 ok(hr == E_INVALIDARG, "ret %08x\n", hr ); 6867 6868 IXMLDOMNode_Release(node); 6869 6870 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node); 6871 ok(hr == S_OK, "ret %08x\n", hr ); 6872 { 6873 BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c}; 6874 6875 hr = IXMLDOMNode_get_nodeTypedValue(node, &value); 6876 ok(hr == S_OK, "ret %08x\n", hr ); 6877 ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n"); 6878 ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n"); 6879 if(V_ARRAY(&value)->rgsabound[0].cElements == 6) 6880 ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n"); 6881 VariantClear(&value); 6882 IXMLDOMNode_Release(node); 6883 } 6884 6885 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi); 6886 ok(hr == S_OK, "ret %08x\n", hr ); 6887 { 6888 V_VT(&value) = VT_NULL; 6889 V_BSTR(&value) = (void*)0xdeadbeef; 6890 hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value); 6891 ok(hr == S_OK, "ret %08x\n", hr ); 6892 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value)); 6893 ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n"); 6894 IXMLDOMProcessingInstruction_Release(pi); 6895 VariantClear(&value); 6896 } 6897 6898 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee that's not right!"), &cdata); 6899 ok(hr == S_OK, "ret %08x\n", hr ); 6900 { 6901 V_VT(&value) = VT_NULL; 6902 V_BSTR(&value) = (void*)0xdeadbeef; 6903 hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value); 6904 ok(hr == S_OK, "ret %08x\n", hr ); 6905 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value)); 6906 ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee that's not right!")), "got wrong value\n"); 6907 IXMLDOMCDATASection_Release(cdata); 6908 VariantClear(&value); 6909 } 6910 6911 hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment); 6912 ok(hr == S_OK, "ret %08x\n", hr ); 6913 { 6914 V_VT(&value) = VT_NULL; 6915 V_BSTR(&value) = (void*)0xdeadbeef; 6916 hr = IXMLDOMComment_get_nodeTypedValue(comment, &value); 6917 ok(hr == S_OK, "ret %08x\n", hr ); 6918 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value)); 6919 ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n"); 6920 IXMLDOMComment_Release(comment); 6921 VariantClear(&value); 6922 } 6923 6924 hr = IXMLDOMDocument_createDocumentFragment(doc, &frag); 6925 ok(hr == S_OK, "ret %08x\n", hr ); 6926 { 6927 V_VT(&value) = VT_EMPTY; 6928 hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value); 6929 ok(hr == S_FALSE, "ret %08x\n", hr ); 6930 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value)); 6931 IXMLDOMDocumentFragment_Release(frag); 6932 } 6933 6934 doc2 = create_document(&IID_IXMLDOMDocument); 6935 6936 b = VARIANT_FALSE; 6937 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b); 6938 ok(hr == S_OK, "ret %08x\n", hr ); 6939 ok(b == VARIANT_TRUE, "got %d\n", b); 6940 6941 EXPECT_REF(doc2, 1); 6942 6943 hr = IXMLDOMDocument_get_doctype(doc2, &doctype); 6944 ok(hr == S_OK, "ret %08x\n", hr ); 6945 6946 EXPECT_REF(doc2, 1); 6947 todo_wine EXPECT_REF(doctype, 2); 6948 6949 { 6950 V_VT(&value) = VT_EMPTY; 6951 hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value); 6952 ok(hr == S_FALSE, "ret %08x\n", hr ); 6953 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value)); 6954 } 6955 6956 hr = IXMLDOMDocument_get_doctype(doc2, &doctype2); 6957 ok(hr == S_OK, "ret %08x\n", hr ); 6958 ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype); 6959 6960 IXMLDOMDocumentType_Release(doctype2); 6961 IXMLDOMDocumentType_Release(doctype); 6962 6963 IXMLDOMDocument_Release(doc2); 6964 6965 while (entry->name) 6966 { 6967 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node); 6968 ok(hr == S_OK, "ret %08x\n", hr ); 6969 6970 hr = IXMLDOMNode_get_nodeTypedValue(node, &value); 6971 ok(hr == S_OK, "ret %08x\n", hr ); 6972 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value)); 6973 6974 if (entry->type == (VT_ARRAY|VT_UI1)) 6975 { 6976 ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value), 6977 "incorrect array size %d\n", V_ARRAY(&value)->rgsabound[0].cElements); 6978 } 6979 6980 if (entry->type != VT_BSTR) 6981 { 6982 if (entry->type == VT_DATE || 6983 entry->type == VT_R8 || 6984 entry->type == VT_CY) 6985 { 6986 if (entry->type == VT_DATE) 6987 { 6988 hr = VariantChangeType(&value, &value, 0, VT_R4); 6989 ok(hr == S_OK, "ret %08x\n", hr ); 6990 } 6991 hr = VariantChangeTypeEx(&value, &value, 6992 MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT), 6993 VARIANT_NOUSEROVERRIDE, VT_BSTR); 6994 ok(hr == S_OK, "ret %08x\n", hr ); 6995 } 6996 else 6997 { 6998 hr = VariantChangeType(&value, &value, 0, VT_BSTR); 6999 ok(hr == S_OK, "ret %08x\n", hr ); 7000 } 7001 7002 /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */ 7003 if (entry->type == (VT_ARRAY|VT_UI1)) 7004 { 7005 ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)), 7006 "expected %s\n", entry->value); 7007 } 7008 else 7009 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0, 7010 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value))); 7011 } 7012 else 7013 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0, 7014 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value))); 7015 7016 VariantClear( &value ); 7017 IXMLDOMNode_Release(node); 7018 7019 entry++; 7020 } 7021 7022 IXMLDOMDocument_Release(doc); 7023 free_bstrs(); 7024 } 7025 7026 static void test_TransformWithLoadingLocalFile(void) 7027 { 7028 IXMLDOMDocument *doc; 7029 IXMLDOMDocument *xsl; 7030 IXMLDOMNode *pNode; 7031 VARIANT_BOOL bSucc; 7032 HRESULT hr; 7033 HANDLE file; 7034 DWORD dwWritten; 7035 char lpPathBuffer[MAX_PATH]; 7036 int i; 7037 7038 /* Create a Temp File. */ 7039 GetTempPathA(MAX_PATH, lpPathBuffer); 7040 strcat(lpPathBuffer, "customers.xml" ); 7041 7042 file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 7043 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError()); 7044 if(file == INVALID_HANDLE_VALUE) 7045 return; 7046 7047 WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL); 7048 CloseHandle(file); 7049 7050 /* Correct path to not include an escape character. */ 7051 for(i=0; i < strlen(lpPathBuffer); i++) 7052 { 7053 if(lpPathBuffer[i] == '\\') 7054 lpPathBuffer[i] = '/'; 7055 } 7056 7057 doc = create_document(&IID_IXMLDOMDocument); 7058 xsl = create_document(&IID_IXMLDOMDocument); 7059 7060 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc); 7061 ok(hr == S_OK, "ret %08x\n", hr ); 7062 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n"); 7063 if(bSucc == VARIANT_TRUE) 7064 { 7065 BSTR sXSL; 7066 BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1); 7067 BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2); 7068 BSTR sFileName = _bstr_(lpPathBuffer); 7069 int nLength = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1; 7070 7071 sXSL = SysAllocStringLen(NULL, nLength); 7072 lstrcpyW(sXSL, sPart1); 7073 lstrcatW(sXSL, sFileName); 7074 lstrcatW(sXSL, sPart2); 7075 7076 hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc); 7077 ok(hr == S_OK, "ret %08x\n", hr ); 7078 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n"); 7079 if(bSucc == VARIANT_TRUE) 7080 { 7081 BSTR sResult; 7082 7083 hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode ); 7084 ok(hr == S_OK, "ret %08x\n", hr ); 7085 if(hr == S_OK) 7086 { 7087 /* This will load the temp file via the XSL */ 7088 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult); 7089 ok(hr == S_OK, "ret %08x\n", hr ); 7090 if(hr == S_OK) 7091 { 7092 ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n"); 7093 SysFreeString(sResult); 7094 } 7095 7096 IXMLDOMNode_Release(pNode); 7097 } 7098 } 7099 7100 SysFreeString(sXSL); 7101 } 7102 7103 IXMLDOMDocument_Release(doc); 7104 IXMLDOMDocument_Release(xsl); 7105 7106 DeleteFileA(lpPathBuffer); 7107 free_bstrs(); 7108 } 7109 7110 static void test_put_nodeValue(void) 7111 { 7112 static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0}; 7113 IXMLDOMDocument *doc; 7114 IXMLDOMText *text; 7115 IXMLDOMEntityReference *entityref; 7116 IXMLDOMAttribute *attr; 7117 IXMLDOMNode *node; 7118 HRESULT hr; 7119 VARIANT data, type; 7120 7121 doc = create_document(&IID_IXMLDOMDocument); 7122 7123 /* test for unsupported types */ 7124 /* NODE_DOCUMENT */ 7125 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node); 7126 ok(hr == S_OK, "ret %08x\n", hr ); 7127 V_VT(&data) = VT_BSTR; 7128 V_BSTR(&data) = _bstr_("one two three"); 7129 hr = IXMLDOMNode_put_nodeValue(node, data); 7130 ok(hr == E_FAIL, "ret %08x\n", hr ); 7131 IXMLDOMNode_Release(node); 7132 7133 /* NODE_DOCUMENT_FRAGMENT */ 7134 V_VT(&type) = VT_I1; 7135 V_I1(&type) = NODE_DOCUMENT_FRAGMENT; 7136 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node); 7137 ok(hr == S_OK, "ret %08x\n", hr ); 7138 V_VT(&data) = VT_BSTR; 7139 V_BSTR(&data) = _bstr_("one two three"); 7140 hr = IXMLDOMNode_put_nodeValue(node, data); 7141 ok(hr == E_FAIL, "ret %08x\n", hr ); 7142 IXMLDOMNode_Release(node); 7143 7144 /* NODE_ELEMENT */ 7145 V_VT(&type) = VT_I1; 7146 V_I1(&type) = NODE_ELEMENT; 7147 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node); 7148 ok(hr == S_OK, "ret %08x\n", hr ); 7149 V_VT(&data) = VT_BSTR; 7150 V_BSTR(&data) = _bstr_("one two three"); 7151 hr = IXMLDOMNode_put_nodeValue(node, data); 7152 ok(hr == E_FAIL, "ret %08x\n", hr ); 7153 IXMLDOMNode_Release(node); 7154 7155 /* NODE_ENTITY_REFERENCE */ 7156 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref); 7157 ok(hr == S_OK, "ret %08x\n", hr ); 7158 7159 V_VT(&data) = VT_BSTR; 7160 V_BSTR(&data) = _bstr_("one two three"); 7161 hr = IXMLDOMEntityReference_put_nodeValue(entityref, data); 7162 ok(hr == E_FAIL, "ret %08x\n", hr ); 7163 7164 hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node); 7165 ok(hr == S_OK, "ret %08x\n", hr ); 7166 V_VT(&data) = VT_BSTR; 7167 V_BSTR(&data) = _bstr_("one two three"); 7168 hr = IXMLDOMNode_put_nodeValue(node, data); 7169 ok(hr == E_FAIL, "ret %08x\n", hr ); 7170 IXMLDOMNode_Release(node); 7171 IXMLDOMEntityReference_Release(entityref); 7172 7173 /* supported types */ 7174 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text); 7175 ok(hr == S_OK, "ret %08x\n", hr ); 7176 V_VT(&data) = VT_BSTR; 7177 V_BSTR(&data) = _bstr_("Jeeves & Wooster"); 7178 hr = IXMLDOMText_put_nodeValue(text, data); 7179 ok(hr == S_OK, "ret %08x\n", hr ); 7180 IXMLDOMText_Release(text); 7181 7182 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); 7183 ok(hr == S_OK, "ret %08x\n", hr ); 7184 V_VT(&data) = VT_BSTR; 7185 V_BSTR(&data) = _bstr_("Jeeves & Wooster"); 7186 hr = IXMLDOMAttribute_put_nodeValue(attr, data); 7187 ok(hr == S_OK, "ret %08x\n", hr ); 7188 hr = IXMLDOMAttribute_get_nodeValue(attr, &data); 7189 ok(hr == S_OK, "ret %08x\n", hr ); 7190 ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n", 7191 wine_dbgstr_w(V_BSTR(&data))); 7192 VariantClear(&data); 7193 IXMLDOMAttribute_Release(attr); 7194 7195 free_bstrs(); 7196 7197 IXMLDOMDocument_Release(doc); 7198 } 7199 7200 static void test_IObjectSafety(void) 7201 { 7202 IXMLDOMDocument *doc; 7203 IObjectSafety *safety; 7204 HRESULT hr; 7205 7206 doc = create_document(&IID_IXMLDOMDocument); 7207 7208 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety); 7209 ok(hr == S_OK, "ret %08x\n", hr ); 7210 7211 test_IObjectSafety_common(safety); 7212 7213 IObjectSafety_Release(safety); 7214 IXMLDOMDocument_Release(doc); 7215 7216 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, 7217 &IID_IObjectSafety, (void**)&safety); 7218 ok(hr == S_OK, "Could not create XMLHTTPRequest instance: %08x\n", hr); 7219 7220 test_IObjectSafety_common(safety); 7221 7222 IObjectSafety_Release(safety); 7223 7224 } 7225 7226 typedef struct _property_test_t { 7227 const GUID *guid; 7228 const char *clsid; 7229 const char *property; 7230 const char *value; 7231 } property_test_t; 7232 7233 static const property_test_t properties_test_data[] = { 7234 { &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" }, 7235 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" }, 7236 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" }, 7237 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" }, 7238 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" }, 7239 { 0 } 7240 }; 7241 7242 static void test_default_properties(void) 7243 { 7244 const property_test_t *entry = properties_test_data; 7245 7246 while (entry->guid) 7247 { 7248 IXMLDOMDocument2 *doc; 7249 VARIANT var; 7250 HRESULT hr; 7251 7252 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2)) 7253 { 7254 entry++; 7255 continue; 7256 } 7257 7258 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc); 7259 ok(hr == S_OK, "got 0x%08x\n", hr); 7260 7261 hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var); 7262 ok(hr == S_OK, "got 0x%08x\n", hr); 7263 ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n", 7264 entry->value, entry->clsid); 7265 VariantClear(&var); 7266 7267 IXMLDOMDocument2_Release(doc); 7268 7269 entry++; 7270 } 7271 } 7272 7273 typedef struct { 7274 const char *query; 7275 const char *list; 7276 BOOL todo; 7277 } xslpattern_test_t; 7278 7279 static const xslpattern_test_t xslpattern_test[] = { 7280 { "root//elem[0]", "E1.E2.D1" }, 7281 { "root//elem[index()=1]", "E2.E2.D1" }, 7282 { "root//elem[index() $eq$ 1]", "E2.E2.D1" }, 7283 { "root//elem[end()]", "E4.E2.D1" }, 7284 { "root//elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" }, 7285 { "root//elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 7286 { "root//elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 7287 { "root//elem[index() < 2]", "E1.E2.D1 E2.E2.D1" }, 7288 { "root//elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" }, 7289 { "root//elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" }, 7290 { "root//elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" }, 7291 { "root//elem[index() > 1]", "E3.E2.D1 E4.E2.D1" }, 7292 { "root//elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" }, 7293 { "root//elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" }, 7294 { "root//elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" }, 7295 { "root//elem[a $ieq$ 'a2 field']", "E2.E2.D1" }, 7296 { "root//elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" }, 7297 { "root//elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" }, 7298 { "root//elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" }, 7299 { "root//elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" }, 7300 { "root//elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" }, 7301 { "root//elem[$any$ *='B2 field']", "E2.E2.D1" }, 7302 { "root//elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" }, 7303 { "root//elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" }, 7304 { "root//elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" }, 7305 { "root//elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" }, 7306 { "root//elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7307 { "root//elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7308 { "root//elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7309 { "root/elem[0]", "E1.E2.D1" }, 7310 { "root/elem[index()=1]", "E2.E2.D1" }, 7311 { "root/elem[index() $eq$ 1]", "E2.E2.D1" }, 7312 { "root/elem[end()]", "E4.E2.D1" }, 7313 { "root/elem[$not$ end()]", "E1.E2.D1 E2.E2.D1 E3.E2.D1" }, 7314 { "root/elem[index() != 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 7315 { "root/elem[index() $ne$ 0]", "E2.E2.D1 E3.E2.D1 E4.E2.D1" }, 7316 { "root/elem[index() < 2]", "E1.E2.D1 E2.E2.D1" }, 7317 { "root/elem[index() $lt$ 2]", "E1.E2.D1 E2.E2.D1" }, 7318 { "root/elem[index() <= 1]", "E1.E2.D1 E2.E2.D1" }, 7319 { "root/elem[index() $le$ 1]", "E1.E2.D1 E2.E2.D1" }, 7320 { "root/elem[index() > 1]", "E3.E2.D1 E4.E2.D1" }, 7321 { "root/elem[index() $gt$ 1]", "E3.E2.D1 E4.E2.D1" }, 7322 { "root/elem[index() >= 2]", "E3.E2.D1 E4.E2.D1" }, 7323 { "root/elem[index() $ge$ 2]", "E3.E2.D1 E4.E2.D1" }, 7324 { "root/elem[a $ieq$ 'a2 field']", "E2.E2.D1" }, 7325 { "root/elem[a $ine$ 'a2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" }, 7326 { "root/elem[a $ilt$ 'a3 field']", "E1.E2.D1 E2.E2.D1" }, 7327 { "root/elem[a $ile$ 'a2 field']", "E1.E2.D1 E2.E2.D1" }, 7328 { "root/elem[a $igt$ 'a2 field']", "E3.E2.D1 E4.E2.D1" }, 7329 { "root/elem[a $ige$ 'a3 field']", "E3.E2.D1 E4.E2.D1" }, 7330 { "root/elem[$any$ *='B2 field']", "E2.E2.D1" }, 7331 { "root/elem[$all$ *!='B2 field']", "E1.E2.D1 E3.E2.D1 E4.E2.D1" }, 7332 { "root/elem[index()=0 or end()]", "E1.E2.D1 E4.E2.D1" }, 7333 { "root/elem[index()=0 $or$ end()]", "E1.E2.D1 E4.E2.D1" }, 7334 { "root/elem[index()=0 || end()]", "E1.E2.D1 E4.E2.D1" }, 7335 { "root/elem[index()>0 and $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7336 { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7337 { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" }, 7338 { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" }, 7339 { "root/elem[@*]", "E2.E2.D1 E3.E2.D1", TRUE }, 7340 { NULL } 7341 }; 7342 7343 static const xslpattern_test_t xslpattern_test_no_ns[] = { 7344 /* prefixes don't need to be registered, you may use them as they are in the doc */ 7345 { "//bar:x", "E6.E1.E5.E1.E2.D1 E6.E2.E5.E1.E2.D1" }, 7346 /* prefixes must be explicitly specified in the name */ 7347 { "//foo:elem", "" }, 7348 { "//foo:c", "E3.E4.E2.D1" }, 7349 { NULL } 7350 }; 7351 7352 static const xslpattern_test_t xslpattern_test_func[] = { 7353 { "attribute()", "" }, 7354 { "attribute('depth')", "" }, 7355 { "root/attribute('depth')", "A'depth'.E3.D1" }, 7356 { "//x/attribute()", "A'id'.E3.E3.D1 A'depth'.E3.E3.D1" }, 7357 { "//x//attribute(id)", NULL }, 7358 { "//x//attribute('id')", "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1" }, 7359 { "comment()", "C2.D1" }, 7360 { "//comment()", "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1" }, 7361 { "element()", "E3.D1" }, 7362 { "root/y/element()", "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1" }, 7363 { "//element(a)", NULL }, 7364 { "//element('a')", "E4.E3.E3.D1 E4.E4.E3.D1" }, 7365 { "node()", "P1.D1 C2.D1 E3.D1" }, 7366 { "//x/node()", "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" }, 7367 { "//x/node()[nodeType()=1]", "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1" }, 7368 { "//x/node()[nodeType()=3]", "T3.E3.E3.D1" }, 7369 { "//x/node()[nodeType()=7]", "P1.E3.E3.D1" }, 7370 { "//x/node()[nodeType()=8]", "C2.E3.E3.D1" }, 7371 { "pi()", "P1.D1" }, 7372 { "//y/pi()", "P1.E4.E3.D1" }, 7373 { "root/textnode()", "T2.E3.D1" }, 7374 { "root/element()/textnode()", "T3.E3.E3.D1 T3.E4.E3.D1" }, 7375 { NULL } 7376 }; 7377 7378 static void test_XSLPattern(void) 7379 { 7380 const xslpattern_test_t *ptr = xslpattern_test; 7381 IXMLDOMDocument2 *doc; 7382 IXMLDOMNodeList *list; 7383 VARIANT_BOOL b; 7384 HRESULT hr; 7385 LONG len; 7386 7387 doc = create_document(&IID_IXMLDOMDocument2); 7388 7389 b = VARIANT_FALSE; 7390 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b); 7391 EXPECT_HR(hr, S_OK); 7392 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 7393 7394 /* switch to XSLPattern */ 7395 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")); 7396 EXPECT_HR(hr, S_OK); 7397 7398 /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */ 7399 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list); 7400 EXPECT_HR(hr, S_OK); 7401 7402 len = 0; 7403 hr = IXMLDOMNodeList_get_length(list, &len); 7404 EXPECT_HR(hr, S_OK); 7405 /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */ 7406 ok(len == 3, "expected 3 entries in list, got %d\n", len); 7407 IXMLDOMNodeList_Release(list); 7408 7409 while (ptr->query) 7410 { 7411 list = NULL; 7412 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list); 7413 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr); 7414 len = 0; 7415 hr = IXMLDOMNodeList_get_length(list, &len); 7416 ok(len != 0, "query=%s, empty list\n", ptr->query); 7417 if (len) { 7418 if (ptr->todo) { 7419 char *str = list_to_string(list); 7420 todo_wine 7421 ok(!strcmp(str, ptr->list), "Invalid node list: %s, expected %s\n", str, ptr->list); 7422 IXMLDOMNodeList_Release(list); 7423 } 7424 else 7425 expect_list_and_release(list, ptr->list); 7426 } 7427 7428 ptr++; 7429 } 7430 7431 /* namespace handling */ 7432 /* no registered namespaces */ 7433 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")); 7434 EXPECT_HR(hr, S_OK); 7435 7436 ptr = xslpattern_test_no_ns; 7437 while (ptr->query) 7438 { 7439 list = NULL; 7440 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list); 7441 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr); 7442 7443 if (*ptr->list) 7444 { 7445 len = 0; 7446 hr = IXMLDOMNodeList_get_length(list, &len); 7447 EXPECT_HR(hr, S_OK); 7448 ok(len != 0, "query=%s, empty list\n", ptr->query); 7449 } 7450 else 7451 { 7452 len = 1; 7453 hr = IXMLDOMNodeList_get_length(list, &len); 7454 EXPECT_HR(hr, S_OK); 7455 ok(len == 0, "query=%s, empty list\n", ptr->query); 7456 } 7457 if (len) 7458 expect_list_and_release(list, ptr->list); 7459 7460 ptr++; 7461 } 7462 7463 /* explicitly register prefix foo */ 7464 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'"))); 7465 7466 /* now we get the same behavior as XPath */ 7467 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list); 7468 EXPECT_HR(hr, S_OK); 7469 len = 0; 7470 hr = IXMLDOMNodeList_get_length(list, &len); 7471 EXPECT_HR(hr, S_OK); 7472 ok(len != 0, "expected filled list\n"); 7473 if (len) 7474 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); 7475 7476 /* set prefix foo to some nonexistent namespace */ 7477 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'")); 7478 EXPECT_HR(hr, S_OK); 7479 7480 /* the registered prefix takes precedence */ 7481 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list); 7482 EXPECT_HR(hr, S_OK); 7483 len = 0; 7484 hr = IXMLDOMNodeList_get_length(list, &len); 7485 EXPECT_HR(hr, S_OK); 7486 ok(len == 0, "expected empty list\n"); 7487 IXMLDOMNodeList_Release(list); 7488 7489 IXMLDOMDocument2_Release(doc); 7490 7491 doc = create_document(&IID_IXMLDOMDocument2); 7492 7493 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b); 7494 EXPECT_HR(hr, S_OK); 7495 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 7496 7497 ptr = xslpattern_test_func; 7498 while (ptr->query) 7499 { 7500 list = NULL; 7501 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_(ptr->query), &list); 7502 if (ptr->list) 7503 { 7504 ok(hr == S_OK, "query=%s, failed with 0x%08x\n", ptr->query, hr); 7505 len = 0; 7506 hr = IXMLDOMNodeList_get_length(list, &len); 7507 ok(hr == S_OK, "Failed to get list length, hr %#x.\n", hr); 7508 if (*ptr->list) 7509 { 7510 ok(len != 0, "query=%s, empty list\n", ptr->query); 7511 if (len) 7512 expect_list_and_release(list, ptr->list); 7513 } 7514 else 7515 ok(len == 0, "query=%s, filled list\n", ptr->query); 7516 } 7517 else 7518 ok(hr == E_FAIL, "query=%s, failed with 0x%08x\n", ptr->query, hr); 7519 7520 ptr++; 7521 } 7522 7523 IXMLDOMDocument2_Release(doc); 7524 free_bstrs(); 7525 } 7526 7527 static void test_splitText(void) 7528 { 7529 IXMLDOMCDATASection *cdata; 7530 IXMLDOMElement *root; 7531 IXMLDOMDocument *doc; 7532 IXMLDOMText *text, *text2; 7533 IXMLDOMNode *node; 7534 VARIANT var; 7535 VARIANT_BOOL success; 7536 LONG length; 7537 HRESULT hr; 7538 7539 doc = create_document(&IID_IXMLDOMDocument); 7540 7541 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success); 7542 ok(hr == S_OK, "got 0x%08x\n", hr); 7543 7544 hr = IXMLDOMDocument_get_documentElement(doc, &root); 7545 ok(hr == S_OK, "got 0x%08x\n", hr); 7546 7547 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata); 7548 ok(hr == S_OK, "got 0x%08x\n", hr); 7549 7550 V_VT(&var) = VT_EMPTY; 7551 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL); 7552 ok(hr == S_OK, "got 0x%08x\n", hr); 7553 7554 length = 0; 7555 hr = IXMLDOMCDATASection_get_length(cdata, &length); 7556 ok(hr == S_OK, "got 0x%08x\n", hr); 7557 ok(length > 0, "got %d\n", length); 7558 7559 hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL); 7560 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7561 7562 text = (void*)0xdeadbeef; 7563 /* negative offset */ 7564 hr = IXMLDOMCDATASection_splitText(cdata, -1, &text); 7565 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7566 ok(text == (void*)0xdeadbeef, "got %p\n", text); 7567 7568 text = (void*)0xdeadbeef; 7569 /* offset outside data */ 7570 hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text); 7571 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7572 ok(text == 0, "got %p\n", text); 7573 7574 text = (void*)0xdeadbeef; 7575 /* offset outside data */ 7576 hr = IXMLDOMCDATASection_splitText(cdata, length, &text); 7577 ok(hr == S_FALSE, "got 0x%08x\n", hr); 7578 ok(text == 0, "got %p\n", text); 7579 7580 /* no empty node created */ 7581 node = (void*)0xdeadbeef; 7582 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node); 7583 ok(hr == S_FALSE, "got 0x%08x\n", hr); 7584 ok(node == 0, "got %p\n", text); 7585 7586 hr = IXMLDOMCDATASection_splitText(cdata, 10, &text); 7587 ok(hr == S_OK, "got 0x%08x\n", hr); 7588 7589 length = 0; 7590 hr = IXMLDOMText_get_length(text, &length); 7591 ok(hr == S_OK, "got 0x%08x\n", hr); 7592 ok(length == 7, "got %d\n", length); 7593 7594 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node); 7595 ok(hr == S_OK, "got 0x%08x\n", hr); 7596 IXMLDOMNode_Release(node); 7597 7598 /* split new text node */ 7599 hr = IXMLDOMText_get_length(text, &length); 7600 ok(hr == S_OK, "got 0x%08x\n", hr); 7601 7602 node = (void*)0xdeadbeef; 7603 hr = IXMLDOMText_get_nextSibling(text, &node); 7604 ok(hr == S_FALSE, "got 0x%08x\n", hr); 7605 ok(node == 0, "got %p\n", text); 7606 7607 hr = IXMLDOMText_splitText(text, 0, NULL); 7608 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7609 7610 text2 = (void*)0xdeadbeef; 7611 /* negative offset */ 7612 hr = IXMLDOMText_splitText(text, -1, &text2); 7613 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7614 ok(text2 == (void*)0xdeadbeef, "got %p\n", text2); 7615 7616 text2 = (void*)0xdeadbeef; 7617 /* offset outside data */ 7618 hr = IXMLDOMText_splitText(text, length + 1, &text2); 7619 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 7620 ok(text2 == 0, "got %p\n", text2); 7621 7622 text2 = (void*)0xdeadbeef; 7623 /* offset outside data */ 7624 hr = IXMLDOMText_splitText(text, length, &text2); 7625 ok(hr == S_FALSE, "got 0x%08x\n", hr); 7626 ok(text2 == 0, "got %p\n", text); 7627 7628 text2 = 0; 7629 hr = IXMLDOMText_splitText(text, 4, &text2); 7630 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); 7631 if (text2) IXMLDOMText_Release(text2); 7632 7633 node = 0; 7634 hr = IXMLDOMText_get_nextSibling(text, &node); 7635 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); 7636 if (node) IXMLDOMNode_Release(node); 7637 7638 IXMLDOMText_Release(text); 7639 IXMLDOMElement_Release(root); 7640 IXMLDOMCDATASection_Release(cdata); 7641 free_bstrs(); 7642 } 7643 7644 typedef struct { 7645 const char *name; 7646 const char *uri; 7647 HRESULT hr; 7648 } ns_item_t; 7649 7650 /* default_ns_doc used */ 7651 static const ns_item_t qualified_item_tests[] = { 7652 { "xml:lang", NULL, S_FALSE }, 7653 { "xml:lang", "http://www.w3.org/XML/1998/namespace", S_FALSE }, 7654 { "lang", "http://www.w3.org/XML/1998/namespace", S_OK }, 7655 { "ns:b", NULL, S_FALSE }, 7656 { "ns:b", "nshref", S_FALSE }, 7657 { "b", "nshref", S_OK }, 7658 { "d", NULL, S_OK }, 7659 { NULL } 7660 }; 7661 7662 static const ns_item_t named_item_tests[] = { 7663 { "xml:lang", NULL, S_OK }, 7664 { "lang", NULL, S_FALSE }, 7665 { "ns:b", NULL, S_OK }, 7666 { "b", NULL, S_FALSE }, 7667 { "d", NULL, S_OK }, 7668 { NULL } 7669 }; 7670 7671 static void test_getQualifiedItem(void) 7672 { 7673 IXMLDOMNode *pr_node, *node; 7674 IXMLDOMNodeList *root_list; 7675 IXMLDOMNamedNodeMap *map; 7676 IXMLDOMElement *element; 7677 const ns_item_t* ptr; 7678 IXMLDOMDocument *doc; 7679 VARIANT_BOOL b; 7680 HRESULT hr; 7681 LONG len; 7682 7683 doc = create_document(&IID_IXMLDOMDocument); 7684 7685 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 7686 EXPECT_HR(hr, S_OK); 7687 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 7688 7689 hr = IXMLDOMDocument_get_documentElement(doc, &element); 7690 EXPECT_HR(hr, S_OK); 7691 7692 hr = IXMLDOMElement_get_childNodes(element, &root_list); 7693 EXPECT_HR(hr, S_OK); 7694 7695 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node); 7696 EXPECT_HR(hr, S_OK); 7697 IXMLDOMNodeList_Release(root_list); 7698 7699 hr = IXMLDOMNode_get_attributes(pr_node, &map); 7700 EXPECT_HR(hr, S_OK); 7701 IXMLDOMNode_Release(pr_node); 7702 7703 len = 0; 7704 hr = IXMLDOMNamedNodeMap_get_length(map, &len); 7705 EXPECT_HR(hr, S_OK); 7706 ok( len == 3, "length %d\n", len); 7707 7708 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL); 7709 EXPECT_HR(hr, E_INVALIDARG); 7710 7711 node = (void*)0xdeadbeef; 7712 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node); 7713 EXPECT_HR(hr, E_INVALIDARG); 7714 ok( node == (void*)0xdeadbeef, "got %p\n", node); 7715 7716 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL); 7717 EXPECT_HR(hr, E_INVALIDARG); 7718 7719 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node); 7720 EXPECT_HR(hr, S_OK); 7721 7722 IXMLDOMNode_Release(node); 7723 IXMLDOMNamedNodeMap_Release(map); 7724 IXMLDOMElement_Release(element); 7725 7726 hr = IXMLDOMDocument_loadXML(doc, _bstr_(default_ns_doc), &b); 7727 EXPECT_HR(hr, S_OK); 7728 7729 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node); 7730 EXPECT_HR(hr, S_OK); 7731 7732 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element); 7733 EXPECT_HR(hr, S_OK); 7734 IXMLDOMNode_Release(node); 7735 7736 hr = IXMLDOMElement_get_attributes(element, &map); 7737 EXPECT_HR(hr, S_OK); 7738 7739 ptr = qualified_item_tests; 7740 while (ptr->name) 7741 { 7742 node = (void*)0xdeadbeef; 7743 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_(ptr->name), _bstr_(ptr->uri), &node); 7744 ok(hr == ptr->hr, "%s, %s: got 0x%08x, expected 0x%08x\n", ptr->name, ptr->uri, hr, ptr->hr); 7745 if (hr == S_OK) 7746 IXMLDOMNode_Release(node); 7747 else 7748 ok(node == NULL, "%s, %s: got %p\n", ptr->name, ptr->uri, node); 7749 ptr++; 7750 } 7751 7752 ptr = named_item_tests; 7753 while (ptr->name) 7754 { 7755 node = (void*)0xdeadbeef; 7756 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_(ptr->name), &node); 7757 ok(hr == ptr->hr, "%s: got 0x%08x, expected 0x%08x\n", ptr->name, hr, ptr->hr); 7758 if (hr == S_OK) 7759 IXMLDOMNode_Release(node); 7760 else 7761 ok(node == NULL, "%s: got %p\n", ptr->name, node); 7762 ptr++; 7763 } 7764 7765 IXMLDOMNamedNodeMap_Release(map); 7766 7767 IXMLDOMElement_Release(element); 7768 IXMLDOMDocument_Release(doc); 7769 free_bstrs(); 7770 } 7771 7772 static void test_removeQualifiedItem(void) 7773 { 7774 IXMLDOMDocument *doc; 7775 IXMLDOMElement *element; 7776 IXMLDOMNode *pr_node, *node; 7777 IXMLDOMNodeList *root_list; 7778 IXMLDOMNamedNodeMap *map; 7779 VARIANT_BOOL b; 7780 LONG len; 7781 HRESULT hr; 7782 7783 doc = create_document(&IID_IXMLDOMDocument); 7784 7785 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 7786 ok( hr == S_OK, "loadXML failed\n"); 7787 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 7788 7789 hr = IXMLDOMDocument_get_documentElement(doc, &element); 7790 ok( hr == S_OK, "ret %08x\n", hr); 7791 7792 hr = IXMLDOMElement_get_childNodes(element, &root_list); 7793 ok( hr == S_OK, "ret %08x\n", hr); 7794 7795 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node); 7796 ok( hr == S_OK, "ret %08x\n", hr); 7797 IXMLDOMNodeList_Release(root_list); 7798 7799 hr = IXMLDOMNode_get_attributes(pr_node, &map); 7800 ok( hr == S_OK, "ret %08x\n", hr); 7801 IXMLDOMNode_Release(pr_node); 7802 7803 hr = IXMLDOMNamedNodeMap_get_length(map, &len); 7804 ok( hr == S_OK, "ret %08x\n", hr); 7805 ok( len == 3, "length %d\n", len); 7806 7807 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL); 7808 ok( hr == E_INVALIDARG, "ret %08x\n", hr); 7809 7810 node = (void*)0xdeadbeef; 7811 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node); 7812 ok( hr == E_INVALIDARG, "ret %08x\n", hr); 7813 ok( node == (void*)0xdeadbeef, "got %p\n", node); 7814 7815 /* out pointer is optional */ 7816 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL); 7817 ok( hr == S_OK, "ret %08x\n", hr); 7818 7819 /* already removed */ 7820 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL); 7821 ok( hr == S_FALSE, "ret %08x\n", hr); 7822 7823 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node); 7824 ok( hr == S_OK, "ret %08x\n", hr); 7825 IXMLDOMNode_Release(node); 7826 7827 IXMLDOMNamedNodeMap_Release( map ); 7828 IXMLDOMElement_Release( element ); 7829 IXMLDOMDocument_Release( doc ); 7830 free_bstrs(); 7831 } 7832 7833 #define check_default_props(doc) _check_default_props(__LINE__, doc) 7834 static inline void _check_default_props(int line, IXMLDOMDocument2* doc) 7835 { 7836 VARIANT_BOOL b; 7837 VARIANT var; 7838 HRESULT hr; 7839 7840 VariantInit(&var); 7841 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var)); 7842 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n"); 7843 VariantClear(&var); 7844 7845 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var)); 7846 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n"); 7847 VariantClear(&var); 7848 7849 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b)); 7850 ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n"); 7851 7852 hr = IXMLDOMDocument2_get_schemas(doc, &var); 7853 ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr); 7854 VariantClear(&var); 7855 } 7856 7857 #define check_set_props(doc) _check_set_props(__LINE__, doc) 7858 static inline void _check_set_props(int line, IXMLDOMDocument2* doc) 7859 { 7860 VARIANT_BOOL b; 7861 VARIANT var; 7862 7863 VariantInit(&var); 7864 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var)); 7865 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n"); 7866 VariantClear(&var); 7867 7868 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var)); 7869 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var))); 7870 VariantClear(&var); 7871 7872 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b)); 7873 ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n"); 7874 7875 helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var)); 7876 ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n"); 7877 VariantClear(&var); 7878 } 7879 7880 #define set_props(doc, cache) _set_props(__LINE__, doc, cache) 7881 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache) 7882 { 7883 VARIANT var; 7884 7885 VariantInit(&var); 7886 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); 7887 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'"))); 7888 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE)); 7889 V_VT(&var) = VT_DISPATCH; 7890 V_DISPATCH(&var) = NULL; 7891 helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var))); 7892 ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n"); 7893 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var)); 7894 VariantClear(&var); 7895 } 7896 7897 #define unset_props(doc) _unset_props(__LINE__, doc) 7898 static inline void _unset_props(int line, IXMLDOMDocument2* doc) 7899 { 7900 VARIANT var; 7901 7902 VariantInit(&var); 7903 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"))); 7904 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_(""))); 7905 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE)); 7906 V_VT(&var) = VT_NULL; 7907 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var)); 7908 VariantClear(&var); 7909 } 7910 7911 static void test_get_ownerDocument(void) 7912 { 7913 IXMLDOMDocument *doc1, *doc2, *doc3; 7914 IXMLDOMDocument2 *doc, *doc_owner; 7915 IXMLDOMNode *node; 7916 IXMLDOMSchemaCollection *cache; 7917 VARIANT_BOOL b; 7918 VARIANT var; 7919 IXMLDOMElement *element; 7920 IXMLDOMNodeList *node_list; 7921 IXMLDOMAttribute *attr; 7922 LONG i, len; 7923 HRESULT hr; 7924 const CHAR nodeXML[] = 7925 "<root id='0'>" 7926 " <!-- comment node 0 -->" 7927 " text node 0" 7928 " <x attr='val'></x>" 7929 " <?foo value='PI for x'?>" 7930 " <![CDATA[ cdata ]]>" 7931 "</root>"; 7932 7933 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return; 7934 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return; 7935 7936 doc = create_document(&IID_IXMLDOMDocument2); 7937 cache = create_cache(&IID_IXMLDOMSchemaCollection); 7938 7939 VariantInit(&var); 7940 7941 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b)); 7942 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 7943 7944 check_default_props(doc); 7945 7946 /* set properties and check that new instances use them */ 7947 set_props(doc, cache); 7948 check_set_props(doc); 7949 7950 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node)); 7951 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1)); 7952 7953 /* new interface keeps props */ 7954 ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner)); 7955 ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc); 7956 check_set_props(doc_owner); 7957 IXMLDOMDocument2_Release(doc_owner); 7958 7959 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2)); 7960 IXMLDOMNode_Release(node); 7961 7962 ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc); 7963 7964 /* reload */ 7965 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b)); 7966 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 7967 7968 /* properties retained even after reload */ 7969 check_set_props(doc); 7970 7971 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node)); 7972 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3)); 7973 IXMLDOMNode_Release(node); 7974 7975 ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner)); 7976 ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2); 7977 check_set_props(doc_owner); 7978 7979 /* changing properties for one instance changes them for all */ 7980 unset_props(doc_owner); 7981 check_default_props(doc_owner); 7982 check_default_props(doc); 7983 7984 /* NULL check */ 7985 hr = IXMLDOMDocument_loadXML(doc1, _bstr_(nodeXML), &b); 7986 EXPECT_HR(hr, S_OK); 7987 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 7988 7989 hr = IXMLDOMDocument_get_documentElement(doc1, &element); 7990 EXPECT_HR(hr, S_OK); 7991 7992 hr = IXMLDOMElement_get_childNodes(element, &node_list); 7993 EXPECT_HR(hr, S_OK); 7994 7995 hr = IXMLDOMNodeList_get_length(node_list, &len); 7996 EXPECT_HR(hr, S_OK); 7997 7998 for(i = 0; i < len; i++) { 7999 hr = IXMLDOMNodeList_get_item(node_list, i, &node); 8000 EXPECT_HR(hr, S_OK); 8001 8002 hr = IXMLDOMNode_get_ownerDocument(node, NULL); 8003 EXPECT_HR(hr, E_INVALIDARG); 8004 8005 IXMLDOMNode_Release(node); 8006 } 8007 IXMLDOMElement_Release(element); 8008 8009 /* Test Attribute Node */ 8010 hr = IXMLDOMNodeList_get_item(node_list, 2, &node); 8011 EXPECT_HR(hr, S_OK); 8012 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&element); 8013 EXPECT_HR(hr, S_OK); 8014 IXMLDOMNode_Release(node); 8015 8016 hr = IXMLDOMElement_getAttributeNode(element, _bstr_("attr"), &attr); 8017 EXPECT_HR(hr, S_OK); 8018 ok(attr != NULL, "attr == NULL\n"); 8019 IXMLDOMElement_Release(element); 8020 hr = IXMLDOMAttribute_get_ownerDocument(attr, NULL); 8021 EXPECT_HR(hr, E_INVALIDARG); 8022 IXMLDOMAttribute_Release(attr); 8023 IXMLDOMNodeList_Release(node_list); 8024 8025 IXMLDOMSchemaCollection_Release(cache); 8026 IXMLDOMDocument_Release(doc1); 8027 IXMLDOMDocument_Release(doc2); 8028 IXMLDOMDocument_Release(doc3); 8029 IXMLDOMDocument2_Release(doc); 8030 //IXMLDOMDocument2_Release(doc_owner); FIXME: double-free! 8031 free_bstrs(); 8032 } 8033 8034 static void test_setAttributeNode(void) 8035 { 8036 IXMLDOMDocument *doc, *doc2; 8037 IXMLDOMElement *elem, *elem2; 8038 IXMLDOMAttribute *attr, *attr2, *ret_attr; 8039 VARIANT_BOOL b; 8040 HRESULT hr; 8041 VARIANT v; 8042 BSTR str; 8043 ULONG ref1, ref2; 8044 8045 doc = create_document(&IID_IXMLDOMDocument); 8046 8047 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 8048 ok( hr == S_OK, "loadXML failed\n"); 8049 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 8050 8051 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 8052 ok( hr == S_OK, "got 0x%08x\n", hr); 8053 8054 hr = IXMLDOMDocument_get_documentElement(doc, &elem2); 8055 ok( hr == S_OK, "got 0x%08x\n", hr); 8056 ok( elem2 != elem, "got same instance\n"); 8057 8058 ret_attr = (void*)0xdeadbeef; 8059 hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr); 8060 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr); 8061 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); 8062 8063 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); 8064 ok( hr == S_OK, "got 0x%08x\n", hr); 8065 8066 ref1 = IXMLDOMElement_AddRef(elem); 8067 IXMLDOMElement_Release(elem); 8068 8069 ret_attr = (void*)0xdeadbeef; 8070 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); 8071 ok( hr == S_OK, "got 0x%08x\n", hr); 8072 ok( ret_attr == NULL, "got %p\n", ret_attr); 8073 8074 /* no reference added */ 8075 ref2 = IXMLDOMElement_AddRef(elem); 8076 IXMLDOMElement_Release(elem); 8077 ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1); 8078 8079 EXPECT_CHILDREN(elem); 8080 EXPECT_CHILDREN(elem2); 8081 8082 IXMLDOMElement_Release(elem2); 8083 8084 attr2 = NULL; 8085 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2); 8086 ok( hr == S_OK, "got 0x%08x\n", hr); 8087 ok( attr2 != attr, "got same instance %p\n", attr2); 8088 IXMLDOMAttribute_Release(attr2); 8089 8090 /* try to add it another time */ 8091 ret_attr = (void*)0xdeadbeef; 8092 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); 8093 ok( hr == E_FAIL, "got 0x%08x\n", hr); 8094 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); 8095 8096 IXMLDOMElement_Release(elem); 8097 8098 /* initially used element is released, attribute still 'has' a container */ 8099 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 8100 ok( hr == S_OK, "got 0x%08x\n", hr); 8101 ret_attr = (void*)0xdeadbeef; 8102 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); 8103 ok( hr == E_FAIL, "got 0x%08x\n", hr); 8104 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); 8105 IXMLDOMElement_Release(elem); 8106 8107 /* add attribute already attached to another document */ 8108 doc2 = create_document(&IID_IXMLDOMDocument); 8109 8110 hr = IXMLDOMDocument_loadXML( doc2, _bstr_(complete4A), &b ); 8111 ok( hr == S_OK, "loadXML failed\n"); 8112 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 8113 8114 hr = IXMLDOMDocument_get_documentElement(doc2, &elem); 8115 ok( hr == S_OK, "got 0x%08x\n", hr); 8116 hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL); 8117 ok( hr == E_FAIL, "got 0x%08x\n", hr); 8118 IXMLDOMElement_Release(elem); 8119 8120 IXMLDOMAttribute_Release(attr); 8121 8122 /* create element, add attribute, see if it's copied or linked */ 8123 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem); 8124 ok( hr == S_OK, "got 0x%08x\n", hr); 8125 8126 attr = NULL; 8127 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); 8128 ok(hr == S_OK, "got 0x%08x\n", hr); 8129 ok(attr != NULL, "got %p\n", attr); 8130 8131 ref1 = IXMLDOMAttribute_AddRef(attr); 8132 IXMLDOMAttribute_Release(attr); 8133 8134 V_VT(&v) = VT_BSTR; 8135 V_BSTR(&v) = _bstr_("attrvalue1"); 8136 hr = IXMLDOMAttribute_put_nodeValue(attr, v); 8137 ok( hr == S_OK, "got 0x%08x\n", hr); 8138 8139 str = NULL; 8140 hr = IXMLDOMAttribute_get_xml(attr, &str); 8141 ok( hr == S_OK, "got 0x%08x\n", hr); 8142 ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0, 8143 "got %s\n", wine_dbgstr_w(str)); 8144 SysFreeString(str); 8145 8146 ret_attr = (void*)0xdeadbeef; 8147 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); 8148 ok(hr == S_OK, "got 0x%08x\n", hr); 8149 ok(ret_attr == NULL, "got %p\n", ret_attr); 8150 8151 /* attribute reference increased */ 8152 ref2 = IXMLDOMAttribute_AddRef(attr); 8153 IXMLDOMAttribute_Release(attr); 8154 ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1); 8155 8156 hr = IXMLDOMElement_get_xml(elem, &str); 8157 ok( hr == S_OK, "got 0x%08x\n", hr); 8158 ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0, 8159 "got %s\n", wine_dbgstr_w(str)); 8160 SysFreeString(str); 8161 8162 V_VT(&v) = VT_BSTR; 8163 V_BSTR(&v) = _bstr_("attrvalue2"); 8164 hr = IXMLDOMAttribute_put_nodeValue(attr, v); 8165 ok( hr == S_OK, "got 0x%08x\n", hr); 8166 8167 hr = IXMLDOMElement_get_xml(elem, &str); 8168 ok( hr == S_OK, "got 0x%08x\n", hr); 8169 todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0, 8170 "got %s\n", wine_dbgstr_w(str)); 8171 SysFreeString(str); 8172 8173 IXMLDOMElement_Release(elem); 8174 IXMLDOMAttribute_Release(attr); 8175 IXMLDOMDocument_Release(doc2); 8176 IXMLDOMDocument_Release(doc); 8177 free_bstrs(); 8178 } 8179 8180 static void test_createNode(void) 8181 { 8182 IXMLDOMDocument *doc; 8183 IXMLDOMElement *elem; 8184 IXMLDOMNode *node; 8185 VARIANT v, var; 8186 BSTR prefix, str; 8187 HRESULT hr; 8188 ULONG ref; 8189 8190 doc = create_document(&IID_IXMLDOMDocument); 8191 8192 EXPECT_REF(doc, 1); 8193 8194 /* reference count tests */ 8195 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem); 8196 ok( hr == S_OK, "got 0x%08x\n", hr); 8197 8198 /* initial reference is 2 */ 8199 todo_wine { 8200 EXPECT_REF(elem, 2); 8201 ref = IXMLDOMElement_Release(elem); 8202 ok(ref == 1, "got %d\n", ref); 8203 /* it's released already, attempt to release now will crash it */ 8204 } 8205 8206 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem); 8207 ok( hr == S_OK, "got 0x%08x\n", hr); 8208 todo_wine EXPECT_REF(elem, 2); 8209 IXMLDOMDocument_Release(doc); 8210 todo_wine EXPECT_REF(elem, 2); 8211 IXMLDOMElement_Release(elem); 8212 8213 doc = create_document(&IID_IXMLDOMDocument); 8214 8215 /* NODE_ELEMENT nodes */ 8216 /* 1. specified namespace */ 8217 V_VT(&v) = VT_I4; 8218 V_I4(&v) = NODE_ELEMENT; 8219 8220 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node); 8221 ok( hr == S_OK, "got 0x%08x\n", hr); 8222 prefix = NULL; 8223 hr = IXMLDOMNode_get_prefix(node, &prefix); 8224 ok( hr == S_OK, "got 0x%08x\n", hr); 8225 ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n"); 8226 SysFreeString(prefix); 8227 IXMLDOMNode_Release(node); 8228 8229 /* 2. default namespace */ 8230 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node); 8231 ok( hr == S_OK, "got 0x%08x\n", hr); 8232 prefix = (void*)0xdeadbeef; 8233 hr = IXMLDOMNode_get_prefix(node, &prefix); 8234 ok( hr == S_FALSE, "got 0x%08x\n", hr); 8235 ok(prefix == 0, "expected empty prefix, got %p\n", prefix); 8236 /* check dump */ 8237 hr = IXMLDOMNode_get_xml(node, &str); 8238 ok( hr == S_OK, "got 0x%08x\n", hr); 8239 ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0, 8240 "got %s\n", wine_dbgstr_w(str)); 8241 SysFreeString(str); 8242 8243 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem); 8244 ok( hr == S_OK, "got 0x%08x\n", hr); 8245 8246 V_VT(&var) = VT_BSTR; 8247 hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var); 8248 ok( hr == S_FALSE, "got 0x%08x\n", hr); 8249 ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var)); 8250 8251 str = NULL; 8252 hr = IXMLDOMElement_get_namespaceURI(elem, &str); 8253 ok( hr == S_OK, "got 0x%08x\n", hr); 8254 ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n"); 8255 SysFreeString(str); 8256 8257 IXMLDOMElement_Release(elem); 8258 IXMLDOMNode_Release(node); 8259 8260 IXMLDOMDocument_Release(doc); 8261 free_bstrs(); 8262 } 8263 8264 static const char get_prefix_doc[] = 8265 "<?xml version=\"1.0\" ?>" 8266 "<a xmlns:ns1=\"ns1 href\" />"; 8267 8268 static void test_get_prefix(void) 8269 { 8270 IXMLDOMDocumentFragment *fragment; 8271 IXMLDOMCDATASection *cdata; 8272 IXMLDOMElement *element; 8273 IXMLDOMComment *comment; 8274 IXMLDOMDocument *doc; 8275 VARIANT_BOOL b; 8276 HRESULT hr; 8277 BSTR str; 8278 8279 doc = create_document(&IID_IXMLDOMDocument); 8280 8281 /* nodes that can't support prefix */ 8282 /* 1. document */ 8283 str = (void*)0xdeadbeef; 8284 hr = IXMLDOMDocument_get_prefix(doc, &str); 8285 EXPECT_HR(hr, S_FALSE); 8286 ok(str == NULL, "got %p\n", str); 8287 8288 hr = IXMLDOMDocument_get_prefix(doc, NULL); 8289 EXPECT_HR(hr, E_INVALIDARG); 8290 8291 /* 2. cdata */ 8292 hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata); 8293 ok(hr == S_OK, "got %08x\n", hr ); 8294 8295 str = (void*)0xdeadbeef; 8296 hr = IXMLDOMCDATASection_get_prefix(cdata, &str); 8297 ok(hr == S_FALSE, "got %08x\n", hr); 8298 ok( str == 0, "got %p\n", str); 8299 8300 hr = IXMLDOMCDATASection_get_prefix(cdata, NULL); 8301 ok(hr == E_INVALIDARG, "got %08x\n", hr); 8302 IXMLDOMCDATASection_Release(cdata); 8303 8304 /* 3. comment */ 8305 hr = IXMLDOMDocument_createComment(doc, NULL, &comment); 8306 ok(hr == S_OK, "got %08x\n", hr ); 8307 8308 str = (void*)0xdeadbeef; 8309 hr = IXMLDOMComment_get_prefix(comment, &str); 8310 ok(hr == S_FALSE, "got %08x\n", hr); 8311 ok( str == 0, "got %p\n", str); 8312 8313 hr = IXMLDOMComment_get_prefix(comment, NULL); 8314 ok(hr == E_INVALIDARG, "got %08x\n", hr); 8315 IXMLDOMComment_Release(comment); 8316 8317 /* 4. fragment */ 8318 hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment); 8319 ok(hr == S_OK, "got %08x\n", hr ); 8320 8321 str = (void*)0xdeadbeef; 8322 hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str); 8323 ok(hr == S_FALSE, "got %08x\n", hr); 8324 ok( str == 0, "got %p\n", str); 8325 8326 hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL); 8327 ok(hr == E_INVALIDARG, "got %08x\n", hr); 8328 IXMLDOMDocumentFragment_Release(fragment); 8329 8330 /* no prefix */ 8331 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element); 8332 ok( hr == S_OK, "got 0x%08x\n", hr); 8333 8334 hr = IXMLDOMElement_get_prefix(element, NULL); 8335 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr); 8336 8337 str = (void*)0xdeadbeef; 8338 hr = IXMLDOMElement_get_prefix(element, &str); 8339 ok( hr == S_FALSE, "got 0x%08x\n", hr); 8340 ok( str == 0, "got %p\n", str); 8341 8342 IXMLDOMElement_Release(element); 8343 8344 /* with prefix */ 8345 hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element); 8346 ok( hr == S_OK, "got 0x%08x\n", hr); 8347 8348 str = (void*)0xdeadbeef; 8349 hr = IXMLDOMElement_get_prefix(element, &str); 8350 ok( hr == S_OK, "got 0x%08x\n", hr); 8351 ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n"); 8352 SysFreeString(str); 8353 8354 str = (void*)0xdeadbeef; 8355 hr = IXMLDOMElement_get_namespaceURI(element, &str); 8356 ok( hr == S_FALSE, "got 0x%08x\n", hr); 8357 ok( str == 0, "got %p\n", str); 8358 8359 IXMLDOMElement_Release(element); 8360 8361 hr = IXMLDOMDocument_loadXML(doc, _bstr_(get_prefix_doc), &b); 8362 EXPECT_HR(hr, S_OK); 8363 8364 hr = IXMLDOMDocument_get_documentElement(doc, &element); 8365 EXPECT_HR(hr, S_OK); 8366 8367 str = (void*)0xdeadbeef; 8368 hr = IXMLDOMElement_get_prefix(element, &str); 8369 EXPECT_HR(hr, S_FALSE); 8370 ok(str == NULL, "got %p\n", str); 8371 8372 str = (void*)0xdeadbeef; 8373 hr = IXMLDOMElement_get_namespaceURI(element, &str); 8374 EXPECT_HR(hr, S_FALSE); 8375 ok(str == NULL, "got %s\n", wine_dbgstr_w(str)); 8376 8377 IXMLDOMDocument_Release(doc); 8378 free_bstrs(); 8379 } 8380 8381 static void test_selectSingleNode(void) 8382 { 8383 IXMLDOMDocument *doc; 8384 IXMLDOMNodeList *list; 8385 IXMLDOMNode *node; 8386 VARIANT_BOOL b; 8387 HRESULT hr; 8388 LONG len; 8389 8390 doc = create_document(&IID_IXMLDOMDocument); 8391 8392 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL); 8393 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8394 8395 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL); 8396 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8397 8398 hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b ); 8399 ok( hr == S_OK, "loadXML failed\n"); 8400 ok( b == VARIANT_TRUE, "failed to load XML string\n"); 8401 8402 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL); 8403 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8404 8405 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL); 8406 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8407 8408 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL); 8409 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8410 8411 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL); 8412 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8413 8414 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node); 8415 ok(hr == S_OK, "got 0x%08x\n", hr); 8416 IXMLDOMNode_Release(node); 8417 8418 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list); 8419 ok(hr == S_OK, "got 0x%08x\n", hr); 8420 IXMLDOMNodeList_Release(list); 8421 8422 list = (void*)0xdeadbeef; 8423 hr = IXMLDOMDocument_selectNodes(doc, NULL, &list); 8424 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8425 ok(list == (void*)0xdeadbeef, "got %p\n", list); 8426 8427 node = (void*)0xdeadbeef; 8428 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node); 8429 ok(hr == S_FALSE, "got 0x%08x\n", hr); 8430 ok(node == 0, "got %p\n", node); 8431 8432 list = (void*)0xdeadbeef; 8433 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list); 8434 ok(hr == S_OK, "got 0x%08x\n", hr); 8435 len = 1; 8436 hr = IXMLDOMNodeList_get_length(list, &len); 8437 ok(hr == S_OK, "got 0x%08x\n", hr); 8438 ok(len == 0, "got %d\n", len); 8439 IXMLDOMNodeList_Release(list); 8440 8441 IXMLDOMDocument_Release(doc); 8442 free_bstrs(); 8443 } 8444 8445 static void test_events(void) 8446 { 8447 IConnectionPointContainer *conn; 8448 IConnectionPoint *point; 8449 IXMLDOMDocument *doc; 8450 HRESULT hr; 8451 VARIANT v; 8452 IDispatch *event; 8453 8454 doc = create_document(&IID_IXMLDOMDocument); 8455 8456 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn); 8457 ok(hr == S_OK, "got 0x%08x\n", hr); 8458 8459 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point); 8460 ok(hr == S_OK, "got 0x%08x\n", hr); 8461 IConnectionPoint_Release(point); 8462 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point); 8463 ok(hr == S_OK, "got 0x%08x\n", hr); 8464 IConnectionPoint_Release(point); 8465 hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point); 8466 ok(hr == S_OK, "got 0x%08x\n", hr); 8467 IConnectionPoint_Release(point); 8468 8469 IConnectionPointContainer_Release(conn); 8470 8471 /* ready state callback */ 8472 VariantInit(&v); 8473 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8474 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr); 8475 8476 event = create_dispevent(); 8477 V_VT(&v) = VT_UNKNOWN; 8478 V_UNKNOWN(&v) = (IUnknown*)event; 8479 8480 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8481 ok(hr == S_OK, "got 0x%08x\n", hr); 8482 EXPECT_REF(event, 2); 8483 8484 V_VT(&v) = VT_DISPATCH; 8485 V_DISPATCH(&v) = event; 8486 8487 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8488 ok(hr == S_OK, "got 0x%08x\n", hr); 8489 EXPECT_REF(event, 2); 8490 8491 /* VT_NULL doesn't reset event handler */ 8492 V_VT(&v) = VT_NULL; 8493 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8494 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr); 8495 EXPECT_REF(event, 2); 8496 8497 V_VT(&v) = VT_DISPATCH; 8498 V_DISPATCH(&v) = NULL; 8499 8500 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8501 ok(hr == S_OK, "got 0x%08x\n", hr); 8502 EXPECT_REF(event, 1); 8503 8504 V_VT(&v) = VT_UNKNOWN; 8505 V_DISPATCH(&v) = NULL; 8506 hr = IXMLDOMDocument_put_onreadystatechange(doc, v); 8507 ok(hr == S_OK, "got 0x%08x\n", hr); 8508 8509 IDispatch_Release(event); 8510 8511 IXMLDOMDocument_Release(doc); 8512 } 8513 8514 static void test_createProcessingInstruction(void) 8515 { 8516 static const WCHAR bodyW[] = {'t','e','s','t',0}; 8517 IXMLDOMProcessingInstruction *pi; 8518 IXMLDOMDocument *doc; 8519 WCHAR buff[10]; 8520 HRESULT hr; 8521 8522 doc = create_document(&IID_IXMLDOMDocument); 8523 8524 /* test for BSTR handling, pass broken BSTR */ 8525 memcpy(&buff[2], bodyW, sizeof(bodyW)); 8526 /* just a big length */ 8527 *(DWORD*)buff = 0xf0f0; 8528 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi); 8529 ok(hr == S_OK, "got 0x%08x\n", hr); 8530 8531 IXMLDOMProcessingInstruction_Release(pi); 8532 IXMLDOMDocument_Release(doc); 8533 } 8534 8535 static void test_put_nodeTypedValue(void) 8536 { 8537 static const BYTE binhexdata[16] = 8538 {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf}; 8539 IXMLDOMDocument *doc; 8540 IXMLDOMElement *elem; 8541 VARIANT type, value; 8542 LONG ubound, lbound; 8543 IXMLDOMNode *node; 8544 SAFEARRAY *array; 8545 HRESULT hr; 8546 BYTE *ptr; 8547 BSTR str; 8548 8549 doc = create_document(&IID_IXMLDOMDocument); 8550 8551 hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem); 8552 EXPECT_HR(hr, S_OK); 8553 8554 V_VT(&type) = VT_EMPTY; 8555 hr = IXMLDOMElement_get_dataType(elem, &type); 8556 EXPECT_HR(hr, S_FALSE); 8557 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type)); 8558 8559 /* set typed value for untyped node */ 8560 V_VT(&type) = VT_I1; 8561 V_I1(&type) = 1; 8562 hr = IXMLDOMElement_put_nodeTypedValue(elem, type); 8563 EXPECT_HR(hr, S_OK); 8564 8565 V_VT(&type) = VT_EMPTY; 8566 hr = IXMLDOMElement_get_dataType(elem, &type); 8567 EXPECT_HR(hr, S_FALSE); 8568 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type)); 8569 8570 /* no type info stored */ 8571 V_VT(&type) = VT_EMPTY; 8572 hr = IXMLDOMElement_get_nodeTypedValue(elem, &type); 8573 EXPECT_HR(hr, S_OK); 8574 ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type)); 8575 ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0, 8576 "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type))); 8577 VariantClear(&type); 8578 8579 hr = IXMLDOMElement_get_firstChild(elem, &node); 8580 EXPECT_HR(hr, S_OK); 8581 hr = IXMLDOMElement_removeChild(elem, node, NULL); 8582 EXPECT_HR(hr, S_OK); 8583 IXMLDOMNode_Release(node); 8584 8585 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)elem, NULL); 8586 EXPECT_HR(hr, S_OK); 8587 8588 /* bin.base64 */ 8589 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.base64")); 8590 EXPECT_HR(hr, S_OK); 8591 8592 V_VT(&value) = VT_BSTR; 8593 V_BSTR(&value) = _bstr_("ABCD"); 8594 hr = IXMLDOMElement_put_nodeTypedValue(elem, value); 8595 EXPECT_HR(hr, S_OK); 8596 8597 V_VT(&value) = VT_EMPTY; 8598 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value); 8599 EXPECT_HR(hr, S_OK); 8600 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value)); 8601 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n"); 8602 ubound = 0; 8603 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound); 8604 EXPECT_HR(hr, S_OK); 8605 ok(ubound == 2, "got %d\n", ubound); 8606 lbound = 0; 8607 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound); 8608 EXPECT_HR(hr, S_OK); 8609 ok(lbound == 0, "got %d\n", lbound); 8610 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr); 8611 EXPECT_HR(hr, S_OK); 8612 ok(ptr[0] == 0, "got %x\n", ptr[0]); 8613 ok(ptr[1] == 0x10, "got %x\n", ptr[1]); 8614 ok(ptr[2] == 0x83, "got %x\n", ptr[2]); 8615 SafeArrayUnaccessData(V_ARRAY(&value)); 8616 VariantClear(&value); 8617 8618 /* when set as VT_BSTR it's stored as is */ 8619 hr = IXMLDOMElement_get_firstChild(elem, &node); 8620 EXPECT_HR(hr, S_OK); 8621 hr = IXMLDOMNode_get_text(node, &str); 8622 EXPECT_HR(hr, S_OK); 8623 ok(!lstrcmpW(str, _bstr_("ABCD")), "%s\n", wine_dbgstr_w(str)); 8624 IXMLDOMNode_Release(node); 8625 SysFreeString(str); 8626 8627 array = SafeArrayCreateVector(VT_UI1, 0, 7); 8628 hr = SafeArrayAccessData(array, (void*)&ptr); 8629 EXPECT_HR(hr, S_OK); 8630 memcpy(ptr, "dGVzdA=", strlen("dGVzdA=")); 8631 SafeArrayUnaccessData(array); 8632 8633 V_VT(&value) = VT_UI1|VT_ARRAY; 8634 V_ARRAY(&value) = array; 8635 hr = IXMLDOMElement_put_nodeTypedValue(elem, value); 8636 EXPECT_HR(hr, S_OK); 8637 8638 V_VT(&value) = VT_EMPTY; 8639 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value); 8640 EXPECT_HR(hr, S_OK); 8641 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value)); 8642 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n"); 8643 ubound = 0; 8644 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound); 8645 EXPECT_HR(hr, S_OK); 8646 ok(ubound == 6, "got %d\n", ubound); 8647 lbound = 0; 8648 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound); 8649 EXPECT_HR(hr, S_OK); 8650 ok(lbound == 0, "got %d\n", lbound); 8651 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr); 8652 EXPECT_HR(hr, S_OK); 8653 ok(!memcmp(ptr, "dGVzdA=", strlen("dGVzdA=")), "got wrong data, %s\n", ptr); 8654 SafeArrayUnaccessData(V_ARRAY(&value)); 8655 VariantClear(&value); 8656 8657 /* if set with VT_UI1|VT_ARRAY it's encoded */ 8658 hr = IXMLDOMElement_get_firstChild(elem, &node); 8659 EXPECT_HR(hr, S_OK); 8660 hr = IXMLDOMNode_get_text(node, &str); 8661 EXPECT_HR(hr, S_OK); 8662 ok(!lstrcmpW(str, _bstr_("ZEdWemRBPQ==")), "%s\n", wine_dbgstr_w(str)); 8663 IXMLDOMNode_Release(node); 8664 SafeArrayDestroyData(array); 8665 SysFreeString(str); 8666 8667 /* bin.hex */ 8668 V_VT(&value) = VT_BSTR; 8669 V_BSTR(&value) = _bstr_(""); 8670 hr = IXMLDOMElement_put_nodeTypedValue(elem, value); 8671 EXPECT_HR(hr, S_OK); 8672 8673 hr = IXMLDOMElement_put_dataType(elem, _bstr_("bin.hex")); 8674 EXPECT_HR(hr, S_OK); 8675 8676 array = SafeArrayCreateVector(VT_UI1, 0, 16); 8677 hr = SafeArrayAccessData(array, (void*)&ptr); 8678 EXPECT_HR(hr, S_OK); 8679 memcpy(ptr, binhexdata, sizeof(binhexdata)); 8680 SafeArrayUnaccessData(array); 8681 8682 V_VT(&value) = VT_UI1|VT_ARRAY; 8683 V_ARRAY(&value) = array; 8684 hr = IXMLDOMElement_put_nodeTypedValue(elem, value); 8685 EXPECT_HR(hr, S_OK); 8686 8687 V_VT(&value) = VT_EMPTY; 8688 hr = IXMLDOMElement_get_nodeTypedValue(elem, &value); 8689 EXPECT_HR(hr, S_OK); 8690 ok(V_VT(&value) == (VT_UI1|VT_ARRAY), "got %d\n", V_VT(&value)); 8691 ok(SafeArrayGetDim(V_ARRAY(&value)) == 1, "got wrong dimension\n"); 8692 ubound = 0; 8693 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound); 8694 EXPECT_HR(hr, S_OK); 8695 ok(ubound == 15, "got %d\n", ubound); 8696 lbound = 0; 8697 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound); 8698 EXPECT_HR(hr, S_OK); 8699 ok(lbound == 0, "got %d\n", lbound); 8700 hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr); 8701 EXPECT_HR(hr, S_OK); 8702 ok(!memcmp(ptr, binhexdata, sizeof(binhexdata)), "got wrong data\n"); 8703 SafeArrayUnaccessData(V_ARRAY(&value)); 8704 VariantClear(&value); 8705 8706 /* if set with VT_UI1|VT_ARRAY it's encoded */ 8707 hr = IXMLDOMElement_get_firstChild(elem, &node); 8708 EXPECT_HR(hr, S_OK); 8709 hr = IXMLDOMNode_get_text(node, &str); 8710 EXPECT_HR(hr, S_OK); 8711 ok(!lstrcmpW(str, _bstr_("000102030405060708090a0b0c0d0e0f")), "%s\n", wine_dbgstr_w(str)); 8712 IXMLDOMNode_Release(node); 8713 SafeArrayDestroyData(array); 8714 SysFreeString(str); 8715 8716 IXMLDOMElement_Release(elem); 8717 IXMLDOMDocument_Release(doc); 8718 free_bstrs(); 8719 } 8720 8721 static void test_get_xml(void) 8722 { 8723 static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n"; 8724 static const char attrA[] = "attr=\""a & b"\""; 8725 static const char attr2A[] = "\"a & b\""; 8726 static const char attr3A[] = "attr=\"&quot;a\""; 8727 static const char attr4A[] = ""a"; 8728 static const char fooA[] = "<foo/>"; 8729 IXMLDOMProcessingInstruction *pi; 8730 IXMLDOMNode *first; 8731 IXMLDOMElement *elem = NULL; 8732 IXMLDOMAttribute *attr; 8733 IXMLDOMDocument *doc; 8734 VARIANT_BOOL b; 8735 VARIANT v; 8736 BSTR xml; 8737 HRESULT hr; 8738 8739 doc = create_document(&IID_IXMLDOMDocument); 8740 8741 b = VARIANT_TRUE; 8742 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b ); 8743 ok(hr == S_OK, "got 0x%08x\n", hr); 8744 ok( b == VARIANT_TRUE, "got %d\n", b); 8745 8746 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), 8747 _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi); 8748 ok(hr == S_OK, "got 0x%08x\n", hr); 8749 8750 hr = IXMLDOMDocument_get_firstChild(doc, &first); 8751 ok(hr == S_OK, "got 0x%08x\n", hr); 8752 8753 V_UNKNOWN(&v) = (IUnknown*)first; 8754 V_VT(&v) = VT_UNKNOWN; 8755 8756 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL); 8757 ok(hr == S_OK, "got 0x%08x\n", hr); 8758 8759 IXMLDOMProcessingInstruction_Release(pi); 8760 IXMLDOMNode_Release(first); 8761 8762 hr = IXMLDOMDocument_get_xml(doc, &xml); 8763 ok(hr == S_OK, "got 0x%08x\n", hr); 8764 8765 ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0, 8766 "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA); 8767 SysFreeString(xml); 8768 8769 IXMLDOMDocument_Release(doc); 8770 8771 doc = create_document(&IID_IXMLDOMDocument); 8772 8773 hr = IXMLDOMDocument_createElement(doc, _bstr_("foo"), &elem); 8774 ok(hr == S_OK, "got 0x%08x\n", hr); 8775 8776 hr = IXMLDOMDocument_putref_documentElement(doc, elem); 8777 ok(hr == S_OK, "got 0x%08x\n", hr); 8778 8779 hr = IXMLDOMDocument_get_xml(doc, &xml); 8780 ok(hr == S_OK, "got 0x%08x\n", hr); 8781 8782 ok(memcmp(xml, _bstr_(fooA), (sizeof(fooA)-1)*sizeof(WCHAR)) == 0, 8783 "got %s, expected %s\n", wine_dbgstr_w(xml), fooA); 8784 SysFreeString(xml); 8785 8786 IXMLDOMElement_Release(elem); 8787 8788 /* attribute node */ 8789 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr); 8790 ok(hr == S_OK, "got 0x%08x\n", hr); 8791 8792 V_VT(&v) = VT_BSTR; 8793 V_BSTR(&v) = _bstr_("\"a & b\""); 8794 hr = IXMLDOMAttribute_put_value(attr, v); 8795 ok(hr == S_OK, "got 0x%08x\n", hr); 8796 8797 xml = NULL; 8798 hr = IXMLDOMAttribute_get_xml(attr, &xml); 8799 ok(hr == S_OK, "got 0x%08x\n", hr); 8800 ok(!memcmp(xml, _bstr_(attrA), (sizeof(attrA)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml)); 8801 SysFreeString(xml); 8802 8803 VariantInit(&v); 8804 hr = IXMLDOMAttribute_get_value(attr, &v); 8805 ok(hr == S_OK, "got 0x%08x\n", hr); 8806 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v)); 8807 ok(!memcmp(V_BSTR(&v), _bstr_(attr2A), (sizeof(attr2A)-1)*sizeof(WCHAR)), 8808 "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 8809 VariantClear(&v); 8810 8811 V_VT(&v) = VT_BSTR; 8812 V_BSTR(&v) = _bstr_(""a"); 8813 hr = IXMLDOMAttribute_put_value(attr, v); 8814 ok(hr == S_OK, "got 0x%08x\n", hr); 8815 8816 xml = NULL; 8817 hr = IXMLDOMAttribute_get_xml(attr, &xml); 8818 ok(hr == S_OK, "got 0x%08x\n", hr); 8819 ok(!memcmp(xml, _bstr_(attr3A), (sizeof(attr3A)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml)); 8820 SysFreeString(xml); 8821 8822 VariantInit(&v); 8823 hr = IXMLDOMAttribute_get_value(attr, &v); 8824 ok(hr == S_OK, "got 0x%08x\n", hr); 8825 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v)); 8826 ok(!memcmp(V_BSTR(&v), _bstr_(attr4A), (sizeof(attr4A)-1)*sizeof(WCHAR)), 8827 "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 8828 VariantClear(&v); 8829 8830 IXMLDOMAttribute_Release(attr); 8831 8832 IXMLDOMDocument_Release(doc); 8833 8834 free_bstrs(); 8835 } 8836 8837 static void test_xsltemplate(void) 8838 { 8839 IXMLDOMDocument *doc, *doc2, *doc3; 8840 IXSLTemplate *template; 8841 IXSLProcessor *processor; 8842 IStream *stream; 8843 VARIANT_BOOL b; 8844 HRESULT hr; 8845 ULONG ref1, ref2; 8846 VARIANT v; 8847 BSTR str; 8848 8849 if (!is_clsid_supported(&CLSID_XSLTemplate, &IID_IXSLTemplate)) return; 8850 template = create_xsltemplate(&IID_IXSLTemplate); 8851 8852 /* works as reset */ 8853 hr = IXSLTemplate_putref_stylesheet(template, NULL); 8854 ok(hr == S_OK, "got 0x%08x\n", hr); 8855 8856 doc = create_document(&IID_IXMLDOMDocument); 8857 8858 b = VARIANT_TRUE; 8859 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b ); 8860 ok(hr == S_OK, "got 0x%08x\n", hr); 8861 ok( b == VARIANT_TRUE, "got %d\n", b); 8862 8863 /* putref with non-xsl document */ 8864 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc); 8865 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr); 8866 8867 b = VARIANT_TRUE; 8868 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b ); 8869 ok(hr == S_OK, "got 0x%08x\n", hr); 8870 ok( b == VARIANT_TRUE, "got %d\n", b); 8871 8872 /* not a freethreaded document */ 8873 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc); 8874 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr); 8875 8876 IXMLDOMDocument_Release(doc); 8877 8878 if (!is_clsid_supported(&CLSID_FreeThreadedDOMDocument, &IID_IXMLDOMDocument)) 8879 { 8880 IXSLTemplate_Release(template); 8881 return; 8882 } 8883 8884 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc); 8885 ok(hr == S_OK, "got 0x%08x\n", hr); 8886 8887 b = VARIANT_TRUE; 8888 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b ); 8889 ok(hr == S_OK, "got 0x%08x\n", hr); 8890 ok( b == VARIANT_TRUE, "got %d\n", b); 8891 8892 /* freethreaded document */ 8893 ref1 = IXMLDOMDocument_AddRef(doc); 8894 IXMLDOMDocument_Release(doc); 8895 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc); 8896 ok(hr == S_OK, "got 0x%08x\n", hr); 8897 ref2 = IXMLDOMDocument_AddRef(doc); 8898 IXMLDOMDocument_Release(doc); 8899 ok(ref2 > ref1, "got %d\n", ref2); 8900 8901 /* processor */ 8902 hr = IXSLTemplate_createProcessor(template, NULL); 8903 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8904 8905 EXPECT_REF(template, 1); 8906 hr = IXSLTemplate_createProcessor(template, &processor); 8907 ok(hr == S_OK, "got 0x%08x\n", hr); 8908 EXPECT_REF(template, 2); 8909 8910 /* input no set yet */ 8911 V_VT(&v) = VT_BSTR; 8912 V_BSTR(&v) = NULL; 8913 hr = IXSLProcessor_get_input(processor, &v); 8914 todo_wine { 8915 ok(hr == S_OK, "got 0x%08x\n", hr); 8916 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); 8917 } 8918 8919 hr = IXSLProcessor_get_output(processor, NULL); 8920 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8921 8922 /* reset before it was set */ 8923 V_VT(&v) = VT_EMPTY; 8924 hr = IXSLProcessor_put_output(processor, v); 8925 ok(hr == S_OK, "got 0x%08x\n", hr); 8926 8927 V_VT(&v) = VT_UNKNOWN; 8928 V_UNKNOWN(&v) = NULL; 8929 hr = IXSLProcessor_put_output(processor, v); 8930 ok(hr == S_OK, "got 0x%08x\n", hr); 8931 8932 V_VT(&v) = VT_UNKNOWN; 8933 V_DISPATCH(&v) = NULL; 8934 hr = IXSLProcessor_put_output(processor, v); 8935 ok(hr == S_OK, "got 0x%08x\n", hr); 8936 8937 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); 8938 ok(hr == S_OK, "got 0x%08x\n", hr); 8939 EXPECT_REF(stream, 1); 8940 8941 V_VT(&v) = VT_UNKNOWN; 8942 V_UNKNOWN(&v) = (IUnknown*)stream; 8943 hr = IXSLProcessor_put_output(processor, v); 8944 ok(hr == S_OK, "got 0x%08x\n", hr); 8945 8946 /* it seems processor grabs 2 references */ 8947 todo_wine EXPECT_REF(stream, 3); 8948 8949 V_VT(&v) = VT_EMPTY; 8950 hr = IXSLProcessor_get_output(processor, &v); 8951 ok(hr == S_OK, "got 0x%08x\n", hr); 8952 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v)); 8953 ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v)); 8954 8955 todo_wine EXPECT_REF(stream, 4); 8956 VariantClear(&v); 8957 8958 hr = IXSLProcessor_transform(processor, NULL); 8959 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 8960 8961 /* reset and check stream refcount */ 8962 V_VT(&v) = VT_EMPTY; 8963 hr = IXSLProcessor_put_output(processor, v); 8964 ok(hr == S_OK, "got 0x%08x\n", hr); 8965 8966 EXPECT_REF(stream, 1); 8967 8968 IStream_Release(stream); 8969 8970 /* no output interface set, check output */ 8971 doc2 = create_document(&IID_IXMLDOMDocument); 8972 8973 b = VARIANT_FALSE; 8974 hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b ); 8975 ok(hr == S_OK, "got 0x%08x\n", hr); 8976 ok( b == VARIANT_TRUE, "got %d\n", b); 8977 8978 V_VT(&v) = VT_UNKNOWN; 8979 V_UNKNOWN(&v) = (IUnknown*)doc2; 8980 hr = IXSLProcessor_put_input(processor, v); 8981 ok(hr == S_OK, "got 0x%08x\n", hr); 8982 8983 hr = IXSLProcessor_transform(processor, &b); 8984 ok(hr == S_OK, "got 0x%08x\n", hr); 8985 8986 V_VT(&v) = VT_EMPTY; 8987 hr = IXSLProcessor_get_output(processor, &v); 8988 ok(hr == S_OK, "got 0x%08x\n", hr); 8989 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v)); 8990 ok(*V_BSTR(&v) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 8991 VariantClear(&v); 8992 8993 /* transform to document */ 8994 b = VARIANT_FALSE; 8995 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformXML), &b); 8996 ok(hr == S_OK, "got 0x%08x\n", hr); 8997 ok(b == VARIANT_TRUE, "got %d\n", b); 8998 8999 V_VT(&v) = VT_UNKNOWN; 9000 V_UNKNOWN(&v) = (IUnknown*)doc2; 9001 hr = IXSLProcessor_put_input(processor, v); 9002 ok(hr == S_OK, "got 0x%08x\n", hr); 9003 9004 doc3 = create_document(&IID_IXMLDOMDocument); 9005 V_VT(&v) = VT_UNKNOWN; 9006 V_UNKNOWN(&v) = (IUnknown *)doc3; 9007 hr = IXSLProcessor_put_output(processor, v); 9008 ok(hr == S_OK, "got 0x%08x\n", hr); 9009 9010 hr = IXMLDOMDocument_get_xml(doc3, &str); 9011 ok(hr == S_OK, "got 0x%08x\n", hr); 9012 ok(!*str, "Expected empty document\n"); 9013 SysFreeString(str); 9014 9015 hr = IXSLProcessor_transform(processor, &b); 9016 ok(hr == S_OK, "got 0x%08x\n", hr); 9017 9018 V_VT(&v) = VT_EMPTY; 9019 hr = IXSLProcessor_get_output(processor, &v); 9020 ok(hr == S_OK, "got 0x%08x\n", hr); 9021 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v)); 9022 VariantClear(&v); 9023 9024 hr = IXMLDOMDocument_get_xml(doc3, &str); 9025 ok(hr == S_OK, "got 0x%08x\n", hr); 9026 ok(!!*str, "Expected document\n"); 9027 SysFreeString(str); 9028 9029 /* transform to IResponse */ 9030 V_VT(&v) = VT_EMPTY; 9031 hr = IXSLProcessor_put_output(processor, v); 9032 ok(hr == S_OK, "got 0x%08x\n", hr); 9033 9034 V_VT(&v) = VT_UNKNOWN; 9035 V_UNKNOWN(&v) = (IUnknown *)&testresponse; 9036 hr = IXSLProcessor_put_output(processor, v); 9037 ok(hr == S_OK, "got 0x%08x\n", hr); 9038 9039 b = VARIANT_FALSE; 9040 hr = IXSLProcessor_transform(processor, &b); 9041 ok(hr == S_OK, "got 0x%08x\n", hr); 9042 ok(b == VARIANT_TRUE, "got %x\n", b); 9043 9044 IXSLProcessor_Release(processor); 9045 IXMLDOMDocument_Release(doc2); 9046 IXMLDOMDocument_Release(doc3); 9047 9048 /* drop reference */ 9049 hr = IXSLTemplate_putref_stylesheet(template, NULL); 9050 ok(hr == S_OK, "got 0x%08x\n", hr); 9051 ref2 = IXMLDOMDocument_AddRef(doc); 9052 IXMLDOMDocument_Release(doc); 9053 ok(ref2 == ref1, "got %d\n", ref2); 9054 9055 IXMLDOMDocument_Release(doc); 9056 IXSLTemplate_Release(template); 9057 free_bstrs(); 9058 } 9059 9060 static void test_insertBefore(void) 9061 { 9062 IXMLDOMDocument *doc, *doc2, *doc3; 9063 IXMLDOMAttribute *attr; 9064 IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5; 9065 IXMLDOMNode *node, *newnode, *cdata; 9066 HRESULT hr; 9067 VARIANT v; 9068 BSTR p; 9069 9070 doc = create_document(&IID_IXMLDOMDocument); 9071 doc3 = create_document(&IID_IXMLDOMDocument); 9072 9073 /* document to document */ 9074 V_VT(&v) = VT_NULL; 9075 node = (void*)0xdeadbeef; 9076 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc3, v, &node); 9077 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9078 ok(node == NULL, "got %p\n", node); 9079 9080 /* document to itself */ 9081 V_VT(&v) = VT_NULL; 9082 node = (void*)0xdeadbeef; 9083 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc, v, &node); 9084 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9085 ok(node == NULL, "got %p\n", node); 9086 9087 /* insertBefore behaviour for attribute node */ 9088 V_VT(&v) = VT_I4; 9089 V_I4(&v) = NODE_ATTRIBUTE; 9090 9091 attr = NULL; 9092 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr); 9093 ok(hr == S_OK, "got 0x%08x\n", hr); 9094 ok(attr != NULL, "got %p\n", attr); 9095 9096 /* attribute to document */ 9097 V_VT(&v) = VT_NULL; 9098 node = (void*)0xdeadbeef; 9099 hr = IXMLDOMDocument_insertBefore(doc3, (IXMLDOMNode*)attr, v, &node); 9100 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9101 ok(node == NULL, "got %p\n", node); 9102 9103 /* cdata to document */ 9104 V_VT(&v) = VT_I4; 9105 V_I4(&v) = NODE_CDATA_SECTION; 9106 9107 cdata = NULL; 9108 hr = IXMLDOMDocument_createNode(doc3, v, _bstr_("cdata"), NULL, &cdata); 9109 ok(hr == S_OK, "got 0x%08x\n", hr); 9110 ok(cdata != NULL, "got %p\n", cdata); 9111 9112 EXPECT_NO_CHILDREN(cdata); 9113 9114 /* attribute to cdata */ 9115 V_VT(&v) = VT_NULL; 9116 node = (void*)0xdeadbeef; 9117 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)attr, v, &node); 9118 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9119 ok(node == NULL, "got %p\n", node); 9120 9121 /* document to cdata */ 9122 V_VT(&v) = VT_NULL; 9123 node = (void*)0xdeadbeef; 9124 hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)doc, v, &node); 9125 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9126 ok(node == NULL, "got %p\n", node); 9127 9128 V_VT(&v) = VT_NULL; 9129 node = (void*)0xdeadbeef; 9130 hr = IXMLDOMDocument_insertBefore(doc3, cdata, v, &node); 9131 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9132 ok(node == NULL, "got %p\n", node); 9133 9134 IXMLDOMNode_Release(cdata); 9135 IXMLDOMDocument_Release(doc3); 9136 9137 /* attribute to attribute */ 9138 V_VT(&v) = VT_I4; 9139 V_I4(&v) = NODE_ATTRIBUTE; 9140 newnode = NULL; 9141 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode); 9142 ok(hr == S_OK, "got 0x%08x\n", hr); 9143 ok(newnode != NULL, "got %p\n", newnode); 9144 9145 V_VT(&v) = VT_NULL; 9146 node = (void*)0xdeadbeef; 9147 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9148 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9149 ok(node == NULL, "got %p\n", node); 9150 9151 V_VT(&v) = VT_UNKNOWN; 9152 V_UNKNOWN(&v) = (IUnknown*)attr; 9153 node = (void*)0xdeadbeef; 9154 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9155 todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9156 ok(node == NULL, "got %p\n", node); 9157 IXMLDOMNode_Release(newnode); 9158 9159 /* cdata to attribute */ 9160 V_VT(&v) = VT_I4; 9161 V_I4(&v) = NODE_CDATA_SECTION; 9162 newnode = NULL; 9163 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); 9164 ok(hr == S_OK, "got 0x%08x\n", hr); 9165 ok(newnode != NULL, "got %p\n", newnode); 9166 9167 V_VT(&v) = VT_NULL; 9168 node = (void*)0xdeadbeef; 9169 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9170 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9171 ok(node == NULL, "got %p\n", node); 9172 IXMLDOMNode_Release(newnode); 9173 9174 /* comment to attribute */ 9175 V_VT(&v) = VT_I4; 9176 V_I4(&v) = NODE_COMMENT; 9177 newnode = NULL; 9178 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); 9179 ok(hr == S_OK, "got 0x%08x\n", hr); 9180 ok(newnode != NULL, "got %p\n", newnode); 9181 9182 V_VT(&v) = VT_NULL; 9183 node = (void*)0xdeadbeef; 9184 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9185 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9186 ok(node == NULL, "got %p\n", node); 9187 IXMLDOMNode_Release(newnode); 9188 9189 /* element to attribute */ 9190 V_VT(&v) = VT_I4; 9191 V_I4(&v) = NODE_ELEMENT; 9192 newnode = NULL; 9193 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); 9194 ok(hr == S_OK, "got 0x%08x\n", hr); 9195 ok(newnode != NULL, "got %p\n", newnode); 9196 9197 V_VT(&v) = VT_NULL; 9198 node = (void*)0xdeadbeef; 9199 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9200 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9201 ok(node == NULL, "got %p\n", node); 9202 IXMLDOMNode_Release(newnode); 9203 9204 /* pi to attribute */ 9205 V_VT(&v) = VT_I4; 9206 V_I4(&v) = NODE_PROCESSING_INSTRUCTION; 9207 newnode = NULL; 9208 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode); 9209 ok(hr == S_OK, "got 0x%08x\n", hr); 9210 ok(newnode != NULL, "got %p\n", newnode); 9211 9212 V_VT(&v) = VT_NULL; 9213 node = (void*)0xdeadbeef; 9214 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node); 9215 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9216 ok(node == NULL, "got %p\n", node); 9217 IXMLDOMNode_Release(newnode); 9218 IXMLDOMAttribute_Release(attr); 9219 9220 /* insertBefore for elements */ 9221 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1); 9222 ok(hr == S_OK, "got 0x%08x\n", hr); 9223 9224 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2); 9225 ok(hr == S_OK, "got 0x%08x\n", hr); 9226 9227 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3); 9228 ok(hr == S_OK, "got 0x%08x\n", hr); 9229 9230 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3); 9231 ok(hr == S_OK, "got 0x%08x\n", hr); 9232 9233 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem4"), &elem4); 9234 ok(hr == S_OK, "got 0x%08x\n", hr); 9235 9236 EXPECT_NO_CHILDREN(elem1); 9237 EXPECT_NO_CHILDREN(elem2); 9238 EXPECT_NO_CHILDREN(elem3); 9239 9240 todo_wine EXPECT_REF(elem2, 2); 9241 9242 /* document to element */ 9243 V_VT(&v) = VT_DISPATCH; 9244 V_DISPATCH(&v) = NULL; 9245 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)doc, v, NULL); 9246 ok(hr == E_FAIL, "got 0x%08x\n", hr); 9247 9248 V_VT(&v) = VT_DISPATCH; 9249 V_DISPATCH(&v) = NULL; 9250 node = NULL; 9251 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem4, v, &node); 9252 ok(hr == S_OK, "got 0x%08x\n", hr); 9253 ok(node == (void*)elem4, "got %p\n", node); 9254 9255 EXPECT_CHILDREN(elem1); 9256 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem4, NULL); 9257 EXPECT_HR(hr, S_OK); 9258 IXMLDOMElement_Release(elem4); 9259 9260 EXPECT_NO_CHILDREN(elem1); 9261 9262 V_VT(&v) = VT_NULL; 9263 node = NULL; 9264 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node); 9265 ok(hr == S_OK, "got 0x%08x\n", hr); 9266 ok(node == (void*)elem2, "got %p\n", node); 9267 9268 EXPECT_CHILDREN(elem1); 9269 todo_wine EXPECT_REF(elem2, 3); 9270 IXMLDOMNode_Release(node); 9271 9272 /* again for already linked node */ 9273 V_VT(&v) = VT_NULL; 9274 node = NULL; 9275 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node); 9276 ok(hr == S_OK, "got 0x%08x\n", hr); 9277 ok(node == (void*)elem2, "got %p\n", node); 9278 9279 EXPECT_CHILDREN(elem1); 9280 9281 /* increments each time */ 9282 todo_wine EXPECT_REF(elem2, 3); 9283 IXMLDOMNode_Release(node); 9284 9285 /* try to add to another element */ 9286 V_VT(&v) = VT_NULL; 9287 node = (void*)0xdeadbeef; 9288 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node); 9289 ok(hr == S_OK, "got 0x%08x\n", hr); 9290 ok(node == (void*)elem2, "got %p\n", node); 9291 9292 EXPECT_CHILDREN(elem3); 9293 EXPECT_NO_CHILDREN(elem1); 9294 9295 IXMLDOMNode_Release(node); 9296 9297 /* cross document case - try to add as child to a node created with other doc */ 9298 doc2 = create_document(&IID_IXMLDOMDocument); 9299 9300 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4); 9301 ok(hr == S_OK, "got 0x%08x\n", hr); 9302 todo_wine EXPECT_REF(elem4, 2); 9303 9304 /* same name, another instance */ 9305 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5); 9306 ok(hr == S_OK, "got 0x%08x\n", hr); 9307 todo_wine EXPECT_REF(elem5, 2); 9308 9309 todo_wine EXPECT_REF(elem3, 2); 9310 V_VT(&v) = VT_NULL; 9311 node = NULL; 9312 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node); 9313 ok(hr == S_OK, "got 0x%08x\n", hr); 9314 ok(node == (void*)elem4, "got %p\n", node); 9315 todo_wine EXPECT_REF(elem4, 3); 9316 todo_wine EXPECT_REF(elem3, 2); 9317 IXMLDOMNode_Release(node); 9318 9319 V_VT(&v) = VT_NULL; 9320 node = NULL; 9321 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node); 9322 ok(hr == S_OK, "got 0x%08x\n", hr); 9323 ok(node == (void*)elem5, "got %p\n", node); 9324 todo_wine EXPECT_REF(elem4, 2); 9325 todo_wine EXPECT_REF(elem5, 3); 9326 IXMLDOMNode_Release(node); 9327 9328 IXMLDOMDocument_Release(doc2); 9329 9330 IXMLDOMElement_Release(elem1); 9331 IXMLDOMElement_Release(elem2); 9332 IXMLDOMElement_Release(elem3); 9333 IXMLDOMElement_Release(elem4); 9334 IXMLDOMElement_Release(elem5); 9335 9336 /* elements with same default namespace */ 9337 V_VT(&v) = VT_I4; 9338 V_I4(&v) = NODE_ELEMENT; 9339 elem1 = NULL; 9340 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1); 9341 ok(hr == S_OK, "got 0x%08x\n", hr); 9342 ok(elem1 != NULL, "got %p\n", elem1); 9343 9344 V_VT(&v) = VT_I4; 9345 V_I4(&v) = NODE_ELEMENT; 9346 elem2 = NULL; 9347 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2); 9348 ok(hr == S_OK, "got 0x%08x\n", hr); 9349 ok(elem2 != NULL, "got %p\n", elem2); 9350 9351 /* check contents so far */ 9352 p = NULL; 9353 hr = IXMLDOMElement_get_xml(elem1, &p); 9354 ok(hr == S_OK, "got 0x%08x\n", hr); 9355 ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p)); 9356 SysFreeString(p); 9357 9358 p = NULL; 9359 hr = IXMLDOMElement_get_xml(elem2, &p); 9360 ok(hr == S_OK, "got 0x%08x\n", hr); 9361 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p)); 9362 SysFreeString(p); 9363 9364 V_VT(&v) = VT_NULL; 9365 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL); 9366 ok(hr == S_OK, "got 0x%08x\n", hr); 9367 9368 /* get_xml depends on context, for top node it omits child namespace attribute, 9369 but at child level it's still returned */ 9370 p = NULL; 9371 hr = IXMLDOMElement_get_xml(elem1, &p); 9372 ok(hr == S_OK, "got 0x%08x\n", hr); 9373 todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")), 9374 "got %s\n", wine_dbgstr_w(p)); 9375 SysFreeString(p); 9376 9377 p = NULL; 9378 hr = IXMLDOMElement_get_xml(elem2, &p); 9379 ok(hr == S_OK, "got 0x%08x\n", hr); 9380 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p)); 9381 SysFreeString(p); 9382 9383 IXMLDOMElement_Release(elem1); 9384 IXMLDOMElement_Release(elem2); 9385 9386 /* child without default namespace added to node with default namespace */ 9387 V_VT(&v) = VT_I4; 9388 V_I4(&v) = NODE_ELEMENT; 9389 elem1 = NULL; 9390 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1); 9391 ok(hr == S_OK, "got 0x%08x\n", hr); 9392 ok(elem1 != NULL, "got %p\n", elem1); 9393 9394 V_VT(&v) = VT_I4; 9395 V_I4(&v) = NODE_ELEMENT; 9396 elem2 = NULL; 9397 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2); 9398 ok(hr == S_OK, "got 0x%08x\n", hr); 9399 ok(elem2 != NULL, "got %p\n", elem2); 9400 9401 EXPECT_REF(elem2, 1); 9402 V_VT(&v) = VT_NULL; 9403 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL); 9404 ok(hr == S_OK, "got 0x%08x\n", hr); 9405 EXPECT_REF(elem2, 1); 9406 9407 p = NULL; 9408 hr = IXMLDOMElement_get_xml(elem2, &p); 9409 ok(hr == S_OK, "got 0x%08x\n", hr); 9410 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p)); 9411 SysFreeString(p); 9412 9413 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL); 9414 ok(hr == S_OK, "got 0x%08x\n", hr); 9415 9416 p = NULL; 9417 hr = IXMLDOMElement_get_xml(elem2, &p); 9418 ok(hr == S_OK, "got 0x%08x\n", hr); 9419 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p)); 9420 SysFreeString(p); 9421 9422 IXMLDOMElement_Release(elem1); 9423 IXMLDOMElement_Release(elem2); 9424 IXMLDOMDocument_Release(doc); 9425 } 9426 9427 static void test_appendChild(void) 9428 { 9429 IXMLDOMDocument *doc, *doc2; 9430 IXMLDOMElement *elem, *elem2; 9431 HRESULT hr; 9432 9433 doc = create_document(&IID_IXMLDOMDocument); 9434 doc2 = create_document(&IID_IXMLDOMDocument); 9435 9436 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem); 9437 ok(hr == S_OK, "got 0x%08x\n", hr); 9438 9439 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2); 9440 ok(hr == S_OK, "got 0x%08x\n", hr); 9441 9442 EXPECT_REF(doc, 1); 9443 todo_wine EXPECT_REF(elem, 2); 9444 EXPECT_REF(doc2, 1); 9445 todo_wine EXPECT_REF(elem2, 2); 9446 EXPECT_NO_CHILDREN(doc); 9447 EXPECT_NO_CHILDREN(doc2); 9448 9449 hr = IXMLDOMDocument_appendChild(doc2, NULL, NULL); 9450 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9451 9452 hr = IXMLDOMElement_appendChild(elem, NULL, NULL); 9453 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9454 9455 /* append from another document */ 9456 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL); 9457 ok(hr == S_OK, "got 0x%08x\n", hr); 9458 9459 EXPECT_REF(doc, 1); 9460 todo_wine EXPECT_REF(elem, 2); 9461 EXPECT_REF(doc2, 1); 9462 todo_wine EXPECT_REF(elem2, 2); 9463 EXPECT_NO_CHILDREN(doc); 9464 EXPECT_CHILDREN(doc2); 9465 9466 IXMLDOMElement_Release(elem); 9467 IXMLDOMElement_Release(elem2); 9468 IXMLDOMDocument_Release(doc); 9469 IXMLDOMDocument_Release(doc2); 9470 } 9471 9472 static void test_get_doctype(void) 9473 { 9474 static const WCHAR emailW[] = {'e','m','a','i','l',0}; 9475 IXMLDOMDocumentType *doctype; 9476 IXMLDOMDocument *doc; 9477 VARIANT_BOOL b; 9478 HRESULT hr; 9479 BSTR s; 9480 9481 doc = create_document(&IID_IXMLDOMDocument); 9482 9483 hr = IXMLDOMDocument_get_doctype(doc, NULL); 9484 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9485 9486 doctype = (void*)0xdeadbeef; 9487 hr = IXMLDOMDocument_get_doctype(doc, &doctype); 9488 ok(hr == S_FALSE, "got 0x%08x\n", hr); 9489 ok(doctype == NULL, "got %p\n", doctype); 9490 9491 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szEmailXML), &b); 9492 ok(hr == S_OK, "got 0x%08x\n", hr); 9493 ok(b == VARIANT_TRUE, "failed to load XML string\n"); 9494 9495 doctype = NULL; 9496 hr = IXMLDOMDocument_get_doctype(doc, &doctype); 9497 ok(hr == S_OK, "got 0x%08x\n", hr); 9498 ok(doctype != NULL, "got %p\n", doctype); 9499 9500 hr = IXMLDOMDocumentType_get_name(doctype, NULL); 9501 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9502 9503 hr = IXMLDOMDocumentType_get_name(doctype, &s); 9504 ok(hr == S_OK, "got 0x%08x\n", hr); 9505 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s)); 9506 SysFreeString(s); 9507 9508 hr = IXMLDOMDocumentType_get_nodeName(doctype, &s); 9509 ok(hr == S_OK, "got 0x%08x\n", hr); 9510 ok(!lstrcmpW(emailW, s), "got name %s\n", wine_dbgstr_w(s)); 9511 SysFreeString(s); 9512 9513 IXMLDOMDocumentType_Release(doctype); 9514 IXMLDOMDocument_Release(doc); 9515 } 9516 9517 static void test_get_tagName(void) 9518 { 9519 IXMLDOMDocument *doc; 9520 IXMLDOMElement *elem, *elem2; 9521 HRESULT hr; 9522 BSTR str; 9523 9524 doc = create_document(&IID_IXMLDOMDocument); 9525 9526 hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem); 9527 ok(hr == S_OK, "got 0x%08x\n", hr); 9528 9529 hr = IXMLDOMElement_get_tagName(elem, NULL); 9530 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9531 9532 str = NULL; 9533 hr = IXMLDOMElement_get_tagName(elem, &str); 9534 ok(hr == S_OK, "got 0x%08x\n", hr); 9535 ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str)); 9536 SysFreeString(str); 9537 9538 hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2); 9539 ok(hr == S_OK, "got 0x%08x\n", hr); 9540 9541 str = NULL; 9542 hr = IXMLDOMElement_get_tagName(elem2, &str); 9543 ok(hr == S_OK, "got 0x%08x\n", hr); 9544 ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str)); 9545 SysFreeString(str); 9546 9547 IXMLDOMElement_Release(elem); 9548 IXMLDOMElement_Release(elem2); 9549 IXMLDOMDocument_Release(doc); 9550 free_bstrs(); 9551 } 9552 9553 typedef struct { 9554 DOMNodeType type; 9555 const char *name; 9556 VARTYPE vt; 9557 HRESULT hr; 9558 } node_type_t; 9559 9560 static const node_type_t get_datatype[] = { 9561 { NODE_ELEMENT, "element", VT_NULL, S_FALSE }, 9562 { NODE_ATTRIBUTE, "attr", VT_NULL, S_FALSE }, 9563 { NODE_TEXT, "text", VT_NULL, S_FALSE }, 9564 { NODE_CDATA_SECTION , "cdata", VT_NULL, S_FALSE }, 9565 { NODE_ENTITY_REFERENCE, "entityref", VT_NULL, S_FALSE }, 9566 { NODE_PROCESSING_INSTRUCTION, "pi", VT_NULL, S_FALSE }, 9567 { NODE_COMMENT, "comment", VT_NULL, S_FALSE }, 9568 { NODE_DOCUMENT_FRAGMENT, "docfrag", VT_NULL, S_FALSE }, 9569 { 0 } 9570 }; 9571 9572 static void test_get_dataType(void) 9573 { 9574 const node_type_t *entry = get_datatype; 9575 IXMLDOMDocument *doc; 9576 9577 doc = create_document(&IID_IXMLDOMDocument); 9578 9579 while (entry->type) 9580 { 9581 IXMLDOMNode *node = NULL; 9582 VARIANT var, type; 9583 HRESULT hr; 9584 9585 V_VT(&var) = VT_I4; 9586 V_I4(&var) = entry->type; 9587 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node); 9588 ok(hr == S_OK, "failed to create node, type %d\n", entry->type); 9589 9590 hr = IXMLDOMNode_get_dataType(node, NULL); 9591 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9592 9593 VariantInit(&type); 9594 hr = IXMLDOMNode_get_dataType(node, &type); 9595 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n", 9596 hr, entry->hr, entry->type); 9597 ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n", 9598 V_VT(&type), entry->vt, entry->type); 9599 VariantClear(&type); 9600 9601 IXMLDOMNode_Release(node); 9602 9603 entry++; 9604 } 9605 9606 IXMLDOMDocument_Release(doc); 9607 free_bstrs(); 9608 } 9609 9610 typedef struct _get_node_typestring_t { 9611 DOMNodeType type; 9612 const char *string; 9613 } get_node_typestring_t; 9614 9615 static const get_node_typestring_t get_node_typestring[] = { 9616 { NODE_ELEMENT, "element" }, 9617 { NODE_ATTRIBUTE, "attribute" }, 9618 { NODE_TEXT, "text" }, 9619 { NODE_CDATA_SECTION , "cdatasection" }, 9620 { NODE_ENTITY_REFERENCE, "entityreference" }, 9621 { NODE_PROCESSING_INSTRUCTION, "processinginstruction" }, 9622 { NODE_COMMENT, "comment" }, 9623 { NODE_DOCUMENT_FRAGMENT, "documentfragment" }, 9624 { 0 } 9625 }; 9626 9627 static void test_get_nodeTypeString(void) 9628 { 9629 const get_node_typestring_t *entry = get_node_typestring; 9630 IXMLDOMDocument *doc; 9631 HRESULT hr; 9632 BSTR str; 9633 9634 doc = create_document(&IID_IXMLDOMDocument); 9635 9636 hr = IXMLDOMDocument_get_nodeTypeString(doc, &str); 9637 ok(hr == S_OK, "got 0x%08x\n", hr); 9638 ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str)); 9639 SysFreeString(str); 9640 9641 while (entry->type) 9642 { 9643 IXMLDOMNode *node = NULL; 9644 VARIANT var; 9645 9646 V_VT(&var) = VT_I4; 9647 V_I4(&var) = entry->type; 9648 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node); 9649 ok(hr == S_OK, "failed to create node, type %d\n", entry->type); 9650 9651 hr = IXMLDOMNode_get_nodeTypeString(node, NULL); 9652 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9653 9654 hr = IXMLDOMNode_get_nodeTypeString(node, &str); 9655 ok(hr == S_OK, "got 0x%08x\n", hr); 9656 ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n", 9657 wine_dbgstr_w(str), entry->string, entry->type); 9658 SysFreeString(str); 9659 IXMLDOMNode_Release(node); 9660 9661 entry++; 9662 } 9663 9664 IXMLDOMDocument_Release(doc); 9665 free_bstrs(); 9666 } 9667 9668 typedef struct _get_attributes_t { 9669 DOMNodeType type; 9670 HRESULT hr; 9671 } get_attributes_t; 9672 9673 static const get_attributes_t get_attributes[] = { 9674 { NODE_ATTRIBUTE, S_FALSE }, 9675 { NODE_TEXT, S_FALSE }, 9676 { NODE_CDATA_SECTION , S_FALSE }, 9677 { NODE_ENTITY_REFERENCE, S_FALSE }, 9678 { NODE_PROCESSING_INSTRUCTION, S_FALSE }, 9679 { NODE_COMMENT, S_FALSE }, 9680 { NODE_DOCUMENT_FRAGMENT, S_FALSE }, 9681 { 0 } 9682 }; 9683 9684 static void test_get_attributes(void) 9685 { 9686 const get_attributes_t *entry = get_attributes; 9687 IXMLDOMNamedNodeMap *map; 9688 IXMLDOMDocument *doc, *doc2; 9689 IXMLDOMNode *node, *node2; 9690 IXMLDOMElement *elem; 9691 VARIANT_BOOL b; 9692 HRESULT hr; 9693 VARIANT v; 9694 BSTR str; 9695 LONG length; 9696 9697 doc = create_document(&IID_IXMLDOMDocument); 9698 9699 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b); 9700 ok(hr == S_OK, "got %08x\n", hr); 9701 9702 hr = IXMLDOMDocument_get_attributes(doc, NULL); 9703 ok(hr == E_INVALIDARG, "got %08x\n", hr); 9704 9705 map = (void*)0xdeadbeef; 9706 hr = IXMLDOMDocument_get_attributes(doc, &map); 9707 ok(hr == S_FALSE, "got %08x\n", hr); 9708 ok(map == NULL, "got %p\n", map); 9709 9710 /* first child is <?xml ?> */ 9711 hr = IXMLDOMDocument_get_firstChild(doc, &node); 9712 ok(hr == S_OK, "got %08x\n", hr); 9713 9714 hr = IXMLDOMNode_get_attributes(node, &map); 9715 ok(hr == S_OK, "got %08x\n", hr); 9716 9717 node2 = (void*)0xdeadbeef; 9718 hr = IXMLDOMNamedNodeMap_getNamedItem(map, _bstr_("attr"), &node2); 9719 ok(hr == S_FALSE, "got %08x\n", hr); 9720 ok(node2 == NULL, "got %p\n", node2); 9721 9722 length = -1; 9723 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9724 EXPECT_HR(hr, S_OK); 9725 todo_wine ok(length == 1, "got %d\n", length); 9726 9727 if (hr == S_OK && length == 1) 9728 { 9729 IXMLDOMAttribute *attr; 9730 DOMNodeType type; 9731 VARIANT v; 9732 9733 node2 = NULL; 9734 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2); 9735 EXPECT_HR(hr, S_OK); 9736 ok(node != NULL, "got %p\n", node2); 9737 9738 hr = IXMLDOMNode_get_nodeName(node2, &str); 9739 EXPECT_HR(hr, S_OK); 9740 ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str)); 9741 SysFreeString(str); 9742 9743 length = -1; 9744 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9745 EXPECT_HR(hr, S_OK); 9746 ok(length == 1, "got %d\n", length); 9747 9748 type = -1; 9749 hr = IXMLDOMNode_get_nodeType(node2, &type); 9750 EXPECT_HR(hr, S_OK); 9751 ok(type == NODE_ATTRIBUTE, "got %d\n", type); 9752 9753 hr = IXMLDOMNode_get_xml(node, &str); 9754 EXPECT_HR(hr, S_OK); 9755 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str)); 9756 SysFreeString(str); 9757 9758 hr = IXMLDOMNode_get_text(node, &str); 9759 EXPECT_HR(hr, S_OK); 9760 ok(!lstrcmpW(str, _bstr_("version=\"1.0\"")), "got %s\n", wine_dbgstr_w(str)); 9761 SysFreeString(str); 9762 9763 hr = IXMLDOMNamedNodeMap_removeNamedItem(map, _bstr_("version"), NULL); 9764 EXPECT_HR(hr, S_OK); 9765 9766 length = -1; 9767 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9768 EXPECT_HR(hr, S_OK); 9769 ok(length == 0, "got %d\n", length); 9770 9771 hr = IXMLDOMNode_get_xml(node, &str); 9772 EXPECT_HR(hr, S_OK); 9773 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str)); 9774 SysFreeString(str); 9775 9776 hr = IXMLDOMNode_get_text(node, &str); 9777 EXPECT_HR(hr, S_OK); 9778 ok(!lstrcmpW(str, _bstr_("")), "got %s\n", wine_dbgstr_w(str)); 9779 SysFreeString(str); 9780 9781 IXMLDOMNamedNodeMap_Release(map); 9782 9783 hr = IXMLDOMNode_get_attributes(node, &map); 9784 ok(hr == S_OK, "got %08x\n", hr); 9785 9786 length = -1; 9787 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9788 EXPECT_HR(hr, S_OK); 9789 ok(length == 0, "got %d\n", length); 9790 9791 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("encoding"), &attr); 9792 EXPECT_HR(hr, S_OK); 9793 9794 V_VT(&v) = VT_BSTR; 9795 V_BSTR(&v) = _bstr_("UTF-8"); 9796 hr = IXMLDOMAttribute_put_nodeValue(attr, v); 9797 EXPECT_HR(hr, S_OK); 9798 9799 EXPECT_REF(attr, 2); 9800 hr = IXMLDOMNamedNodeMap_setNamedItem(map, (IXMLDOMNode*)attr, NULL); 9801 EXPECT_HR(hr, S_OK); 9802 EXPECT_REF(attr, 2); 9803 9804 hr = IXMLDOMNode_get_attributes(node, &map); 9805 ok(hr == S_OK, "got %08x\n", hr); 9806 9807 length = -1; 9808 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9809 EXPECT_HR(hr, S_OK); 9810 ok(length == 1, "got %d\n", length); 9811 9812 hr = IXMLDOMNode_get_xml(node, &str); 9813 EXPECT_HR(hr, S_OK); 9814 ok(!lstrcmpW(str, _bstr_("<?xml version=\"1.0\"?>")), "got %s\n", wine_dbgstr_w(str)); 9815 SysFreeString(str); 9816 9817 hr = IXMLDOMNode_get_text(node, &str); 9818 EXPECT_HR(hr, S_OK); 9819 ok(!lstrcmpW(str, _bstr_("encoding=\"UTF-8\"")), "got %s\n", wine_dbgstr_w(str)); 9820 SysFreeString(str); 9821 9822 IXMLDOMNamedNodeMap_Release(map); 9823 IXMLDOMNode_Release(node2); 9824 } 9825 9826 IXMLDOMNode_Release(node); 9827 9828 /* last child is element */ 9829 EXPECT_REF(doc, 1); 9830 hr = IXMLDOMDocument_get_lastChild(doc, &node); 9831 ok(hr == S_OK, "got %08x\n", hr); 9832 EXPECT_REF(doc, 1); 9833 9834 EXPECT_REF(node, 1); 9835 hr = IXMLDOMNode_get_attributes(node, &map); 9836 ok(hr == S_OK, "got %08x\n", hr); 9837 EXPECT_REF(node, 1); 9838 EXPECT_REF(doc, 1); 9839 9840 EXPECT_REF(map, 1); 9841 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2); 9842 ok(hr == S_OK, "got %08x\n", hr); 9843 EXPECT_REF(node, 1); 9844 EXPECT_REF(node2, 1); 9845 EXPECT_REF(map, 1); 9846 EXPECT_REF(doc, 1); 9847 IXMLDOMNode_Release(node2); 9848 9849 /* release node before map release, map still works */ 9850 IXMLDOMNode_Release(node); 9851 9852 length = 0; 9853 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9854 ok(hr == S_OK, "got %08x\n", hr); 9855 ok(length == 1, "got %d\n", length); 9856 9857 node2 = NULL; 9858 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2); 9859 ok(hr == S_OK, "got %08x\n", hr); 9860 EXPECT_REF(node2, 1); 9861 IXMLDOMNode_Release(node2); 9862 9863 IXMLDOMNamedNodeMap_Release(map); 9864 9865 /* append created element a different document, map still works */ 9866 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem); 9867 ok(hr == S_OK, "createElement failed: %08x\n", hr); 9868 9869 V_VT(&v) = VT_I4; 9870 V_I4(&v) = 1; 9871 hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v); 9872 ok(hr == S_OK, "setAttribute failed: %08x\n", hr); 9873 9874 hr = IXMLDOMElement_get_attributes(elem, &map); 9875 ok(hr == S_OK, "get_attributes failed: %08x\n", hr); 9876 9877 length = 0; 9878 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9879 ok(hr == S_OK, "got %08x\n", hr); 9880 ok(length == 1, "got %d\n", length); 9881 9882 doc2 = create_document(&IID_IXMLDOMDocument); 9883 9884 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node); 9885 ok(hr == S_OK, "appendChild failed: %08x\n", hr); 9886 ok(node == (IXMLDOMNode*)elem, "node != elem\n"); 9887 IXMLDOMNode_Release(node); 9888 IXMLDOMElement_Release(elem); 9889 IXMLDOMDocument_Release(doc2); 9890 9891 length = 0; 9892 hr = IXMLDOMNamedNodeMap_get_length(map, &length); 9893 ok(hr == S_OK, "got %08x\n", hr); 9894 ok(length == 1, "got %d\n", length); 9895 9896 IXMLDOMNamedNodeMap_Release(map); 9897 9898 while (entry->type) 9899 { 9900 VARIANT var; 9901 9902 node = NULL; 9903 9904 V_VT(&var) = VT_I4; 9905 V_I4(&var) = entry->type; 9906 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node); 9907 ok(hr == S_OK, "failed to create node, type %d\n", entry->type); 9908 9909 hr = IXMLDOMNode_get_attributes(node, NULL); 9910 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 9911 9912 map = (void*)0xdeadbeef; 9913 hr = IXMLDOMNode_get_attributes(node, &map); 9914 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n", 9915 hr, entry->hr, entry->type); 9916 ok(map == NULL, "got %p\n", map); 9917 9918 IXMLDOMNode_Release(node); 9919 9920 entry++; 9921 } 9922 9923 IXMLDOMDocument_Release(doc); 9924 free_bstrs(); 9925 } 9926 9927 static void test_selection(void) 9928 { 9929 IXMLDOMSelection *selection, *selection2; 9930 IEnumVARIANT *enum1, *enum2, *enum3; 9931 IXMLDOMNodeList *list; 9932 IUnknown *unk1, *unk2; 9933 IXMLDOMDocument *doc; 9934 IDispatchEx *dispex; 9935 IXMLDOMNode *node; 9936 IDispatch *disp; 9937 VARIANT_BOOL b; 9938 HRESULT hr; 9939 DISPID did; 9940 VARIANT v; 9941 BSTR name; 9942 ULONG ret; 9943 LONG len; 9944 9945 doc = create_document(&IID_IXMLDOMDocument); 9946 9947 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b); 9948 EXPECT_HR(hr, S_OK); 9949 9950 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list); 9951 EXPECT_HR(hr, S_OK); 9952 9953 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection); 9954 EXPECT_HR(hr, S_OK); 9955 IXMLDOMSelection_Release(selection); 9956 9957 /* collection disp id */ 9958 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IDispatchEx, (void**)&dispex); 9959 EXPECT_HR(hr, S_OK); 9960 did = 0; 9961 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did); 9962 EXPECT_HR(hr, S_OK); 9963 ok(did == DISPID_DOM_COLLECTION_BASE, "got %d\n", did); 9964 len = 0; 9965 hr = IXMLDOMSelection_get_length(selection, &len); 9966 EXPECT_HR(hr, S_OK); 9967 ok(len == 1, "got %d\n", len); 9968 hr = IDispatchEx_GetDispID(dispex, _bstr_("10"), 0, &did); 9969 EXPECT_HR(hr, S_OK); 9970 ok(did == DISPID_DOM_COLLECTION_BASE+10, "got %d\n", did); 9971 IDispatchEx_Release(dispex); 9972 9973 /* IEnumVARIANT tests */ 9974 enum1 = NULL; 9975 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1); 9976 EXPECT_HR(hr, S_OK); 9977 ok(enum1 != NULL, "got %p\n", enum1); 9978 EXPECT_REF(enum1, 2); 9979 9980 EXPECT_REF(selection, 1); 9981 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1); 9982 EXPECT_HR(hr, S_OK); 9983 EXPECT_REF(selection, 2); 9984 EXPECT_REF(enum1, 2); 9985 9986 /* enumerator and selection object return same IUnknown* */ 9987 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2); 9988 EXPECT_HR(hr, S_OK); 9989 EXPECT_REF(selection, 3); 9990 EXPECT_REF(enum1, 2); 9991 ok(unk2 == unk1, "got %p, %p\n", unk1, unk2); 9992 IUnknown_Release(unk2); 9993 9994 EXPECT_REF(selection, 2); 9995 IEnumVARIANT_AddRef(enum1); 9996 EXPECT_REF(selection, 2); 9997 IEnumVARIANT_Release(enum1); 9998 9999 enum3 = NULL; 10000 hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3); 10001 EXPECT_HR(hr, S_OK); 10002 ok(enum3 != NULL, "got %p\n", enum3); 10003 ok(enum1 == enum3, "got %p and %p\n", enum1, enum3); 10004 EXPECT_REF(enum1, 3); 10005 IEnumVARIANT_Release(enum3); 10006 10007 EXPECT_REF(selection, 2); 10008 EXPECT_REF(enum1, 2); 10009 10010 enum2 = NULL; 10011 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2); 10012 EXPECT_HR(hr, S_OK); 10013 ok(enum2 != NULL, "got %p\n", enum2); 10014 10015 EXPECT_REF(selection, 3); 10016 EXPECT_REF(enum1, 2); 10017 EXPECT_REF(enum2, 1); 10018 10019 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2); 10020 10021 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2); 10022 EXPECT_HR(hr, S_OK); 10023 EXPECT_REF(selection, 3); 10024 EXPECT_REF(enum2, 2); 10025 ok(unk2 != unk1, "got %p, %p\n", unk1, unk2); 10026 IUnknown_Release(unk2); 10027 IUnknown_Release(unk1); 10028 10029 selection2 = NULL; 10030 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2); 10031 EXPECT_HR(hr, S_OK); 10032 ok(selection2 == selection, "got %p and %p\n", selection, selection2); 10033 EXPECT_REF(selection, 3); 10034 EXPECT_REF(enum1, 2); 10035 10036 IXMLDOMSelection_Release(selection2); 10037 10038 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp); 10039 EXPECT_HR(hr, S_OK); 10040 EXPECT_REF(selection, 3); 10041 IDispatch_Release(disp); 10042 10043 hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3); 10044 EXPECT_HR(hr, S_OK); 10045 ok(enum3 == enum1, "got %p and %p\n", enum3, enum1); 10046 EXPECT_REF(selection, 2); 10047 EXPECT_REF(enum1, 3); 10048 10049 IEnumVARIANT_Release(enum1); 10050 IEnumVARIANT_Release(enum2); 10051 IEnumVARIANT_Release(enum3); 10052 10053 enum1 = NULL; 10054 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1); 10055 EXPECT_HR(hr, S_OK); 10056 ok(enum1 != NULL, "got %p\n", enum1); 10057 EXPECT_REF(enum1, 1); 10058 EXPECT_REF(selection, 2); 10059 10060 enum2 = NULL; 10061 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2); 10062 EXPECT_HR(hr, S_OK); 10063 ok(enum2 != NULL, "got %p\n", enum2); 10064 EXPECT_REF(enum2, 1); 10065 EXPECT_REF(selection, 3); 10066 10067 ok(enum1 != enum2, "got %p, %p\n", enum1, enum2); 10068 10069 IEnumVARIANT_AddRef(enum1); 10070 EXPECT_REF(selection, 3); 10071 EXPECT_REF(enum1, 2); 10072 EXPECT_REF(enum2, 1); 10073 IEnumVARIANT_Release(enum1); 10074 10075 IEnumVARIANT_Release(enum1); 10076 IEnumVARIANT_Release(enum2); 10077 10078 EXPECT_REF(selection, 1); 10079 10080 IXMLDOMNodeList_Release(list); 10081 10082 hr = IXMLDOMDocument_get_childNodes(doc, &list); 10083 EXPECT_HR(hr, S_OK); 10084 10085 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection); 10086 EXPECT_HR(hr, E_NOINTERFACE); 10087 10088 IXMLDOMNodeList_Release(list); 10089 10090 /* test if IEnumVARIANT touches selection context */ 10091 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b); 10092 EXPECT_HR(hr, S_OK); 10093 10094 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list); 10095 EXPECT_HR(hr, S_OK); 10096 10097 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection); 10098 EXPECT_HR(hr, S_OK); 10099 10100 len = 0; 10101 hr = IXMLDOMSelection_get_length(selection, &len); 10102 EXPECT_HR(hr, S_OK); 10103 ok(len == 4, "got %d\n", len); 10104 10105 enum1 = NULL; 10106 hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1); 10107 EXPECT_HR(hr, S_OK); 10108 10109 /* no-op if zero count */ 10110 V_VT(&v) = VT_I2; 10111 hr = IEnumVARIANT_Next(enum1, 0, &v, NULL); 10112 EXPECT_HR(hr, S_OK); 10113 ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v)); 10114 10115 /* positive count, null array pointer */ 10116 hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL); 10117 EXPECT_HR(hr, E_INVALIDARG); 10118 10119 ret = 1; 10120 hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret); 10121 EXPECT_HR(hr, E_INVALIDARG); 10122 ok(ret == 0, "got %d\n", ret); 10123 10124 V_VT(&v) = VT_I2; 10125 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); 10126 EXPECT_HR(hr, S_OK); 10127 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); 10128 10129 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); 10130 EXPECT_HR(hr, S_OK); 10131 hr = IXMLDOMNode_get_nodeName(node, &name); 10132 EXPECT_HR(hr, S_OK); 10133 ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name)); 10134 SysFreeString(name); 10135 IXMLDOMNode_Release(node); 10136 VariantClear(&v); 10137 10138 /* list cursor is updated */ 10139 hr = IXMLDOMSelection_nextNode(selection, &node); 10140 EXPECT_HR(hr, S_OK); 10141 hr = IXMLDOMNode_get_nodeName(node, &name); 10142 EXPECT_HR(hr, S_OK); 10143 ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name)); 10144 IXMLDOMNode_Release(node); 10145 SysFreeString(name); 10146 10147 V_VT(&v) = VT_I2; 10148 hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); 10149 EXPECT_HR(hr, S_OK); 10150 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); 10151 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); 10152 EXPECT_HR(hr, S_OK); 10153 hr = IXMLDOMNode_get_nodeName(node, &name); 10154 EXPECT_HR(hr, S_OK); 10155 ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name)); 10156 SysFreeString(name); 10157 IXMLDOMNode_Release(node); 10158 VariantClear(&v); 10159 IEnumVARIANT_Release(enum1); 10160 10161 hr = IXMLDOMSelection_nextNode(selection, &node); 10162 EXPECT_HR(hr, S_OK); 10163 hr = IXMLDOMNode_get_nodeName(node, &name); 10164 EXPECT_HR(hr, S_OK); 10165 ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name)); 10166 IXMLDOMNode_Release(node); 10167 SysFreeString(name); 10168 10169 IXMLDOMSelection_Release(selection); 10170 IXMLDOMNodeList_Release(list); 10171 IXMLDOMDocument_Release(doc); 10172 10173 free_bstrs(); 10174 } 10175 10176 static void write_to_file(const char *name, const char *data) 10177 { 10178 DWORD written; 10179 HANDLE hfile; 10180 BOOL ret; 10181 10182 hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 10183 ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name); 10184 10185 ret = WriteFile(hfile, data, strlen(data), &written, NULL); 10186 ok(ret, "WriteFile failed: %s, %d\n", name, GetLastError()); 10187 10188 CloseHandle(hfile); 10189 } 10190 10191 static void test_doc_load_from_path(IXMLDOMDocument *doc, const char *path) 10192 { 10193 IXMLDOMDocument *doc2; 10194 IXMLDOMElement *elem; 10195 BSTR url, url2; 10196 VARIANT_BOOL b; 10197 VARIANT src; 10198 HRESULT hr; 10199 10200 url = _bstr_(path); 10201 10202 V_VT(&src) = VT_BSTR; 10203 V_BSTR(&src) = url; 10204 hr = IXMLDOMDocument_load(doc, src, &b); 10205 ok(hr == S_OK, "Failed to load document, %#x.\n", hr); 10206 ok(b == VARIANT_TRUE, "got %d\n", b); 10207 10208 V_VT(&src) = VT_BSTR | VT_BYREF; 10209 V_BSTRREF(&src) = &url; 10210 hr = IXMLDOMDocument_load(doc, src, &b); 10211 ok(hr == S_OK, "Failed to load document, %#x.\n", hr); 10212 ok(b == VARIANT_TRUE, "got %d\n", b); 10213 10214 url = NULL; 10215 hr = IXMLDOMDocument_get_url(doc, &url); 10216 ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr); 10217 10218 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 10219 ok(hr == S_OK, "got 0x%08x\n", hr); 10220 10221 /* Create another instance for the same document, check url */ 10222 hr = IXMLDOMElement_get_ownerDocument(elem, &doc2); 10223 ok(hr == S_OK, "Failed to get owner document, hr %#x.\n", hr); 10224 10225 hr = IXMLDOMDocument_get_url(doc2, &url2); 10226 ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr); 10227 ok(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2)); 10228 10229 IXMLDOMDocument_Release(doc2); 10230 IXMLDOMElement_Release(elem); 10231 SysFreeString(url2); 10232 SysFreeString(url); 10233 } 10234 10235 static void url_forward_slash(char *url) 10236 { 10237 char *p = url; 10238 10239 while (*p) 10240 { 10241 if (*p == '\\') 10242 *p = '/'; 10243 p++; 10244 } 10245 } 10246 10247 static void test_load(void) 10248 { 10249 char path[MAX_PATH], path2[MAX_PATH]; 10250 IXMLDOMNodeList *list; 10251 IXMLDOMDocument *doc; 10252 BSTR bstr1, bstr2; 10253 VARIANT_BOOL b; 10254 VARIANT src; 10255 HRESULT hr; 10256 void* ptr; 10257 10258 GetTempPathA(MAX_PATH, path); 10259 strcat(path, "winetest.xml"); 10260 10261 /* prepare a file */ 10262 write_to_file(path, win1252xml); 10263 10264 doc = create_document(&IID_IXMLDOMDocument); 10265 10266 /* null pointer as input */ 10267 V_VT(&src) = VT_UNKNOWN; 10268 V_UNKNOWN(&src) = NULL; 10269 hr = IXMLDOMDocument_load(doc, src, &b); 10270 EXPECT_HR(hr, E_INVALIDARG); 10271 ok(b == VARIANT_FALSE, "got %d\n", b); 10272 10273 /* "file://" url */ 10274 strcpy(path2, "file://"); 10275 strcat(path2, path); 10276 test_doc_load_from_path(doc, path2); 10277 10278 /* file:// url, forward slashes */ 10279 url_forward_slash(path2); 10280 test_doc_load_from_path(doc, path2); 10281 10282 /* "file:/" url */ 10283 strcpy(path2, "file:/"); 10284 strcat(path2, path); 10285 test_doc_load_from_path(doc, path); 10286 10287 /* file:/ with forward slashes. */ 10288 url_forward_slash(path2); 10289 test_doc_load_from_path(doc, path2); 10290 10291 /* Regular local path. */ 10292 test_doc_load_from_path(doc, path); 10293 10294 /* load from a path: VT_BSTR|VT_BYREF, null ptr */ 10295 V_VT(&src) = VT_BSTR | VT_BYREF; 10296 V_BSTRREF(&src) = NULL; 10297 hr = IXMLDOMDocument_load(doc, src, &b); 10298 EXPECT_HR(hr, E_INVALIDARG); 10299 ok(b == VARIANT_FALSE, "got %d\n", b); 10300 10301 bstr1 = NULL; 10302 hr = IXMLDOMDocument_get_url(doc, &bstr1); 10303 ok(hr == S_OK, "got 0x%08x\n", hr); 10304 SysFreeString(bstr1); 10305 10306 DeleteFileA(path); 10307 10308 /* load from existing path, no xml content */ 10309 write_to_file(path, nocontent); 10310 10311 V_VT(&src) = VT_BSTR; 10312 V_BSTR(&src) = _bstr_(path); 10313 b = VARIANT_TRUE; 10314 hr = IXMLDOMDocument_load(doc, src, &b); 10315 ok(hr == S_FALSE, "got 0x%08x\n", hr); 10316 ok(b == VARIANT_FALSE, "got %d\n", b); 10317 10318 bstr1 = (void *)0xdeadbeef; 10319 hr = IXMLDOMDocument_get_url(doc, &bstr1); 10320 ok(hr == S_FALSE, "got 0x%08x\n", hr); 10321 ok(bstr1 == NULL, "got %p\n", bstr1); 10322 10323 DeleteFileA(path); 10324 IXMLDOMDocument_Release(doc); 10325 10326 doc = create_document(&IID_IXMLDOMDocument); 10327 10328 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &b); 10329 EXPECT_HR(hr, S_OK); 10330 ok(b == VARIANT_TRUE, "got %d\n", b); 10331 10332 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list); 10333 EXPECT_HR(hr, S_OK); 10334 bstr1 = _bstr_(list_to_string(list)); 10335 10336 hr = IXMLDOMNodeList_reset(list); 10337 EXPECT_HR(hr, S_OK); 10338 10339 IXMLDOMDocument_Release(doc); 10340 10341 doc = create_document(&IID_IXMLDOMDocument); 10342 10343 VariantInit(&src); 10344 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenA(szExampleXML)); 10345 V_VT(&src) = VT_ARRAY|VT_UI1; 10346 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n"); 10347 ptr = NULL; 10348 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr); 10349 EXPECT_HR(hr, S_OK); 10350 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n"); 10351 10352 memcpy(ptr, szExampleXML, lstrlenA(szExampleXML)); 10353 hr = SafeArrayUnlock(V_ARRAY(&src)); 10354 EXPECT_HR(hr, S_OK); 10355 10356 hr = IXMLDOMDocument_load(doc, src, &b); 10357 EXPECT_HR(hr, S_OK); 10358 ok(b == VARIANT_TRUE, "got %d\n", b); 10359 10360 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("//*"), &list); 10361 EXPECT_HR(hr, S_OK); 10362 bstr2 = _bstr_(list_to_string(list)); 10363 10364 hr = IXMLDOMNodeList_reset(list); 10365 EXPECT_HR(hr, S_OK); 10366 10367 ok(lstrcmpW(bstr1, bstr2) == 0, "strings not equal: %s : %s\n", 10368 wine_dbgstr_w(bstr1), wine_dbgstr_w(bstr2)); 10369 10370 IXMLDOMDocument_Release(doc); 10371 IXMLDOMNodeList_Release(list); 10372 VariantClear(&src); 10373 10374 /* UTF-16 isn't accepted */ 10375 doc = create_document(&IID_IXMLDOMDocument); 10376 10377 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI1, 0, lstrlenW(szComplete1) * sizeof(WCHAR)); 10378 V_VT(&src) = VT_ARRAY|VT_UI1; 10379 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n"); 10380 ptr = NULL; 10381 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr); 10382 EXPECT_HR(hr, S_OK); 10383 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n"); 10384 10385 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR)); 10386 hr = SafeArrayUnlock(V_ARRAY(&src)); 10387 EXPECT_HR(hr, S_OK); 10388 10389 hr = IXMLDOMDocument_load(doc, src, &b); 10390 todo_wine EXPECT_HR(hr, S_FALSE); 10391 todo_wine ok(b == VARIANT_FALSE, "got %d\n", b); 10392 10393 VariantClear(&src); 10394 10395 /* it doesn't like it as a VT_ARRAY|VT_UI2 either */ 10396 V_ARRAY(&src) = SafeArrayCreateVector(VT_UI2, 0, lstrlenW(szComplete1)); 10397 V_VT(&src) = VT_ARRAY|VT_UI2; 10398 ok(V_ARRAY(&src) != NULL, "SafeArrayCreateVector() returned NULL\n"); 10399 ptr = NULL; 10400 hr = SafeArrayAccessData(V_ARRAY(&src), &ptr); 10401 EXPECT_HR(hr, S_OK); 10402 ok(ptr != NULL, "SafeArrayAccessData() returned NULL\n"); 10403 10404 memcpy(ptr, szComplete1, lstrlenW(szComplete1) * sizeof(WCHAR)); 10405 hr = SafeArrayUnlock(V_ARRAY(&src)); 10406 EXPECT_HR(hr, S_OK); 10407 10408 hr = IXMLDOMDocument_load(doc, src, &b); 10409 todo_wine EXPECT_HR(hr, E_INVALIDARG); 10410 ok(b == VARIANT_FALSE, "got %d\n", b); 10411 10412 VariantClear(&src); 10413 IXMLDOMDocument_Release(doc); 10414 10415 free_bstrs(); 10416 } 10417 10418 static void test_domobj_dispex(IUnknown *obj) 10419 { 10420 static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0}; 10421 DISPID dispid = DISPID_XMLDOM_NODELIST_RESET; 10422 IDispatchEx *dispex; 10423 IUnknown *unk; 10424 DWORD props; 10425 UINT ticnt; 10426 HRESULT hr; 10427 BSTR name; 10428 10429 hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex); 10430 EXPECT_HR(hr, S_OK); 10431 if (FAILED(hr)) return; 10432 10433 ticnt = 0; 10434 hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); 10435 EXPECT_HR(hr, S_OK); 10436 ok(ticnt == 1, "ticnt=%u\n", ticnt); 10437 10438 name = SysAllocString(szstar); 10439 hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive); 10440 EXPECT_HR(hr, E_NOTIMPL); 10441 SysFreeString(name); 10442 10443 hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid); 10444 EXPECT_HR(hr, E_NOTIMPL); 10445 10446 props = 0; 10447 hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props); 10448 EXPECT_HR(hr, E_NOTIMPL); 10449 ok(props == 0, "expected 0 got %d\n", props); 10450 10451 hr = IDispatchEx_GetMemberName(dispex, dispid, &name); 10452 EXPECT_HR(hr, E_NOTIMPL); 10453 if (SUCCEEDED(hr)) SysFreeString(name); 10454 10455 hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid); 10456 EXPECT_HR(hr, E_NOTIMPL); 10457 10458 unk = (IUnknown*)0xdeadbeef; 10459 hr = IDispatchEx_GetNameSpaceParent(dispex, &unk); 10460 EXPECT_HR(hr, E_NOTIMPL); 10461 ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk); 10462 10463 name = SysAllocString(testW); 10464 hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid); 10465 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); 10466 SysFreeString(name); 10467 10468 IDispatchEx_Release(dispex); 10469 } 10470 10471 static void test_mxnamespacemanager(void) 10472 { 10473 static const char xmluriA[] = "http://www.w3.org/XML/1998/namespace"; 10474 IMXNamespacePrefixes *prefixes; 10475 IVBMXNamespaceManager *mgr2; 10476 IMXNamespaceManager *nsmgr; 10477 IUnknown *unk1, *unk2; 10478 WCHAR buffW[250]; 10479 IDispatch *disp; 10480 IUnknown *unk; 10481 HRESULT hr; 10482 INT len; 10483 10484 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER, 10485 &IID_IMXNamespaceManager, (void**)&nsmgr); 10486 EXPECT_HR(hr, S_OK); 10487 10488 /* IMXNamespaceManager inherits from IUnknown */ 10489 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IDispatch, (void**)&disp); 10490 EXPECT_HR(hr, S_OK); 10491 IDispatch_Release(disp); 10492 10493 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IVBMXNamespaceManager, (void**)&mgr2); 10494 EXPECT_HR(hr, S_OK); 10495 10496 EXPECT_REF(nsmgr, 2); 10497 EXPECT_REF(mgr2, 2); 10498 prefixes = NULL; 10499 hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes); 10500 todo_wine 10501 ok(hr == S_OK, "got 0x%08x\n", hr); 10502 if (hr == S_OK) 10503 { 10504 IDispatchEx *dispex; 10505 VARIANT arg, ret; 10506 DISPPARAMS dispparams; 10507 10508 ok(prefixes != NULL, "got %p\n", prefixes); 10509 EXPECT_REF(nsmgr, 2); 10510 EXPECT_REF(mgr2, 2); 10511 EXPECT_REF(prefixes, 1); 10512 10513 IVBMXNamespaceManager_QueryInterface(mgr2, &IID_IUnknown, (void**)&unk1); 10514 IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IUnknown, (void**)&unk2); 10515 10516 EXPECT_REF(mgr2, 3); 10517 EXPECT_REF(prefixes, 2); 10518 10519 IUnknown_Release(unk1); 10520 IUnknown_Release(unk2); 10521 10522 hr = IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IDispatchEx, (void**)&dispex); 10523 ok(hr == S_OK, "got 0x%08x\n", hr); 10524 10525 V_VT(&arg) = VT_I4; 10526 V_I4(&arg) = 0; 10527 dispparams.cArgs = 1; 10528 dispparams.cNamedArgs = 0; 10529 dispparams.rgdispidNamedArgs = NULL; 10530 dispparams.rgvarg = &arg; 10531 10532 V_VT(&ret) = VT_EMPTY; 10533 V_DISPATCH(&ret) = (void*)0x1; 10534 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 10535 ok(hr == S_OK, "got 0x%08x\n", hr); 10536 ok(V_VT(&ret) == VT_BSTR, "got %d\n", V_VT(&ret)); 10537 ok(V_BSTR(&ret) != NULL, "got %p\n", V_BSTR(&ret)); 10538 VariantClear(&ret); 10539 10540 IDispatchEx_Release(dispex); 10541 IMXNamespacePrefixes_Release(prefixes); 10542 } 10543 IVBMXNamespaceManager_Release(mgr2); 10544 10545 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL); 10546 EXPECT_HR(hr, S_OK); 10547 10548 /* prefix already added */ 10549 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri")); 10550 EXPECT_HR(hr, S_FALSE); 10551 10552 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), NULL); 10553 EXPECT_HR(hr, E_INVALIDARG); 10554 10555 /* "xml" and "xmlns" are not allowed here */ 10556 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xml"), _bstr_("uri1")); 10557 EXPECT_HR(hr, E_INVALIDARG); 10558 10559 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("xmlns"), _bstr_("uri1")); 10560 EXPECT_HR(hr, E_INVALIDARG); 10561 todo_wine { 10562 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, -1, NULL, NULL); 10563 EXPECT_HR(hr, E_FAIL); 10564 } 10565 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, NULL); 10566 EXPECT_HR(hr, E_POINTER); 10567 10568 len = -1; 10569 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, NULL, &len); 10570 EXPECT_HR(hr, S_OK); 10571 ok(len == 3, "got %d\n", len); 10572 10573 len = -1; 10574 buffW[0] = 0x1; 10575 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len); 10576 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL); 10577 ok(len == -1, "got %d\n", len); 10578 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10579 10580 len = 10; 10581 buffW[0] = 0x1; 10582 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len); 10583 EXPECT_HR(hr, S_OK); 10584 ok(len == 3, "got %d\n", len); 10585 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10586 10587 /* getURI */ 10588 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, NULL); 10589 EXPECT_HR(hr, E_INVALIDARG); 10590 10591 len = -1; 10592 hr = IMXNamespaceManager_getURI(nsmgr, NULL, NULL, NULL, &len); 10593 EXPECT_HR(hr, E_INVALIDARG); 10594 ok(len == -1, "got %d\n", len); 10595 10596 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, NULL); 10597 EXPECT_HR(hr, E_POINTER); 10598 10599 len = -1; 10600 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, NULL, &len); 10601 EXPECT_HR(hr, S_OK); 10602 /* length of "xml" uri is constant */ 10603 ok(len == strlen(xmluriA), "got %d\n", len); 10604 10605 len = 100; 10606 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len); 10607 EXPECT_HR(hr, S_OK); 10608 ok(len == strlen(xmluriA), "got %d\n", len); 10609 ok(!lstrcmpW(buffW, _bstr_(xmluriA)), "got prefix %s\n", wine_dbgstr_w(buffW)); 10610 10611 len = strlen(xmluriA)-1; 10612 buffW[0] = 0x1; 10613 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml"), NULL, buffW, &len); 10614 EXPECT_HR(hr, E_XML_BUFFERTOOSMALL); 10615 ok(len == strlen(xmluriA)-1, "got %d\n", len); 10616 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10617 10618 /* prefix xml1 not defined */ 10619 len = -1; 10620 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, NULL, &len); 10621 EXPECT_HR(hr, S_FALSE); 10622 ok(len == 0, "got %d\n", len); 10623 10624 len = 100; 10625 buffW[0] = 0x1; 10626 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_("xml1"), NULL, buffW, &len); 10627 EXPECT_HR(hr, S_FALSE); 10628 ok(buffW[0] == 0, "got %x\n", buffW[0]); 10629 ok(len == 0, "got %d\n", len); 10630 10631 /* IDispatchEx tests */ 10632 hr = IMXNamespaceManager_QueryInterface(nsmgr, &IID_IUnknown, (void**)&unk); 10633 EXPECT_HR(hr, S_OK); 10634 test_domobj_dispex(unk); 10635 IUnknown_Release(unk); 10636 10637 IMXNamespaceManager_Release(nsmgr); 10638 10639 /* ::getPrefix() */ 10640 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER, 10641 &IID_IMXNamespaceManager, (void**)&nsmgr); 10642 EXPECT_HR(hr, S_OK); 10643 10644 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, NULL); 10645 EXPECT_HR(hr, E_INVALIDARG); 10646 10647 len = -1; 10648 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, NULL, &len); 10649 EXPECT_HR(hr, E_INVALIDARG); 10650 ok(len == -1, "got %d\n", len); 10651 10652 len = 100; 10653 buffW[0] = 0x1; 10654 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len); 10655 EXPECT_HR(hr, E_FAIL); 10656 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10657 ok(len == 100, "got %d\n", len); 10658 10659 len = 0; 10660 buffW[0] = 0x1; 10661 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 0, buffW, &len); 10662 EXPECT_HR(hr, E_FAIL); 10663 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10664 ok(len == 0, "got %d\n", len); 10665 10666 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri")); 10667 EXPECT_HR(hr, S_OK); 10668 10669 len = 100; 10670 buffW[0] = 0x1; 10671 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10672 EXPECT_HR(hr, S_OK); 10673 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10674 ok(len == 3, "got %d\n", len); 10675 10676 len = 100; 10677 buffW[0] = 0x1; 10678 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, buffW, &len); 10679 EXPECT_HR(hr, S_OK); 10680 ok(!lstrcmpW(buffW, _bstr_("xml")), "got %s\n", wine_dbgstr_w(buffW)); 10681 ok(len == 3, "got %d\n", len); 10682 10683 /* with null buffer it's possible to get required length */ 10684 len = 100; 10685 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len); 10686 EXPECT_HR(hr, S_OK); 10687 ok(len == 3, "got %d\n", len); 10688 10689 len = 0; 10690 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("http://www.w3.org/XML/1998/namespace"), 0, NULL, &len); 10691 EXPECT_HR(hr, S_OK); 10692 ok(len == 3, "got %d\n", len); 10693 10694 len = 100; 10695 buffW[0] = 0x1; 10696 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 1, buffW, &len); 10697 EXPECT_HR(hr, E_FAIL); 10698 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10699 ok(len == 100, "got %d\n", len); 10700 10701 len = 100; 10702 buffW[0] = 0x1; 10703 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 2, buffW, &len); 10704 EXPECT_HR(hr, E_FAIL); 10705 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10706 ok(len == 100, "got %d\n", len); 10707 10708 len = 100; 10709 buffW[0] = 0x1; 10710 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 0, buffW, &len); 10711 EXPECT_HR(hr, E_INVALIDARG); 10712 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10713 ok(len == 100, "got %d\n", len); 10714 10715 len = 100; 10716 buffW[0] = 0x1; 10717 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len); 10718 EXPECT_HR(hr, E_INVALIDARG); 10719 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10720 ok(len == 100, "got %d\n", len); 10721 10722 len = 100; 10723 buffW[0] = 0x1; 10724 hr = IMXNamespaceManager_getPrefix(nsmgr, NULL, 0, buffW, &len); 10725 EXPECT_HR(hr, E_INVALIDARG); 10726 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10727 ok(len == 100, "got %d\n", len); 10728 10729 len = 100; 10730 buffW[0] = 0x1; 10731 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns0 uri"), 1, buffW, &len); 10732 EXPECT_HR(hr, E_FAIL); 10733 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10734 ok(len == 100, "got %d\n", len); 10735 10736 len = 100; 10737 buffW[0] = 0x1; 10738 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len); 10739 EXPECT_HR(hr, E_INVALIDARG); 10740 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10741 ok(len == 100, "got %d\n", len); 10742 10743 /* declare another one, indices are shifted */ 10744 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri")); 10745 EXPECT_HR(hr, S_OK); 10746 10747 len = 100; 10748 buffW[0] = 0x1; 10749 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10750 EXPECT_HR(hr, S_OK); 10751 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10752 ok(len == 3, "got %d\n", len); 10753 10754 len = 100; 10755 buffW[0] = 0x1; 10756 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); 10757 EXPECT_HR(hr, S_OK); 10758 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW)); 10759 ok(len == 3, "got %d\n", len); 10760 10761 len = 100; 10762 buffW[0] = 0x1; 10763 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 1, buffW, &len); 10764 EXPECT_HR(hr, E_FAIL); 10765 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10766 ok(len == 100, "got %d\n", len); 10767 10768 len = 100; 10769 buffW[0] = 0x1; 10770 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_(""), 1, buffW, &len); 10771 EXPECT_HR(hr, E_INVALIDARG); 10772 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10773 ok(len == 100, "got %d\n", len); 10774 10775 IMXNamespaceManager_Release(nsmgr); 10776 10777 /* push/pop tests */ 10778 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER, 10779 &IID_IMXNamespaceManager, (void**)&nsmgr); 10780 EXPECT_HR(hr, S_OK); 10781 10782 /* pop with empty stack */ 10783 hr = IMXNamespaceManager_popContext(nsmgr); 10784 EXPECT_HR(hr, E_FAIL); 10785 10786 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri")); 10787 EXPECT_HR(hr, S_OK); 10788 10789 len = 100; 10790 buffW[0] = 0x1; 10791 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10792 EXPECT_HR(hr, S_OK); 10793 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10794 ok(len == 3, "got %d\n", len); 10795 10796 hr = IMXNamespaceManager_pushContext(nsmgr); 10797 EXPECT_HR(hr, S_OK); 10798 10799 len = 100; 10800 buffW[0] = 0x1; 10801 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10802 EXPECT_HR(hr, S_OK); 10803 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10804 ok(len == 3, "got %d\n", len); 10805 10806 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns2"), _bstr_("ns2 uri")); 10807 EXPECT_HR(hr, S_OK); 10808 10809 len = 100; 10810 buffW[0] = 0x1; 10811 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); 10812 EXPECT_HR(hr, S_OK); 10813 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW)); 10814 ok(len == 3, "got %d\n", len); 10815 10816 hr = IMXNamespaceManager_pushContext(nsmgr); 10817 EXPECT_HR(hr, S_OK); 10818 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns3"), _bstr_("ns3 uri")); 10819 EXPECT_HR(hr, S_OK); 10820 10821 len = 100; 10822 buffW[0] = 0x1; 10823 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); 10824 EXPECT_HR(hr, S_OK); 10825 ok(!lstrcmpW(buffW, _bstr_("ns2")), "got %s\n", wine_dbgstr_w(buffW)); 10826 ok(len == 3, "got %d\n", len); 10827 10828 len = 100; 10829 buffW[0] = 0x1; 10830 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10831 EXPECT_HR(hr, S_OK); 10832 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10833 ok(len == 3, "got %d\n", len); 10834 10835 hr = IMXNamespaceManager_popContext(nsmgr); 10836 EXPECT_HR(hr, S_OK); 10837 10838 hr = IMXNamespaceManager_popContext(nsmgr); 10839 EXPECT_HR(hr, S_OK); 10840 10841 len = 100; 10842 buffW[0] = 0x1; 10843 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns2 uri"), 0, buffW, &len); 10844 EXPECT_HR(hr, E_FAIL); 10845 ok(buffW[0] == 0x1, "got %x\n", buffW[0]); 10846 ok(len == 100, "got %d\n", len); 10847 10848 len = 100; 10849 buffW[0] = 0x1; 10850 hr = IMXNamespaceManager_getPrefix(nsmgr, _bstr_("ns1 uri"), 0, buffW, &len); 10851 EXPECT_HR(hr, S_OK); 10852 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got %s\n", wine_dbgstr_w(buffW)); 10853 ok(len == 3, "got %d\n", len); 10854 10855 IMXNamespaceManager_Release(nsmgr); 10856 10857 free_bstrs(); 10858 } 10859 10860 static void test_mxnamespacemanager_override(void) 10861 { 10862 IMXNamespaceManager *nsmgr; 10863 WCHAR buffW[250]; 10864 VARIANT_BOOL b; 10865 HRESULT hr; 10866 INT len; 10867 10868 hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER, 10869 &IID_IMXNamespaceManager, (void**)&nsmgr); 10870 EXPECT_HR(hr, S_OK); 10871 10872 len = ARRAY_SIZE(buffW); 10873 buffW[0] = 0; 10874 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len); 10875 EXPECT_HR(hr, S_OK); 10876 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10877 10878 len = ARRAY_SIZE(buffW); 10879 buffW[0] = 0; 10880 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len); 10881 EXPECT_HR(hr, E_FAIL); 10882 10883 hr = IMXNamespaceManager_getAllowOverride(nsmgr, NULL); 10884 EXPECT_HR(hr, E_POINTER); 10885 10886 b = VARIANT_FALSE; 10887 hr = IMXNamespaceManager_getAllowOverride(nsmgr, &b); 10888 EXPECT_HR(hr, S_OK); 10889 ok(b == VARIANT_TRUE, "got %d\n", b); 10890 10891 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_FALSE); 10892 EXPECT_HR(hr, S_OK); 10893 10894 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri")); 10895 EXPECT_HR(hr, S_OK); 10896 10897 len = ARRAY_SIZE(buffW); 10898 buffW[0] = 0; 10899 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len); 10900 EXPECT_HR(hr, S_OK); 10901 ok(!lstrcmpW(buffW, _bstr_("ns0 uri")), "got uri %s\n", wine_dbgstr_w(buffW)); 10902 10903 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns0"), _bstr_("ns0 uri")); 10904 EXPECT_HR(hr, S_OK); 10905 10906 len = ARRAY_SIZE(buffW); 10907 buffW[0] = 0; 10908 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 0, buffW, &len); 10909 EXPECT_HR(hr, S_OK); 10910 ok(!lstrcmpW(buffW, _bstr_("xml")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10911 10912 len = ARRAY_SIZE(buffW); 10913 buffW[0] = 0; 10914 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len); 10915 EXPECT_HR(hr, S_OK); 10916 ok(!lstrcmpW(buffW, _bstr_("ns0")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10917 10918 len = ARRAY_SIZE(buffW); 10919 buffW[0] = 0; 10920 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 2, buffW, &len); 10921 EXPECT_HR(hr, S_OK); 10922 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10923 10924 /* new prefix placed at index 1 always */ 10925 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_("ns1"), _bstr_("ns1 uri")); 10926 EXPECT_HR(hr, S_OK); 10927 10928 len = ARRAY_SIZE(buffW); 10929 buffW[0] = 0; 10930 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 1, buffW, &len); 10931 EXPECT_HR(hr, S_OK); 10932 ok(!lstrcmpW(buffW, _bstr_("ns1")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10933 10934 hr = IMXNamespaceManager_declarePrefix(nsmgr, _bstr_(""), NULL); 10935 todo_wine EXPECT_HR(hr, E_FAIL); 10936 10937 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, NULL); 10938 EXPECT_HR(hr, E_FAIL); 10939 10940 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri")); 10941 EXPECT_HR(hr, E_FAIL); 10942 10943 hr = IMXNamespaceManager_putAllowOverride(nsmgr, VARIANT_TRUE); 10944 EXPECT_HR(hr, S_OK); 10945 10946 hr = IMXNamespaceManager_declarePrefix(nsmgr, NULL, _bstr_("ns0 uri override")); 10947 EXPECT_HR(hr, S_FALSE); 10948 10949 len = ARRAY_SIZE(buffW); 10950 buffW[0] = 0; 10951 hr = IMXNamespaceManager_getURI(nsmgr, _bstr_(""), NULL, buffW, &len); 10952 EXPECT_HR(hr, S_OK); 10953 ok(!lstrcmpW(buffW, _bstr_("ns0 uri override")), "got uri %s\n", wine_dbgstr_w(buffW)); 10954 10955 len = ARRAY_SIZE(buffW); 10956 buffW[0] = 0; 10957 hr = IMXNamespaceManager_getDeclaredPrefix(nsmgr, 3, buffW, &len); 10958 EXPECT_HR(hr, S_OK); 10959 ok(!lstrcmpW(buffW, _bstr_("")), "got prefix %s\n", wine_dbgstr_w(buffW)); 10960 10961 IMXNamespaceManager_Release(nsmgr); 10962 10963 free_bstrs(); 10964 } 10965 10966 static const DOMNodeType nodetypes_test[] = 10967 { 10968 NODE_ELEMENT, 10969 NODE_ATTRIBUTE, 10970 NODE_TEXT, 10971 NODE_CDATA_SECTION, 10972 NODE_ENTITY_REFERENCE, 10973 NODE_PROCESSING_INSTRUCTION, 10974 NODE_COMMENT, 10975 NODE_DOCUMENT_FRAGMENT, 10976 NODE_INVALID 10977 }; 10978 10979 static void test_dispex(void) 10980 { 10981 const DOMNodeType *type = nodetypes_test; 10982 IXMLDOMImplementation *impl; 10983 IXMLDOMNodeList *node_list; 10984 IXMLDOMParseError *error; 10985 IXMLDOMNamedNodeMap *map; 10986 IXSLProcessor *processor; 10987 IXSLTemplate *template; 10988 IXMLDOMDocument *doc; 10989 IXMLHTTPRequest *req; 10990 IXMLDOMElement *elem; 10991 IDispatchEx *dispex; 10992 DISPPARAMS dispparams; 10993 IXMLDOMNode *node; 10994 VARIANT arg, ret; 10995 VARIANT_BOOL b; 10996 IUnknown *unk; 10997 HRESULT hr; 10998 DISPID did; 10999 11000 doc = create_document(&IID_IXMLDOMDocument); 11001 11002 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk); 11003 ok(hr == S_OK, "got 0x%08x\n", hr); 11004 test_domobj_dispex(unk); 11005 IUnknown_Release(unk); 11006 11007 for(; *type != NODE_INVALID; type++) 11008 { 11009 IXMLDOMNode *node; 11010 VARIANT v; 11011 11012 V_VT(&v) = VT_I2; 11013 V_I2(&v) = *type; 11014 11015 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node); 11016 ok(hr == S_OK, "failed to create node type %d\n", *type); 11017 11018 IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk); 11019 11020 test_domobj_dispex(unk); 11021 IUnknown_Release(unk); 11022 IXMLDOMNode_Release(node); 11023 } 11024 11025 /* IXMLDOMNodeList */ 11026 hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list); 11027 EXPECT_HR(hr, S_OK); 11028 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk); 11029 ok(hr == S_OK, "got 0x%08x\n", hr); 11030 test_domobj_dispex(unk); 11031 IUnknown_Release(unk); 11032 IXMLDOMNodeList_Release(node_list); 11033 11034 /* IXMLDOMNodeList for children list */ 11035 hr = IXMLDOMDocument_get_childNodes(doc, &node_list); 11036 EXPECT_HR(hr, S_OK); 11037 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk); 11038 ok(hr == S_OK, "got 0x%08x\n", hr); 11039 test_domobj_dispex(unk); 11040 IUnknown_Release(unk); 11041 11042 /* collection dispex test, empty collection */ 11043 hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IDispatchEx, (void**)&dispex); 11044 EXPECT_HR(hr, S_OK); 11045 did = 0; 11046 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did); 11047 EXPECT_HR(hr, S_OK); 11048 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did); 11049 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did); 11050 EXPECT_HR(hr, S_OK); 11051 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did); 11052 IDispatchEx_Release(dispex); 11053 11054 did = -1; 11055 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did); 11056 ok(hr == S_OK, "got 0x%08x\n", hr); 11057 ok(did == DISPID_VALUE, "got %d\n", did); 11058 11059 V_VT(&arg) = VT_I4; 11060 V_I4(&arg) = 0; 11061 dispparams.cArgs = 0; 11062 dispparams.cNamedArgs = 0; 11063 dispparams.rgdispidNamedArgs = NULL; 11064 dispparams.rgvarg = &arg; 11065 11066 V_VT(&ret) = VT_EMPTY; 11067 V_DISPATCH(&ret) = (void*)0x1; 11068 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11069 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr); 11070 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11071 todo_wine 11072 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret)); 11073 11074 V_VT(&arg) = VT_I4; 11075 V_I4(&arg) = 0; 11076 dispparams.cArgs = 2; 11077 dispparams.cNamedArgs = 0; 11078 dispparams.rgdispidNamedArgs = NULL; 11079 dispparams.rgvarg = &arg; 11080 11081 V_VT(&ret) = VT_EMPTY; 11082 V_DISPATCH(&ret) = (void*)0x1; 11083 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11084 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr); 11085 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11086 todo_wine 11087 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret)); 11088 11089 V_VT(&arg) = VT_I4; 11090 V_I4(&arg) = 0; 11091 dispparams.cArgs = 1; 11092 dispparams.cNamedArgs = 0; 11093 dispparams.rgdispidNamedArgs = NULL; 11094 dispparams.rgvarg = &arg; 11095 11096 V_VT(&ret) = VT_EMPTY; 11097 V_DISPATCH(&ret) = (void*)0x1; 11098 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11099 ok(hr == S_OK, "got 0x%08x\n", hr); 11100 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11101 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11102 11103 V_VT(&ret) = VT_EMPTY; 11104 V_DISPATCH(&ret) = (void*)0x1; 11105 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL); 11106 ok(hr == S_OK, "got 0x%08x\n", hr); 11107 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11108 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11109 11110 V_VT(&ret) = VT_EMPTY; 11111 V_DISPATCH(&ret) = (void*)0x1; 11112 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11113 ok(hr == S_OK, "got 0x%08x\n", hr); 11114 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11115 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11116 11117 dispparams.cArgs = 0; 11118 dispparams.cNamedArgs = 0; 11119 dispparams.rgdispidNamedArgs = NULL; 11120 dispparams.rgvarg = NULL; 11121 11122 V_VT(&ret) = VT_EMPTY; 11123 V_I4(&ret) = 1; 11124 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL); 11125 ok(hr == S_OK, "got 0x%08x\n", hr); 11126 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret)); 11127 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret)); 11128 11129 dispparams.cArgs = 0; 11130 dispparams.cNamedArgs = 0; 11131 dispparams.rgdispidNamedArgs = NULL; 11132 dispparams.rgvarg = NULL; 11133 11134 V_VT(&ret) = VT_EMPTY; 11135 V_I4(&ret) = 1; 11136 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11137 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr); 11138 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11139 todo_wine 11140 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret)); 11141 11142 IXMLDOMNodeList_Release(node_list); 11143 11144 /* IXMLDOMParseError */ 11145 hr = IXMLDOMDocument_get_parseError(doc, &error); 11146 EXPECT_HR(hr, S_OK); 11147 IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk); 11148 test_domobj_dispex(unk); 11149 11150 hr = IXMLDOMParseError_QueryInterface(error, &IID_IDispatchEx, (void**)&dispex); 11151 ok(hr == S_OK, "got 0x%08x\n", hr); 11152 11153 V_VT(&arg) = VT_I4; 11154 V_I4(&arg) = 0; 11155 dispparams.cArgs = 1; 11156 dispparams.cNamedArgs = 0; 11157 dispparams.rgdispidNamedArgs = NULL; 11158 dispparams.rgvarg = &arg; 11159 11160 V_VT(&ret) = VT_EMPTY; 11161 V_DISPATCH(&ret) = (void*)0x1; 11162 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11163 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr); 11164 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11165 todo_wine 11166 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret)); 11167 11168 IDispatchEx_Release(dispex); 11169 11170 IUnknown_Release(unk); 11171 IXMLDOMParseError_Release(error); 11172 11173 /* IXMLDOMNamedNodeMap */ 11174 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xpath_simple_list), &b); 11175 EXPECT_HR(hr, S_OK); 11176 11177 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/a"), &node_list); 11178 EXPECT_HR(hr, S_OK); 11179 hr = IXMLDOMNodeList_get_item(node_list, 0, &node); 11180 EXPECT_HR(hr, S_OK); 11181 IXMLDOMNodeList_Release(node_list); 11182 11183 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem); 11184 EXPECT_HR(hr, S_OK); 11185 IXMLDOMNode_Release(node); 11186 hr = IXMLDOMElement_get_attributes(elem, &map); 11187 EXPECT_HR(hr, S_OK); 11188 IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk); 11189 test_domobj_dispex(unk); 11190 IUnknown_Release(unk); 11191 /* collection dispex test */ 11192 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex); 11193 EXPECT_HR(hr, S_OK); 11194 did = 0; 11195 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did); 11196 EXPECT_HR(hr, S_OK); 11197 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did); 11198 IDispatchEx_Release(dispex); 11199 IXMLDOMNamedNodeMap_Release(map); 11200 11201 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list); 11202 EXPECT_HR(hr, S_OK); 11203 hr = IXMLDOMNodeList_get_item(node_list, 0, &node); 11204 EXPECT_HR(hr, S_OK); 11205 IXMLDOMNodeList_Release(node_list); 11206 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem); 11207 EXPECT_HR(hr, S_OK); 11208 IXMLDOMNode_Release(node); 11209 hr = IXMLDOMElement_get_attributes(elem, &map); 11210 EXPECT_HR(hr, S_OK); 11211 /* collection dispex test, empty collection */ 11212 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IDispatchEx, (void**)&dispex); 11213 EXPECT_HR(hr, S_OK); 11214 did = 0; 11215 hr = IDispatchEx_GetDispID(dispex, _bstr_("0"), 0, &did); 11216 EXPECT_HR(hr, S_OK); 11217 ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did); 11218 hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did); 11219 EXPECT_HR(hr, S_OK); 11220 ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did); 11221 IXMLDOMNamedNodeMap_Release(map); 11222 11223 did = -1; 11224 hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did); 11225 ok(hr == S_OK, "got 0x%08x\n", hr); 11226 ok(did == DISPID_VALUE, "got %d\n", did); 11227 11228 V_VT(&arg) = VT_I4; 11229 V_I4(&arg) = 0; 11230 dispparams.cArgs = 0; 11231 dispparams.cNamedArgs = 0; 11232 dispparams.rgdispidNamedArgs = NULL; 11233 dispparams.rgvarg = &arg; 11234 11235 V_VT(&ret) = VT_EMPTY; 11236 V_DISPATCH(&ret) = (void*)0x1; 11237 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11238 todo_wine { 11239 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr); 11240 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11241 } 11242 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret)); 11243 11244 V_VT(&arg) = VT_I4; 11245 V_I4(&arg) = 0; 11246 dispparams.cArgs = 2; 11247 dispparams.cNamedArgs = 0; 11248 dispparams.rgdispidNamedArgs = NULL; 11249 dispparams.rgvarg = &arg; 11250 11251 V_VT(&ret) = VT_EMPTY; 11252 V_DISPATCH(&ret) = (void*)0x1; 11253 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11254 todo_wine { 11255 ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr); 11256 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11257 } 11258 ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret)); 11259 11260 V_VT(&arg) = VT_I4; 11261 V_I4(&arg) = 0; 11262 dispparams.cArgs = 1; 11263 dispparams.cNamedArgs = 0; 11264 dispparams.rgdispidNamedArgs = NULL; 11265 dispparams.rgvarg = &arg; 11266 11267 V_VT(&ret) = VT_EMPTY; 11268 V_DISPATCH(&ret) = (void*)0x1; 11269 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11270 todo_wine 11271 ok(hr == S_OK, "got 0x%08x\n", hr); 11272 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11273 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11274 11275 V_VT(&ret) = VT_EMPTY; 11276 V_DISPATCH(&ret) = (void*)0x1; 11277 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL); 11278 ok(hr == S_OK, "got 0x%08x\n", hr); 11279 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11280 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11281 11282 V_VT(&ret) = VT_EMPTY; 11283 V_DISPATCH(&ret) = (void*)0x1; 11284 hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11285 ok(hr == S_OK, "got 0x%08x\n", hr); 11286 ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret)); 11287 ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret)); 11288 11289 dispparams.cArgs = 0; 11290 dispparams.cNamedArgs = 0; 11291 dispparams.rgdispidNamedArgs = NULL; 11292 dispparams.rgvarg = NULL; 11293 11294 V_VT(&ret) = VT_EMPTY; 11295 V_I4(&ret) = 1; 11296 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL); 11297 ok(hr == S_OK, "got 0x%08x\n", hr); 11298 ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret)); 11299 ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret)); 11300 11301 dispparams.cArgs = 0; 11302 dispparams.cNamedArgs = 0; 11303 dispparams.rgdispidNamedArgs = NULL; 11304 dispparams.rgvarg = NULL; 11305 11306 V_VT(&ret) = VT_EMPTY; 11307 V_I4(&ret) = 1; 11308 hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL); 11309 ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr); 11310 todo_wine 11311 ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret)); 11312 ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret)); 11313 11314 IDispatchEx_Release(dispex); 11315 IXMLDOMElement_Release(elem); 11316 11317 /* IXMLDOMImplementation */ 11318 hr = IXMLDOMDocument_get_implementation(doc, &impl); 11319 EXPECT_HR(hr, S_OK); 11320 11321 hr = IXMLDOMImplementation_QueryInterface(impl, &IID_IDispatchEx, (void**)&dispex); 11322 EXPECT_HR(hr, S_OK); 11323 IDispatchEx_Release(dispex); 11324 IXMLDOMImplementation_Release(impl); 11325 11326 IXMLDOMDocument_Release(doc); 11327 11328 /* IXMLHTTPRequest */ 11329 hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, 11330 &IID_IXMLHttpRequest, (void**)&req); 11331 if (hr == S_OK) 11332 { 11333 hr = IXMLHTTPRequest_QueryInterface(req, &IID_IDispatchEx, (void**)&dispex); 11334 EXPECT_HR(hr, E_NOINTERFACE); 11335 IXMLHTTPRequest_Release(req); 11336 } 11337 11338 /* IXSLTemplate */ 11339 template = create_xsltemplate(&IID_IXSLTemplate); 11340 hr = IXSLTemplate_QueryInterface(template, &IID_IDispatchEx, (void**)&dispex); 11341 EXPECT_HR(hr, S_OK); 11342 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk); 11343 EXPECT_HR(hr, S_OK); 11344 test_domobj_dispex(unk); 11345 IUnknown_Release(unk); 11346 IDispatchEx_Release(dispex); 11347 11348 /* IXSLProcessor */ 11349 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc); 11350 EXPECT_HR(hr, S_OK); 11351 b = VARIANT_FALSE; 11352 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformSSXML), &b); 11353 EXPECT_HR(hr, S_OK); 11354 ok(b == VARIANT_TRUE, "got %d\n", b); 11355 11356 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc); 11357 EXPECT_HR(hr, S_OK); 11358 IXMLDOMDocument_Release(doc); 11359 11360 hr = IXSLTemplate_createProcessor(template, &processor); 11361 EXPECT_HR(hr, S_OK); 11362 hr = IXSLProcessor_QueryInterface(processor, &IID_IDispatchEx, (void**)&dispex); 11363 EXPECT_HR(hr, S_OK); 11364 hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk); 11365 EXPECT_HR(hr, S_OK); 11366 test_domobj_dispex(unk); 11367 IUnknown_Release(unk); 11368 IDispatchEx_Release(dispex); 11369 11370 IXSLProcessor_Release(processor); 11371 IXSLTemplate_Release(template); 11372 11373 if (is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) 11374 { 11375 doc = create_document_version(60, &IID_IXMLDOMDocument); 11376 test_domobj_dispex((IUnknown*)doc); 11377 IXMLDOMDocument_Release(doc); 11378 } 11379 11380 free_bstrs(); 11381 } 11382 11383 static void test_parseerror(void) 11384 { 11385 IXMLDOMParseError2 *error2; 11386 IXMLDOMParseError *error; 11387 IXMLDOMDocument *doc; 11388 HRESULT hr; 11389 11390 doc = create_document(&IID_IXMLDOMDocument); 11391 11392 hr = IXMLDOMDocument_get_parseError(doc, &error); 11393 EXPECT_HR(hr, S_OK); 11394 11395 hr = IXMLDOMParseError_get_line(error, NULL); 11396 EXPECT_HR(hr, E_INVALIDARG); 11397 11398 hr = IXMLDOMParseError_get_srcText(error, NULL); 11399 EXPECT_HR(hr, E_INVALIDARG); 11400 11401 hr = IXMLDOMParseError_get_linepos(error, NULL); 11402 EXPECT_HR(hr, E_INVALIDARG); 11403 11404 IXMLDOMParseError_Release(error); 11405 IXMLDOMDocument_Release(doc); 11406 11407 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) return; 11408 doc = create_document_version(60, &IID_IXMLDOMDocument); 11409 11410 hr = IXMLDOMDocument_get_parseError(doc, &error); 11411 EXPECT_HR(hr, S_OK); 11412 hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2); 11413 EXPECT_HR(hr, S_OK); 11414 IXMLDOMParseError2_Release(error2); 11415 IXMLDOMParseError_Release(error); 11416 IXMLDOMDocument_Release(doc); 11417 } 11418 11419 static void test_getAttributeNode(void) 11420 { 11421 IXMLDOMAttribute *attr; 11422 IXMLDOMDocument *doc; 11423 IXMLDOMElement *elem; 11424 VARIANT_BOOL v; 11425 HRESULT hr; 11426 BSTR str; 11427 11428 doc = create_document(&IID_IXMLDOMDocument); 11429 11430 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v); 11431 EXPECT_HR(hr, S_OK); 11432 11433 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 11434 EXPECT_HR(hr, S_OK); 11435 11436 str = SysAllocString(nonexistent_fileW); 11437 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL); 11438 EXPECT_HR(hr, E_FAIL); 11439 11440 attr = (IXMLDOMAttribute*)0xdeadbeef; 11441 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr); 11442 EXPECT_HR(hr, E_FAIL); 11443 ok(attr == NULL, "got %p\n", attr); 11444 SysFreeString(str); 11445 11446 str = SysAllocString(nonexistent_attrW); 11447 hr = IXMLDOMElement_getAttributeNode(elem, str, NULL); 11448 EXPECT_HR(hr, S_FALSE); 11449 11450 attr = (IXMLDOMAttribute*)0xdeadbeef; 11451 hr = IXMLDOMElement_getAttributeNode(elem, str, &attr); 11452 EXPECT_HR(hr, S_FALSE); 11453 ok(attr == NULL, "got %p\n", attr); 11454 SysFreeString(str); 11455 11456 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("foo:b"), &attr); 11457 EXPECT_HR(hr, S_OK); 11458 IXMLDOMAttribute_Release(attr); 11459 11460 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("b"), &attr); 11461 EXPECT_HR(hr, S_FALSE); 11462 11463 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("a"), &attr); 11464 EXPECT_HR(hr, S_OK); 11465 IXMLDOMAttribute_Release(attr); 11466 11467 IXMLDOMElement_Release(elem); 11468 IXMLDOMDocument_Release(doc); 11469 free_bstrs(); 11470 } 11471 11472 static void test_getAttribute(void) 11473 { 11474 IXMLDOMDocument *doc; 11475 IXMLDOMElement *elem; 11476 VARIANT_BOOL v; 11477 VARIANT var; 11478 HRESULT hr; 11479 11480 doc = create_document(&IID_IXMLDOMDocument); 11481 11482 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szExampleXML), &v); 11483 EXPECT_HR(hr, S_OK); 11484 11485 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 11486 EXPECT_HR(hr, S_OK); 11487 11488 VariantInit(&var); 11489 hr = IXMLDOMElement_getAttribute( elem, _bstr_("xmlns:foo"), &var ); 11490 EXPECT_HR(hr, S_OK); 11491 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); 11492 ok( !lstrcmpW(V_BSTR(&var), _bstr_("urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); 11493 VariantClear(&var); 11494 11495 hr = IXMLDOMElement_getAttribute( elem, _bstr_("a"), &var ); 11496 EXPECT_HR(hr, S_OK); 11497 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); 11498 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr a")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); 11499 VariantClear(&var); 11500 11501 hr = IXMLDOMElement_getAttribute( elem, _bstr_("foo:b"), &var ); 11502 EXPECT_HR(hr, S_OK); 11503 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var)); 11504 ok( !lstrcmpW(V_BSTR(&var), _bstr_("attr b")), "wrong attr value: %s\n", wine_dbgstr_w(V_BSTR(&var))); 11505 VariantClear(&var); 11506 11507 hr = IXMLDOMElement_getAttribute( elem, _bstr_("b"), &var ); 11508 EXPECT_HR(hr, S_FALSE); 11509 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var)); 11510 VariantClear(&var); 11511 11512 hr = IXMLDOMElement_getAttribute( elem, _bstr_("non-existent"), &var ); 11513 EXPECT_HR(hr, S_FALSE); 11514 ok( V_VT(&var) == VT_NULL, "vt = %x\n", V_VT(&var)); 11515 VariantClear(&var); 11516 11517 IXMLDOMElement_Release(elem); 11518 IXMLDOMDocument_Release(doc); 11519 free_bstrs(); 11520 } 11521 11522 typedef struct { 11523 DOMNodeType type; 11524 const char *name; 11525 REFIID iids[3]; 11526 } supporterror_t; 11527 11528 static const supporterror_t supporterror_test[] = { 11529 { NODE_ELEMENT, "element", { &IID_IXMLDOMNode, &IID_IXMLDOMElement } }, 11530 { NODE_ATTRIBUTE, "attribute", { &IID_IXMLDOMNode, &IID_IXMLDOMAttribute } }, 11531 { NODE_CDATA_SECTION, "cdata", { &IID_IXMLDOMNode, &IID_IXMLDOMCDATASection } }, 11532 { NODE_ENTITY_REFERENCE, "entityref", { &IID_IXMLDOMNode, &IID_IXMLDOMEntityReference } }, 11533 { NODE_PROCESSING_INSTRUCTION, "pi", { &IID_IXMLDOMNode, &IID_IXMLDOMProcessingInstruction } }, 11534 { NODE_COMMENT, "comment", { &IID_IXMLDOMNode, &IID_IXMLDOMComment } }, 11535 { NODE_DOCUMENT_FRAGMENT, "fragment", { &IID_IXMLDOMNode, &IID_IXMLDOMDocumentFragment } }, 11536 { NODE_INVALID } 11537 }; 11538 11539 static void test_supporterrorinfo(void) 11540 { 11541 static REFIID iids[5] = { &IID_IXMLDOMNode, &IID_IXMLDOMDocument, 11542 &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 }; 11543 const supporterror_t *ptr = supporterror_test; 11544 ISupportErrorInfo *errorinfo, *info2; 11545 IXMLDOMSchemaCollection *schemacache; 11546 IXMLDOMNamedNodeMap *map, *map2; 11547 IXMLDOMDocument *doc; 11548 IXMLDOMElement *elem; 11549 VARIANT_BOOL b; 11550 IUnknown *unk; 11551 REFIID *iid; 11552 void *dummy; 11553 HRESULT hr; 11554 11555 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument3)) return; 11556 doc = create_document_version(60, &IID_IXMLDOMDocument3); 11557 11558 EXPECT_REF(doc, 1); 11559 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo); 11560 EXPECT_HR(hr, S_OK); 11561 EXPECT_REF(doc, 1); 11562 ISupportErrorInfo_AddRef(errorinfo); 11563 EXPECT_REF(errorinfo, 2); 11564 EXPECT_REF(doc, 1); 11565 ISupportErrorInfo_Release(errorinfo); 11566 11567 hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&info2); 11568 EXPECT_HR(hr, S_OK); 11569 ok(errorinfo != info2, "got %p, %p\n", info2, errorinfo); 11570 11571 /* error interface can't be queried back for DOM interface */ 11572 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMDocument, &dummy); 11573 EXPECT_HR(hr, E_NOINTERFACE); 11574 hr = ISupportErrorInfo_QueryInterface(info2, &IID_IXMLDOMNode, &dummy); 11575 EXPECT_HR(hr, E_NOINTERFACE); 11576 11577 ISupportErrorInfo_Release(info2); 11578 11579 iid = iids; 11580 while (*iid) 11581 { 11582 hr = IXMLDOMDocument_QueryInterface(doc, *iid, (void**)&unk); 11583 EXPECT_HR(hr, S_OK); 11584 if (hr == S_OK) 11585 { 11586 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid); 11587 ok(hr == S_OK, "got 0x%08x for %s\n", hr, wine_dbgstr_guid(*iid)); 11588 IUnknown_Release(unk); 11589 } 11590 11591 iid++; 11592 } 11593 11594 ISupportErrorInfo_Release(errorinfo); 11595 11596 while (ptr->type != NODE_INVALID) 11597 { 11598 IXMLDOMNode *node; 11599 VARIANT type; 11600 11601 V_VT(&type) = VT_I1; 11602 V_I1(&type) = ptr->type; 11603 11604 hr = IXMLDOMDocument_createNode(doc, type, _bstr_(ptr->name), NULL, &node); 11605 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr); 11606 11607 EXPECT_REF(node, 1); 11608 hr = IXMLDOMNode_QueryInterface(node, &IID_ISupportErrorInfo, (void**)&errorinfo); 11609 ok(hr == S_OK, "%d: got 0x%08x\n", ptr->type, hr); 11610 EXPECT_REF(node, 1); 11611 11612 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNode, &dummy); 11613 ok(hr == E_NOINTERFACE, "%d: got 0x%08x\n", ptr->type, hr); 11614 11615 iid = ptr->iids; 11616 11617 while (*iid) 11618 { 11619 hr = IXMLDOMNode_QueryInterface(node, *iid, (void**)&unk); 11620 if (hr == S_OK) 11621 { 11622 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid); 11623 ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, wine_dbgstr_guid(*iid)); 11624 IUnknown_Release(unk); 11625 } 11626 11627 iid++; 11628 } 11629 11630 ISupportErrorInfo_Release(errorinfo); 11631 IXMLDOMNode_Release(node); 11632 ptr++; 11633 } 11634 11635 /* IXMLDOMNamedNodeMap */ 11636 b = VARIANT_FALSE; 11637 hr = IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b); 11638 EXPECT_HR(hr, S_OK); 11639 ok(b == VARIANT_TRUE, "got %d\n", b); 11640 11641 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 11642 EXPECT_HR(hr, S_OK); 11643 11644 hr = IXMLDOMElement_get_attributes(elem, &map); 11645 EXPECT_HR(hr, S_OK); 11646 11647 EXPECT_REF(map, 1); 11648 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_ISupportErrorInfo, (void**)&errorinfo); 11649 EXPECT_HR(hr, S_OK); 11650 EXPECT_REF(map, 2); 11651 11652 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMNamedNodeMap); 11653 EXPECT_HR(hr, S_OK); 11654 11655 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IXMLDOMNamedNodeMap, (void**)&map2); 11656 EXPECT_HR(hr, S_OK); 11657 ok(map == map2, "got %p\n", map2); 11658 IXMLDOMNamedNodeMap_Release(map2); 11659 11660 EXPECT_REF(errorinfo, 2); 11661 hr = ISupportErrorInfo_QueryInterface(errorinfo, &IID_IUnknown, (void**)&unk); 11662 EXPECT_HR(hr, S_OK); 11663 EXPECT_REF(errorinfo, 3); 11664 EXPECT_REF(map, 3); 11665 IUnknown_Release(unk); 11666 11667 ISupportErrorInfo_Release(errorinfo); 11668 IXMLDOMNamedNodeMap_Release(map); 11669 IXMLDOMElement_Release(elem); 11670 11671 IXMLDOMDocument_Release(doc); 11672 11673 /* IXMLDOMSchemaCollection */ 11674 hr = CoCreateInstance(&CLSID_XMLSchemaCache, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (void**)&schemacache); 11675 ok(hr == S_OK, "failed to create schema collection, 0x%08x\n", hr); 11676 11677 hr = IXMLDOMSchemaCollection_QueryInterface(schemacache, &IID_ISupportErrorInfo, (void**)&errorinfo); 11678 ok(hr == S_OK, "got 0x%08x\n", hr); 11679 11680 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMSchemaCollection); 11681 ok(hr == S_OK, "got 0x%08x\n", hr); 11682 11683 ISupportErrorInfo_Release(errorinfo); 11684 IXMLDOMSchemaCollection_Release(schemacache); 11685 11686 free_bstrs(); 11687 } 11688 11689 typedef struct { 11690 DOMNodeType type; 11691 const char *name; 11692 const char *put_content; 11693 HRESULT put_hr; 11694 VARTYPE get_vt; 11695 HRESULT get_hr; 11696 } node_value_t; 11697 11698 static const node_value_t nodevalue_test[] = { 11699 { NODE_ELEMENT, "element", "", E_FAIL, VT_NULL, S_FALSE }, 11700 { NODE_ATTRIBUTE, "attr", "value", S_OK, VT_BSTR, S_OK }, 11701 { NODE_TEXT, "text", "textdata", S_OK, VT_BSTR, S_OK }, 11702 { NODE_CDATA_SECTION , "cdata", "cdata data", S_OK, VT_BSTR, S_OK }, 11703 { NODE_ENTITY_REFERENCE, "entityref", "ref", E_FAIL, VT_NULL, S_FALSE }, 11704 { NODE_PROCESSING_INSTRUCTION, "pi", "instr", S_OK, VT_BSTR, S_OK }, 11705 { NODE_COMMENT, "comment", "comment data", S_OK, VT_BSTR, S_OK }, 11706 { NODE_DOCUMENT_FRAGMENT, "docfrag", "", E_FAIL, VT_NULL, S_FALSE }, 11707 { NODE_INVALID } 11708 }; 11709 11710 static void test_nodeValue(void) 11711 { 11712 const node_value_t *ptr = nodevalue_test; 11713 IXMLDOMDocument *doc; 11714 HRESULT hr; 11715 11716 doc = create_document(&IID_IXMLDOMDocument); 11717 11718 while (ptr->type != NODE_INVALID) 11719 { 11720 IXMLDOMNode *node; 11721 VARIANT v; 11722 11723 V_VT(&v) = VT_I2; 11724 V_I2(&v) = ptr->type; 11725 11726 hr = IXMLDOMDocument_createNode(doc, v, _bstr_(ptr->name), NULL, &node); 11727 ok(hr == S_OK, "failed to create node type %d\n", ptr->type); 11728 11729 hr = IXMLDOMNode_get_nodeValue(node, NULL); 11730 ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", ptr->type, hr); 11731 11732 V_VT(&v) = VT_BSTR; 11733 V_BSTR(&v) = _bstr_(ptr->put_content); 11734 hr = IXMLDOMNode_put_nodeValue(node, v); 11735 ok(hr == ptr->put_hr, "%d: got 0x%08x\n", ptr->type, hr); 11736 11737 V_VT(&v) = VT_EMPTY; 11738 hr = IXMLDOMNode_get_nodeValue(node, &v); 11739 ok(hr == ptr->get_hr, "%d: got 0x%08x, expected 0x%08x\n", ptr->type, hr, ptr->get_hr); 11740 ok(V_VT(&v) == ptr->get_vt, "%d: got %d, expected %d\n", ptr->type, V_VT(&v), ptr->get_vt); 11741 if (hr == S_OK) 11742 ok(!lstrcmpW(V_BSTR(&v), _bstr_(ptr->put_content)), "%d: got %s\n", ptr->type, 11743 wine_dbgstr_w(V_BSTR(&v))); 11744 VariantClear(&v); 11745 11746 IXMLDOMNode_Release(node); 11747 11748 ptr++; 11749 } 11750 11751 IXMLDOMDocument_Release(doc); 11752 } 11753 11754 static void test_xmlns_attribute(void) 11755 { 11756 BSTR str; 11757 IXMLDOMDocument *doc; 11758 IXMLDOMElement *root; 11759 IXMLDOMAttribute *pAttribute; 11760 IXMLDOMElement *elem; 11761 HRESULT hr; 11762 VARIANT v; 11763 11764 doc = create_document(&IID_IXMLDOMDocument); 11765 11766 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root); 11767 EXPECT_HR(hr, S_OK); 11768 11769 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL); 11770 EXPECT_HR(hr, S_OK); 11771 11772 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("xmlns:dt"), &pAttribute); 11773 ok( hr == S_OK, "returns %08x\n", hr ); 11774 11775 V_VT(&v) = VT_BSTR; 11776 V_BSTR(&v) = _bstr_("urn:schemas-microsoft-com:datatypes"); 11777 hr = IXMLDOMAttribute_put_nodeValue(pAttribute, v); 11778 ok(hr == S_OK, "ret %08x\n", hr ); 11779 11780 hr = IXMLDOMElement_setAttributeNode(root, pAttribute, NULL); 11781 ok(hr == S_OK, "ret %08x\n", hr ); 11782 11783 hr = IXMLDOMNode_put_dataType((IXMLDOMNode*)root, _bstr_("bin.base64")); 11784 ok(hr == S_OK, "ret %08x\n", hr ); 11785 11786 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 11787 EXPECT_HR(hr, S_OK); 11788 11789 str = NULL; 11790 hr = IXMLDOMElement_get_xml(elem, &str); 11791 ok( hr == S_OK, "got 0x%08x\n", hr); 11792 todo_wine ok( lstrcmpW(str, _bstr_("<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>")) == 0, 11793 "got %s\n", wine_dbgstr_w(str)); 11794 SysFreeString(str); 11795 11796 IXMLDOMElement_Release(elem); 11797 IXMLDOMAttribute_Release( pAttribute); 11798 11799 IXMLDOMDocument_Release(doc); 11800 11801 free_bstrs(); 11802 } 11803 11804 static const char namespacesA[] = 11805 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" 11806 " <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >" 11807 " <ns2:elem2 xmlns:ns2=\"http://blah.org\"/>" 11808 " <ns1:elem3/>" 11809 " <ns1:elem4/>" 11810 " <elem5 xmlns=\"http://blahblah.org\"/>" 11811 " <ns1:elem6>true</ns1:elem6>" 11812 " </ns1:elem1>"; 11813 11814 static const char xsd_schema1_uri[] = "x-schema:test1.xsd"; 11815 static const char xsd_schema1_xml[] = 11816 "<?xml version='1.0'?>" 11817 "<schema xmlns='http://www.w3.org/2001/XMLSchema'" 11818 " targetNamespace='x-schema:test1.xsd'>" 11819 " <element name='root'>" 11820 " <complexType>" 11821 " <sequence maxOccurs='unbounded'>" 11822 " <any/>" 11823 " </sequence>" 11824 " </complexType>" 11825 " </element>" 11826 "</schema>"; 11827 11828 static void test_get_namespaces(void) 11829 { 11830 IXMLDOMSchemaCollection *collection, *collection2; 11831 IXMLDOMDocument2 *doc, *doc2; 11832 IEnumVARIANT *enumv, *enum2; 11833 IUnknown *unk1, *unk2; 11834 IXMLDOMNode *node; 11835 VARIANT_BOOL b; 11836 HRESULT hr; 11837 VARIANT v; 11838 LONG len; 11839 BSTR s; 11840 11841 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return; 11842 doc = create_document(&IID_IXMLDOMDocument2); 11843 11844 /* null pointer */ 11845 hr = IXMLDOMDocument2_get_namespaces(doc, NULL); 11846 EXPECT_HR(hr, E_POINTER); 11847 11848 /* no document loaded */ 11849 collection = (void*)0xdeadbeef; 11850 hr = IXMLDOMDocument2_get_namespaces(doc, &collection); 11851 EXPECT_HR(hr, S_OK); 11852 if (hr != S_OK) 11853 { 11854 IXMLDOMDocument2_Release(doc); 11855 return; 11856 } 11857 EXPECT_REF(collection, 2); 11858 11859 collection2 = (void*)0xdeadbeef; 11860 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2); 11861 EXPECT_HR(hr, S_OK); 11862 ok(collection == collection2, "got %p\n", collection2); 11863 EXPECT_REF(collection, 3); 11864 IXMLDOMSchemaCollection_Release(collection); 11865 11866 len = -1; 11867 hr = IXMLDOMSchemaCollection_get_length(collection, &len); 11868 EXPECT_HR(hr, S_OK); 11869 ok(len == 0, "got %d\n", len); 11870 IXMLDOMSchemaCollection_Release(collection); 11871 11872 /* now with document */ 11873 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b); 11874 EXPECT_HR(hr, S_OK); 11875 11876 hr = IXMLDOMDocument2_get_namespaces(doc, &collection); 11877 EXPECT_HR(hr, S_OK); 11878 11879 len = -1; 11880 hr = IXMLDOMSchemaCollection_get_length(collection, &len); 11881 EXPECT_HR(hr, S_OK); 11882 ok(len == 2, "got %d\n", len); 11883 11884 /* try to lookup some uris */ 11885 node = (void*)0xdeadbeef; 11886 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node); 11887 EXPECT_HR(hr, S_OK); 11888 ok(node == NULL, "got %p\n", node); 11889 11890 node = (void*)0xdeadbeef; 11891 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah1.org"), &node); 11892 EXPECT_HR(hr, S_OK); 11893 ok(node == NULL, "got %p\n", node); 11894 11895 /* load schema and try to add it */ 11896 doc2 = create_document(&IID_IXMLDOMDocument2); 11897 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b); 11898 EXPECT_HR(hr, S_OK); 11899 11900 V_VT(&v) = VT_DISPATCH; 11901 V_DISPATCH(&v) = (IDispatch*)doc2; 11902 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v); 11903 EXPECT_HR(hr, E_FAIL); 11904 11905 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s); 11906 EXPECT_HR(hr, S_OK); 11907 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s)); 11908 SysFreeString(s); 11909 11910 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s); 11911 EXPECT_HR(hr, S_OK); 11912 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s)); 11913 SysFreeString(s); 11914 11915 s = (void*)0xdeadbeef; 11916 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s); 11917 EXPECT_HR(hr, E_FAIL); 11918 ok(s == (void*)0xdeadbeef, "got %p\n", s); 11919 11920 /* enumerate */ 11921 enumv = (void*)0xdeadbeef; 11922 EXPECT_REF(collection, 2); 11923 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); 11924 EXPECT_HR(hr, S_OK); 11925 EXPECT_REF(collection, 3); 11926 ok(enumv != NULL, "got %p\n", enumv); 11927 11928 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IUnknown, (void**)&unk1); 11929 EXPECT_HR(hr, S_OK); 11930 hr = IEnumVARIANT_QueryInterface(enumv, &IID_IUnknown, (void**)&unk2); 11931 EXPECT_HR(hr, S_OK); 11932 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2); 11933 IUnknown_Release(unk1); 11934 IUnknown_Release(unk2); 11935 11936 hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2); 11937 EXPECT_HR(hr, E_NOINTERFACE); 11938 11939 V_VT(&v) = VT_EMPTY; 11940 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 11941 EXPECT_HR(hr, S_OK); 11942 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); 11943 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 11944 VariantClear(&v); 11945 11946 V_VT(&v) = VT_EMPTY; 11947 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 11948 EXPECT_HR(hr, S_OK); 11949 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); 11950 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 11951 VariantClear(&v); 11952 11953 V_VT(&v) = VT_NULL; 11954 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 11955 EXPECT_HR(hr, S_FALSE); 11956 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); 11957 11958 IEnumVARIANT_Release(enumv); 11959 IXMLDOMSchemaCollection_Release(collection); 11960 11961 IXMLDOMDocument2_Release(doc); 11962 11963 /* now with CLSID_DOMDocument60 */ 11964 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) return; 11965 doc = create_document_version(60, &IID_IXMLDOMDocument2); 11966 11967 /* null pointer */ 11968 hr = IXMLDOMDocument2_get_namespaces(doc, NULL); 11969 EXPECT_HR(hr, E_POINTER); 11970 11971 /* no document loaded */ 11972 collection = (void*)0xdeadbeef; 11973 hr = IXMLDOMDocument2_get_namespaces(doc, &collection); 11974 EXPECT_HR(hr, S_OK); 11975 if (hr != S_OK) 11976 { 11977 IXMLDOMDocument2_Release(doc); 11978 return; 11979 } 11980 EXPECT_REF(collection, 2); 11981 11982 collection2 = (void*)0xdeadbeef; 11983 hr = IXMLDOMDocument2_get_namespaces(doc, &collection2); 11984 EXPECT_HR(hr, S_OK); 11985 ok(collection == collection2, "got %p\n", collection2); 11986 EXPECT_REF(collection, 3); 11987 IXMLDOMSchemaCollection_Release(collection); 11988 11989 len = -1; 11990 hr = IXMLDOMSchemaCollection_get_length(collection, &len); 11991 EXPECT_HR(hr, S_OK); 11992 ok(len == 0, "got %d\n", len); 11993 IXMLDOMSchemaCollection_Release(collection); 11994 11995 /* now with document */ 11996 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(namespacesA), &b); 11997 EXPECT_HR(hr, S_OK); 11998 11999 hr = IXMLDOMDocument2_get_namespaces(doc, &collection); 12000 EXPECT_HR(hr, S_OK); 12001 12002 len = -1; 12003 hr = IXMLDOMSchemaCollection_get_length(collection, &len); 12004 EXPECT_HR(hr, S_OK); 12005 ok(len == 2, "got %d\n", len); 12006 12007 /* try to lookup some uris */ 12008 node = (void*)0xdeadbeef; 12009 hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node); 12010 EXPECT_HR(hr, E_NOTIMPL); 12011 ok(broken(node == (void*)0xdeadbeef) || (node == NULL), "got %p\n", node); 12012 12013 /* load schema and try to add it */ 12014 doc2 = create_document(&IID_IXMLDOMDocument2); 12015 hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b); 12016 EXPECT_HR(hr, S_OK); 12017 12018 V_VT(&v) = VT_DISPATCH; 12019 V_DISPATCH(&v) = (IDispatch*)doc2; 12020 hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v); 12021 EXPECT_HR(hr, E_FAIL); 12022 IXMLDOMDocument2_Release(doc2); 12023 12024 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s); 12025 EXPECT_HR(hr, S_OK); 12026 ok(!lstrcmpW(s, _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(s)); 12027 SysFreeString(s); 12028 12029 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 1, &s); 12030 EXPECT_HR(hr, S_OK); 12031 ok(!lstrcmpW(s, _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(s)); 12032 SysFreeString(s); 12033 12034 s = (void*)0xdeadbeef; 12035 hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s); 12036 EXPECT_HR(hr, E_FAIL); 12037 ok(broken(s == (void*)0xdeadbeef) || (s == NULL), "got %p\n", s); 12038 12039 /* enumerate */ 12040 enumv = (void*)0xdeadbeef; 12041 hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); 12042 EXPECT_HR(hr, S_OK); 12043 ok(enumv != NULL, "got %p\n", enumv); 12044 12045 V_VT(&v) = VT_EMPTY; 12046 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 12047 EXPECT_HR(hr, S_OK); 12048 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); 12049 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 12050 VariantClear(&v); 12051 12052 V_VT(&v) = VT_EMPTY; 12053 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 12054 EXPECT_HR(hr, S_OK); 12055 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); 12056 ok(!lstrcmpW(V_BSTR(&v), _bstr_("http://blahblah.org")), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 12057 VariantClear(&v); 12058 12059 V_VT(&v) = VT_NULL; 12060 hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); 12061 EXPECT_HR(hr, S_FALSE); 12062 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); 12063 12064 IEnumVARIANT_Release(enumv); 12065 IXMLDOMSchemaCollection_Release(collection); 12066 IXMLDOMDocument2_Release(doc); 12067 free_bstrs(); 12068 } 12069 12070 static const DOMNodeType put_data_types[] = { 12071 NODE_TEXT, 12072 NODE_CDATA_SECTION, 12073 NODE_PROCESSING_INSTRUCTION, 12074 NODE_COMMENT, 12075 NODE_INVALID 12076 }; 12077 12078 static void test_put_data(void) 12079 { 12080 static const WCHAR test_data[] = {'t','e','s','t',' ','n','o','d','e',' ','d','a','t','a',0}; 12081 WCHAR buff[100], *data; 12082 IXMLDOMDocument *doc; 12083 const DOMNodeType *type; 12084 IXMLDOMText *text; 12085 IXMLDOMNode *node; 12086 VARIANT v; 12087 BSTR get_data; 12088 HRESULT hr; 12089 12090 doc = create_document(&IID_IXMLDOMDocument); 12091 12092 memcpy(&buff[2], test_data, sizeof(test_data)); 12093 /* just a big length */ 12094 *(DWORD*)buff = 0xf0f0; 12095 data = &buff[2]; 12096 12097 type = put_data_types; 12098 while (*type != NODE_INVALID) 12099 { 12100 V_VT(&v) = VT_I2; 12101 V_I2(&v) = *type; 12102 12103 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node); 12104 EXPECT_HR(hr, S_OK); 12105 12106 /* put_data() is interface-specific */ 12107 switch (*type) 12108 { 12109 case NODE_TEXT: 12110 { 12111 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text); 12112 EXPECT_HR(hr, S_OK); 12113 hr = IXMLDOMText_put_data(text, data); 12114 EXPECT_HR(hr, S_OK); 12115 12116 hr = IXMLDOMText_get_data(text, &get_data); 12117 EXPECT_HR(hr, S_OK); 12118 12119 IXMLDOMText_Release(text); 12120 break; 12121 } 12122 case NODE_CDATA_SECTION: 12123 { 12124 IXMLDOMCDATASection *cdata; 12125 12126 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata); 12127 EXPECT_HR(hr, S_OK); 12128 hr = IXMLDOMCDATASection_put_data(cdata, data); 12129 EXPECT_HR(hr, S_OK); 12130 12131 hr = IXMLDOMCDATASection_get_data(cdata, &get_data); 12132 EXPECT_HR(hr, S_OK); 12133 12134 IXMLDOMCDATASection_Release(cdata); 12135 break; 12136 } 12137 case NODE_PROCESSING_INSTRUCTION: 12138 { 12139 IXMLDOMProcessingInstruction *pi; 12140 12141 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)&pi); 12142 EXPECT_HR(hr, S_OK); 12143 hr = IXMLDOMProcessingInstruction_put_data(pi, data); 12144 EXPECT_HR(hr, S_OK); 12145 12146 hr = IXMLDOMProcessingInstruction_get_data(pi, &get_data); 12147 EXPECT_HR(hr, S_OK); 12148 12149 IXMLDOMProcessingInstruction_Release(pi); 12150 break; 12151 } 12152 case NODE_COMMENT: 12153 { 12154 IXMLDOMComment *comment; 12155 12156 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment); 12157 EXPECT_HR(hr, S_OK); 12158 hr = IXMLDOMComment_put_data(comment, data); 12159 EXPECT_HR(hr, S_OK); 12160 12161 hr = IXMLDOMComment_get_data(comment, &get_data); 12162 EXPECT_HR(hr, S_OK); 12163 12164 IXMLDOMComment_Release(comment); 12165 break; 12166 } 12167 default: 12168 get_data = NULL; 12169 break; 12170 } 12171 12172 /* compare */ 12173 ok(!lstrcmpW(data, get_data), "%d: got wrong data %s, expected %s\n", *type, wine_dbgstr_w(get_data), 12174 wine_dbgstr_w(data)); 12175 SysFreeString(get_data); 12176 12177 IXMLDOMNode_Release(node); 12178 type++; 12179 } 12180 12181 IXMLDOMDocument_Release(doc); 12182 free_bstrs(); 12183 } 12184 12185 static void test_newline_normalization(void) 12186 { 12187 const struct msxmlsupported_data_t *table = domdoc_support_data; 12188 IXMLDOMDocument *doc; 12189 IXMLDOMText *text; 12190 IXMLDOMNode *node; 12191 VARIANT v; 12192 VARIANT_BOOL b; 12193 BSTR s; 12194 HRESULT hr; 12195 LONG length; 12196 12197 V_VT(&v) = VT_I2; 12198 V_I2(&v) = NODE_TEXT; 12199 12200 while (table->clsid) 12201 { 12202 if (!is_clsid_supported(table->clsid, &IID_IXMLDOMDocument)) 12203 { 12204 table++; 12205 continue; 12206 } 12207 12208 hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc); 12209 ok(hr == S_OK, "got 0x%08x\n", hr); 12210 12211 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node); 12212 ok(hr == S_OK, "got 0x%08x\n", hr); 12213 12214 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text); 12215 12216 /* \r\n is normalized to \n and back to \r\n */ 12217 12218 hr = IXMLDOMText_put_data(text, _bstr_("\r\n")); 12219 ok(hr == S_OK, "got 0x%08x\n", hr); 12220 12221 hr = IXMLDOMText_get_data(text, &s); 12222 ok(hr == S_OK, "got 0x%08x\n", hr); 12223 ok(!lstrcmpW(s, _bstr_("\n")), "got %s\n", wine_dbgstr_w(s)); 12224 SysFreeString(s); 12225 12226 hr = IXMLDOMText_get_length(text, &length); 12227 ok(hr == S_OK, "got 0x%08x\n", hr); 12228 ok(length == 1, "got %d, expected 1\n", length); 12229 12230 hr = IXMLDOMText_get_xml(text, &s); 12231 ok(hr == S_OK, "got 0x%08x\n", hr); 12232 ok(!lstrcmpW(s, _bstr_("\r\n")), "got %s\n", wine_dbgstr_w(s)); 12233 SysFreeString(s); 12234 12235 /* \r\r\n is normalized to \n\n and back to \r\n\r\n */ 12236 12237 hr = IXMLDOMText_put_data(text, _bstr_("\r\r\n")); 12238 ok(hr == S_OK, "got 0x%08x\n", hr); 12239 12240 hr = IXMLDOMText_get_data(text, &s); 12241 ok(hr == S_OK, "got 0x%08x\n", hr); 12242 ok(!lstrcmpW(s, _bstr_("\n\n")), "got %s\n", wine_dbgstr_w(s)); 12243 SysFreeString(s); 12244 12245 hr = IXMLDOMText_get_length(text, &length); 12246 ok(hr == S_OK, "got 0x%08x\n", hr); 12247 ok(length == 2, "got %d, expected 2\n", length); 12248 12249 hr = IXMLDOMText_get_xml(text, &s); 12250 ok(hr == S_OK, "got 0x%08x\n", hr); 12251 ok(!lstrcmpW(s, _bstr_("\r\n\r\n")), "got %s\n", wine_dbgstr_w(s)); 12252 SysFreeString(s); 12253 12254 /* the same normalizations are applied when loading a document as a whole */ 12255 12256 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?><root>foo\n\r\n\r\r\nbar</root>"), &b); 12257 ok(hr == S_OK, "got 0x%08x\n", hr); 12258 12259 hr = IXMLDOMDocument_get_text(doc, &s); 12260 ok(hr == S_OK, "got 0x%08x\n", hr); 12261 ok(!lstrcmpW(s, _bstr_("foo\n\n\n\nbar")), "got %s\n", wine_dbgstr_w(s)); 12262 SysFreeString(s); 12263 12264 hr = IXMLDOMDocument_get_xml(doc, &s); 12265 ok(hr == S_OK, "got 0x%08x\n", hr); 12266 ok(!lstrcmpW(s, _bstr_("<?xml version=\"1.0\"?>\r\n<root>foo\r\n\r\n\r\n\r\nbar</root>\r\n")), 12267 "got %s\n", wine_dbgstr_w(s)); 12268 SysFreeString(s); 12269 12270 /* even if xml:space="preserve" */ 12271 12272 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?>" 12273 "<root xml:space=\"preserve\">foo\n\r\n\r\r\nbar</root>"), &b); 12274 ok(hr == S_OK, "got 0x%08x\n", hr); 12275 12276 hr = IXMLDOMDocument_get_text(doc, &s); 12277 ok(hr == S_OK, "got 0x%08x\n", hr); 12278 ok(!lstrcmpW(s, _bstr_("foo\n\n\n\nbar")), "got %s\n", wine_dbgstr_w(s)); 12279 SysFreeString(s); 12280 12281 hr = IXMLDOMDocument_get_xml(doc, &s); 12282 ok(hr == S_OK, "got 0x%08x\n", hr); 12283 ok(!lstrcmpW(s, _bstr_("<?xml version=\"1.0\"?>\r\n" 12284 "<root xml:space=\"preserve\">foo\r\n\r\n\r\n\r\nbar</root>\r\n")), 12285 "got %s\n", wine_dbgstr_w(s)); 12286 SysFreeString(s); 12287 12288 /* or preserveWhiteSpace is set */ 12289 12290 hr = IXMLDOMDocument_put_preserveWhiteSpace(doc, VARIANT_TRUE); 12291 ok(hr == S_OK, "got 0x%08x\n", hr); 12292 12293 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\"?><root>foo\n\r\n\r\r\nbar</root>"), &b); 12294 ok(hr == S_OK, "got 0x%08x\n", hr); 12295 12296 hr = IXMLDOMDocument_get_text(doc, &s); 12297 ok(hr == S_OK, "got 0x%08x\n", hr); 12298 ok(!lstrcmpW(s, _bstr_("foo\n\n\n\nbar")), "got %s\n", wine_dbgstr_w(s)); 12299 SysFreeString(s); 12300 12301 hr = IXMLDOMDocument_get_xml(doc, &s); 12302 ok(hr == S_OK, "got 0x%08x\n", hr); 12303 if (IsEqualGUID(table->clsid, &CLSID_DOMDocument60)) 12304 { 12305 /* DOMDocument60 does the newline normalization but does not insert line breaks around the root node */ 12306 todo_wine 12307 ok(!lstrcmpW(s, _bstr_("<?xml version=\"1.0\"?><root>foo\r\n\r\n\r\n\r\nbar</root>")), 12308 "got %s\n", wine_dbgstr_w(s)); 12309 } 12310 else 12311 { 12312 ok(!lstrcmpW(s, _bstr_("<?xml version=\"1.0\"?>\r\n<root>foo\r\n\r\n\r\n\r\nbar</root>\r\n")), 12313 "got %s\n", wine_dbgstr_w(s)); 12314 } 12315 SysFreeString(s); 12316 12317 IXMLDOMText_Release(text); 12318 IXMLDOMNode_Release(node); 12319 IXMLDOMDocument_Release(doc); 12320 free_bstrs(); 12321 table++; 12322 } 12323 } 12324 12325 static void test_putref_schemas(void) 12326 { 12327 IXMLDOMSchemaCollection *cache; 12328 IXMLDOMDocument2 *doc; 12329 VARIANT schema; 12330 HRESULT hr; 12331 12332 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return; 12333 if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return; 12334 12335 doc = create_document(&IID_IXMLDOMDocument2); 12336 cache = create_cache(&IID_IXMLDOMSchemaCollection); 12337 12338 /* set to NULL iface when no schema is set */ 12339 V_VT(&schema) = VT_DISPATCH; 12340 V_DISPATCH(&schema) = NULL; 12341 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12342 EXPECT_HR(hr, S_OK); 12343 12344 V_VT(&schema) = VT_UNKNOWN; 12345 V_UNKNOWN(&schema) = NULL; 12346 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12347 EXPECT_HR(hr, S_OK); 12348 12349 /* set as VT_DISPATCH, reset with it */ 12350 V_VT(&schema) = VT_DISPATCH; 12351 V_DISPATCH(&schema) = (IDispatch*)cache; 12352 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12353 EXPECT_HR(hr, S_OK); 12354 12355 V_DISPATCH(&schema) = NULL; 12356 hr = IXMLDOMDocument2_get_schemas(doc, &schema); 12357 EXPECT_HR(hr, S_OK); 12358 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema)); 12359 12360 V_VT(&schema) = VT_DISPATCH; 12361 V_DISPATCH(&schema) = NULL; 12362 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12363 EXPECT_HR(hr, S_OK); 12364 12365 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef; 12366 V_VT(&schema) = VT_I2; 12367 hr = IXMLDOMDocument2_get_schemas(doc, &schema); 12368 EXPECT_HR(hr, S_FALSE); 12369 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema)); 12370 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema)); 12371 12372 /* set as VT_UNKNOWN, reset with it */ 12373 V_VT(&schema) = VT_UNKNOWN; 12374 V_UNKNOWN(&schema) = (IUnknown*)cache; 12375 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12376 EXPECT_HR(hr, S_OK); 12377 12378 V_DISPATCH(&schema) = NULL; 12379 hr = IXMLDOMDocument2_get_schemas(doc, &schema); 12380 EXPECT_HR(hr, S_OK); 12381 ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema)); 12382 12383 V_VT(&schema) = VT_UNKNOWN; 12384 V_UNKNOWN(&schema) = NULL; 12385 hr = IXMLDOMDocument2_putref_schemas(doc, schema); 12386 EXPECT_HR(hr, S_OK); 12387 12388 V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef; 12389 V_VT(&schema) = VT_I2; 12390 hr = IXMLDOMDocument2_get_schemas(doc, &schema); 12391 EXPECT_HR(hr, S_FALSE); 12392 ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema)); 12393 ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema)); 12394 12395 IXMLDOMSchemaCollection_Release(cache); 12396 IXMLDOMDocument2_Release(doc); 12397 } 12398 12399 static void test_namedmap_newenum(void) 12400 { 12401 IEnumVARIANT *enum1, *enum2, *enum3; 12402 IXMLDOMNamedNodeMap *map; 12403 IUnknown *unk1, *unk2; 12404 IXMLDOMDocument *doc; 12405 IXMLDOMElement *elem; 12406 IXMLDOMNode *node; 12407 VARIANT_BOOL b; 12408 HRESULT hr; 12409 VARIANT v; 12410 BSTR str; 12411 12412 doc = create_document(&IID_IXMLDOMDocument); 12413 12414 hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b); 12415 EXPECT_HR(hr, S_OK); 12416 12417 hr = IXMLDOMDocument_get_documentElement(doc, &elem); 12418 EXPECT_HR(hr, S_OK); 12419 12420 hr = IXMLDOMElement_get_attributes(elem, &map); 12421 EXPECT_HR(hr, S_OK); 12422 IXMLDOMElement_Release(elem); 12423 12424 enum1 = NULL; 12425 EXPECT_REF(map, 1); 12426 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1); 12427 EXPECT_HR(hr, S_OK); 12428 ok(enum1 != NULL, "got %p\n", enum1); 12429 EXPECT_REF(map, 1); 12430 EXPECT_REF(enum1, 2); 12431 12432 enum2 = NULL; 12433 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2); 12434 EXPECT_HR(hr, S_OK); 12435 ok(enum2 == enum1, "got %p\n", enum2); 12436 12437 IEnumVARIANT_Release(enum2); 12438 12439 EXPECT_REF(map, 1); 12440 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2); 12441 EXPECT_HR(hr, S_OK); 12442 EXPECT_REF(map, 2); 12443 EXPECT_REF(enum2, 1); 12444 ok(enum2 != enum1, "got %p, %p\n", enum2, enum1); 12445 12446 IEnumVARIANT_Release(enum1); 12447 12448 /* enumerator created with _newEnum() doesn't share IUnknown* with main object */ 12449 hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1); 12450 EXPECT_HR(hr, S_OK); 12451 hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2); 12452 EXPECT_HR(hr, S_OK); 12453 EXPECT_REF(map, 3); 12454 EXPECT_REF(enum2, 2); 12455 ok(unk1 != unk2, "got %p, %p\n", unk1, unk2); 12456 IUnknown_Release(unk1); 12457 IUnknown_Release(unk2); 12458 12459 hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3); 12460 EXPECT_HR(hr, S_OK); 12461 ok(enum2 != enum3, "got %p, %p\n", enum2, enum3); 12462 IEnumVARIANT_Release(enum3); 12463 12464 /* iteration tests */ 12465 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node); 12466 EXPECT_HR(hr, S_OK); 12467 hr = IXMLDOMNode_get_nodeName(node, &str); 12468 EXPECT_HR(hr, S_OK); 12469 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str)); 12470 SysFreeString(str); 12471 IXMLDOMNode_Release(node); 12472 12473 hr = IXMLDOMNamedNodeMap_nextNode(map, &node); 12474 EXPECT_HR(hr, S_OK); 12475 hr = IXMLDOMNode_get_nodeName(node, &str); 12476 EXPECT_HR(hr, S_OK); 12477 ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str)); 12478 SysFreeString(str); 12479 IXMLDOMNode_Release(node); 12480 12481 V_VT(&v) = VT_EMPTY; 12482 hr = IEnumVARIANT_Next(enum2, 1, &v, NULL); 12483 EXPECT_HR(hr, S_OK); 12484 ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); 12485 hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); 12486 EXPECT_HR(hr, S_OK); 12487 hr = IXMLDOMNode_get_nodeName(node, &str); 12488 EXPECT_HR(hr, S_OK); 12489 ok(!lstrcmpW(str, _bstr_("attr1")), "got node name %s\n", wine_dbgstr_w(str)); 12490 SysFreeString(str); 12491 IXMLDOMNode_Release(node); 12492 VariantClear(&v); 12493 12494 hr = IXMLDOMNamedNodeMap_nextNode(map, &node); 12495 EXPECT_HR(hr, S_OK); 12496 hr = IXMLDOMNode_get_nodeName(node, &str); 12497 EXPECT_HR(hr, S_OK); 12498 ok(!lstrcmpW(str, _bstr_("attr2")), "got %s\n", wine_dbgstr_w(str)); 12499 SysFreeString(str); 12500 IXMLDOMNode_Release(node); 12501 12502 IEnumVARIANT_Release(enum2); 12503 IXMLDOMNamedNodeMap_Release(map); 12504 IXMLDOMDocument_Release(doc); 12505 } 12506 12507 static const char xsltext_xsl[] = 12508 "<?xml version=\"1.0\"?>" 12509 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >" 12510 "<xsl:output method=\"html\" encoding=\"us-ascii\"/>" 12511 "<xsl:template match=\"/\">" 12512 " <xsl:choose>" 12513 " <xsl:when test=\"testkey\">" 12514 " <xsl:text>testdata</xsl:text>" 12515 " </xsl:when>" 12516 " </xsl:choose>" 12517 "</xsl:template>" 12518 "</xsl:stylesheet>"; 12519 12520 static const char omitxmldecl_xsl[] = 12521 "<?xml version=\"1.0\"?>" 12522 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >" 12523 "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>" 12524 "<xsl:template match=\"/\">" 12525 " <xsl:for-each select=\"/a/item\">" 12526 " <xsl:element name=\"node\">" 12527 " <xsl:value-of select=\"@name\"/>" 12528 " </xsl:element>" 12529 " </xsl:for-each>" 12530 "</xsl:template>" 12531 "</xsl:stylesheet>"; 12532 12533 static const char omitxmldecl_doc[] = 12534 "<?xml version=\"1.0\"?>" 12535 "<a>" 12536 " <item name=\"item1\"/>" 12537 " <item name=\"item2\"/>" 12538 "</a>"; 12539 12540 static void test_xsltext(void) 12541 { 12542 IXMLDOMDocument *doc, *doc2; 12543 VARIANT_BOOL b; 12544 HRESULT hr; 12545 BSTR ret; 12546 12547 doc = create_document(&IID_IXMLDOMDocument); 12548 doc2 = create_document(&IID_IXMLDOMDocument); 12549 12550 hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b); 12551 EXPECT_HR(hr, S_OK); 12552 12553 hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b); 12554 EXPECT_HR(hr, S_OK); 12555 12556 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret); 12557 EXPECT_HR(hr, S_OK); 12558 ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret)); 12559 SysFreeString(ret); 12560 12561 /* omit-xml-declaration */ 12562 hr = IXMLDOMDocument_loadXML(doc, _bstr_(omitxmldecl_xsl), &b); 12563 ok(hr == S_OK, "got 0x%08x\n", hr); 12564 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(omitxmldecl_doc), &b); 12565 ok(hr == S_OK, "got 0x%08x\n", hr); 12566 12567 hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret); 12568 ok(hr == S_OK, "got 0x%08x\n", hr); 12569 ok(!lstrcmpW(ret, _bstr_("<node>item1</node><node>item2</node>")), "transform result %s\n", wine_dbgstr_w(ret)); 12570 SysFreeString(ret); 12571 12572 IXMLDOMDocument_Release(doc2); 12573 IXMLDOMDocument_Release(doc); 12574 free_bstrs(); 12575 } 12576 12577 struct attrtest_t { 12578 const char *name; 12579 const char *uri; 12580 const char *prefix; 12581 const char *href; 12582 }; 12583 12584 static struct attrtest_t attrtests[] = { 12585 { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" }, 12586 { "xmlns", "nondefaulturi", "xmlns", "xmlns" }, 12587 { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" }, 12588 { "c", "nsref1", NULL, "nsref1" }, 12589 { "ns:c", "nsref1", "ns", "nsref1" }, 12590 { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" }, 12591 { "xmlns:c", "nondefaulturi", "xmlns", "" }, 12592 { 0 } 12593 }; 12594 12595 static void test_create_attribute(void) 12596 { 12597 struct attrtest_t *ptr = attrtests; 12598 IXMLDOMElement *el; 12599 IXMLDOMDocument *doc; 12600 IXMLDOMNode *node, *node2; 12601 VARIANT var; 12602 HRESULT hr; 12603 int i = 0; 12604 BSTR str; 12605 12606 doc = create_document(&IID_IXMLDOMDocument); 12607 12608 while (ptr->name) 12609 { 12610 V_VT(&var) = VT_I1; 12611 V_I1(&var) = NODE_ATTRIBUTE; 12612 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node); 12613 ok(hr == S_OK, "got 0x%08x\n", hr); 12614 12615 str = NULL; 12616 hr = IXMLDOMNode_get_prefix(node, &str); 12617 if (ptr->prefix) 12618 { 12619 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr); 12620 ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix); 12621 } 12622 else 12623 { 12624 ok(hr == S_FALSE, "%d: got 0x%08x\n", i, hr); 12625 ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str)); 12626 } 12627 SysFreeString(str); 12628 12629 str = NULL; 12630 hr = IXMLDOMNode_get_namespaceURI(node, &str); 12631 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr); 12632 ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href); 12633 SysFreeString(str); 12634 12635 IXMLDOMNode_Release(node); 12636 free_bstrs(); 12637 12638 i++; 12639 ptr++; 12640 } 12641 12642 V_VT(&var) = VT_I1; 12643 V_I1(&var) = NODE_ELEMENT; 12644 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2); 12645 ok(hr == S_OK, "got 0x%08x\n", hr); 12646 12647 hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el); 12648 ok(hr == S_OK, "got 0x%08x\n", hr); 12649 IXMLDOMNode_Release(node2); 12650 12651 V_VT(&var) = VT_I1; 12652 V_I1(&var) = NODE_ATTRIBUTE; 12653 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node); 12654 ok(hr == S_OK, "got 0x%08x\n", hr); 12655 12656 hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL); 12657 ok(hr == S_OK, "got 0x%08x\n", hr); 12658 12659 /* for some reason default namespace uri is not reported */ 12660 hr = IXMLDOMNode_get_namespaceURI(node, &str); 12661 ok(hr == S_OK, "got 0x%08x\n", hr); 12662 ok(!lstrcmpW(str, _bstr_("")), "got uri %s\n", wine_dbgstr_w(str)); 12663 SysFreeString(str); 12664 12665 IXMLDOMNode_Release(node); 12666 IXMLDOMElement_Release(el); 12667 IXMLDOMDocument_Release(doc); 12668 free_bstrs(); 12669 } 12670 12671 static void test_url(void) 12672 { 12673 IXMLDOMDocument *doc; 12674 HRESULT hr; 12675 BSTR s; 12676 12677 doc = create_document(&IID_IXMLDOMDocument); 12678 12679 hr = IXMLDOMDocument_get_url(doc, NULL); 12680 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 12681 12682 s = (void *)0xdeadbeef; 12683 hr = IXMLDOMDocument_get_url(doc, &s); 12684 ok(hr == S_FALSE, "got 0x%08x\n", hr); 12685 ok(s == NULL, "got %s\n", wine_dbgstr_w(s)); 12686 12687 IXMLDOMDocument_Release(doc); 12688 } 12689 12690 static void test_merging_text(void) 12691 { 12692 IXMLDOMText *nodetext; 12693 IXMLDOMText *newtext; 12694 IXMLDOMElement *root; 12695 IXMLDOMDocument *doc; 12696 IXMLDOMNode *first; 12697 HRESULT hr; 12698 VARIANT v; 12699 BSTR str; 12700 int i; 12701 12702 doc = create_document(&IID_IXMLDOMDocument); 12703 12704 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root); 12705 EXPECT_HR(hr, S_OK); 12706 12707 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL); 12708 EXPECT_HR(hr, S_OK); 12709 12710 /* test xmlAddChild */ 12711 for (i = 0; i < 10; i++) 12712 { 12713 str = SysAllocString(szstr1); 12714 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext); 12715 SysFreeString(str); 12716 EXPECT_HR(hr, S_OK); 12717 12718 newtext = NULL; 12719 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)nodetext, (IXMLDOMNode**)&newtext); 12720 EXPECT_HR(hr, S_OK); 12721 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext); 12722 12723 IXMLDOMText_Release(newtext); 12724 IXMLDOMText_Release(nodetext); 12725 } 12726 12727 /* test xmlAddPrevSibling */ 12728 hr = IXMLDOMElement_get_firstChild(root, &first); 12729 EXPECT_HR(hr, S_OK); 12730 V_VT(&v) = VT_UNKNOWN; 12731 V_UNKNOWN(&v) = (IUnknown*)first; 12732 for (i = 0; i < 10; i++) 12733 { 12734 str = SysAllocString(szstr2); 12735 hr = IXMLDOMDocument_createTextNode(doc, str, &nodetext); 12736 SysFreeString(str); 12737 EXPECT_HR(hr, S_OK); 12738 12739 newtext = NULL; 12740 hr = IXMLDOMElement_insertBefore(root, (IXMLDOMNode*)nodetext, v, (IXMLDOMNode**)&newtext); 12741 EXPECT_HR(hr, S_OK); 12742 ok(nodetext == newtext, "expected %p, got %p\n", nodetext, newtext); 12743 12744 IXMLDOMText_Release(newtext); 12745 IXMLDOMText_Release(nodetext); 12746 } 12747 12748 IXMLDOMNode_Release(first); 12749 IXMLDOMElement_Release(root); 12750 IXMLDOMDocument_Release(doc); 12751 12752 free_bstrs(); 12753 } 12754 12755 static HRESULT WINAPI transformdest_QueryInterface(IUnknown *iface, REFIID riid, void **obj) 12756 { 12757 BOOL known_iid = IsEqualIID(riid, &IID_IHTMLObjectElement) || 12758 IsEqualIID(riid, &IID_transformdest_unknown) || 12759 IsEqualIID(riid, &IID_IServiceProvider) || 12760 IsEqualIID(riid, &IID_IStream) || 12761 IsEqualIID(riid, &IID_ISequentialStream) || 12762 IsEqualIID(riid, &IID_IRequestDictionary); 12763 12764 todo_wine_if(IsEqualIID(riid, &IID_IXMLDOMDocument)) 12765 ok(known_iid, "Unexpected riid %s\n", wine_dbgstr_guid(riid)); 12766 12767 return E_NOINTERFACE; 12768 } 12769 12770 static ULONG WINAPI transformdest_AddRef(IUnknown *iface) 12771 { 12772 return 2; 12773 } 12774 12775 static ULONG WINAPI transformdest_Release(IUnknown *iface) 12776 { 12777 return 1; 12778 } 12779 12780 static const IUnknownVtbl transformdestvtbl = 12781 { 12782 transformdest_QueryInterface, 12783 transformdest_AddRef, 12784 transformdest_Release, 12785 }; 12786 12787 static void test_transformNodeToObject(void) 12788 { 12789 IUnknown transformdest = { &transformdestvtbl }; 12790 IXMLDOMDocument *doc, *doc2, *doc3; 12791 VARIANT_BOOL b; 12792 HRESULT hr; 12793 VARIANT v; 12794 12795 doc = create_document(&IID_IXMLDOMDocument); 12796 doc2 = create_document(&IID_IXMLDOMDocument); 12797 doc3 = create_document(&IID_IXMLDOMDocument); 12798 12799 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &b); 12800 ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr); 12801 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szTransformSSXML), &b); 12802 ok(hr == S_OK, "Failed to load document, hr %#x.\n", hr); 12803 12804 V_VT(&v) = VT_UNKNOWN; 12805 V_UNKNOWN(&v) = &transformdest; 12806 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); 12807 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); 12808 12809 V_VT(&v) = VT_UNKNOWN; 12810 V_UNKNOWN(&v) = NULL; 12811 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); 12812 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); 12813 12814 V_VT(&v) = VT_DISPATCH; 12815 V_DISPATCH(&v) = NULL; 12816 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); 12817 ok(hr == E_INVALIDARG, "Failed to transform node, hr %#x.\n", hr); 12818 12819 V_VT(&v) = VT_DISPATCH; 12820 V_DISPATCH(&v) = (IDispatch *)doc3; 12821 hr = IXMLDOMDocument_transformNodeToObject(doc, (IXMLDOMNode *)doc2, v); 12822 ok(hr == S_OK, "Failed to transform node, hr %#x.\n", hr); 12823 12824 IXMLDOMDocument_Release(doc3); 12825 IXMLDOMDocument_Release(doc2); 12826 IXMLDOMDocument_Release(doc); 12827 free_bstrs(); 12828 } 12829 12830 static void test_normalize_attribute_values(void) 12831 { 12832 IXMLDOMDocument2 *doc; 12833 VARIANT var; 12834 HRESULT hr; 12835 12836 if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) 12837 { 12838 win_skip("NormalizeAttributeValues is not supported.\n"); 12839 return; 12840 } 12841 12842 doc = create_document_version(60, &IID_IXMLDOMDocument2); 12843 12844 V_VT(&var) = VT_I2; 12845 V_I2(&var) = 10; 12846 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("NormalizeAttributeValues"), &var); 12847 todo_wine { 12848 ok(hr == S_OK, "Failed to get property value, hr %#x.\n", hr); 12849 ok(V_VT(&var) == VT_BOOL, "Unexpected property value type, vt %d.\n", V_VT(&var)); 12850 ok(V_BOOL(&var) == VARIANT_FALSE, "Unexpected property value.\n"); 12851 } 12852 V_VT(&var) = VT_BOOL; 12853 V_BOOL(&var) = VARIANT_TRUE; 12854 hr = IXMLDOMDocument2_setProperty(doc, _bstr_("NormalizeAttributeValues"), var); 12855 ok(hr == S_OK, "Failed to set property, hr %#x.\n", hr); 12856 12857 V_VT(&var) = VT_I2; 12858 V_I2(&var) = 10; 12859 hr = IXMLDOMDocument2_getProperty(doc, _bstr_("NormalizeAttributeValues"), &var); 12860 todo_wine { 12861 ok(hr == S_OK, "Failed to get property value, hr %#x.\n", hr); 12862 ok(V_VT(&var) == VT_BOOL, "Unexpected property value type, vt %d.\n", V_VT(&var)); 12863 ok(V_BOOL(&var) == VARIANT_TRUE, "Unexpected property value.\n"); 12864 } 12865 IXMLDOMDocument2_Release(doc); 12866 } 12867 12868 typedef struct _namespace_as_attribute_t { 12869 const GUID *guid; 12870 const char *clsid; 12871 const char *xmlns_uri; 12872 } namespace_as_attribute_t; 12873 12874 static const namespace_as_attribute_t namespace_as_attribute_test_data[] = { 12875 { &CLSID_DOMDocument, "CLSID_DOMDocument", "" }, 12876 { &CLSID_DOMDocument2, "CLSID_DOMDocument2", "" }, 12877 { &CLSID_DOMDocument26, "CLSID_DOMDocument26", "" }, 12878 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "" }, 12879 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "" }, 12880 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "http://www.w3.org/2000/xmlns/" }, 12881 { 0 } 12882 }; 12883 12884 static void test_namespaces_as_attributes(void) 12885 { 12886 const namespace_as_attribute_t *entry = namespace_as_attribute_test_data; 12887 struct test { 12888 const char *xml; 12889 int explen; 12890 const char *names[3]; 12891 const char *prefixes[3]; 12892 const char *basenames[3]; 12893 const char *uris[3]; 12894 const char *texts[3]; 12895 }; 12896 static const struct test tests[] = { 12897 { 12898 "<a ns:b=\"b attr\" d=\"d attr\" xmlns:ns=\"nshref\" />", 3, 12899 { "ns:b", "d", "xmlns:ns" }, /* nodeName */ 12900 { "ns", NULL, "xmlns" }, /* prefix */ 12901 { "b", "d", "ns" }, /* baseName */ 12902 { "nshref", NULL, "" }, /* namespaceURI */ 12903 { "b attr", "d attr", "nshref" }, /* text */ 12904 }, 12905 /* property only */ 12906 { 12907 "<a d=\"d attr\" />", 1, 12908 { "d" }, /* nodeName */ 12909 { NULL }, /* prefix */ 12910 { "d" }, /* baseName */ 12911 { NULL }, /* namespaceURI */ 12912 { "d attr" }, /* text */ 12913 }, 12914 /* namespace only */ 12915 { 12916 "<a xmlns:ns=\"nshref\" />", 1, 12917 { "xmlns:ns" }, /* nodeName */ 12918 { "xmlns" }, /* prefix */ 12919 { "ns" }, /* baseName */ 12920 { "" }, /* namespaceURI */ 12921 { "nshref" }, /* text */ 12922 }, 12923 /* no properties or namespaces */ 12924 { 12925 "<a />", 0, 12926 }, 12927 12928 { NULL } 12929 }; 12930 const struct test *test; 12931 IXMLDOMNamedNodeMap *map; 12932 IXMLDOMNode *node, *item; 12933 IXMLDOMDocument *doc; 12934 VARIANT_BOOL b; 12935 LONG len, i; 12936 HRESULT hr; 12937 BSTR str; 12938 12939 while (entry->guid) 12940 { 12941 if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2)) 12942 { 12943 entry++; 12944 continue; 12945 } 12946 12947 test = tests; 12948 while (test->xml) { 12949 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void **)&doc); 12950 ok(SUCCEEDED(hr), "Failed to create document %s, hr %#x.\n", wine_dbgstr_guid(entry->guid), hr); 12951 12952 hr = IXMLDOMDocument_loadXML(doc, _bstr_(test->xml), &b); 12953 ok(hr == S_OK, "Failed to load xml, hr %#x.\n", hr); 12954 12955 node = NULL; 12956 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("a"), &node); 12957 ok(SUCCEEDED(hr), "Failed to select a node, hr %#x.\n", hr); 12958 12959 hr = IXMLDOMNode_get_attributes(node, &map); 12960 ok(SUCCEEDED(hr), "Failed to get attributes, hr %#x.\n", hr); 12961 12962 len = -1; 12963 hr = IXMLDOMNamedNodeMap_get_length(map, &len); 12964 ok(SUCCEEDED(hr), "Failed to get map length, hr %#x.\n", hr); 12965 ok(len == test->explen, "got %d\n", len); 12966 12967 item = NULL; 12968 hr = IXMLDOMNamedNodeMap_get_item(map, test->explen+1, &item); 12969 ok(hr == S_FALSE, "Failed to get item, hr %#x.\n", hr); 12970 ok(!item, "Item should be NULL\n"); 12971 12972 for (i = 0; i < len; i++) 12973 { 12974 item = NULL; 12975 hr = IXMLDOMNamedNodeMap_get_item(map, i, &item); 12976 ok(SUCCEEDED(hr), "Failed to get item, hr %#x.\n", hr); 12977 12978 str = NULL; 12979 hr = IXMLDOMNode_get_nodeName(item, &str); 12980 ok(SUCCEEDED(hr), "Failed to get node name, hr %#x.\n", hr); 12981 ok(!lstrcmpW(str, _bstr_(test->names[i])), "got %s\n", wine_dbgstr_w(str)); 12982 SysFreeString(str); 12983 12984 str = NULL; 12985 hr = IXMLDOMNode_get_prefix(item, &str); 12986 if (test->prefixes[i]) 12987 { 12988 ok(hr == S_OK, "Failed to get node name, hr %#x.\n", hr); 12989 ok(!lstrcmpW(str, _bstr_(test->prefixes[i])), "got %s\n", wine_dbgstr_w(str)); 12990 SysFreeString(str); 12991 } 12992 else 12993 ok(hr == S_FALSE, "Failed to get node name, hr %#x.\n", hr); 12994 12995 str = NULL; 12996 hr = IXMLDOMNode_get_baseName(item, &str); 12997 ok(SUCCEEDED(hr), "Failed to get base name, hr %#x.\n", hr); 12998 ok(!lstrcmpW(str, _bstr_(test->basenames[i])), "got %s\n", wine_dbgstr_w(str)); 12999 SysFreeString(str); 13000 13001 str = NULL; 13002 hr = IXMLDOMNode_get_namespaceURI(item, &str); 13003 if (test->uris[i]) 13004 { 13005 ok(hr == S_OK, "Failed to get node name, hr %#x.\n", hr); 13006 if (test->prefixes[i] && !strcmp(test->prefixes[i], "xmlns")) 13007 ok(!lstrcmpW(str, _bstr_(entry->xmlns_uri)), "got %s\n", wine_dbgstr_w(str)); 13008 else 13009 ok(!lstrcmpW(str, _bstr_(test->uris[i])), "got %s\n", wine_dbgstr_w(str)); 13010 SysFreeString(str); 13011 } 13012 else 13013 ok(hr == S_FALSE, "Failed to get node name, hr %#x.\n", hr); 13014 13015 str = NULL; 13016 hr = IXMLDOMNode_get_text(item, &str); 13017 ok(SUCCEEDED(hr), "Failed to get node text, hr %#x.\n", hr); 13018 ok(!lstrcmpW(str, _bstr_(test->texts[i])), "got %s\n", wine_dbgstr_w(str)); 13019 SysFreeString(str); 13020 13021 IXMLDOMNode_Release(item); 13022 } 13023 13024 IXMLDOMNamedNodeMap_Release(map); 13025 IXMLDOMNode_Release(node); 13026 IXMLDOMDocument_Release(doc); 13027 13028 test++; 13029 } 13030 13031 entry++; 13032 } 13033 free_bstrs(); 13034 } 13035 13036 START_TEST(domdoc) 13037 { 13038 HRESULT hr; 13039 13040 hr = CoInitialize( NULL ); 13041 ok( hr == S_OK, "failed to init com\n"); 13042 if (hr != S_OK) return; 13043 13044 get_class_support_data(domdoc_support_data); 13045 if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument)) 13046 { 13047 win_skip("DOMDocument2 is not supported. Skipping all tests.\n"); 13048 CoUninitialize(); 13049 return; 13050 } 13051 13052 test_domdoc(); 13053 test_persiststream(); 13054 test_domnode(); 13055 test_refs(); 13056 test_create(); 13057 test_getElementsByTagName(); 13058 test_get_text(); 13059 test_get_childNodes(); 13060 test_get_firstChild(); 13061 test_get_lastChild(); 13062 test_removeChild(); 13063 test_replaceChild(); 13064 test_removeNamedItem(); 13065 test_IXMLDOMDocument2(); 13066 test_whitespace(); 13067 test_XPath(); 13068 test_XSLPattern(); 13069 test_cloneNode(); 13070 test_xmlTypes(); 13071 test_save(); 13072 test_testTransforms(); 13073 test_namespaces_basic(); 13074 test_namespaces_change(); 13075 test_FormattingXML(); 13076 test_nodeTypedValue(); 13077 test_TransformWithLoadingLocalFile(); 13078 test_put_nodeValue(); 13079 test_IObjectSafety(); 13080 test_splitText(); 13081 test_getQualifiedItem(); 13082 test_removeQualifiedItem(); 13083 test_get_ownerDocument(); 13084 test_setAttributeNode(); 13085 test_put_dataType(); 13086 test_createNode(); 13087 test_create_attribute(); 13088 test_get_prefix(); 13089 test_default_properties(); 13090 test_selectSingleNode(); 13091 test_events(); 13092 test_createProcessingInstruction(); 13093 test_put_nodeTypedValue(); 13094 test_get_xml(); 13095 test_insertBefore(); 13096 test_appendChild(); 13097 test_get_doctype(); 13098 test_get_tagName(); 13099 test_get_dataType(); 13100 test_get_nodeTypeString(); 13101 test_get_attributes(); 13102 test_selection(); 13103 test_load(); 13104 test_dispex(); 13105 test_parseerror(); 13106 test_getAttributeNode(); 13107 test_getAttribute(); 13108 test_supporterrorinfo(); 13109 test_nodeValue(); 13110 test_get_namespaces(); 13111 test_put_data(); 13112 test_newline_normalization(); 13113 test_putref_schemas(); 13114 test_namedmap_newenum(); 13115 test_xmlns_attribute(); 13116 test_url(); 13117 test_merging_text(); 13118 test_transformNodeToObject(); 13119 test_normalize_attribute_values(); 13120 test_namespaces_as_attributes(); 13121 13122 test_xsltemplate(); 13123 test_xsltext(); 13124 13125 if (is_clsid_supported(&CLSID_MXNamespaceManager40, &IID_IMXNamespaceManager)) 13126 { 13127 test_mxnamespacemanager(); 13128 test_mxnamespacemanager_override(); 13129 } 13130 13131 CoUninitialize(); 13132 } 13133