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