2011-08-21 19:30:58 +02:00
|
|
|
/*
|
|
|
|
* IMXNamespaceManager implementation
|
|
|
|
*
|
2012-01-23 05:45:44 +01:00
|
|
|
* Copyright 2011-2012 Nikolay Sivov for CodeWeavers
|
2011-08-21 19:30:58 +02:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
#define NONAMELESSUNION
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#ifdef HAVE_LIBXML2
|
|
|
|
# include <libxml/parser.h>
|
|
|
|
# include <libxml/xmlerror.h>
|
|
|
|
# include <libxml/encoding.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
#include "msxml6.h"
|
|
|
|
|
|
|
|
#include "msxml_private.h"
|
|
|
|
|
|
|
|
#include "wine/debug.h"
|
2011-08-21 19:47:09 +02:00
|
|
|
#include "wine/list.h"
|
2011-08-21 19:30:58 +02:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
|
|
|
|
2011-08-21 19:47:09 +02:00
|
|
|
struct ns
|
|
|
|
{
|
|
|
|
BSTR prefix;
|
|
|
|
BSTR uri;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct nscontext
|
|
|
|
{
|
|
|
|
struct list entry;
|
|
|
|
|
|
|
|
struct ns *ns;
|
|
|
|
int count;
|
|
|
|
int max_alloc;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DEFAULT_PREFIX_ALLOC_COUNT 16
|
|
|
|
|
|
|
|
static const WCHAR xmlW[] = {'x','m','l',0};
|
|
|
|
static const WCHAR xmluriW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','3','.','o','r','g',
|
|
|
|
'/','X','M','L','/','1','9','9','8','/','n','a','m','e','s','p','a','c','e',0};
|
|
|
|
|
2011-08-21 19:30:58 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2011-12-11 12:31:05 +01:00
|
|
|
DispatchEx dispex;
|
2011-08-21 19:44:28 +02:00
|
|
|
IMXNamespaceManager IMXNamespaceManager_iface;
|
|
|
|
IVBMXNamespaceManager IVBMXNamespaceManager_iface;
|
2011-08-21 19:30:58 +02:00
|
|
|
LONG ref;
|
2011-08-21 19:47:09 +02:00
|
|
|
|
|
|
|
struct list ctxts;
|
2011-08-21 19:49:21 +02:00
|
|
|
|
|
|
|
VARIANT_BOOL override;
|
2011-08-21 19:30:58 +02:00
|
|
|
} namespacemanager;
|
|
|
|
|
|
|
|
static inline namespacemanager *impl_from_IMXNamespaceManager( IMXNamespaceManager *iface )
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, namespacemanager, IMXNamespaceManager_iface);
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:44:28 +02:00
|
|
|
static inline namespacemanager *impl_from_IVBMXNamespaceManager( IVBMXNamespaceManager *iface )
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, namespacemanager, IVBMXNamespaceManager_iface);
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:49:21 +02:00
|
|
|
static HRESULT declare_prefix(namespacemanager *This, const WCHAR *prefix, const WCHAR *uri)
|
2011-08-21 19:47:09 +02:00
|
|
|
{
|
2011-08-21 19:49:21 +02:00
|
|
|
struct nscontext *ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
|
|
|
|
static const WCHAR emptyW[] = {0};
|
|
|
|
struct ns *ns;
|
|
|
|
int i;
|
|
|
|
|
2011-08-21 19:47:09 +02:00
|
|
|
if (ctxt->count == ctxt->max_alloc)
|
|
|
|
{
|
|
|
|
ctxt->max_alloc *= 2;
|
|
|
|
ctxt->ns = heap_realloc(ctxt->ns, ctxt->max_alloc*sizeof(*ctxt->ns));
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:49:21 +02:00
|
|
|
if (!prefix) prefix = emptyW;
|
|
|
|
|
|
|
|
ns = NULL;
|
|
|
|
for (i = 0; i < ctxt->count; i++)
|
|
|
|
if (!strcmpW(ctxt->ns[i].prefix, prefix))
|
|
|
|
{
|
|
|
|
ns = &ctxt->ns[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ns)
|
|
|
|
{
|
|
|
|
if (This->override == VARIANT_TRUE)
|
|
|
|
{
|
|
|
|
SysFreeString(ns->uri);
|
|
|
|
ns->uri = SysAllocString(uri);
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ctxt->ns[ctxt->count].prefix = SysAllocString(prefix);
|
|
|
|
ctxt->ns[ctxt->count].uri = SysAllocString(uri);
|
|
|
|
ctxt->count++;
|
|
|
|
}
|
2011-08-21 19:47:09 +02:00
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returned stored pointer, caller needs to copy it */
|
|
|
|
static HRESULT get_declared_prefix_idx(const struct nscontext *ctxt, LONG index, BSTR *prefix)
|
|
|
|
{
|
2011-08-21 19:48:15 +02:00
|
|
|
*prefix = NULL;
|
|
|
|
|
2011-08-21 19:47:09 +02:00
|
|
|
if (index >= ctxt->count || index < 0) return E_FAIL;
|
|
|
|
|
|
|
|
if (index > 0) index = ctxt->count - index;
|
|
|
|
*prefix = ctxt->ns[index].prefix;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2012-01-23 05:45:44 +01:00
|
|
|
/* returned stored pointer, caller needs to copy it */
|
2012-04-22 21:37:47 +02:00
|
|
|
static HRESULT get_declared_prefix_uri(const struct list *ctxts, const WCHAR *uri, BSTR *prefix)
|
2012-01-23 05:45:44 +01:00
|
|
|
{
|
2012-04-22 21:37:47 +02:00
|
|
|
struct nscontext *ctxt;
|
2012-01-23 05:45:44 +01:00
|
|
|
|
2012-04-22 21:37:47 +02:00
|
|
|
LIST_FOR_EACH_ENTRY(ctxt, ctxts, struct nscontext, entry)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ctxt->count; i++)
|
|
|
|
if (!strcmpW(ctxt->ns[i].uri, uri))
|
|
|
|
{
|
|
|
|
*prefix = ctxt->ns[i].prefix;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
2012-01-23 05:45:44 +01:00
|
|
|
|
|
|
|
*prefix = NULL;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:48:15 +02:00
|
|
|
static HRESULT get_uri_from_prefix(const struct nscontext *ctxt, const WCHAR *prefix, BSTR *uri)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ctxt->count; i++)
|
|
|
|
if (!strcmpW(ctxt->ns[i].prefix, prefix))
|
|
|
|
{
|
|
|
|
*uri = ctxt->ns[i].uri;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*uri = NULL;
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:47:09 +02:00
|
|
|
static struct nscontext* alloc_ns_context(void)
|
|
|
|
{
|
|
|
|
struct nscontext *ctxt;
|
|
|
|
|
|
|
|
ctxt = heap_alloc(sizeof(*ctxt));
|
|
|
|
if (!ctxt) return NULL;
|
|
|
|
|
|
|
|
ctxt->count = 0;
|
|
|
|
ctxt->max_alloc = DEFAULT_PREFIX_ALLOC_COUNT;
|
|
|
|
ctxt->ns = heap_alloc(ctxt->max_alloc*sizeof(*ctxt->ns));
|
2012-04-22 21:30:22 +02:00
|
|
|
if (!ctxt->ns)
|
|
|
|
{
|
|
|
|
heap_free(ctxt);
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-08-21 19:47:09 +02:00
|
|
|
|
|
|
|
/* first allocated prefix is always 'xml' */
|
|
|
|
ctxt->ns[0].prefix = SysAllocString(xmlW);
|
|
|
|
ctxt->ns[0].uri = SysAllocString(xmluriW);
|
|
|
|
ctxt->count++;
|
2012-04-22 21:30:22 +02:00
|
|
|
if (!ctxt->ns[0].prefix || !ctxt->ns[0].uri)
|
|
|
|
{
|
|
|
|
heap_free(ctxt->ns);
|
|
|
|
heap_free(ctxt);
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-08-21 19:47:09 +02:00
|
|
|
|
|
|
|
return ctxt;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_ns_context(struct nscontext *ctxt)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ctxt->count; i++)
|
|
|
|
{
|
|
|
|
SysFreeString(ctxt->ns[i].prefix);
|
|
|
|
SysFreeString(ctxt->ns[i].uri);
|
|
|
|
}
|
|
|
|
|
|
|
|
heap_free(ctxt->ns);
|
|
|
|
heap_free(ctxt);
|
|
|
|
}
|
|
|
|
|
2011-08-21 19:30:58 +02:00
|
|
|
static HRESULT WINAPI namespacemanager_QueryInterface(IMXNamespaceManager *iface, REFIID riid, void **ppvObject)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_QueryInterface(&This->IVBMXNamespaceManager_iface, riid, ppvObject);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI namespacemanager_AddRef(IMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_AddRef(&This->IVBMXNamespaceManager_iface);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI namespacemanager_Release(IMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_Release(&This->IVBMXNamespaceManager_iface);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_putAllowOverride(IMXNamespaceManager *iface,
|
|
|
|
VARIANT_BOOL override)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_put_allowOverride(&This->IVBMXNamespaceManager_iface, override);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_getAllowOverride(IMXNamespaceManager *iface,
|
|
|
|
VARIANT_BOOL *override)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_get_allowOverride(&This->IVBMXNamespaceManager_iface, override);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_reset(IMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_reset(&This->IVBMXNamespaceManager_iface);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_pushContext(IMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_pushContext(&This->IVBMXNamespaceManager_iface);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_pushNodeContext(IMXNamespaceManager *iface,
|
|
|
|
IXMLDOMNode *node, VARIANT_BOOL deep)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_pushNodeContext(&This->IVBMXNamespaceManager_iface, node, deep);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_popContext(IMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:44:28 +02:00
|
|
|
return IVBMXNamespaceManager_popContext(&This->IVBMXNamespaceManager_iface);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_declarePrefix(IMXNamespaceManager *iface,
|
|
|
|
const WCHAR *prefix, const WCHAR *namespaceURI)
|
|
|
|
{
|
2011-08-21 19:47:09 +02:00
|
|
|
static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
|
|
|
|
|
2011-08-21 19:30:58 +02:00
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:47:09 +02:00
|
|
|
|
|
|
|
TRACE("(%p)->(%s %s)\n", This, debugstr_w(prefix), debugstr_w(namespaceURI));
|
|
|
|
|
2011-08-21 19:49:21 +02:00
|
|
|
if (prefix && (!strcmpW(prefix, xmlW) || !strcmpW(prefix, xmlnsW) || !namespaceURI))
|
2011-08-21 19:47:09 +02:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2011-08-21 19:49:21 +02:00
|
|
|
return declare_prefix(This, prefix, namespaceURI);
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_getDeclaredPrefix(IMXNamespaceManager *iface,
|
|
|
|
LONG index, WCHAR *prefix, int *prefix_len)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:47:09 +02:00
|
|
|
struct nscontext *ctxt;
|
|
|
|
HRESULT hr;
|
|
|
|
BSTR prfx;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%d %p %p)\n", This, index, prefix, prefix_len);
|
|
|
|
|
|
|
|
if (!prefix_len) return E_POINTER;
|
|
|
|
|
|
|
|
ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
|
|
|
|
hr = get_declared_prefix_idx(ctxt, index, &prfx);
|
|
|
|
if (hr != S_OK) return hr;
|
|
|
|
|
|
|
|
if (prefix)
|
|
|
|
{
|
|
|
|
if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
|
|
|
|
strcpyW(prefix, prfx);
|
|
|
|
}
|
|
|
|
|
|
|
|
*prefix_len = SysStringLen(prfx);
|
|
|
|
|
|
|
|
return S_OK;
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_getPrefix(IMXNamespaceManager *iface,
|
|
|
|
const WCHAR *uri, LONG index, WCHAR *prefix, int *prefix_len)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2012-01-23 05:45:44 +01:00
|
|
|
HRESULT hr;
|
|
|
|
BSTR prfx;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(uri), index, prefix, prefix_len);
|
|
|
|
|
|
|
|
if (!uri || !*uri || !prefix_len) return E_INVALIDARG;
|
|
|
|
|
2012-04-22 21:37:47 +02:00
|
|
|
hr = get_declared_prefix_uri(&This->ctxts, uri, &prfx);
|
2012-01-23 05:45:44 +01:00
|
|
|
if (hr == S_OK)
|
|
|
|
{
|
|
|
|
/* TODO: figure out what index argument is for */
|
|
|
|
if (index) return E_FAIL;
|
|
|
|
|
|
|
|
if (prefix)
|
|
|
|
{
|
|
|
|
if (*prefix_len < (INT)SysStringLen(prfx)) return E_XML_BUFFERTOOSMALL;
|
|
|
|
strcpyW(prefix, prfx);
|
|
|
|
}
|
|
|
|
|
|
|
|
*prefix_len = SysStringLen(prfx);
|
|
|
|
TRACE("prefix=%s\n", debugstr_w(prfx));
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI namespacemanager_getURI(IMXNamespaceManager *iface,
|
|
|
|
const WCHAR *prefix, IXMLDOMNode *node, WCHAR *uri, int *uri_len)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IMXNamespaceManager( iface );
|
2011-08-21 19:48:15 +02:00
|
|
|
struct nscontext *ctxt;
|
|
|
|
HRESULT hr;
|
|
|
|
BSTR urib;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%s %p %p %p)\n", This, debugstr_w(prefix), node, uri, uri_len);
|
|
|
|
|
|
|
|
if (!prefix) return E_INVALIDARG;
|
|
|
|
if (!uri_len) return E_POINTER;
|
|
|
|
|
|
|
|
if (node)
|
|
|
|
{
|
|
|
|
FIXME("namespaces from DOM node not supported\n");
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
|
|
|
|
hr = get_uri_from_prefix(ctxt, prefix, &urib);
|
|
|
|
if (hr == S_OK)
|
|
|
|
{
|
|
|
|
if (uri)
|
|
|
|
{
|
|
|
|
if (*uri_len < (INT)SysStringLen(urib)) return E_XML_BUFFERTOOSMALL;
|
|
|
|
strcpyW(uri, urib);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (uri) *uri = 0;
|
|
|
|
|
|
|
|
*uri_len = SysStringLen(urib);
|
|
|
|
|
|
|
|
return hr;
|
2011-08-21 19:30:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct IMXNamespaceManagerVtbl MXNamespaceManagerVtbl =
|
|
|
|
{
|
|
|
|
namespacemanager_QueryInterface,
|
|
|
|
namespacemanager_AddRef,
|
|
|
|
namespacemanager_Release,
|
|
|
|
namespacemanager_putAllowOverride,
|
|
|
|
namespacemanager_getAllowOverride,
|
|
|
|
namespacemanager_reset,
|
|
|
|
namespacemanager_pushContext,
|
|
|
|
namespacemanager_pushNodeContext,
|
|
|
|
namespacemanager_popContext,
|
|
|
|
namespacemanager_declarePrefix,
|
|
|
|
namespacemanager_getDeclaredPrefix,
|
|
|
|
namespacemanager_getPrefix,
|
|
|
|
namespacemanager_getURI
|
|
|
|
};
|
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
static HRESULT WINAPI vbnamespacemanager_QueryInterface(IVBMXNamespaceManager *iface, REFIID riid, void **obj)
|
2011-08-21 19:44:28 +02:00
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-12-11 12:31:05 +01:00
|
|
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
|
2011-08-21 19:44:28 +02:00
|
|
|
|
|
|
|
if ( IsEqualGUID( riid, &IID_IMXNamespaceManager) ||
|
|
|
|
IsEqualGUID( riid, &IID_IUnknown) )
|
|
|
|
{
|
2011-12-11 12:31:05 +01:00
|
|
|
*obj = &This->IMXNamespaceManager_iface;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
else if ( IsEqualGUID( riid, &IID_IVBMXNamespaceManager) ||
|
|
|
|
IsEqualGUID( riid, &IID_IDispatch) )
|
|
|
|
{
|
2011-12-11 12:31:05 +01:00
|
|
|
*obj = &This->IVBMXNamespaceManager_iface;
|
|
|
|
}
|
|
|
|
else if (dispex_query_interface(&This->dispex, riid, obj))
|
|
|
|
{
|
|
|
|
return *obj ? S_OK : E_NOINTERFACE;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TRACE("Unsupported interface %s\n", debugstr_guid(riid));
|
2011-12-11 12:31:05 +01:00
|
|
|
*obj = NULL;
|
2011-08-21 19:44:28 +02:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
IVBMXNamespaceManager_AddRef( iface );
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI vbnamespacemanager_AddRef(IVBMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
ULONG ref = InterlockedIncrement( &This->ref );
|
|
|
|
TRACE("(%p)->(%u)\n", This, ref );
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI vbnamespacemanager_Release(IVBMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
ULONG ref = InterlockedDecrement( &This->ref );
|
|
|
|
|
|
|
|
TRACE("(%p)->(%u)\n", This, ref );
|
|
|
|
|
|
|
|
if ( ref == 0 )
|
2011-08-21 19:47:09 +02:00
|
|
|
{
|
|
|
|
struct nscontext *ctxt, *ctxt2;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY_SAFE(ctxt, ctxt2, &This->ctxts, struct nscontext, entry)
|
|
|
|
{
|
|
|
|
list_remove(&ctxt->entry);
|
|
|
|
free_ns_context(ctxt);
|
|
|
|
}
|
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
release_dispex(&This->dispex);
|
2011-08-21 19:44:28 +02:00
|
|
|
heap_free( This );
|
2011-08-21 19:47:09 +02:00
|
|
|
}
|
2011-08-21 19:44:28 +02:00
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_GetTypeInfoCount(IVBMXNamespaceManager *iface, UINT *pctinfo)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-12-11 12:31:05 +01:00
|
|
|
return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_GetTypeInfo(IVBMXNamespaceManager *iface, UINT iTInfo,
|
|
|
|
LCID lcid, ITypeInfo **ppTInfo)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-12-11 12:31:05 +01:00
|
|
|
return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
|
|
|
|
iTInfo, lcid, ppTInfo);
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_GetIDsOfNames(IVBMXNamespaceManager *iface, REFIID riid,
|
|
|
|
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-12-11 12:31:05 +01:00
|
|
|
return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
|
|
|
|
riid, rgszNames, cNames, lcid, rgDispId);
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_Invoke(IVBMXNamespaceManager *iface, DISPID dispIdMember, REFIID riid,
|
|
|
|
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
|
|
|
|
EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-12-11 12:31:05 +01:00
|
|
|
return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
|
|
|
|
dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_put_allowOverride(IVBMXNamespaceManager *iface,
|
|
|
|
VARIANT_BOOL override)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-08-21 19:49:21 +02:00
|
|
|
|
|
|
|
TRACE("(%p)->(%d)\n", This, override);
|
|
|
|
This->override = override;
|
|
|
|
|
|
|
|
return S_OK;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_get_allowOverride(IVBMXNamespaceManager *iface,
|
|
|
|
VARIANT_BOOL *override)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-08-21 19:49:21 +02:00
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", This, override);
|
|
|
|
|
|
|
|
if (!override) return E_POINTER;
|
|
|
|
*override = This->override;
|
|
|
|
|
|
|
|
return S_OK;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_reset(IVBMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p): stub\n", This);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_pushContext(IVBMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2012-04-22 21:30:22 +02:00
|
|
|
struct nscontext *ctxt;
|
|
|
|
|
|
|
|
TRACE("(%p)\n", This);
|
|
|
|
|
|
|
|
ctxt = alloc_ns_context();
|
|
|
|
if (!ctxt) return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
list_add_head(&This->ctxts, &ctxt->entry);
|
|
|
|
|
|
|
|
return S_OK;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_pushNodeContext(IVBMXNamespaceManager *iface,
|
|
|
|
IXMLDOMNode *node, VARIANT_BOOL deep)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p)->(%p %d): stub\n", This, node, deep);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_popContext(IVBMXNamespaceManager *iface)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2012-04-22 21:30:22 +02:00
|
|
|
const struct list *next;
|
|
|
|
struct nscontext *ctxt;
|
|
|
|
|
|
|
|
TRACE("(%p)\n", This);
|
|
|
|
|
|
|
|
next = list_next(&This->ctxts, list_head(&This->ctxts));
|
|
|
|
if (!next) return E_FAIL;
|
|
|
|
|
|
|
|
ctxt = LIST_ENTRY(list_head(&This->ctxts), struct nscontext, entry);
|
|
|
|
list_remove(list_head(&This->ctxts));
|
|
|
|
|
|
|
|
free_ns_context(ctxt);
|
|
|
|
|
|
|
|
return S_OK;
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_declarePrefix(IVBMXNamespaceManager *iface,
|
|
|
|
BSTR prefix, BSTR namespaceURI)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
2011-08-21 19:47:09 +02:00
|
|
|
return IMXNamespaceManager_declarePrefix(&This->IMXNamespaceManager_iface, prefix, namespaceURI);
|
2011-08-21 19:44:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_getDeclaredPrefixes(IVBMXNamespaceManager *iface,
|
|
|
|
IMXNamespacePrefixes** prefixes)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p)->(%p): stub\n", This, prefixes);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_getPrefixes(IVBMXNamespaceManager *iface,
|
|
|
|
BSTR namespaceURI, IMXNamespacePrefixes** prefixes)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(namespaceURI), prefixes);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_getURI(IVBMXNamespaceManager *iface,
|
|
|
|
BSTR prefix, VARIANT* uri)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(prefix), uri);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI vbnamespacemanager_getURIFromNode(IVBMXNamespaceManager *iface,
|
|
|
|
BSTR prefix, IXMLDOMNode *node, VARIANT *uri)
|
|
|
|
{
|
|
|
|
namespacemanager *This = impl_from_IVBMXNamespaceManager( iface );
|
|
|
|
FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(prefix), node, uri);
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct IVBMXNamespaceManagerVtbl VBMXNamespaceManagerVtbl =
|
|
|
|
{
|
|
|
|
vbnamespacemanager_QueryInterface,
|
|
|
|
vbnamespacemanager_AddRef,
|
|
|
|
vbnamespacemanager_Release,
|
|
|
|
vbnamespacemanager_GetTypeInfoCount,
|
|
|
|
vbnamespacemanager_GetTypeInfo,
|
|
|
|
vbnamespacemanager_GetIDsOfNames,
|
|
|
|
vbnamespacemanager_Invoke,
|
|
|
|
vbnamespacemanager_put_allowOverride,
|
|
|
|
vbnamespacemanager_get_allowOverride,
|
|
|
|
vbnamespacemanager_reset,
|
|
|
|
vbnamespacemanager_pushContext,
|
|
|
|
vbnamespacemanager_pushNodeContext,
|
|
|
|
vbnamespacemanager_popContext,
|
|
|
|
vbnamespacemanager_declarePrefix,
|
|
|
|
vbnamespacemanager_getDeclaredPrefixes,
|
|
|
|
vbnamespacemanager_getPrefixes,
|
|
|
|
vbnamespacemanager_getURI,
|
|
|
|
vbnamespacemanager_getURIFromNode
|
|
|
|
};
|
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
static const tid_t namespacemanager_iface_tids[] = {
|
|
|
|
IVBMXNamespaceManager_tid,
|
|
|
|
0
|
|
|
|
};
|
2012-04-22 21:30:22 +02:00
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
static dispex_static_data_t namespacemanager_dispex = {
|
|
|
|
NULL,
|
|
|
|
IVBMXNamespaceManager_tid,
|
|
|
|
NULL,
|
|
|
|
namespacemanager_iface_tids
|
|
|
|
};
|
|
|
|
|
2014-01-09 12:57:58 +01:00
|
|
|
HRESULT MXNamespaceManager_create(void **obj)
|
2011-08-21 19:30:58 +02:00
|
|
|
{
|
2011-12-11 12:31:05 +01:00
|
|
|
namespacemanager *This;
|
2011-08-21 19:47:09 +02:00
|
|
|
struct nscontext *ctxt;
|
2011-08-21 19:30:58 +02:00
|
|
|
|
2014-01-09 12:57:58 +01:00
|
|
|
TRACE("(%p)\n", obj);
|
2011-08-21 19:30:58 +02:00
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
This = heap_alloc( sizeof (*This) );
|
|
|
|
if( !This )
|
2011-08-21 19:30:58 +02:00
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
This->IMXNamespaceManager_iface.lpVtbl = &MXNamespaceManagerVtbl;
|
|
|
|
This->IVBMXNamespaceManager_iface.lpVtbl = &VBMXNamespaceManagerVtbl;
|
|
|
|
This->ref = 1;
|
|
|
|
init_dispex(&This->dispex, (IUnknown*)&This->IVBMXNamespaceManager_iface, &namespacemanager_dispex);
|
2011-08-21 19:30:58 +02:00
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
list_init(&This->ctxts);
|
2011-08-21 19:47:09 +02:00
|
|
|
ctxt = alloc_ns_context();
|
2012-04-22 21:30:22 +02:00
|
|
|
if (!ctxt)
|
|
|
|
{
|
|
|
|
heap_free(This);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
list_add_head(&This->ctxts, &ctxt->entry);
|
2011-08-21 19:47:09 +02:00
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
This->override = VARIANT_TRUE;
|
2011-08-21 19:49:21 +02:00
|
|
|
|
2011-12-11 12:31:05 +01:00
|
|
|
*obj = &This->IMXNamespaceManager_iface;
|
2011-08-21 19:30:58 +02:00
|
|
|
|
|
|
|
TRACE("returning iface %p\n", *obj);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|