1 /* 2 * IMXNamespaceManager implementation 3 * 4 * Copyright 2011-2012 Nikolay Sivov for CodeWeavers 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 # include <libxml/encoding.h> 30 #endif 31 32 #include "windef.h" 33 #include "winbase.h" 34 #include "winuser.h" 35 #include "ole2.h" 36 #include "msxml6.h" 37 38 #include "msxml_private.h" 39 40 #include "wine/debug.h" 41 42 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 43 44 struct ns 45 { 46 BSTR prefix; 47 BSTR uri; 48 }; 49 50 struct nscontext 51 { 52 struct list entry; 53 54 struct ns *ns; 55 int count; 56 int max_alloc; 57 }; 58 59 #define DEFAULT_PREFIX_ALLOC_COUNT 16 60 61 static const WCHAR xmlW[] = {'x','m','l',0}; 62 static const WCHAR xmluriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g', 63 '/','X','M','L','/','1','9','9','8','/','n','a','m','e','s','p','a','c','e',0}; 64 65 typedef struct 66 { 67 DispatchEx dispex; 68 IMXNamespaceManager IMXNamespaceManager_iface; 69 IVBMXNamespaceManager IVBMXNamespaceManager_iface; 70 LONG ref; 71 72 struct list ctxts; 73 74 VARIANT_BOOL override; 75 } namespacemanager; 76 77 static inline namespacemanager *impl_from_IMXNamespaceManager( IMXNamespaceManager *iface ) 78 { 79 return CONTAINING_RECORD(iface, namespacemanager, IMXNamespaceManager_iface); 80 } 81 82 static inline namespacemanager *impl_from_IVBMXNamespaceManager( IVBMXNamespaceManager *iface ) 83 { 84 return CONTAINING_RECORD(iface, namespacemanager, IVBMXNamespaceManager_iface); 85 } 86 87 static HRESULT declare_prefix(namespacemanager *This, const WCHAR *prefix, const WCHAR *uri) 88 { 89 struct nscontext *ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry); 90 static const WCHAR emptyW[] = {0}; 91 struct ns *ns; 92 int i; 93 94 if (ctxt->count == ctxt->max_alloc) 95 { 96 ctxt->max_alloc *= 2; 97 ctxt->ns = heap_realloc(ctxt->ns, ctxt->max_alloc*sizeof(*ctxt->ns)); 98 } 99 100 if (!prefix) prefix = emptyW; 101 102 ns = NULL; 103 for (i = 0; i < ctxt->count; i++) 104 if (!strcmpW(ctxt->ns[i].prefix, prefix)) 105 { 106 ns = &ctxt->ns[i]; 107 break; 108 } 109 110 if (ns) 111 { 112 if (This->override == VARIANT_TRUE) 113 { 114 SysFreeString(ns->uri); 115 ns->uri = SysAllocString(uri); 116 return S_FALSE; 117 } 118 else 119 return E_FAIL; 120 } 121 else 122 { 123 ctxt->ns[ctxt->count].prefix = SysAllocString(prefix); 124 ctxt->ns[ctxt->count].uri = SysAllocString(uri); 125 ctxt->count++; 126 } 127 128 return S_OK; 129 } 130 131 /* returned stored pointer, caller needs to copy it */ 132 static HRESULT get_declared_prefix_idx(const struct nscontext *ctxt, LONG index, BSTR *prefix) 133 { 134 *prefix = NULL; 135 136 if (index >= ctxt->count || index < 0) return E_FAIL; 137 138 if (index > 0) index = ctxt->count - index; 139 *prefix = ctxt->ns[index].prefix; 140 141 return S_OK; 142 } 143 144 /* returned stored pointer, caller needs to copy it */ 145 static HRESULT get_declared_prefix_uri(const struct list *ctxts, const WCHAR *uri, BSTR *prefix) 146 { 147 struct nscontext *ctxt; 148 149 LIST_FOR_EACH_ENTRY(ctxt, ctxts, struct nscontext, entry) 150 { 151 int i; 152 for (i = 0; i < ctxt->count; i++) 153 if (!strcmpW(ctxt->ns[i].uri, uri)) 154 { 155 *prefix = ctxt->ns[i].prefix; 156 return S_OK; 157 } 158 } 159 160 *prefix = NULL; 161 return E_FAIL; 162 } 163 164 static HRESULT get_uri_from_prefix(const struct nscontext *ctxt, const WCHAR *prefix, BSTR *uri) 165 { 166 int i; 167 168 for (i = 0; i < ctxt->count; i++) 169 if (!strcmpW(ctxt->ns[i].prefix, prefix)) 170 { 171 *uri = ctxt->ns[i].uri; 172 return S_OK; 173 } 174 175 *uri = NULL; 176 return S_FALSE; 177 } 178 179 static struct nscontext* alloc_ns_context(void) 180 { 181 struct nscontext *ctxt; 182 183 ctxt = heap_alloc(sizeof(*ctxt)); 184 if (!ctxt) return NULL; 185 186 ctxt->count = 0; 187 ctxt->max_alloc = DEFAULT_PREFIX_ALLOC_COUNT; 188 ctxt->ns = heap_alloc(ctxt->max_alloc*sizeof(*ctxt->ns)); 189 if (!ctxt->ns) 190 { 191 heap_free(ctxt); 192 return NULL; 193 } 194 195 /* first allocated prefix is always 'xml' */ 196 ctxt->ns[0].prefix = SysAllocString(xmlW); 197 ctxt->ns[0].uri = SysAllocString(xmluriW); 198 ctxt->count++; 199 if (!ctxt->ns[0].prefix || !ctxt->ns[0].uri) 200 { 201 heap_free(ctxt->ns); 202 heap_free(ctxt); 203 return NULL; 204 } 205 206 return ctxt; 207 } 208 209 static void free_ns_context(struct nscontext *ctxt) 210 { 211 int i; 212 213 for (i = 0; i < ctxt->count; i++) 214 { 215 SysFreeString(ctxt->ns[i].prefix); 216 SysFreeString(ctxt->ns[i].uri); 217 } 218 219 heap_free(ctxt->ns); 220 heap_free(ctxt); 221 } 222 223 static HRESULT WINAPI namespacemanager_QueryInterface(IMXNamespaceManager *iface, REFIID riid, void **ppvObject) 224 { 225 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 226 return IVBMXNamespaceManager_QueryInterface(&This->IVBMXNamespaceManager_iface, riid, ppvObject); 227 } 228 229 static ULONG WINAPI namespacemanager_AddRef(IMXNamespaceManager *iface) 230 { 231 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 232 return IVBMXNamespaceManager_AddRef(&This->IVBMXNamespaceManager_iface); 233 } 234 235 static ULONG WINAPI namespacemanager_Release(IMXNamespaceManager *iface) 236 { 237 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 238 return IVBMXNamespaceManager_Release(&This->IVBMXNamespaceManager_iface); 239 } 240 241 static HRESULT WINAPI namespacemanager_putAllowOverride(IMXNamespaceManager *iface, 242 VARIANT_BOOL override) 243 { 244 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 245 return IVBMXNamespaceManager_put_allowOverride(&This->IVBMXNamespaceManager_iface, override); 246 } 247 248 static HRESULT WINAPI namespacemanager_getAllowOverride(IMXNamespaceManager *iface, 249 VARIANT_BOOL *override) 250 { 251 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 252 return IVBMXNamespaceManager_get_allowOverride(&This->IVBMXNamespaceManager_iface, override); 253 } 254 255 static HRESULT WINAPI namespacemanager_reset(IMXNamespaceManager *iface) 256 { 257 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 258 return IVBMXNamespaceManager_reset(&This->IVBMXNamespaceManager_iface); 259 } 260 261 static HRESULT WINAPI namespacemanager_pushContext(IMXNamespaceManager *iface) 262 { 263 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 264 return IVBMXNamespaceManager_pushContext(&This->IVBMXNamespaceManager_iface); 265 } 266 267 static HRESULT WINAPI namespacemanager_pushNodeContext(IMXNamespaceManager *iface, 268 IXMLDOMNode *node, VARIANT_BOOL deep) 269 { 270 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 271 return IVBMXNamespaceManager_pushNodeContext(&This->IVBMXNamespaceManager_iface, node, deep); 272 } 273 274 static HRESULT WINAPI namespacemanager_popContext(IMXNamespaceManager *iface) 275 { 276 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 277 return IVBMXNamespaceManager_popContext(&This->IVBMXNamespaceManager_iface); 278 } 279 280 static HRESULT WINAPI namespacemanager_declarePrefix(IMXNamespaceManager *iface, 281 const WCHAR *prefix, const WCHAR *namespaceURI) 282 { 283 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0}; 284 285 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 286 287 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prefix), debugstr_w(namespaceURI)); 288 289 if (prefix && (!strcmpW(prefix, xmlW) || !strcmpW(prefix, xmlnsW) || !namespaceURI)) 290 return E_INVALIDARG; 291 292 return declare_prefix(This, prefix, namespaceURI); 293 } 294 295 static HRESULT WINAPI namespacemanager_getDeclaredPrefix(IMXNamespaceManager *iface, 296 LONG index, WCHAR *prefix, int *prefix_len) 297 { 298 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 299 struct nscontext *ctxt; 300 HRESULT hr; 301 BSTR prfx; 302 303 TRACE("(%p)->(%d %p %p)\n", This, index, prefix, prefix_len); 304 305 if (!prefix_len) return E_POINTER; 306 307 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry); 308 hr = get_declared_prefix_idx(ctxt, index, &prfx); 309 if (hr != S_OK) return hr; 310 311 if (prefix) 312 { 313 if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL; 314 strcpyW(prefix, prfx); 315 } 316 317 *prefix_len = SysStringLen(prfx); 318 319 return S_OK; 320 } 321 322 static HRESULT WINAPI namespacemanager_getPrefix(IMXNamespaceManager *iface, 323 const WCHAR *uri, LONG index, WCHAR *prefix, int *prefix_len) 324 { 325 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 326 HRESULT hr; 327 BSTR prfx; 328 329 TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(uri), index, prefix, prefix_len); 330 331 if (!uri || !*uri || !prefix_len) return E_INVALIDARG; 332 333 hr = get_declared_prefix_uri(&This->ctxts, uri, &prfx); 334 if (hr == S_OK) 335 { 336 /* TODO: figure out what index argument is for */ 337 if (index) return E_FAIL; 338 339 if (prefix) 340 { 341 if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL; 342 strcpyW(prefix, prfx); 343 } 344 345 *prefix_len = SysStringLen(prfx); 346 TRACE("prefix=%s\n", debugstr_w(prfx)); 347 } 348 349 return hr; 350 } 351 352 static HRESULT WINAPI namespacemanager_getURI(IMXNamespaceManager *iface, 353 const WCHAR *prefix, IXMLDOMNode *node, WCHAR *uri, int *uri_len) 354 { 355 namespacemanager *This = impl_from_IMXNamespaceManager( iface ); 356 struct nscontext *ctxt; 357 HRESULT hr; 358 BSTR urib; 359 360 TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_w(prefix), node, uri, uri_len); 361 362 if (!prefix) return E_INVALIDARG; 363 if (!uri_len) return E_POINTER; 364 365 if (node) 366 { 367 FIXME("namespaces from DOM node not supported\n"); 368 return E_NOTIMPL; 369 } 370 371 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry); 372 hr = get_uri_from_prefix(ctxt, prefix, &urib); 373 if (hr == S_OK) 374 { 375 if (uri) 376 { 377 if (*uri_len < (INT)SysStringLen(urib)) return E_XML_BUFFERTOOSMALL; 378 strcpyW(uri, urib); 379 } 380 } 381 else 382 if (uri) *uri = 0; 383 384 *uri_len = SysStringLen(urib); 385 386 return hr; 387 } 388 389 static const struct IMXNamespaceManagerVtbl MXNamespaceManagerVtbl = 390 { 391 namespacemanager_QueryInterface, 392 namespacemanager_AddRef, 393 namespacemanager_Release, 394 namespacemanager_putAllowOverride, 395 namespacemanager_getAllowOverride, 396 namespacemanager_reset, 397 namespacemanager_pushContext, 398 namespacemanager_pushNodeContext, 399 namespacemanager_popContext, 400 namespacemanager_declarePrefix, 401 namespacemanager_getDeclaredPrefix, 402 namespacemanager_getPrefix, 403 namespacemanager_getURI 404 }; 405 406 static HRESULT WINAPI vbnamespacemanager_QueryInterface(IVBMXNamespaceManager *iface, REFIID riid, void **obj) 407 { 408 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 409 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); 410 411 if ( IsEqualGUID( riid, &IID_IMXNamespaceManager) || 412 IsEqualGUID( riid, &IID_IUnknown) ) 413 { 414 *obj = &This->IMXNamespaceManager_iface; 415 } 416 else if ( IsEqualGUID( riid, &IID_IVBMXNamespaceManager) || 417 IsEqualGUID( riid, &IID_IDispatch) ) 418 { 419 *obj = &This->IVBMXNamespaceManager_iface; 420 } 421 else if (dispex_query_interface(&This->dispex, riid, obj)) 422 { 423 return *obj ? S_OK : E_NOINTERFACE; 424 } 425 else 426 { 427 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 428 *obj = NULL; 429 return E_NOINTERFACE; 430 } 431 432 IVBMXNamespaceManager_AddRef( iface ); 433 434 return S_OK; 435 } 436 437 static ULONG WINAPI vbnamespacemanager_AddRef(IVBMXNamespaceManager *iface) 438 { 439 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 440 ULONG ref = InterlockedIncrement( &This->ref ); 441 TRACE("(%p)->(%u)\n", This, ref ); 442 return ref; 443 } 444 445 static ULONG WINAPI vbnamespacemanager_Release(IVBMXNamespaceManager *iface) 446 { 447 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 448 ULONG ref = InterlockedDecrement( &This->ref ); 449 450 TRACE("(%p)->(%u)\n", This, ref ); 451 452 if ( ref == 0 ) 453 { 454 struct nscontext *ctxt, *ctxt2; 455 456 LIST_FOR_EACH_ENTRY_SAFE(ctxt, ctxt2, &This->ctxts, struct nscontext, entry) 457 { 458 list_remove(&ctxt->entry); 459 free_ns_context(ctxt); 460 } 461 462 heap_free( This ); 463 } 464 465 return ref; 466 } 467 468 static HRESULT WINAPI vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager *iface, UINT *pctinfo) 469 { 470 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 471 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); 472 } 473 474 static HRESULT WINAPI vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager *iface, UINT iTInfo, 475 LCID lcid, ITypeInfo **ppTInfo) 476 { 477 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 478 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, 479 iTInfo, lcid, ppTInfo); 480 } 481 482 static HRESULT WINAPI vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager *iface, REFIID riid, 483 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 484 { 485 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 486 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, 487 riid, rgszNames, cNames, lcid, rgDispId); 488 } 489 490 static HRESULT WINAPI vbnamespacemanager_Invoke(IVBMXNamespaceManager *iface, DISPID dispIdMember, REFIID riid, 491 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, 492 EXCEPINFO *pExcepInfo, UINT *puArgErr) 493 { 494 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 495 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, 496 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 497 } 498 499 static HRESULT WINAPI vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager *iface, 500 VARIANT_BOOL override) 501 { 502 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 503 504 TRACE("(%p)->(%d)\n", This, override); 505 This->override = override; 506 507 return S_OK; 508 } 509 510 static HRESULT WINAPI vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager *iface, 511 VARIANT_BOOL *override) 512 { 513 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 514 515 TRACE("(%p)->(%p)\n", This, override); 516 517 if (!override) return E_POINTER; 518 *override = This->override; 519 520 return S_OK; 521 } 522 523 static HRESULT WINAPI vbnamespacemanager_reset(IVBMXNamespaceManager *iface) 524 { 525 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 526 FIXME("(%p): stub\n", This); 527 return E_NOTIMPL; 528 } 529 530 static HRESULT WINAPI vbnamespacemanager_pushContext(IVBMXNamespaceManager *iface) 531 { 532 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 533 struct nscontext *ctxt; 534 535 TRACE("(%p)\n", This); 536 537 ctxt = alloc_ns_context(); 538 if (!ctxt) return E_OUTOFMEMORY; 539 540 list_add_head(&This->ctxts, &ctxt->entry); 541 542 return S_OK; 543 } 544 545 static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager *iface, 546 IXMLDOMNode *node, VARIANT_BOOL deep) 547 { 548 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 549 FIXME("(%p)->(%p %d): stub\n", This, node, deep); 550 return E_NOTIMPL; 551 } 552 553 static HRESULT WINAPI vbnamespacemanager_popContext(IVBMXNamespaceManager *iface) 554 { 555 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 556 const struct list *next; 557 struct nscontext *ctxt; 558 559 TRACE("(%p)\n", This); 560 561 next = list_next(&This->ctxts, list_head(&This->ctxts)); 562 if (!next) return E_FAIL; 563 564 ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry); 565 list_remove(list_head(&This->ctxts)); 566 567 free_ns_context(ctxt); 568 569 return S_OK; 570 } 571 572 static HRESULT WINAPI vbnamespacemanager_declarePrefix(IVBMXNamespaceManager *iface, 573 BSTR prefix, BSTR namespaceURI) 574 { 575 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 576 return IMXNamespaceManager_declarePrefix(&This->IMXNamespaceManager_iface, prefix, namespaceURI); 577 } 578 579 static HRESULT WINAPI vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager *iface, 580 IMXNamespacePrefixes** prefixes) 581 { 582 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 583 FIXME("(%p)->(%p): stub\n", This, prefixes); 584 return E_NOTIMPL; 585 } 586 587 static HRESULT WINAPI vbnamespacemanager_getPrefixes(IVBMXNamespaceManager *iface, 588 BSTR namespaceURI, IMXNamespacePrefixes** prefixes) 589 { 590 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 591 FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(namespaceURI), prefixes); 592 return E_NOTIMPL; 593 } 594 595 static HRESULT WINAPI vbnamespacemanager_getURI(IVBMXNamespaceManager *iface, 596 BSTR prefix, VARIANT* uri) 597 { 598 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 599 FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(prefix), uri); 600 return E_NOTIMPL; 601 } 602 603 static HRESULT WINAPI vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager *iface, 604 BSTR prefix, IXMLDOMNode *node, VARIANT *uri) 605 { 606 namespacemanager *This = impl_from_IVBMXNamespaceManager( iface ); 607 FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(prefix), node, uri); 608 return E_NOTIMPL; 609 } 610 611 static const struct IVBMXNamespaceManagerVtbl VBMXNamespaceManagerVtbl = 612 { 613 vbnamespacemanager_QueryInterface, 614 vbnamespacemanager_AddRef, 615 vbnamespacemanager_Release, 616 vbnamespacemanager_GetTypeInfoCount, 617 vbnamespacemanager_GetTypeInfo, 618 vbnamespacemanager_GetIDsOfNames, 619 vbnamespacemanager_Invoke, 620 vbnamespacemanager_put_allowOverride, 621 vbnamespacemanager_get_allowOverride, 622 vbnamespacemanager_reset, 623 vbnamespacemanager_pushContext, 624 vbnamespacemanager_pushNodeContext, 625 vbnamespacemanager_popContext, 626 vbnamespacemanager_declarePrefix, 627 vbnamespacemanager_getDeclaredPrefixes, 628 vbnamespacemanager_getPrefixes, 629 vbnamespacemanager_getURI, 630 vbnamespacemanager_getURIFromNode 631 }; 632 633 static const tid_t namespacemanager_iface_tids[] = { 634 IVBMXNamespaceManager_tid, 635 0 636 }; 637 638 static dispex_static_data_t namespacemanager_dispex = { 639 NULL, 640 IVBMXNamespaceManager_tid, 641 NULL, 642 namespacemanager_iface_tids 643 }; 644 645 HRESULT MXNamespaceManager_create(void **obj) 646 { 647 namespacemanager *This; 648 struct nscontext *ctxt; 649 650 TRACE("(%p)\n", obj); 651 652 This = heap_alloc( sizeof (*This) ); 653 if( !This ) 654 return E_OUTOFMEMORY; 655 656 This->IMXNamespaceManager_iface.lpVtbl = &MXNamespaceManagerVtbl; 657 This->IVBMXNamespaceManager_iface.lpVtbl = &VBMXNamespaceManagerVtbl; 658 This->ref = 1; 659 init_dispex(&This->dispex, (IUnknown*)&This->IVBMXNamespaceManager_iface, &namespacemanager_dispex); 660 661 list_init(&This->ctxts); 662 ctxt = alloc_ns_context(); 663 if (!ctxt) 664 { 665 heap_free(This); 666 return E_OUTOFMEMORY; 667 } 668 669 list_add_head(&This->ctxts, &ctxt->entry); 670 671 This->override = VARIANT_TRUE; 672 673 *obj = &This->IMXNamespaceManager_iface; 674 675 TRACE("returning iface %p\n", *obj); 676 677 return S_OK; 678 } 679