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
impl_from_IMXNamespaceManager(IMXNamespaceManager * iface)77 static inline namespacemanager *impl_from_IMXNamespaceManager( IMXNamespaceManager *iface )
78 {
79 return CONTAINING_RECORD(iface, namespacemanager, IMXNamespaceManager_iface);
80 }
81
impl_from_IVBMXNamespaceManager(IVBMXNamespaceManager * iface)82 static inline namespacemanager *impl_from_IVBMXNamespaceManager( IVBMXNamespaceManager *iface )
83 {
84 return CONTAINING_RECORD(iface, namespacemanager, IVBMXNamespaceManager_iface);
85 }
86
declare_prefix(namespacemanager * This,const WCHAR * prefix,const WCHAR * uri)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 */
get_declared_prefix_idx(const struct nscontext * ctxt,LONG index,BSTR * prefix)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 */
get_declared_prefix_uri(const struct list * ctxts,const WCHAR * uri,BSTR * prefix)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
get_uri_from_prefix(const struct nscontext * ctxt,const WCHAR * prefix,BSTR * uri)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
alloc_ns_context(void)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
free_ns_context(struct nscontext * ctxt)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
namespacemanager_QueryInterface(IMXNamespaceManager * iface,REFIID riid,void ** ppvObject)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
namespacemanager_AddRef(IMXNamespaceManager * iface)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
namespacemanager_Release(IMXNamespaceManager * iface)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
namespacemanager_putAllowOverride(IMXNamespaceManager * iface,VARIANT_BOOL override)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
namespacemanager_getAllowOverride(IMXNamespaceManager * iface,VARIANT_BOOL * override)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
namespacemanager_reset(IMXNamespaceManager * iface)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
namespacemanager_pushContext(IMXNamespaceManager * iface)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
namespacemanager_pushNodeContext(IMXNamespaceManager * iface,IXMLDOMNode * node,VARIANT_BOOL deep)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
namespacemanager_popContext(IMXNamespaceManager * iface)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
namespacemanager_declarePrefix(IMXNamespaceManager * iface,const WCHAR * prefix,const WCHAR * namespaceURI)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
namespacemanager_getDeclaredPrefix(IMXNamespaceManager * iface,LONG index,WCHAR * prefix,int * prefix_len)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
namespacemanager_getPrefix(IMXNamespaceManager * iface,const WCHAR * uri,LONG index,WCHAR * prefix,int * prefix_len)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
namespacemanager_getURI(IMXNamespaceManager * iface,const WCHAR * prefix,IXMLDOMNode * node,WCHAR * uri,int * uri_len)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
vbnamespacemanager_QueryInterface(IVBMXNamespaceManager * iface,REFIID riid,void ** obj)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
vbnamespacemanager_AddRef(IVBMXNamespaceManager * iface)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
vbnamespacemanager_Release(IVBMXNamespaceManager * iface)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
vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager * iface,UINT * pctinfo)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
vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)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
vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)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
vbnamespacemanager_Invoke(IVBMXNamespaceManager * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)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
vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager * iface,VARIANT_BOOL override)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
vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager * iface,VARIANT_BOOL * override)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
vbnamespacemanager_reset(IVBMXNamespaceManager * iface)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
vbnamespacemanager_pushContext(IVBMXNamespaceManager * iface)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
vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager * iface,IXMLDOMNode * node,VARIANT_BOOL deep)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
vbnamespacemanager_popContext(IVBMXNamespaceManager * iface)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
vbnamespacemanager_declarePrefix(IVBMXNamespaceManager * iface,BSTR prefix,BSTR namespaceURI)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
vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager * iface,IMXNamespacePrefixes ** prefixes)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
vbnamespacemanager_getPrefixes(IVBMXNamespaceManager * iface,BSTR namespaceURI,IMXNamespacePrefixes ** prefixes)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
vbnamespacemanager_getURI(IVBMXNamespaceManager * iface,BSTR prefix,VARIANT * uri)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
vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager * iface,BSTR prefix,IXMLDOMNode * node,VARIANT * uri)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
MXNamespaceManager_create(void ** obj)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