[MSXML3_WINETEST]
[reactos.git] / rostests / winetests / msxml3 / domdoc.c
index 9253fc6..eb8c62a 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright 2005 Mike McCormack for CodeWeavers
  * Copyright 2007-2008 Alistair Leslie-Hughes
  * Copyright 2010-2011 Adam Martinson for CodeWeavers
- * Copyright 2010-2012 Nikolay Sivov for CodeWeavers
+ * Copyright 2010-2013 Nikolay Sivov for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
 
 
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
 #define COBJMACROS
 #define CONST_VTABLE
 
 #include <stdio.h>
 #include <assert.h>
 
-#include "windows.h"
-
-#include "msxml2.h"
-#include "msxml2did.h"
-#include "ole2.h"
-#include "dispex.h"
+//#include "windows.h"
 
-#include "initguid.h"
-#include "objsafe.h"
-#include "mshtml.h"
+#include <wine/test.h>
 
-#include "wine/test.h"
+#include <winnls.h>
+#include <ole2.h>
+#include <msxml.h>
+#include <msxml2.h>
+#include <msxml2did.h>
+#include <dispex.h>
+#include <objsafe.h>
+//#include "initguid.h"
 
 /* undef the #define in msxml2 so that we can access all versions */
 #undef CLSID_DOMDocument
 
-DEFINE_GUID(SID_SContainerDispatch, 0xb722be00, 0x4e68, 0x101b, 0xa2, 0xbc, 0x00, 0xaa, 0x00, 0x40, 0x47, 0x70);
-DEFINE_GUID(SID_UnknownSID, 0x75dd09cb, 0x6c40, 0x11d5, 0x85, 0x43, 0x00, 0xc0, 0x4f, 0xa0, 0xfb, 0xa3);
-DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
-
-#define DEFINE_EXPECT(func) \
-    static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
-
-#define SET_EXPECT(func) \
-    expect_ ## func = TRUE
-
-#define CHECK_EXPECT2(func) \
-    do { \
-        ok(expect_ ##func, "unexpected call " #func "\n"); \
-        called_ ## func = TRUE; \
-    }while(0)
-
-#define CHECK_CALLED(func) \
-    do { \
-        ok(called_ ## func, "expected " #func "\n"); \
-        expect_ ## func = called_ ## func = FALSE; \
-    }while(0)
-
-static const char *debugstr_guid(REFIID riid)
-{
-    static char buf[50];
-
-    if(!riid)
-        return "(null)";
-
-    sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
-            riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
-            riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
-            riid->Data4[5], riid->Data4[6], riid->Data4[7]);
-
-    return buf;
-}
-
-static int g_unexpectedcall, g_expectedcall;
-
-typedef struct
-{
-    IDispatch IDispatch_iface;
-    LONG ref;
-} dispevent;
-
-static inline dispevent *impl_from_IDispatch( IDispatch *iface )
-{
-    return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
-}
-
-static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
-{
-    *ppvObject = NULL;
-
-    if ( IsEqualGUID( riid, &IID_IDispatch) ||
-         IsEqualGUID( riid, &IID_IUnknown) )
-    {
-        *ppvObject = iface;
-    }
-    else
-        return E_NOINTERFACE;
-
-    IDispatch_AddRef( iface );
-
-    return S_OK;
-}
-
-static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
-{
-    dispevent *This = impl_from_IDispatch( iface );
-    return InterlockedIncrement( &This->ref );
-}
-
-static ULONG WINAPI dispevent_Release(IDispatch *iface)
-{
-    dispevent *This = impl_from_IDispatch( iface );
-    ULONG ref = InterlockedDecrement( &This->ref );
-
-    if (ref == 0)
-        HeapFree(GetProcessHeap(), 0, This);
-
-    return ref;
-}
-
-static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
-{
-    g_unexpectedcall++;
-    *pctinfo = 0;
-    return S_OK;
-}
-
-static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
-        LCID lcid, ITypeInfo **ppTInfo)
-{
-    g_unexpectedcall++;
-    return S_OK;
-}
-
-static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
-        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
-{
-    g_unexpectedcall++;
-    return S_OK;
-}
-
-static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
-        LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
-        EXCEPINFO *excepInfo, UINT *argErr)
-{
-    ok(member == 0, "expected 0 member, got %d\n", member);
-    ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
-    ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
-
-    ok(params->cArgs == 0, "got %d\n", params->cArgs);
-    ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
-    ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
-    ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
-
-    ok(result == NULL, "got %p\n", result);
-    ok(excepInfo == NULL, "got %p\n", excepInfo);
-    ok(argErr == NULL, "got %p\n", argErr);
-
-    g_expectedcall++;
-    return E_FAIL;
-}
-
-static const IDispatchVtbl dispeventVtbl =
-{
-    dispevent_QueryInterface,
-    dispevent_AddRef,
-    dispevent_Release,
-    dispevent_GetTypeInfoCount,
-    dispevent_GetTypeInfo,
-    dispevent_GetIDsOfNames,
-    dispevent_Invoke
-};
-
-static IDispatch* create_dispevent(void)
-{
-    dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
-
-    event->IDispatch_iface.lpVtbl = &dispeventVtbl;
-    event->ref = 1;
-
-    return (IDispatch*)&event->IDispatch_iface;
-}
-
-/* object site */
-DEFINE_EXPECT(site_qi_IServiceProvider);
-DEFINE_EXPECT(site_qi_IXMLDOMDocument);
-DEFINE_EXPECT(site_qi_IOleClientSite);
-
-DEFINE_EXPECT(sp_queryservice_SID_SBindHost);
-DEFINE_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-DEFINE_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
-DEFINE_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
-DEFINE_EXPECT(sp_queryservice_SID_secmgr_secmgr);
-
-DEFINE_EXPECT(htmldoc2_get_all);
-DEFINE_EXPECT(htmldoc2_get_url);
-DEFINE_EXPECT(collection_get_length);
-
-typedef struct
-{
-    IServiceProvider IServiceProvider_iface;
-} testprov_t;
-
-testprov_t testprov;
-
-static HRESULT WINAPI site_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
-{
-    *ppvObject = NULL;
-
-    if (IsEqualGUID(riid, &IID_IServiceProvider))
-        CHECK_EXPECT2(site_qi_IServiceProvider);
-
-    if (IsEqualGUID(riid, &IID_IXMLDOMDocument))
-        CHECK_EXPECT2(site_qi_IXMLDOMDocument);
-
-    if (IsEqualGUID(riid, &IID_IOleClientSite))
-        CHECK_EXPECT2(site_qi_IOleClientSite);
-
-    if (IsEqualGUID(riid, &IID_IUnknown))
-         *ppvObject = iface;
-    else if (IsEqualGUID(riid, &IID_IServiceProvider))
-         *ppvObject = &testprov.IServiceProvider_iface;
-
-    if (*ppvObject) IUnknown_AddRef(iface);
-
-    return *ppvObject ? S_OK : E_NOINTERFACE;
-}
-
-static ULONG WINAPI site_AddRef(IUnknown *iface)
-{
-    return 2;
-}
-
-static ULONG WINAPI site_Release(IUnknown *iface)
-{
-    return 1;
-}
-
-static const IUnknownVtbl testsiteVtbl =
-{
-    site_QueryInterface,
-    site_AddRef,
-    site_Release
-};
-
-typedef struct
-{
-    IUnknown IUnknown_iface;
-} testsite_t;
-
-static testsite_t testsite = { { &testsiteVtbl } };
-
-/* test IHTMLElementCollection */
-static HRESULT WINAPI htmlecoll_QueryInterface(IHTMLElementCollection *iface, REFIID riid, void **ppvObject)
-{
-    ok(0, "unexpected call\n");
-    *ppvObject = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI htmlecoll_AddRef(IHTMLElementCollection *iface)
-{
-    return 2;
-}
-
-static ULONG WINAPI htmlecoll_Release(IHTMLElementCollection *iface)
-{
-    return 1;
-}
-
-static HRESULT WINAPI htmlecoll_GetTypeInfoCount(IHTMLElementCollection *iface, UINT *pctinfo)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_GetTypeInfo(IHTMLElementCollection *iface, UINT iTInfo,
-                                                LCID lcid, ITypeInfo **ppTInfo)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_GetIDsOfNames(IHTMLElementCollection *iface, REFIID riid,
-                                                LPOLESTR *rgszNames, UINT cNames,
-                                                LCID lcid, DISPID *rgDispId)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_Invoke(IHTMLElementCollection *iface, DISPID dispIdMember,
-                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
-                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_toString(IHTMLElementCollection *iface, BSTR *String)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_put_length(IHTMLElementCollection *iface, LONG v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_get_length(IHTMLElementCollection *iface, LONG *v)
-{
-    CHECK_EXPECT2(collection_get_length);
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_get__newEnum(IHTMLElementCollection *iface, IUnknown **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_item(IHTMLElementCollection *iface, VARIANT name, VARIANT index, IDispatch **pdisp)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmlecoll_tags(IHTMLElementCollection *iface, VARIANT tagName, IDispatch **pdisp)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static const IHTMLElementCollectionVtbl TestHTMLECollectionVtbl = {
-    htmlecoll_QueryInterface,
-    htmlecoll_AddRef,
-    htmlecoll_Release,
-    htmlecoll_GetTypeInfoCount,
-    htmlecoll_GetTypeInfo,
-    htmlecoll_GetIDsOfNames,
-    htmlecoll_Invoke,
-
-    htmlecoll_toString,
-    htmlecoll_put_length,
-    htmlecoll_get_length,
-    htmlecoll_get__newEnum,
-    htmlecoll_item,
-    htmlecoll_tags
-};
-
-typedef struct
-{
-    IHTMLElementCollection IHTMLElementCollection_iface;
-} testhtmlecoll_t;
-
-static testhtmlecoll_t htmlecoll = { { &TestHTMLECollectionVtbl } };
-
-/* test IHTMLDocument2 */
-static HRESULT WINAPI htmldoc2_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppvObject)
-{
-   trace("\n");
-   *ppvObject = NULL;
-   return E_NOINTERFACE;
-}
-
-static ULONG WINAPI htmldoc2_AddRef(IHTMLDocument2 *iface)
-{
-    return 2;
-}
-
-static ULONG WINAPI htmldoc2_Release(IHTMLDocument2 *iface)
-{
-    return 1;
-}
-
-static HRESULT WINAPI htmldoc2_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
-                                                LCID lcid, ITypeInfo **ppTInfo)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
-                                                LPOLESTR *rgszNames, UINT cNames,
-                                                LCID lcid, DISPID *rgDispId)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
-                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
-                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_Script(IHTMLDocument2 *iface, IDispatch **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    CHECK_EXPECT2(htmldoc2_get_all);
-    *p = &htmlecoll.IHTMLElementCollection_iface;
-    return S_OK;
-}
-
-static HRESULT WINAPI htmldoc2_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_title(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_title(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_designMode(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_designMode(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_readyState(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_referrer(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_URL(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_URL(IHTMLDocument2 *iface, BSTR *p)
-{
-    CHECK_EXPECT2(htmldoc2_get_url);
-    *p = SysAllocString(NULL);
-    return S_OK;
-}
-
-static HRESULT WINAPI htmldoc2_put_domain(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_domain(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_cookie(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_cookie(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_charset(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_charset(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_security(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_protocol(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
-                        VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_close(IHTMLDocument2 *iface)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_clear(IHTMLDocument2 *iface)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        BSTR *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
-                                VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
-                                                        VARIANT_BOOL *pfRet)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_createElement(IHTMLDocument2 *iface, BSTR eTag,
-                                                 IHTMLElement **newElem)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onclick(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
-
-static HRESULT WINAPI htmldoc2_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
-static HRESULT WINAPI htmldoc2_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+static int g_unexpectedcall, g_expectedcall;
 
-static HRESULT WINAPI htmldoc2_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
+struct msxmlsupported_data_t
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    const GUID *clsid;
+    const char *name;
+    const IID  *ifaces[3];
+    BOOL        supported[3];
+};
 
-static HRESULT WINAPI htmldoc2_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+static struct msxmlsupported_data_t domdoc_support_data[] =
+{
+    { &CLSID_DOMDocument,   "DOMDocument",   {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
+    { &CLSID_DOMDocument2,  "DOMDocument2",  {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
+    { &CLSID_DOMDocument30, "DOMDocument30", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
+    { &CLSID_DOMDocument40, "DOMDocument40", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
+    { &CLSID_DOMDocument60, "DOMDocument60", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3} },
+    { &CLSID_FreeThreadedDOMDocument, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument, &IID_IXMLDOMDocument2} },
+    { &CLSID_XMLSchemaCache, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection} },
+    { &CLSID_XSLTemplate,    "XSLTemplate", {&IID_IXSLTemplate} },
+    { &CLSID_MXNamespaceManager40, "MXNamespaceManager40", {&IID_IMXNamespaceManager} },
+    { NULL }
+};
 
-static HRESULT WINAPI htmldoc2_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
+static const char *debugstr_msxml_guid(REFIID riid)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    if(!riid)
+        return "(null)";
 
-static HRESULT WINAPI htmldoc2_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    if (IsEqualIID(&IID_IXMLDOMDocument, riid))
+        return "IXMLDOMDocument";
+    else if (IsEqualIID(&IID_IXMLDOMDocument2, riid))
+        return "IXMLDOMDocument2";
+    else if (IsEqualIID(&IID_IXMLDOMDocument3, riid))
+        return "IXMLDOMDocument3";
+    else if (IsEqualIID(&IID_IXMLDOMSchemaCollection, riid))
+        return "IXMLDOMSchemaCollection";
+    else if (IsEqualIID(&IID_IXSLTemplate, riid))
+        return "IXSLTemplate";
+    else if (IsEqualIID(&IID_IMXNamespaceManager, riid))
+        return "IMXNamespaceManager";
+    else
+        return wine_dbgstr_guid(riid);
 }
 
-static HRESULT WINAPI htmldoc2_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
+static void get_class_support_data(struct msxmlsupported_data_t *table)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    while (table->clsid)
+    {
+        IUnknown *unk;
+        HRESULT hr;
+        int i;
 
-static HRESULT WINAPI htmldoc2_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+        for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
+        {
+            hr = CoCreateInstance(table->clsid, NULL, CLSCTX_INPROC_SERVER, table->ifaces[i], (void**)&unk);
+            if (hr == S_OK) IUnknown_Release(unk);
 
-static HRESULT WINAPI htmldoc2_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+            table->supported[i] = hr == S_OK;
+            if (hr != S_OK) win_skip("class %s, iface %s not supported\n", table->name, debugstr_msxml_guid(table->ifaces[i]));
+        }
 
-static HRESULT WINAPI htmldoc2_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+        table++;
+    }
 }
 
-static HRESULT WINAPI htmldoc2_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
+static BOOL is_clsid_supported(const GUID *clsid, REFIID riid)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    const struct msxmlsupported_data_t *table = domdoc_support_data;
+    while (table->clsid)
+    {
+        if (table->clsid == clsid)
+        {
+            int i;
 
-static HRESULT WINAPI htmldoc2_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+            for (i = 0; i < sizeof(table->ifaces)/sizeof(table->ifaces[0]) && table->ifaces[i] != NULL; i++)
+                if (table->ifaces[i] == riid) return table->supported[i];
+        }
 
-static HRESULT WINAPI htmldoc2_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+        table++;
+    }
+    return FALSE;
 }
 
-static HRESULT WINAPI htmldoc2_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
+typedef struct
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    IDispatch IDispatch_iface;
+    LONG ref;
+} dispevent;
 
-static HRESULT WINAPI htmldoc2_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
+static inline dispevent *impl_from_IDispatch( IDispatch *iface )
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    return CONTAINING_RECORD(iface, dispevent, IDispatch_iface);
 }
 
-static HRESULT WINAPI htmldoc2_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
+static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    *ppvObject = NULL;
 
-static HRESULT WINAPI htmldoc2_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    if ( IsEqualGUID( riid, &IID_IDispatch) ||
+         IsEqualGUID( riid, &IID_IUnknown) )
+    {
+        *ppvObject = iface;
+    }
+    else
+        return E_NOINTERFACE;
 
-static HRESULT WINAPI htmldoc2_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
-                                                        IHTMLElement **elementHit)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    IDispatch_AddRef( iface );
 
-static HRESULT WINAPI htmldoc2_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    return S_OK;
 }
 
-static HRESULT WINAPI htmldoc2_get_styleSheets(IHTMLDocument2 *iface,
-                                                   IHTMLStyleSheetsCollection **p)
+static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    dispevent *This = impl_from_IDispatch( iface );
+    return InterlockedIncrement( &This->ref );
 }
 
-static HRESULT WINAPI htmldoc2_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
+static ULONG WINAPI dispevent_Release(IDispatch *iface)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    dispevent *This = impl_from_IDispatch( iface );
+    ULONG ref = InterlockedDecrement( &This->ref );
 
-static HRESULT WINAPI htmldoc2_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
-}
+    if (ref == 0)
+        HeapFree(GetProcessHeap(), 0, This);
 
-static HRESULT WINAPI htmldoc2_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
-{
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    return ref;
 }
 
-static HRESULT WINAPI htmldoc2_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
+static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    g_unexpectedcall++;
+    *pctinfo = 0;
+    return S_OK;
 }
 
-static HRESULT WINAPI htmldoc2_toString(IHTMLDocument2 *iface, BSTR *String)
+static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    g_unexpectedcall++;
+    return S_OK;
 }
 
-static HRESULT WINAPI htmldoc2_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
-                                            LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
+static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    g_unexpectedcall++;
+    return S_OK;
 }
 
-static const IHTMLDocument2Vtbl TestHTMLDocumentVtbl = {
-    htmldoc2_QueryInterface,
-    htmldoc2_AddRef,
-    htmldoc2_Release,
-    htmldoc2_GetTypeInfoCount,
-    htmldoc2_GetTypeInfo,
-    htmldoc2_GetIDsOfNames,
-    htmldoc2_Invoke,
-    htmldoc2_get_Script,
-    htmldoc2_get_all,
-    htmldoc2_get_body,
-    htmldoc2_get_activeElement,
-    htmldoc2_get_images,
-    htmldoc2_get_applets,
-    htmldoc2_get_links,
-    htmldoc2_get_forms,
-    htmldoc2_get_anchors,
-    htmldoc2_put_title,
-    htmldoc2_get_title,
-    htmldoc2_get_scripts,
-    htmldoc2_put_designMode,
-    htmldoc2_get_designMode,
-    htmldoc2_get_selection,
-    htmldoc2_get_readyState,
-    htmldoc2_get_frames,
-    htmldoc2_get_embeds,
-    htmldoc2_get_plugins,
-    htmldoc2_put_alinkColor,
-    htmldoc2_get_alinkColor,
-    htmldoc2_put_bgColor,
-    htmldoc2_get_bgColor,
-    htmldoc2_put_fgColor,
-    htmldoc2_get_fgColor,
-    htmldoc2_put_linkColor,
-    htmldoc2_get_linkColor,
-    htmldoc2_put_vlinkColor,
-    htmldoc2_get_vlinkColor,
-    htmldoc2_get_referrer,
-    htmldoc2_get_location,
-    htmldoc2_get_lastModified,
-    htmldoc2_put_URL,
-    htmldoc2_get_URL,
-    htmldoc2_put_domain,
-    htmldoc2_get_domain,
-    htmldoc2_put_cookie,
-    htmldoc2_get_cookie,
-    htmldoc2_put_expando,
-    htmldoc2_get_expando,
-    htmldoc2_put_charset,
-    htmldoc2_get_charset,
-    htmldoc2_put_defaultCharset,
-    htmldoc2_get_defaultCharset,
-    htmldoc2_get_mimeType,
-    htmldoc2_get_fileSize,
-    htmldoc2_get_fileCreatedDate,
-    htmldoc2_get_fileModifiedDate,
-    htmldoc2_get_fileUpdatedDate,
-    htmldoc2_get_security,
-    htmldoc2_get_protocol,
-    htmldoc2_get_nameProp,
-    htmldoc2_write,
-    htmldoc2_writeln,
-    htmldoc2_open,
-    htmldoc2_close,
-    htmldoc2_clear,
-    htmldoc2_queryCommandSupported,
-    htmldoc2_queryCommandEnabled,
-    htmldoc2_queryCommandState,
-    htmldoc2_queryCommandIndeterm,
-    htmldoc2_queryCommandText,
-    htmldoc2_queryCommandValue,
-    htmldoc2_execCommand,
-    htmldoc2_execCommandShowHelp,
-    htmldoc2_createElement,
-    htmldoc2_put_onhelp,
-    htmldoc2_get_onhelp,
-    htmldoc2_put_onclick,
-    htmldoc2_get_onclick,
-    htmldoc2_put_ondblclick,
-    htmldoc2_get_ondblclick,
-    htmldoc2_put_onkeyup,
-    htmldoc2_get_onkeyup,
-    htmldoc2_put_onkeydown,
-    htmldoc2_get_onkeydown,
-    htmldoc2_put_onkeypress,
-    htmldoc2_get_onkeypress,
-    htmldoc2_put_onmouseup,
-    htmldoc2_get_onmouseup,
-    htmldoc2_put_onmousedown,
-    htmldoc2_get_onmousedown,
-    htmldoc2_put_onmousemove,
-    htmldoc2_get_onmousemove,
-    htmldoc2_put_onmouseout,
-    htmldoc2_get_onmouseout,
-    htmldoc2_put_onmouseover,
-    htmldoc2_get_onmouseover,
-    htmldoc2_put_onreadystatechange,
-    htmldoc2_get_onreadystatechange,
-    htmldoc2_put_onafterupdate,
-    htmldoc2_get_onafterupdate,
-    htmldoc2_put_onrowexit,
-    htmldoc2_get_onrowexit,
-    htmldoc2_put_onrowenter,
-    htmldoc2_get_onrowenter,
-    htmldoc2_put_ondragstart,
-    htmldoc2_get_ondragstart,
-    htmldoc2_put_onselectstart,
-    htmldoc2_get_onselectstart,
-    htmldoc2_elementFromPoint,
-    htmldoc2_get_parentWindow,
-    htmldoc2_get_styleSheets,
-    htmldoc2_put_onbeforeupdate,
-    htmldoc2_get_onbeforeupdate,
-    htmldoc2_put_onerrorupdate,
-    htmldoc2_get_onerrorupdate,
-    htmldoc2_toString,
-    htmldoc2_createStyleSheet
-};
-
-typedef struct
-{
-    IHTMLDocument2 IHTMLDocument2_iface;
-} testhtmldoc2_t;
-
-static testhtmldoc2_t htmldoc2 = { { &TestHTMLDocumentVtbl } };
-
-static HRESULT WINAPI sp_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObject)
+static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
+        LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
+        EXCEPINFO *excepInfo, UINT *argErr)
 {
-    *ppvObject = NULL;
-
-    if (IsEqualGUID(riid, &IID_IUnknown) ||
-        IsEqualGUID(riid, &IID_IServiceProvider))
-    {
-        *ppvObject = iface;
-        IServiceProvider_AddRef(iface);
-        return S_OK;
-    }
+    ok(member == 0, "expected 0 member, got %d\n", member);
+    ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
+    ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
 
-    ok(0, "unexpected query interface: %s\n", debugstr_guid(riid));
+    ok(params->cArgs == 0, "got %d\n", params->cArgs);
+    ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
+    ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
+    ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
 
-    return E_NOINTERFACE;
-}
+    ok(result == NULL, "got %p\n", result);
+    ok(excepInfo == NULL, "got %p\n", excepInfo);
+    ok(argErr == NULL, "got %p\n", argErr);
 
-static ULONG WINAPI sp_AddRef(IServiceProvider *iface)
-{
-    return 2;
+    g_expectedcall++;
+    return E_FAIL;
 }
 
-static ULONG WINAPI sp_Release(IServiceProvider *iface)
+static const IDispatchVtbl dispeventVtbl =
 {
-    return 1;
-}
+    dispevent_QueryInterface,
+    dispevent_AddRef,
+    dispevent_Release,
+    dispevent_GetTypeInfoCount,
+    dispevent_GetTypeInfo,
+    dispevent_GetIDsOfNames,
+    dispevent_Invoke
+};
 
-static HRESULT WINAPI sp_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
+static IDispatch* create_dispevent(void)
 {
-    *obj = NULL;
+    dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
 
-    if (IsEqualGUID(service, &SID_SBindHost) &&
-        IsEqualGUID(riid, &IID_IBindHost))
-    {
-        CHECK_EXPECT2(sp_queryservice_SID_SBindHost);
-    }
-    else if (IsEqualGUID(service, &SID_SContainerDispatch) &&
-             IsEqualGUID(riid, &IID_IHTMLDocument2))
-    {
-        CHECK_EXPECT2(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-    }
-    else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
-             IsEqualGUID(riid, &IID_IHTMLDocument2))
-    {
-        CHECK_EXPECT2(sp_queryservice_SID_secmgr_htmldoc2);
-        *obj = &htmldoc2.IHTMLDocument2_iface;
-        return S_OK;
-    }
-    else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
-             IsEqualGUID(riid, &IID_IXMLDOMDocument))
-    {
-        CHECK_EXPECT2(sp_queryservice_SID_secmgr_xmldomdoc);
-    }
-    else if (IsEqualGUID(service, &SID_SInternetHostSecurityManager) &&
-             IsEqualGUID(riid, &IID_IInternetHostSecurityManager))
-    {
-        CHECK_EXPECT2(sp_queryservice_SID_secmgr_secmgr);
-    }
-    else if (IsEqualGUID(service, &SID_UnknownSID) &&
-             IsEqualGUID(riid, &IID_IStream))
-    {
-        /* FIXME: unidentified service id */
-    }
-    else
-        ok(0, "unexpected request: sid %s, riid %s\n", debugstr_guid(service), debugstr_guid(riid));
+    event->IDispatch_iface.lpVtbl = &dispeventVtbl;
+    event->ref = 1;
 
-    return E_NOTIMPL;
+    return (IDispatch*)&event->IDispatch_iface;
 }
 
-static const IServiceProviderVtbl testprovVtbl =
-{
-    sp_QueryInterface,
-    sp_AddRef,
-    sp_Release,
-    sp_QueryService
-};
-
-testprov_t testprov = { { &testprovVtbl } };
-
 /* IStream */
 static HRESULT WINAPI istream_QueryInterface(IStream *iface, REFIID riid, void **ppvObject)
 {
@@ -1398,7 +352,9 @@ static const IStreamVtbl StreamVtbl = {
     istream_Clone
 };
 
+#if CORE_6738_IS_FIXED
 static IStream savestream = { &StreamVtbl };
+#endif
 
 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
 static void _expect_children(IXMLDOMNode *node, int line)
@@ -1427,9 +383,10 @@ static void _expect_no_children(IXMLDOMNode *node, int line)
 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
 {
-    ULONG rc = IUnknown_AddRef(obj);
-    IUnknown_Release(obj);
-    ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
+    ULONG rc;
+    IUnknown_AddRef(obj);
+    rc = IUnknown_Release(obj);
+    ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
 }
 
 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
@@ -1507,6 +464,15 @@ static const WCHAR szComplete6[] = {
     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
 };
 
+static const char complete7[] = {
+    "<?xml version=\"1.0\"?>\n\t"
+    "<root>\n"
+    "\t<a/>\n"
+    "\t<b/>\n"
+    "\t<c/>\n"
+    "</root>"
+};
+
 #define DECL_WIN_1252 \
 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
 
@@ -1518,6 +484,8 @@ static const char win1252decl[] =
 DECL_WIN_1252
 ;
 
+static const char nocontent[] = "no xml content here";
+
 static const char szExampleXML[] =
 "<?xml version='1.0' encoding='utf-8'?>\n"
 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
@@ -1536,7 +504,7 @@ static const char szExampleXML[] =
 "        </description>\n"
 "    </elem>\n"
 "\n"
-"    <elem>\n"
+"    <elem a='a'>\n"
 "        <a>A2 field</a>\n"
 "        <b>B2 field</b>\n"
 "        <c type=\"old\">C2 field</c>\n"
@@ -1557,6 +525,13 @@ static const char szExampleXML[] =
 "    </elem>\n"
 "</root>\n";
 
+static const char charrefsxml[] =
+"<?xml version='1.0'?>"
+"<a>"
+"<b1> Text &#65; end </b1>"
+"<b2>&#65;&#66; &#67; </b2>"
+"</a>";
+
 static const CHAR szNodeTypesXML[] =
 "<?xml version='1.0'?>"
 "<!-- comment node 0 -->"
@@ -1887,41 +862,41 @@ static const WCHAR szDocument[] = {
 };
 
 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
-static WCHAR szdl[] = { 'd','l',0 };
+static const WCHAR szdl[] = { 'd','l',0 };
 static const WCHAR szvr[] = { 'v','r',0 };
 static const WCHAR szlc[] = { 'l','c',0 };
-static WCHAR szbs[] = { 'b','s',0 };
+static const WCHAR szbs[] = { 'b','s',0 };
 static const WCHAR szstr1[] = { 's','t','r','1',0 };
 static const WCHAR szstr2[] = { 's','t','r','2',0 };
 static const WCHAR szstar[] = { '*',0 };
 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
 
-static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
-static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
-static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
+static const WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
+static const WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
+static const WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
 
 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
-static WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
-static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
-static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
-                                'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
-static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
-                                '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
-
-static WCHAR szAttribute[] = {'A','t','t','r',0 };
-static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
-
-static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
-                          ' ','n','o','t',' ','r','i','g','h','t','!', 0};
-static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
-                             'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
-                             '!',']',']','>',0};
-static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
-static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
-
-static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
-static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
-static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
+static const WCHAR szElementXML[]  = {'<','E','l','e','T','e','s','t','/','>',0 };
+static const WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
+static const WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
+                                      'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
+static const WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
+                                      '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
+
+static const WCHAR szAttribute[] = {'A','t','t','r',0 };
+static const WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
+
+static const WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
+                                ' ','n','o','t',' ','r','i','g','h','t','!', 0};
+static const WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
+                                   'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
+                                   '!',']',']','>',0};
+static const WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
+static const WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
+
+static const WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
+static const WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
+static const WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
 
 #define expect_bstr_eq_and_free(bstr, expect) { \
     BSTR bstrExp = alloc_str_from_narrow(expect); \
@@ -1950,8 +925,7 @@ static void* _create_object(const GUID *clsid, const char *name, const IID *iid,
     HRESULT hr;
 
     hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
-    if (hr != S_OK)
-        win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
+    ok(hr == S_OK, "failed to create %s instance: 0x%08x\n", name, hr);
 
     return obj;
 }
@@ -1961,7 +935,6 @@ static void* _create_object(const GUID *clsid, const char *name, const IID *iid,
 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
-#define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
 
 static BSTR alloc_str_from_narrow(const char *str)
@@ -2092,7 +1065,7 @@ static void node_to_string(IXMLDOMNode *node, char *buf)
         else
         {
             r = IXMLDOMNode_get_parentNode(node, &new_node);
-            wsprintf(buf, "%d", get_node_position(node));
+            sprintf(buf, "%d", get_node_position(node));
             buf += strlen(buf);
         }
 
@@ -2111,14 +1084,16 @@ static char *list_to_string(IXMLDOMNodeList *list)
     static char buf[4096];
     char *pos = buf;
     LONG len = 0;
+    HRESULT hr;
     int i;
 
     if (list == NULL)
     {
-        lstrcpyA(buf, "(null)");
+        strcpy(buf, "(null)");
         return buf;
     }
-    ole_check(IXMLDOMNodeList_get_length(list, &len));
+    hr = IXMLDOMNodeList_get_length(list, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     for (i = 0; i < len; i++)
     {
         IXMLDOMNode *node;
@@ -2205,10 +1180,12 @@ static void test_domdoc( void )
         HRESULT hr;
         int i;
 
-        hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
-             &IID_IXMLDOMDocument, (void**)&doc);
-        if (hr != S_OK) {
-            win_skip("%d: failed to create class instance for %s\n", index, class_ptr->name);
+        if (is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
+        {
+            hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
+        }
+        else
+        {
             class_ptr++;
             index++;
             continue;
@@ -2231,10 +1208,9 @@ static void test_domdoc( void )
             V_VT(&var) = VT_BSTR;
             V_BSTR(&var) = _bstr_(path);
             hr = IXMLDOMDocument_load(doc, var, &b);
-        todo_wine {
             EXPECT_HR(hr, class_ptr->ret[0].hr);
             ok(b == class_ptr->ret[0].b, "%d:%d, got %d, expected %d\n", index, i, b, class_ptr->ret[0].b);
-        }
+
             DeleteFileA(path);
 
             b = 0xc;
@@ -2281,6 +1257,11 @@ if (0)
     ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
     SysFreeString( str );
 
+    str = (BSTR)0x1;
+    hr = IXMLDOMDocument_get_url(doc, &str);
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+    ok(str == NULL, "got %p\n", str);
+
     /* try load an empty document */
     b = VARIANT_TRUE;
     str = SysAllocString( szEmpty );
@@ -2369,7 +1350,7 @@ if (0)
     SysFreeString( str );
 
     /* test put_text */
-    r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
+    r = IXMLDOMDocument_put_text( doc, _bstr_("Should fail") );
     ok( r == E_FAIL, "ret %08x\n", r );
 
     /* check that there's a document element */
@@ -2877,16 +1858,19 @@ static void test_persiststreaminit(void)
 {
     IXMLDOMDocument *doc;
     IPersistStreamInit *streaminit;
+    ULARGE_INTEGER size;
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
-    ok( hr == S_OK, "failed with 0x%08x\n", hr );
+    ok(hr == S_OK, "got 0x%08x\n", hr);
 
     hr = IPersistStreamInit_InitNew(streaminit);
-    ok( hr == S_OK, "failed with 0x%08x\n", hr );
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IPersistStreamInit_GetSizeMax(streaminit, &size);
+    ok(hr == E_NOTIMPL, "got 0x%08x\n", hr);
 
     IXMLDOMDocument_Release(doc);
 }
@@ -2907,7 +1891,6 @@ static void test_domnode( void )
     LONG count;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     b = FALSE;
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
@@ -2969,6 +1952,7 @@ static void test_domnode( void )
         ok( r == E_FAIL, "getAttribute ret %08x\n", r );
         ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
         VariantClear(&var);
+        SysFreeString(str);
 
         str = SysAllocString( szdl );  
         V_VT(&var) = VT_I4;
@@ -3306,7 +2290,6 @@ static void test_refs(void)
     LONG ref;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     ptr = refcount_test;
     while (ptr->type != NODE_INVALID)
@@ -3444,7 +2427,6 @@ todo_wine {
     IUnknown_Release(unk);
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     EXPECT_REF(doc, 1);
     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
@@ -3525,18 +2507,18 @@ todo_wine {
     EXPECT_REF(elem2, 2);
 
     todo_wine ok(unk == unk2, "got %p and %p\n", unk, unk2);
-
     IUnknown_Release(unk);
-    IUnknown_Release(unk2);
 
     /* IUnknown refcount is not affected by node refcount */
-    todo_wine EXPECT_REF(unk2, 3);
+    todo_wine EXPECT_REF(unk2, 4);
     IXMLDOMElement_AddRef(elem2);
-    todo_wine EXPECT_REF(unk2, 3);
+    todo_wine EXPECT_REF(unk2, 4);
     IXMLDOMElement_Release(elem2);
 
     IXMLDOMElement_Release(elem2);
-    todo_wine EXPECT_REF(unk2, 2);
+    todo_wine EXPECT_REF(unk2, 3);
+
+    IUnknown_Release(unk2);
 
     hr = IXMLDOMElement_get_childNodes( element, &node_list );
     EXPECT_HR(hr, S_OK);
@@ -3611,7 +2593,6 @@ static void test_create(void)
     LONG num;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     EXPECT_REF(doc, 1);
 
@@ -4042,8 +3023,24 @@ static void test_create(void)
     IXMLDOMDocument_Release( doc );
 }
 
+struct queryresult_t {
+    const char *query;
+    const char *result;
+    int len;
+};
+
+static const struct queryresult_t elementsbytagname[] = {
+    { "",    "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 },
+    { "*",   "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
+    { "bs",  "E1.E2.D1", 1 },
+    { "dl",  "", 0 },
+    { "str1","", 0 },
+    { NULL }
+};
+
 static void test_getElementsByTagName(void)
 {
+    const struct queryresult_t *ptr = elementsbytagname;
     IXMLDOMNodeList *node_list;
     IXMLDOMDocument *doc;
     IXMLDOMElement *elem;
@@ -4054,28 +3051,29 @@ static void test_getElementsByTagName(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
     ok( b == VARIANT_TRUE, "failed to load XML string\n");
 
-    str = SysAllocString( szstar );
-
     /* null arguments cases */
     r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
     ok( r == E_INVALIDARG, "ret %08x\n", r );
-    r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
-    ok( r == E_INVALIDARG, "ret %08x\n", r );
-
-    r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
-    ok( r == S_OK, "ret %08x\n", r );
-    r = IXMLDOMNodeList_get_length( node_list, &len );
-    ok( r == S_OK, "ret %08x\n", r );
-    ok( len == 6, "len %d\n", len );
+    r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), NULL);
+    ok( r == E_INVALIDARG, "ret %08x\n", r );
 
-    IXMLDOMNodeList_Release( node_list );
-    SysFreeString( str );
+    while (ptr->query)
+    {
+        r = IXMLDOMDocument_getElementsByTagName(doc, _bstr_(ptr->query), &node_list);
+        ok(r == S_OK, "ret %08x\n", r);
+        r = IXMLDOMNodeList_get_length(node_list, &len);
+        ok(r == S_OK, "ret %08x\n", r);
+        ok(len == ptr->len, "%s: got len %d, expected %d\n", ptr->query, len, ptr->len);
+        expect_list_and_release(node_list, ptr->result);
+
+        free_bstrs();
+        ptr++;
+    }
 
     /* broken query BSTR */
     memcpy(&buff[2], szstar, sizeof(szstar));
@@ -4088,33 +3086,6 @@ static void test_getElementsByTagName(void)
     ok( len == 6, "len %d\n", len );
     IXMLDOMNodeList_Release( node_list );
 
-    str = SysAllocString( szbs );
-    r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
-    ok( r == S_OK, "ret %08x\n", r );
-    r = IXMLDOMNodeList_get_length( node_list, &len );
-    ok( r == S_OK, "ret %08x\n", r );
-    ok( len == 1, "len %d\n", len );
-    IXMLDOMNodeList_Release( node_list );
-    SysFreeString( str );
-
-    str = SysAllocString( szdl );
-    r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
-    ok( r == S_OK, "ret %08x\n", r );
-    r = IXMLDOMNodeList_get_length( node_list, &len );
-    ok( r == S_OK, "ret %08x\n", r );
-    ok( len == 0, "len %d\n", len );
-    IXMLDOMNodeList_Release( node_list );
-    SysFreeString( str );
-
-    str = SysAllocString( szstr1 );
-    r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
-    ok( r == S_OK, "ret %08x\n", r );
-    r = IXMLDOMNodeList_get_length( node_list, &len );
-    ok( r == S_OK, "ret %08x\n", r );
-    ok( len == 0, "len %d\n", len );
-    IXMLDOMNodeList_Release( node_list );
-    SysFreeString( str );
-
     /* test for element */
     r = IXMLDOMDocument_get_documentElement(doc, &elem);
     ok( r == S_OK, "ret %08x\n", r );
@@ -4166,7 +3137,6 @@ static void test_get_text(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4247,6 +3217,7 @@ static void test_get_text(void)
     free_bstrs();
 }
 
+#ifdef __REACTOS__
 /*
  * This function is to display that xmlnodelist_QueryInterface
  * generates SEGV for these conditions, and once fixed make sure
@@ -4270,6 +3241,7 @@ static void verify_nodelist_query_interface(IXMLDOMNodeList *node_list)
     hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IXMLDOMNodeList, NULL);
     EXPECT_NOT_HR(hr, S_OK);
 }
+#endif
 
 static void test_get_childNodes(void)
 {
@@ -4286,7 +3258,6 @@ static void test_get_childNodes(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     EXPECT_HR(hr, S_OK);
@@ -4298,7 +3269,9 @@ static void test_get_childNodes(void)
     hr = IXMLDOMElement_get_childNodes( element, &node_list );
     EXPECT_HR(hr, S_OK);
 
+#ifdef __REACTOS__
     verify_nodelist_query_interface(node_list);
+#endif
 
     hr = IXMLDOMNodeList_get_length( node_list, &len );
     EXPECT_HR(hr, S_OK);
@@ -4439,7 +3412,7 @@ static void test_get_childNodes(void)
 
 static void test_get_firstChild(void)
 {
-    static WCHAR xmlW[] = {'x','m','l',0};
+    static const WCHAR xmlW[] = {'x','m','l',0};
     IXMLDOMDocument *doc;
     IXMLDOMNode *node;
     VARIANT_BOOL b;
@@ -4447,7 +3420,6 @@ static void test_get_firstChild(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4470,8 +3442,8 @@ static void test_get_firstChild(void)
 
 static void test_get_lastChild(void)
 {
-    static WCHAR lcW[] = {'l','c',0};
-    static WCHAR foW[] = {'f','o',0};
+    static const WCHAR lcW[] = {'l','c',0};
+    static const WCHAR foW[] = {'f','o',0};
     IXMLDOMDocument *doc;
     IXMLDOMNode *node, *child;
     VARIANT_BOOL b;
@@ -4479,7 +3451,6 @@ static void test_get_lastChild(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4520,7 +3491,6 @@ static void test_removeChild(void)
     IXMLDOMNodeList *root_list, *fo_list;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4622,7 +3592,6 @@ static void test_replaceChild(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4736,7 +3705,6 @@ static void test_removeNamedItem(void)
     HRESULT r;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     r = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( r == S_OK, "loadXML failed\n");
@@ -4939,386 +3907,6 @@ static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
              "got %08x\n", supported);
 }
 
-static void test_XMLHTTP(void)
-{
-    static const char bodyA[] = "mode=Test";
-    static const char urlA[] = "http://crossover.codeweavers.com/posttest.php";
-    static const char xmltestA[] = "http://crossover.codeweavers.com/xmltest.xml";
-    static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
-    static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
-
-    IXMLHttpRequest *xhr;
-    IObjectSafety *safety;
-    IObjectWithSite *obj_site, *obj_site2;
-    BSTR bstrResponse, str, str1;
-    VARIANT varbody, varbody_ref;
-    VARIANT dummy;
-    VARIANT async;
-    LONG state, status, bound;
-    IDispatch *event;
-    void *ptr;
-    HRESULT hr;
-    HGLOBAL g;
-
-    hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
-        &IID_IXMLHttpRequest, (void**)&xhr);
-    if (FAILED(hr))
-    {
-        win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
-        return;
-    }
-
-    VariantInit(&dummy);
-    V_VT(&dummy) = VT_ERROR;
-    V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
-    VariantInit(&async);
-    V_VT(&async) = VT_BOOL;
-    V_BOOL(&async) = VARIANT_FALSE;
-
-    hr = IXMLHttpRequest_put_onreadystatechange(xhr, NULL);
-    EXPECT_HR(hr, S_OK);
-
-    hr = IXMLHttpRequest_abort(xhr);
-    EXPECT_HR(hr, S_OK);
-
-    V_VT(&varbody) = VT_I2;
-    V_I2(&varbody) = 1;
-    hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
-    EXPECT_HR(hr, E_PENDING);
-    ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
-    ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
-
-    V_VT(&varbody) = VT_I2;
-    V_I2(&varbody) = 1;
-    hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
-    EXPECT_HR(hr, E_PENDING);
-    ok(V_VT(&varbody) == VT_EMPTY, "got type %d\n", V_VT(&varbody));
-    ok(V_I2(&varbody) == 1, "got %d\n", V_I2(&varbody));
-
-    /* send before open */
-    hr = IXMLHttpRequest_send(xhr, dummy);
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-
-    /* initial status code */
-    hr = IXMLHttpRequest_get_status(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    status = 0xdeadbeef;
-    hr = IXMLHttpRequest_get_status(xhr, &status);
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-    ok(status == 0xdeadbeef, "got %d\n", status);
-
-    hr = IXMLHttpRequest_get_statusText(xhr, &str);
-    ok(hr == E_FAIL, "got 0x%08x\n", hr);
-
-    /* invalid parameters */
-    hr = IXMLHttpRequest_open(xhr, NULL, NULL, async, dummy, dummy);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), NULL, async, dummy, dummy);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_open(xhr, NULL, _bstr_(urlA), async, dummy, dummy);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), NULL);
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-
-    hr = IXMLHttpRequest_get_readyState(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    state = -1;
-    hr = IXMLHttpRequest_get_readyState(xhr, &state);
-    EXPECT_HR(hr, S_OK);
-    ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
-
-    event = create_dispevent();
-
-    EXPECT_REF(event, 1);
-    hr = IXMLHttpRequest_put_onreadystatechange(xhr, event);
-    EXPECT_HR(hr, S_OK);
-    EXPECT_REF(event, 2);
-
-    g_unexpectedcall = g_expectedcall = 0;
-
-    hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
-    EXPECT_HR(hr, S_OK);
-
-    ok(g_unexpectedcall == 0, "unexpected disp event call\n");
-    ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
-
-    /* status code after ::open() */
-    status = 0xdeadbeef;
-    hr = IXMLHttpRequest_get_status(xhr, &status);
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-    ok(status == 0xdeadbeef, "got %d\n", status);
-
-    state = -1;
-    hr = IXMLHttpRequest_get_readyState(xhr, &state);
-    EXPECT_HR(hr, S_OK);
-    ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
-
-    hr = IXMLHttpRequest_abort(xhr);
-    EXPECT_HR(hr, S_OK);
-
-    state = -1;
-    hr = IXMLHttpRequest_get_readyState(xhr, &state);
-    EXPECT_HR(hr, S_OK);
-    ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
-        "got %d, expected READYSTATE_UNINITIALIZED\n", state);
-
-    hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
-    EXPECT_HR(hr, S_OK);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_("header1"), _bstr_("value1"));
-    EXPECT_HR(hr, S_OK);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, NULL, _bstr_("value1"));
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_setRequestHeader(xhr, _bstr_(""), _bstr_("value1"));
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    V_VT(&varbody) = VT_BSTR;
-    V_BSTR(&varbody) = _bstr_(bodyA);
-
-    hr = IXMLHttpRequest_send(xhr, varbody);
-    if (hr == INET_E_RESOURCE_NOT_FOUND)
-    {
-        skip("No connection could be made with crossover.codeweavers.com\n");
-        IXMLHttpRequest_Release(xhr);
-        return;
-    }
-    EXPECT_HR(hr, S_OK);
-
-    /* response headers */
-    hr = IXMLHttpRequest_getAllResponseHeaders(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-    hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str);
-    EXPECT_HR(hr, S_OK);
-    /* status line is stripped already */
-    ok(memcmp(str, _bstr_("HTTP"), 4*sizeof(WCHAR)), "got response headers %s\n", wine_dbgstr_w(str));
-    ok(*str, "got empty headers\n");
-    hr = IXMLHttpRequest_getAllResponseHeaders(xhr, &str1);
-    EXPECT_HR(hr, S_OK);
-    ok(str1 != str, "got %p\n", str1);
-    SysFreeString(str1);
-    SysFreeString(str);
-
-    hr = IXMLHttpRequest_getResponseHeader(xhr, NULL, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-    hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-    hr = IXMLHttpRequest_getResponseHeader(xhr, _bstr_("Date"), &str);
-    EXPECT_HR(hr, S_OK);
-    ok(*str != ' ', "got leading space in header %s\n", wine_dbgstr_w(str));
-    SysFreeString(str);
-
-    /* status code after ::send() */
-    status = 0xdeadbeef;
-    hr = IXMLHttpRequest_get_status(xhr, &status);
-    EXPECT_HR(hr, S_OK);
-    ok(status == 200, "got %d\n", status);
-
-    hr = IXMLHttpRequest_get_statusText(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_get_statusText(xhr, &str);
-    EXPECT_HR(hr, S_OK);
-    ok(!lstrcmpW(str, _bstr_("OK")), "got status %s\n", wine_dbgstr_w(str));
-    SysFreeString(str);
-
-    /* another ::send() after completed request */
-    V_VT(&varbody) = VT_BSTR;
-    V_BSTR(&varbody) = _bstr_(bodyA);
-
-    hr = IXMLHttpRequest_send(xhr, varbody);
-    ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
-
-    hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
-    EXPECT_HR(hr, S_OK);
-    /* the server currently returns "FAILED" because the Content-Type header is
-     * not what the server expects */
-    if(hr == S_OK)
-    {
-        ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
-            "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
-        SysFreeString(bstrResponse);
-    }
-
-    /* POST: VT_VARIANT|VT_BYREF body */
-    V_VT(&varbody_ref) = VT_VARIANT|VT_BYREF;
-    V_VARIANTREF(&varbody_ref) = &varbody;
-    hr = IXMLHttpRequest_open(xhr, _bstr_("POST"), _bstr_(urlA), async, dummy, dummy);
-    EXPECT_HR(hr, S_OK);
-    hr = IXMLHttpRequest_send(xhr, varbody_ref);
-    EXPECT_HR(hr, S_OK);
-
-    /* GET request */
-    hr = IXMLHttpRequest_open(xhr, _bstr_("GET"), _bstr_(xmltestA), async, dummy, dummy);
-    EXPECT_HR(hr, S_OK);
-
-    V_VT(&varbody) = VT_EMPTY;
-
-    hr = IXMLHttpRequest_send(xhr, varbody);
-    if (hr == INET_E_RESOURCE_NOT_FOUND)
-    {
-        skip("No connection could be made with crossover.codeweavers.com\n");
-        IXMLHttpRequest_Release(xhr);
-        return;
-    }
-    EXPECT_HR(hr, S_OK);
-
-    hr = IXMLHttpRequest_get_responseText(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    hr = IXMLHttpRequest_get_responseText(xhr, &bstrResponse);
-    EXPECT_HR(hr, S_OK);
-    ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
-        "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
-    SysFreeString(bstrResponse);
-
-    hr = IXMLHttpRequest_get_responseBody(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    V_VT(&varbody) = VT_EMPTY;
-    hr = IXMLHttpRequest_get_responseBody(xhr, &varbody);
-    EXPECT_HR(hr, S_OK);
-    ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
-    ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
-
-    bound = -1;
-    hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
-    EXPECT_HR(hr, S_OK);
-    ok(bound == 0, "got %d, expected zero bound\n", bound);
-
-    hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
-    EXPECT_HR(hr, S_OK);
-    ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrong body data\n");
-    SafeArrayUnaccessData(V_ARRAY(&varbody));
-
-    VariantClear(&varbody);
-
-    /* get_responseStream */
-    hr = IXMLHttpRequest_get_responseStream(xhr, NULL);
-    EXPECT_HR(hr, E_INVALIDARG);
-
-    V_VT(&varbody) = VT_EMPTY;
-    hr = IXMLHttpRequest_get_responseStream(xhr, &varbody);
-    ok(V_VT(&varbody) == VT_UNKNOWN, "got type %d\n", V_VT(&varbody));
-    EXPECT_HR(hr, S_OK);
-    EXPECT_REF(V_UNKNOWN(&varbody), 1);
-
-    g = NULL;
-    hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g);
-    EXPECT_HR(hr, S_OK);
-    ok(g != NULL, "got %p\n", g);
-
-    hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectSafety, (void**)&safety);
-    EXPECT_HR(hr, S_OK);
-    if(hr == S_OK)
-    {
-        test_IObjectSafety_common(safety);
-        IObjectSafety_Release(safety);
-    }
-
-    IDispatch_Release(event);
-
-    /* interaction with object site */
-    EXPECT_REF(xhr, 1);
-    hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site);
-    EXPECT_HR(hr, S_OK);
-todo_wine {
-    EXPECT_REF(xhr, 1);
-    EXPECT_REF(obj_site, 1);
-}
-
-    IObjectWithSite_AddRef(obj_site);
-todo_wine {
-    EXPECT_REF(obj_site, 2);
-    EXPECT_REF(xhr, 1);
-}
-    IObjectWithSite_Release(obj_site);
-
-    hr = IXMLHttpRequest_QueryInterface(xhr, &IID_IObjectWithSite, (void**)&obj_site2);
-    EXPECT_HR(hr, S_OK);
-todo_wine {
-    EXPECT_REF(xhr, 1);
-    EXPECT_REF(obj_site, 1);
-    EXPECT_REF(obj_site2, 1);
-    ok(obj_site != obj_site2, "expected new instance\n");
-}
-    SET_EXPECT(site_qi_IServiceProvider);
-    SET_EXPECT(sp_queryservice_SID_SBindHost);
-    SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-    SET_EXPECT(sp_queryservice_SID_secmgr_htmldoc2);
-    SET_EXPECT(sp_queryservice_SID_secmgr_xmldomdoc);
-    SET_EXPECT(sp_queryservice_SID_secmgr_secmgr);
-
-    /* calls to IHTMLDocument2 */
-    SET_EXPECT(htmldoc2_get_all);
-    SET_EXPECT(collection_get_length);
-    SET_EXPECT(htmldoc2_get_url);
-
-    SET_EXPECT(site_qi_IXMLDOMDocument);
-    SET_EXPECT(site_qi_IOleClientSite);
-
-    hr = IObjectWithSite_SetSite(obj_site, &testsite.IUnknown_iface);
-    EXPECT_HR(hr, S_OK);
-
-    CHECK_CALLED(site_qi_IServiceProvider);
-todo_wine
-    CHECK_CALLED(sp_queryservice_SID_SBindHost);
-    CHECK_CALLED(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-todo_wine {
-    CHECK_CALLED(sp_queryservice_SID_secmgr_htmldoc2);
-    CHECK_CALLED(sp_queryservice_SID_secmgr_xmldomdoc);
-    /* this one isn't very reliable
-    CHECK_CALLED(sp_queryservice_SID_secmgr_secmgr); */
-
-    CHECK_CALLED(htmldoc2_get_all);
-    CHECK_CALLED(collection_get_length);
-    CHECK_CALLED(htmldoc2_get_url);
-
-    CHECK_CALLED(site_qi_IXMLDOMDocument);
-    CHECK_CALLED(site_qi_IOleClientSite);
-}
-    IObjectWithSite_Release(obj_site);
-
-    /* try to set site another time */
-
-    /* to be removed once IObjectWithSite is properly separated */
-    SET_EXPECT(site_qi_IServiceProvider);
-    SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-
-    hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
-    EXPECT_HR(hr, S_OK);
-
-    todo_wine EXPECT_REF(xhr, 1);
-    IXMLHttpRequest_Release(xhr);
-
-    /* still works after request is released */
-
-    /* to be removed once IObjectWithSite is properly separated */
-    SET_EXPECT(site_qi_IServiceProvider);
-    SET_EXPECT(sp_queryservice_SID_SContainerDispatch_htmldoc2);
-
-    hr = IObjectWithSite_SetSite(obj_site2, &testsite.IUnknown_iface);
-    EXPECT_HR(hr, S_OK);
-    IObjectWithSite_Release(obj_site2);
-
-    free_bstrs();
-}
-
 static void test_IXMLDOMDocument2(void)
 {
     static const WCHAR emptyW[] = {0};
@@ -5331,15 +3919,10 @@ static void test_IXMLDOMDocument2(void)
     HRESULT r;
     LONG res;
 
-    doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
 
+    doc = create_document(&IID_IXMLDOMDocument);
     dtddoc2 = create_document(&IID_IXMLDOMDocument2);
-    if (!dtddoc2)
-    {
-        IXMLDOMDocument_Release(doc);
-        return;
-    }
 
     r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
     ok( r == S_OK, "ret %08x\n", r );
@@ -5678,14 +4261,66 @@ static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char con
     IXMLDOMNode_Release(node2);
 }
 
-static void test_whitespace(void)
+static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
 {
+    static const WCHAR b1_p[] = {' ','T','e','x','t',' ','A',' ','e','n','d',' ',0};
+    static const WCHAR b1_i[] = {'T','e','x','t',' ','A',' ','e','n','d',0};
+    static const WCHAR b2_p[] = {'A','B',' ','C',' ',0};
+    static const WCHAR b2_i[] = {'A','B',' ','C',0};
+    IXMLDOMNodeList *list;
+    IXMLDOMElement *root;
+    IXMLDOMNode *node;
+    const WCHAR *text;
     VARIANT_BOOL b;
+    HRESULT hr;
+    BSTR s;
+
+    hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc, preserve);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument2_loadXML(doc, _bstr_(charrefsxml), &b);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument2_get_documentElement(doc, &root);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMElement_get_childNodes(root, &list);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IXMLDOMElement_Release(root);
+
+    text = preserve == VARIANT_TRUE ? b1_p : b1_i;
+    hr = IXMLDOMNodeList_get_item(list, 0, &node);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMNode_get_text(node, &s);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
+    SysFreeString(s);
+    IXMLDOMNode_Release(node);
+
+    text = preserve == VARIANT_TRUE ? b2_p : b2_i;
+    hr = IXMLDOMNodeList_get_item(list, 1, &node);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMNode_get_text(node, &s);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(s, text), "0x%x, got %s\n", preserve, wine_dbgstr_w(s));
+    SysFreeString(s);
+    IXMLDOMNode_Release(node);
+
+    IXMLDOMNodeList_Release(list);
+}
+
+static void test_whitespace(void)
+{
     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
+    IXMLDOMNodeList *list;
+    IXMLDOMElement *root;
+    VARIANT_BOOL b;
+    HRESULT hr;
+    LONG len;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
     doc1 = create_document(&IID_IXMLDOMDocument2);
     doc2 = create_document(&IID_IXMLDOMDocument2);
-    if (!doc1 || !doc2) return;
 
     ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
     ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
@@ -5748,10 +4383,35 @@ static void test_whitespace(void)
     check_ws_preserved(doc3, NULL);
     check_ws_ignored(doc4, NULL);
 
+    IXMLDOMDocument2_Release(doc2);
+    IXMLDOMDocument2_Release(doc3);
+    IXMLDOMDocument2_Release(doc4);
+
+    /* text with char references */
+    test_preserve_charref(doc1, VARIANT_TRUE);
+    test_preserve_charref(doc1, VARIANT_FALSE);
+
+    /* formatting whitespaces */
+    hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(b == VARIANT_TRUE, "for %x\n", b);
+
+    hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMElement_get_childNodes(root, &list);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    len = 0;
+    hr = IXMLDOMNodeList_get_length(list, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == 3, "got %d\n", len);
+    IXMLDOMNodeList_Release(list);
+    IXMLDOMElement_Release(root);
+
     IXMLDOMDocument2_Release(doc1);
-    IXMLDOMDocument2_Release(doc2);
-    IXMLDOMDocument2_Release(doc3);
-    IXMLDOMDocument2_Release(doc4);
+
     free_bstrs();
 }
 
@@ -5792,9 +4452,50 @@ static const selection_ns_t selection_ns_data[] = {
     { NULL }
 };
 
+typedef struct {
+    const char *query;
+    const char *list;
+} xpath_test_t;
+
+static const xpath_test_t xpath_test[] = {
+    { "*/a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
+    { "*/b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
+    { "*/c", "E3.E1.E2.D1 E3.E2.E2.D1" },
+    { "*/d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
+    { "//a", "E1.E1.E2.D1 E1.E2.E2.D1 E1.E4.E2.D1" },
+    { "//b", "E2.E1.E2.D1 E2.E2.E2.D1 E2.E4.E2.D1" },
+    { "//c", "E3.E1.E2.D1 E3.E2.E2.D1" },
+    { "//d", "E4.E1.E2.D1 E4.E2.E2.D1 E4.E4.E2.D1" },
+    { "//c[@type]", "E3.E2.E2.D1" },
+    { "//c[@type]/ancestor::node()[1]", "E2.E2.D1" },
+    { "//c[@type]/ancestor-or-self::node()[1]", "E3.E2.E2.D1" },
+    { "//c[@type]/attribute::node()[1]", "A'type'.E3.E2.E2.D1" },
+    { "//c[@type]/child::node()[1]", "T1.E3.E2.E2.D1"  },
+    { "//c[@type]/descendant::node()[1]", "T1.E3.E2.E2.D1" },
+    { "//c[@type]/descendant-or-self::node()[1]", "E3.E2.E2.D1" },
+    { "//c[@type]/following::node()[1]", "E4.E2.E2.D1" },
+    { "//c[@type]/following-sibling::node()[1]", "E4.E2.E2.D1" },
+    { "//c[@type]/parent::node()[1]", "E2.E2.D1" },
+    { "//c[@type]/preceding::node()[1]", "T1.E2.E2.E2.D1" },
+    { "//c[@type]/self::node()[1]", "E3.E2.E2.D1" },
+    { "child::*", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
+    { "child::node()", "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1" },
+    { "child::text()", "" },
+    { "child::*/..", "E2.D1" },
+    { "child::*//@*/..", "E2.E5.E1.E2.D1 E2.E2.D1 E3.E2.E2.D1" },
+    { "self::node()", "E2.D1" },
+    { "ancestor::node()", "D1" },
+    { "elem[c][last()]/a", "E1.E2.E2.D1"},
+    { "ancestor-or-self::node()[1]", "E2.D1" },
+    { "((//a)[1])[last()]", "E1.E1.E2.D1" },
+    { "//elem[@*]", "E2.E2.D1" },
+    { NULL }
+};
+
 static void test_XPath(void)
 {
     const selection_ns_t *ptr = selection_ns_data;
+    const xpath_test_t *xptest = xpath_test;
     VARIANT var;
     VARIANT_BOOL b;
     IXMLDOMDocument2 *doc;
@@ -5810,8 +4511,8 @@ static void test_XPath(void)
     LONG len;
     BSTR str;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
     doc = create_document(&IID_IXMLDOMDocument2);
-    if (!doc) return;
 
     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
     EXPECT_HR(hr, S_OK);
@@ -5837,6 +4538,26 @@ static void test_XPath(void)
     EXPECT_HR(hr, S_OK);
     expect_list_and_release(list, "E2.D1");
 
+    /* peform xpath tests */
+    for ( ; xptest->query ; xptest++ )
+    {
+        char *str;
+
+        hr = IXMLDOMNode_selectNodes(rootNode, _bstr_(xptest->query), &list);
+        ok(hr == S_OK, "query evaluation failed for query=%s\n", xptest->query);
+
+        if (hr != S_OK)
+            continue;
+
+        str = list_to_string(list);
+
+        ok(!strcmp(str, xptest->list), "query=%s, invalid node list: \"%s\", expected \"%s\"\n",
+            xptest->query, str, xptest->list);
+
+        if (list)
+            IXMLDOMNodeList_Release(list);
+    }
+
 if (0)
 {
     /* namespace:: axis test is disabled until namespace definitions
@@ -6053,10 +4774,13 @@ if (0)
 
     while (ptr->clsid)
     {
-        hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
-        if (hr != S_OK)
+        if (is_clsid_supported(ptr->clsid, &IID_IXMLDOMDocument2))
+        {
+            hr = CoCreateInstance(ptr->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
+            ok(hr == S_OK, "got 0x%08x\n", hr);
+        }
+        else
         {
-            win_skip("can't create instance of %s\n", ptr->name);
             ptr++;
             continue;
         }
@@ -6102,13 +4826,12 @@ static void test_cloneNode(void )
     IXMLDOMNamedNodeMap *mapAttr;
     LONG length, length1;
     LONG attr_cnt, attr_cnt1;
-    IXMLDOMNode *node;
+    IXMLDOMNode *node, *attr;
     IXMLDOMNode *node_clone;
     IXMLDOMNode *node_first;
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b));
     ok(b == VARIANT_TRUE, "failed to load XML string\n");
@@ -6163,6 +4886,11 @@ static void test_cloneNode(void )
     hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
     ok( hr == S_OK, "ret %08x\n", hr );
     ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
+    /* now really get some attributes from cloned element */
+    attr = NULL;
+    hr = IXMLDOMNamedNodeMap_getNamedItem(mapAttr, _bstr_("id"), &attr);
+    ok(hr == S_OK, "ret %08x\n", hr);
+    IXMLDOMNode_Release(attr);
     IXMLDOMNamedNodeMap_Release(mapAttr);
 
     ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
@@ -6219,7 +4947,6 @@ static void test_xmlTypes(void)
     LONG len = 0;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     pNextChild = (void*)0xdeadbeef;
     hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
@@ -7191,7 +5918,6 @@ static void test_put_dataType( void )
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
     EXPECT_HR(hr, E_INVALIDARG);
@@ -7274,6 +6000,7 @@ static void test_put_dataType( void )
     free_bstrs();
 }
 
+#if CORE_6738_IS_FIXED
 static void test_save(void)
 {
     IXMLDOMDocument *doc, *doc2;
@@ -7290,14 +6017,7 @@ static void test_save(void)
     char *ptr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
-
     doc2 = create_document(&IID_IXMLDOMDocument);
-    if (!doc2)
-    {
-        IXMLDOMDocument_Release(doc);
-        return;
-    }
 
     /* save to IXMLDOMDocument */
     hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
@@ -7342,7 +6062,7 @@ static void test_save(void)
     ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
 
     CloseHandle(hfile);
-    DeleteFile("test.xml");
+    DeleteFileA("test.xml");
 
     /* save to path VT_BSTR | VT_BYREF */
     filename = _bstr_("test.xml");
@@ -7363,7 +6083,7 @@ static void test_save(void)
        ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
 
        CloseHandle(hfile);
-       DeleteFile("test.xml");
+       DeleteFileA("test.xml");
     }
 
     /* save to stream */
@@ -7394,7 +6114,8 @@ static void test_save(void)
     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<a/>"), &b);
     EXPECT_HR(hr, S_OK);
 
-    CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     V_VT(&dest) = VT_UNKNOWN;
     V_UNKNOWN(&dest) = (IUnknown*)stream;
     hr = IXMLDOMDocument_save(doc, dest);
@@ -7410,24 +6131,17 @@ static void test_save(void)
     IXMLDOMDocument_Release(doc);
     free_bstrs();
 }
+#endif /* CORE_6738_IS_FIXED */
 
 static void test_testTransforms(void)
 {
     IXMLDOMDocument *doc, *docSS;
     IXMLDOMNode *pNode;
     VARIANT_BOOL bSucc;
-
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
-
     docSS = create_document(&IID_IXMLDOMDocument);
-    if (!docSS)
-    {
-        IXMLDOMDocument_Release(doc);
-        return;
-    }
 
     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
     ok(hr == S_OK, "ret %08x\n", hr );
@@ -7445,7 +6159,7 @@ static void test_testTransforms(void)
         ok(hr == S_OK, "ret %08x\n", hr );
         if(hr == S_OK)
         {
-            ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
+            ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "got output %s\n", wine_dbgstr_w(bOut));
             SysFreeString(bOut);
         }
 
@@ -7487,15 +6201,16 @@ static void test_namespaces_change(void)
         HRESULT hr;
         BSTR str;
 
-        hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
-                              &IID_IXMLDOMDocument, (void**)&doc);
-        if (hr != S_OK)
+        if (!is_clsid_supported(class_ptr->clsid, &IID_IXMLDOMDocument))
         {
-            win_skip("failed to create class instance for %s\n", class_ptr->name);
             class_ptr++;
             continue;
         }
 
+        hr = CoCreateInstance(class_ptr->clsid, NULL, CLSCTX_INPROC_SERVER,
+                              &IID_IXMLDOMDocument, (void**)&doc);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
         V_VT(&var) = VT_I2;
         V_I2(&var) = NODE_ELEMENT;
 
@@ -7556,7 +6271,6 @@ static void test_namespaces_basic(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML(doc, _bstr_(namespaces_xmlA), &b);
     EXPECT_HR(hr, S_OK);
@@ -7642,7 +6356,6 @@ static void test_FormattingXML(void)
     static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
     ok(hr == S_OK, "ret %08x\n", hr );
@@ -7718,7 +6431,6 @@ static void test_nodeTypedValue(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     b = VARIANT_FALSE;
     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
@@ -7936,7 +6648,7 @@ static void test_TransformWithLoadingLocalFile(void)
     WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
     CloseHandle(file);
 
-    /* Correct path to not include a escape character. */
+    /* Correct path to not include an escape character. */
     for(i=0; i < strlen(lpPathBuffer); i++)
     {
         if(lpPathBuffer[i] == '\\')
@@ -7944,14 +6656,7 @@ static void test_TransformWithLoadingLocalFile(void)
     }
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
-
     xsl = create_document(&IID_IXMLDOMDocument);
-    if (!xsl)
-    {
-        IXMLDOMDocument_Release(doc);
-        return;
-    }
 
     hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
     ok(hr == S_OK, "ret %08x\n", hr );
@@ -7999,7 +6704,7 @@ static void test_TransformWithLoadingLocalFile(void)
     IXMLDOMDocument_Release(doc);
     IXMLDOMDocument_Release(xsl);
 
-    DeleteFile(lpPathBuffer);
+    DeleteFileA(lpPathBuffer);
     free_bstrs();
 }
 
@@ -8015,7 +6720,6 @@ static void test_put_nodeValue(void)
     VARIANT data, type;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     /* test for unsupported types */
     /* NODE_DOCUMENT */
@@ -8094,14 +6798,13 @@ static void test_put_nodeValue(void)
     IXMLDOMDocument_Release(doc);
 }
 
-static void test_document_IObjectSafety(void)
+static void test_IObjectSafety(void)
 {
     IXMLDOMDocument *doc;
     IObjectSafety *safety;
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
     ok(hr == S_OK, "ret %08x\n", hr );
@@ -8109,8 +6812,16 @@ static void test_document_IObjectSafety(void)
     test_IObjectSafety_common(safety);
 
     IObjectSafety_Release(safety);
-
     IXMLDOMDocument_Release(doc);
+
+    hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER,
+        &IID_IObjectSafety, (void**)&safety);
+    ok(hr == S_OK, "Could not create XMLHTTPRequest instance: %08x\n", hr);
+
+    test_IObjectSafety_common(safety);
+
+    IObjectSafety_Release(safety);
+
 }
 
 typedef struct _property_test_t {
@@ -8139,14 +6850,15 @@ static void test_default_properties(void)
         VARIANT var;
         HRESULT hr;
 
-        hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
-        if (hr != S_OK)
+        if (!is_clsid_supported(entry->guid, &IID_IXMLDOMDocument2))
         {
-            win_skip("can't create %s instance\n", entry->clsid);
             entry++;
             continue;
         }
 
+        hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
         hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
         ok(hr == S_OK, "got 0x%08x\n", hr);
         ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
@@ -8162,6 +6874,7 @@ static void test_default_properties(void)
 typedef struct {
     const char *query;
     const char *list;
+    BOOL todo;
 } xslpattern_test_t;
 
 static const xslpattern_test_t xslpattern_test[] = {
@@ -8224,6 +6937,7 @@ static const xslpattern_test_t xslpattern_test[] = {
     { "root/elem[index()>0 $and$ $not$ end()]", "E2.E2.D1 E3.E2.D1" },
     { "root/elem[index()>0 && $not$ end()]", "E2.E2.D1 E3.E2.D1" },
     { "root/elem[d]", "E1.E2.D1 E2.E2.D1 E4.E2.D1" },
+    { "root/elem[@*]", "E2.E2.D1 E3.E2.D1", TRUE },
     { NULL }
 };
 
@@ -8272,7 +6986,6 @@ static void test_XSLPattern(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument2);
-    if (!doc) return;
 
     b = VARIANT_FALSE;
     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
@@ -8302,8 +7015,16 @@ static void test_XSLPattern(void)
         len = 0;
         hr = IXMLDOMNodeList_get_length(list, &len);
         ok(len != 0, "query=%s, empty list\n", ptr->query);
-        if (len)
-            expect_list_and_release(list, ptr->list);
+        if (len) {
+            if (ptr->todo) {
+                char *str = list_to_string(list);
+            todo_wine
+                ok(!strcmp(str, ptr->list), "Invalid node list: %s, expected %s\n", str, ptr->list);
+                IXMLDOMNodeList_Release(list);
+            }
+            else
+                expect_list_and_release(list, ptr->list);
+        }
 
         ptr++;
     }
@@ -8369,7 +7090,6 @@ static void test_XSLPattern(void)
     IXMLDOMDocument2_Release(doc);
 
     doc = create_document(&IID_IXMLDOMDocument2);
-    if (!doc) return;
 
     hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b);
     EXPECT_HR(hr, S_OK);
@@ -8417,7 +7137,6 @@ static void test_splitText(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -8562,7 +7281,6 @@ static void test_getQualifiedItem(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     EXPECT_HR(hr, S_OK);
@@ -8663,7 +7381,6 @@ static void test_removeQualifiedItem(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( hr == S_OK, "loadXML failed\n");
@@ -8800,14 +7517,11 @@ static void test_get_ownerDocument(void)
     VARIANT_BOOL b;
     VARIANT var;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
+    if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
+
     doc = create_document(&IID_IXMLDOMDocument2);
     cache = create_cache(&IID_IXMLDOMSchemaCollection);
-    if (!doc || !cache)
-    {
-        if (doc) IXMLDOMDocument2_Release(doc);
-        if (cache) IXMLDOMSchemaCollection_Release(cache);
-        return;
-    }
 
     VariantInit(&var);
 
@@ -8875,7 +7589,6 @@ static void test_setAttributeNode(void)
     ULONG ref1, ref2;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_loadXML( doc, _bstr_(complete4A), &b );
     ok( hr == S_OK, "loadXML failed\n");
@@ -9021,7 +7734,6 @@ static void test_createNode(void)
     ULONG ref;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     EXPECT_REF(doc, 1);
 
@@ -9111,7 +7823,6 @@ static void test_get_prefix(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     /* nodes that can't support prefix */
     /* 1. document */
@@ -9223,7 +7934,6 @@ static void test_selectSingleNode(void)
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
@@ -9288,7 +7998,6 @@ static void test_events(void)
     IDispatch *event;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -9357,7 +8066,6 @@ static void test_createProcessingInstruction(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     /* test for BSTR handling, pass broken BSTR */
     memcpy(&buff[2], bodyW, sizeof(bodyW));
@@ -9385,7 +8093,6 @@ static void test_put_nodeTypedValue(void)
     BSTR str;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
     EXPECT_HR(hr, S_OK);
@@ -9461,6 +8168,7 @@ static void test_put_nodeTypedValue(void)
     EXPECT_HR(hr, S_OK);
     ok(!lstrcmpW(str, _bstr_("ABCD")), "%s\n", wine_dbgstr_w(str));
     IXMLDOMNode_Release(node);
+    SysFreeString(str);
 
     array = SafeArrayCreateVector(VT_UI1, 0, 7);
     hr = SafeArrayAccessData(array, (void*)&ptr);
@@ -9500,6 +8208,7 @@ static void test_put_nodeTypedValue(void)
     ok(!lstrcmpW(str, _bstr_("ZEdWemRBPQ==")), "%s\n", wine_dbgstr_w(str));
     IXMLDOMNode_Release(node);
     SafeArrayDestroyData(array);
+    SysFreeString(str);
 
     /* bin.hex */
     V_VT(&value) = VT_BSTR;
@@ -9548,6 +8257,7 @@ static void test_put_nodeTypedValue(void)
     ok(!lstrcmpW(str, _bstr_("000102030405060708090a0b0c0d0e0f")), "%s\n", wine_dbgstr_w(str));
     IXMLDOMNode_Release(node);
     SafeArrayDestroyData(array);
+    SysFreeString(str);
 
     IXMLDOMElement_Release(elem);
     IXMLDOMDocument_Release(doc);
@@ -9557,10 +8267,15 @@ static void test_put_nodeTypedValue(void)
 static void test_get_xml(void)
 {
     static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
+    static const char attrA[] = "attr=\"&quot;a &amp; b&quot;\"";
+    static const char attr2A[] = "\"a & b\"";
+    static const char attr3A[] = "attr=\"&amp;quot;a\"";
+    static const char attr4A[] = "&quot;a";
     static const char fooA[] = "<foo/>";
     IXMLDOMProcessingInstruction *pi;
     IXMLDOMNode *first;
     IXMLDOMElement *elem = NULL;
+    IXMLDOMAttribute *attr;
     IXMLDOMDocument *doc;
     VARIANT_BOOL b;
     VARIANT v;
@@ -9568,7 +8283,6 @@ static void test_get_xml(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     b = VARIANT_TRUE;
     hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
@@ -9616,6 +8330,51 @@ static void test_get_xml(void)
     SysFreeString(xml);
 
     IXMLDOMElement_Release(elem);
+
+    /* attribute node */
+    hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = _bstr_("\"a & b\"");
+    hr = IXMLDOMAttribute_put_value(attr, v);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    xml = NULL;
+    hr = IXMLDOMAttribute_get_xml(attr, &xml);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!memcmp(xml, _bstr_(attrA), (sizeof(attrA)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
+    SysFreeString(xml);
+
+    VariantInit(&v);
+    hr = IXMLDOMAttribute_get_value(attr, &v);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
+    ok(!memcmp(V_BSTR(&v), _bstr_(attr2A), (sizeof(attr2A)-1)*sizeof(WCHAR)),
+        "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = _bstr_("&quot;a");
+    hr = IXMLDOMAttribute_put_value(attr, v);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    xml = NULL;
+    hr = IXMLDOMAttribute_get_xml(attr, &xml);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!memcmp(xml, _bstr_(attr3A), (sizeof(attr3A)-1)*sizeof(WCHAR)), "got %s\n", wine_dbgstr_w(xml));
+    SysFreeString(xml);
+
+    VariantInit(&v);
+    hr = IXMLDOMAttribute_get_value(attr, &v);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
+    ok(!memcmp(V_BSTR(&v), _bstr_(attr4A), (sizeof(attr4A)-1)*sizeof(WCHAR)),
+        "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    IXMLDOMAttribute_Release(attr);
+
     IXMLDOMDocument_Release(doc);
 
     free_bstrs();
@@ -9632,8 +8391,8 @@ static void test_xsltemplate(void)
     ULONG ref1, ref2;
     VARIANT v;
 
+    if (!is_clsid_supported(&CLSID_XSLTemplate, &IID_IXSLTemplate)) return;
     template = create_xsltemplate(&IID_IXSLTemplate);
-    if (!template) return;
 
     /* works as reset */
     hr = IXSLTemplate_putref_stylesheet(template, NULL);
@@ -9661,14 +8420,15 @@ static void test_xsltemplate(void)
 
     IXMLDOMDocument_Release(doc);
 
-    hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
-    if (hr != S_OK)
+    if (!is_clsid_supported(&CLSID_FreeThreadedDOMDocument, &IID_IXMLDOMDocument))
     {
-        win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
         IXSLTemplate_Release(template);
         return;
     }
 
+    hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
     b = VARIANT_TRUE;
     hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -9709,7 +8469,8 @@ todo_wine {
     hr = IXSLProcessor_put_output(processor, v);
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
-    CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     EXPECT_REF(stream, 1);
 
     V_VT(&v) = VT_UNKNOWN;
@@ -9761,8 +8522,7 @@ todo_wine {
     hr = IXSLProcessor_get_output(processor, &v);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
-    /* we currently output one '\n' instead of empty string */
-    todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    ok(*V_BSTR(&v) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
     IXMLDOMDocument_Release(doc2);
     VariantClear(&v);
 
@@ -9782,15 +8542,30 @@ todo_wine {
 
 static void test_insertBefore(void)
 {
-    IXMLDOMDocument *doc, *doc2;
+    IXMLDOMDocument *doc, *doc2, *doc3;
     IXMLDOMAttribute *attr;
     IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
-    IXMLDOMNode *node, *newnode;
+    IXMLDOMNode *node, *newnode, *cdata;
     HRESULT hr;
     VARIANT v;
     BSTR p;
 
     doc = create_document(&IID_IXMLDOMDocument);
+    doc3 = create_document(&IID_IXMLDOMDocument);
+
+    /* document to document */
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc3, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
+
+    /* document to itself */
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)doc, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
 
     /* insertBefore behaviour for attribute node */
     V_VT(&v) = VT_I4;
@@ -9801,6 +8576,47 @@ static void test_insertBefore(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
     ok(attr != NULL, "got %p\n", attr);
 
+    /* attribute to document */
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMDocument_insertBefore(doc3, (IXMLDOMNode*)attr, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
+
+    /* cdata to document */
+    V_VT(&v) = VT_I4;
+    V_I4(&v) = NODE_CDATA_SECTION;
+
+    cdata = NULL;
+    hr = IXMLDOMDocument_createNode(doc3, v, _bstr_("cdata"), NULL, &cdata);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(cdata != NULL, "got %p\n", cdata);
+
+    EXPECT_NO_CHILDREN(cdata);
+
+    /* attribute to cdata */
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)attr, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
+
+    /* document to cdata */
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMNode_insertBefore(cdata, (IXMLDOMNode*)doc, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
+
+    V_VT(&v) = VT_NULL;
+    node = (void*)0xdeadbeef;
+    hr = IXMLDOMDocument_insertBefore(doc3, cdata, v, &node);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+    ok(node == NULL, "got %p\n", node);
+
+    IXMLDOMNode_Release(cdata);
+    IXMLDOMDocument_Release(doc3);
+
     /* attribute to attribute */
     V_VT(&v) = VT_I4;
     V_I4(&v) = NODE_ATTRIBUTE;
@@ -9906,6 +8722,12 @@ static void test_insertBefore(void)
 
     todo_wine EXPECT_REF(elem2, 2);
 
+    /* document to element */
+    V_VT(&v) = VT_DISPATCH;
+    V_DISPATCH(&v) = NULL;
+    hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)doc, v, NULL);
+    ok(hr == E_FAIL, "got 0x%08x\n", hr);
+
     V_VT(&v) = VT_DISPATCH;
     V_DISPATCH(&v) = NULL;
     node = NULL;
@@ -10107,6 +8929,12 @@ static void test_appendChild(void)
     EXPECT_NO_CHILDREN(doc);
     EXPECT_NO_CHILDREN(doc2);
 
+    hr = IXMLDOMDocument_appendChild(doc2, NULL, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMElement_appendChild(elem, NULL, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
     /* append from another document */
     hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -10637,6 +9465,7 @@ static void test_selection(void)
 
     IEnumVARIANT_Release(enum1);
     IEnumVARIANT_Release(enum2);
+    IEnumVARIANT_Release(enum3);
 
     enum1 = NULL;
     hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
@@ -10730,6 +9559,7 @@ static void test_selection(void)
     EXPECT_HR(hr, S_OK);
     ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
     IXMLDOMNode_Release(node);
+    SysFreeString(name);
 
     V_VT(&v) = VT_I2;
     hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
@@ -10751,6 +9581,7 @@ static void test_selection(void)
     EXPECT_HR(hr, S_OK);
     ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
     IXMLDOMNode_Release(node);
+    SysFreeString(name);
 
     IXMLDOMSelection_Release(selection);
     IXMLDOMNodeList_Release(list);
@@ -10759,28 +9590,34 @@ static void test_selection(void)
     free_bstrs();
 }
 
+static void write_to_file(const char *name, const char *data)
+{
+    DWORD written;
+    HANDLE hfile;
+    BOOL ret;
+
+    hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
+    ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name);
+
+    ret = WriteFile(hfile, data, strlen(data), &written, NULL);
+    ok(ret, "WriteFile failed: %s, %d\n", name, GetLastError());
+
+    CloseHandle(hfile);
+}
+
 static void test_load(void)
 {
-    IXMLDOMDocument *doc;
+    IXMLDOMDocument *doc, *doc2;
     IXMLDOMNodeList *list;
+    IXMLDOMElement *elem;
     VARIANT_BOOL b;
-    HANDLE hfile;
     VARIANT src;
     HRESULT hr;
-    BOOL ret;
     BSTR path, bstr1, bstr2;
-    DWORD written;
     void* ptr;
 
     /* prepare a file */
-    hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
-    ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
-    if(hfile == INVALID_HANDLE_VALUE) return;
-
-    ret = WriteFile(hfile, win1252xml, strlen(win1252xml), &written, NULL);
-    ok(ret, "WriteFile failed\n");
-
-    CloseHandle(hfile);
+    write_to_file("test.xml", win1252xml);
 
     doc = create_document(&IID_IXMLDOMDocument);
 
@@ -10800,6 +9637,11 @@ static void test_load(void)
     EXPECT_HR(hr, S_OK);
     ok(b == VARIANT_TRUE, "got %d\n", b);
 
+    bstr1 = NULL;
+    hr = IXMLDOMDocument_get_url(doc, &bstr1);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    SysFreeString(bstr1);
+
     /* load from a path: VT_BSTR|VT_BYREF */
     V_VT(&src) = VT_BSTR | VT_BYREF;
     V_BSTRREF(&src) = &path;
@@ -10807,6 +9649,27 @@ static void test_load(void)
     EXPECT_HR(hr, S_OK);
     ok(b == VARIANT_TRUE, "got %d\n", b);
 
+    bstr1 = NULL;
+    hr = IXMLDOMDocument_get_url(doc, &bstr1);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument_get_documentElement(doc, &elem);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    /* create another instance for the same document, check url */
+    hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument_get_url(doc, &bstr2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(bstr1, bstr2), "got %s\n", wine_dbgstr_w(bstr2));
+
+    IXMLDOMDocument_Release(doc2);
+    IXMLDOMElement_Release(elem);
+
+    SysFreeString(bstr1);
+    SysFreeString(bstr2);
+
     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
     V_VT(&src) = VT_BSTR | VT_BYREF;
     V_BSTRREF(&src) = NULL;
@@ -10814,9 +9677,30 @@ static void test_load(void)
     EXPECT_HR(hr, E_INVALIDARG);
     ok(b == VARIANT_FALSE, "got %d\n", b);
 
-    IXMLDOMDocument_Release(doc);
+    bstr1 = NULL;
+    hr = IXMLDOMDocument_get_url(doc, &bstr1);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    SysFreeString(bstr1);
+
+    DeleteFileA("test.xml");
+
+    /* load from existing path, no xml content */
+    write_to_file("test.xml", nocontent);
+
+    V_VT(&src) = VT_BSTR;
+    V_BSTR(&src) = path;
+    b = VARIANT_TRUE;
+    hr = IXMLDOMDocument_load(doc, src, &b);
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+    ok(b == VARIANT_FALSE, "got %d\n", b);
+
+    bstr1 = (BSTR)0x1;
+    hr = IXMLDOMDocument_get_url(doc, &bstr1);
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+    ok(bstr1 == NULL, "got %p\n", bstr1);
 
     DeleteFileA("test.xml");
+    IXMLDOMDocument_Release(doc);
 
     doc = create_document(&IID_IXMLDOMDocument);
 
@@ -10912,6 +9796,7 @@ static void test_load(void)
 
 static void test_domobj_dispex(IUnknown *obj)
 {
+    static const WCHAR testW[] = {'t','e','s','t','p','r','o','p',0};
     DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
     IDispatchEx *dispex;
     IUnknown *unk;
@@ -10949,9 +9834,15 @@ static void test_domobj_dispex(IUnknown *obj)
     hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
     EXPECT_HR(hr, E_NOTIMPL);
 
+    unk = (IUnknown*)0xdeadbeef;
     hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
     EXPECT_HR(hr, E_NOTIMPL);
-    if (hr == S_OK && unk) IUnknown_Release(unk);
+    ok(unk == (IUnknown*)0xdeadbeef, "got %p\n", unk);
+
+    name = SysAllocString(testW);
+    hr = IDispatchEx_GetDispID(dispex, name, fdexNameEnsure, &dispid);
+    ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
+    SysFreeString(name);
 
     IDispatchEx_Release(dispex);
 }
@@ -10985,8 +9876,14 @@ static void test_mxnamespacemanager(void)
     EXPECT_REF(mgr2, 2);
     prefixes = NULL;
     hr = IVBMXNamespaceManager_getDeclaredPrefixes(mgr2, &prefixes);
+todo_wine
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     if (hr == S_OK)
     {
+        IDispatchEx *dispex;
+        VARIANT arg, ret;
+        DISPPARAMS dispparams;
+
         ok(prefixes != NULL, "got %p\n", prefixes);
         EXPECT_REF(nsmgr, 2);
         EXPECT_REF(mgr2, 2);
@@ -10998,8 +9895,28 @@ static void test_mxnamespacemanager(void)
         EXPECT_REF(mgr2, 3);
         EXPECT_REF(prefixes, 2);
 
-        IUnknown_Release(unk1);
-        IUnknown_Release(unk2);
+        IUnknown_Release(unk1);
+        IUnknown_Release(unk2);
+
+        hr = IMXNamespacePrefixes_QueryInterface(prefixes, &IID_IDispatchEx, (void**)&dispex);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        V_VT(&arg) = VT_I4;
+        V_I4(&arg) = 0;
+        dispparams.cArgs = 1;
+        dispparams.cNamedArgs = 0;
+        dispparams.rgdispidNamedArgs = NULL;
+        dispparams.rgvarg = &arg;
+
+        V_VT(&ret) = VT_EMPTY;
+        V_DISPATCH(&ret) = (void*)0x1;
+        hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(V_VT(&ret) == VT_BSTR, "got %d\n", V_VT(&ret));
+        ok(V_BSTR(&ret) != NULL, "got %p\n", V_BSTR(&ret));
+        VariantClear(&ret);
+
+        IDispatchEx_Release(dispex);
         IMXNamespacePrefixes_Release(prefixes);
     }
     IVBMXNamespaceManager_Release(mgr2);
@@ -11451,7 +10368,9 @@ static void test_dispex(void)
     IXMLHTTPRequest *req;
     IXMLDOMElement *elem;
     IDispatchEx *dispex;
+    DISPPARAMS dispparams;
     IXMLDOMNode *node;
+    VARIANT arg, ret;
     VARIANT_BOOL b;
     IUnknown *unk;
     HRESULT hr;
@@ -11459,7 +10378,8 @@ static void test_dispex(void)
 
     doc = create_document(&IID_IXMLDOMDocument);
 
-    IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
+    hr = IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     test_domobj_dispex(unk);
     IUnknown_Release(unk);
 
@@ -11492,7 +10412,8 @@ static void test_dispex(void)
     /* IXMLDOMNodeList for children list */
     hr = IXMLDOMDocument_get_childNodes(doc, &node_list);
     EXPECT_HR(hr, S_OK);
-    IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
+    hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     test_domobj_dispex(unk);
     IUnknown_Release(unk);
 
@@ -11508,6 +10429,94 @@ static void test_dispex(void)
     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
     IDispatchEx_Release(dispex);
 
+    did = -1;
+    hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(did == DISPID_VALUE, "got %d\n", did);
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+todo_wine
+    ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 2;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+todo_wine
+    ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 1;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = NULL;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_I4(&ret) = 1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
+    ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
+
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = NULL;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_I4(&ret) = 1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+todo_wine
+    ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
+
     IXMLDOMNodeList_Release(node_list);
 
     /* IXMLDOMParseError */
@@ -11515,6 +10524,27 @@ static void test_dispex(void)
     EXPECT_HR(hr, S_OK);
     IXMLDOMParseError_QueryInterface(error, &IID_IUnknown, (void**)&unk);
     test_domobj_dispex(unk);
+
+    hr = IXMLDOMParseError_QueryInterface(error, &IID_IDispatchEx, (void**)&dispex);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 1;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+todo_wine
+    ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
+
+    IDispatchEx_Release(dispex);
+
     IUnknown_Release(unk);
     IXMLDOMParseError_Release(error);
 
@@ -11544,6 +10574,7 @@ static void test_dispex(void)
     EXPECT_HR(hr, S_OK);
     ok(did == DISPID_DOM_COLLECTION_BASE, "got 0x%08x\n", did);
     IDispatchEx_Release(dispex);
+    IXMLDOMNamedNodeMap_Release(map);
 
     hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/b"), &node_list);
     EXPECT_HR(hr, S_OK);
@@ -11565,9 +10596,100 @@ static void test_dispex(void)
     hr = IDispatchEx_GetDispID(dispex, _bstr_("1"), 0, &did);
     EXPECT_HR(hr, S_OK);
     ok(did == DISPID_DOM_COLLECTION_BASE+1, "got 0x%08x\n", did);
-    IDispatchEx_Release(dispex);
-
     IXMLDOMNamedNodeMap_Release(map);
+
+    did = -1;
+    hr = IDispatchEx_GetDispID(dispex, _bstr_("item"), 0, &did);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(did == DISPID_VALUE, "got %d\n", did);
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+todo_wine {
+    ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+}
+    ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 2;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+todo_wine {
+    ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+}
+    ok(broken(V_DISPATCH(&ret) == (void*)0x1) || (V_DISPATCH(&ret) == NULL), "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&arg) = VT_I4;
+    V_I4(&arg) = 0;
+    dispparams.cArgs = 1;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = &arg;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+todo_wine
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    V_VT(&ret) = VT_EMPTY;
+    V_DISPATCH(&ret) = (void*)0x1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_DISPATCH, "got %d\n", V_VT(&ret));
+    ok(V_DISPATCH(&ret) == NULL, "got %p\n", V_DISPATCH(&ret));
+
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = NULL;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_I4(&ret) = 1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &ret, NULL, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&ret) == VT_I4, "got %d\n", V_VT(&ret));
+    ok(V_I4(&ret) == 0, "got %d\n", V_I4(&ret));
+
+    dispparams.cArgs = 0;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = NULL;
+
+    V_VT(&ret) = VT_EMPTY;
+    V_I4(&ret) = 1;
+    hr = IDispatchEx_Invoke(dispex, DISPID_DOM_NODELIST_LENGTH, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &ret, NULL, NULL);
+    ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x\n", hr);
+todo_wine
+    ok(V_VT(&ret) == VT_EMPTY, "got %d\n", V_VT(&ret));
+    ok(broken(V_I4(&ret) == 1) || (V_I4(&ret) == 0), "got %d\n", V_I4(&ret));
+
+    IDispatchEx_Release(dispex);
     IXMLDOMElement_Release(elem);
 
     /* IXMLDOMImplementation */
@@ -11626,6 +10748,13 @@ static void test_dispex(void)
     IXSLProcessor_Release(processor);
     IXSLTemplate_Release(template);
 
+    if (is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument))
+    {
+        doc = create_document_version(60, &IID_IXMLDOMDocument);
+        test_domobj_dispex((IUnknown*)doc);
+        IXMLDOMDocument_Release(doc);
+    }
+
     free_bstrs();
 }
 
@@ -11653,8 +10782,9 @@ static void test_parseerror(void)
     IXMLDOMParseError_Release(error);
     IXMLDOMDocument_Release(doc);
 
+    if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument)) return;
     doc = create_document_version(60, &IID_IXMLDOMDocument);
-    if (!doc) return;
+
     hr = IXMLDOMDocument_get_parseError(doc, &error);
     EXPECT_HR(hr, S_OK);
     hr = IXMLDOMParseError_QueryInterface(error, &IID_IXMLDOMParseError2, (void**)&error2);
@@ -11740,6 +10870,7 @@ static void test_supporterrorinfo(void)
                               &IID_IXMLDOMDocument2, &IID_IXMLDOMDocument3 };
     const supporterror_t *ptr = supporterror_test;
     ISupportErrorInfo *errorinfo, *info2;
+    IXMLDOMSchemaCollection *schemacache;
     IXMLDOMNamedNodeMap *map, *map2;
     IXMLDOMDocument *doc;
     IXMLDOMElement *elem;
@@ -11749,8 +10880,8 @@ static void test_supporterrorinfo(void)
     void *dummy;
     HRESULT hr;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument3)) return;
     doc = create_document_version(60, &IID_IXMLDOMDocument3);
-    if (!doc) return;
 
     EXPECT_REF(doc, 1);
     hr = IXMLDOMDocument_QueryInterface(doc, &IID_ISupportErrorInfo, (void**)&errorinfo);
@@ -11781,7 +10912,7 @@ static void test_supporterrorinfo(void)
         if (hr == S_OK)
         {
             hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
-            ok(hr == S_OK, "got 0x%08x for %s\n", hr, debugstr_guid(*iid));
+            ok(hr == S_OK, "got 0x%08x for %s\n", hr, wine_dbgstr_guid(*iid));
             IUnknown_Release(unk);
         }
 
@@ -11817,7 +10948,7 @@ static void test_supporterrorinfo(void)
             if (hr == S_OK)
             {
                 hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, *iid);
-                ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, debugstr_guid(*iid));
+                ok(hr == S_OK, "%d: got 0x%08x for %s\n", ptr->type, hr, wine_dbgstr_guid(*iid));
                 IUnknown_Release(unk);
             }
 
@@ -11866,6 +10997,20 @@ static void test_supporterrorinfo(void)
     IXMLDOMElement_Release(elem);
 
     IXMLDOMDocument_Release(doc);
+
+    /* IXMLDOMSchemaCollection */
+    hr = CoCreateInstance(&CLSID_XMLSchemaCache, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (void**)&schemacache);
+    ok(hr == S_OK, "failed to create schema collection, 0x%08x\n", hr);
+
+    hr = IXMLDOMSchemaCollection_QueryInterface(schemacache, &IID_ISupportErrorInfo, (void**)&errorinfo);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = ISupportErrorInfo_InterfaceSupportsErrorInfo(errorinfo, &IID_IXMLDOMSchemaCollection);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    ISupportErrorInfo_Release(errorinfo);
+    IXMLDOMSchemaCollection_Release(schemacache);
+
     free_bstrs();
 }
 
@@ -11897,7 +11042,6 @@ static void test_nodeValue(void)
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     while (ptr->type != NODE_INVALID)
     {
@@ -11935,6 +11079,55 @@ static void test_nodeValue(void)
     IXMLDOMDocument_Release(doc);
 }
 
+static void test_xmlns_attribute(void)
+{
+    BSTR str;
+    IXMLDOMDocument *doc;
+    IXMLDOMElement *root;
+    IXMLDOMAttribute *pAttribute;
+    IXMLDOMElement *elem;
+    HRESULT hr;
+    VARIANT v;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+
+    hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IXMLDOMDocument_createAttribute(doc, _bstr_("xmlns:dt"), &pAttribute);
+    ok( hr == S_OK, "returns %08x\n", hr );
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = _bstr_("urn:schemas-microsoft-com:datatypes");
+    hr = IXMLDOMAttribute_put_nodeValue(pAttribute, v);
+
+    hr = IXMLDOMElement_setAttributeNode(root, pAttribute, NULL);
+    ok(hr == S_OK, "ret %08x\n", hr );
+
+    hr = IXMLDOMNode_put_dataType((IXMLDOMNode*)root, _bstr_("bin.base64"));
+    ok(hr == S_OK, "ret %08x\n", hr );
+
+    hr = IXMLDOMDocument_get_documentElement(doc, &elem);
+    EXPECT_HR(hr, S_OK);
+
+    str = NULL;
+    hr = IXMLDOMElement_get_xml(elem, &str);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    todo_wine ok( lstrcmpW(str, _bstr_("<Testing xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"bin.base64\"/>")) == 0,
+    "got %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    IXMLDOMElement_Release(elem);
+    IXMLDOMAttribute_Release( pAttribute);
+
+    IXMLDOMDocument_Release(doc);
+
+    free_bstrs();
+}
+
 static const char namespacesA[] =
 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
 "   <ns1:elem1 xmlns:ns1=\"http://blah.org\" b='1' >"
@@ -11972,8 +11165,8 @@ static void test_get_namespaces(void)
     LONG len;
     BSTR s;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
     doc = create_document(&IID_IXMLDOMDocument2);
-    if (!doc) return;
 
     /* null pointer */
     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
@@ -12095,8 +11288,8 @@ static void test_get_namespaces(void)
     IXMLDOMDocument2_Release(doc);
 
     /* now with CLSID_DOMDocument60 */
+    if (!is_clsid_supported(&CLSID_DOMDocument60, &IID_IXMLDOMDocument2)) return;
     doc = create_document_version(60, &IID_IXMLDOMDocument2);
-    if (!doc) return;
 
     /* null pointer */
     hr = IXMLDOMDocument2_get_namespaces(doc, NULL);
@@ -12142,7 +11335,7 @@ static void test_get_namespaces(void)
     node = (void*)0xdeadbeef;
     hr = IXMLDOMSchemaCollection_get(collection, _bstr_("http://blah.org"), &node);
     EXPECT_HR(hr, E_NOTIMPL);
-    ok(node == (void*)0xdeadbeef, "got %p\n", node);
+    ok(broken(node == (void*)0xdeadbeef) || (node == NULL), "got %p\n", node);
 
     /* load schema and try to add it */
     doc2 = create_document(&IID_IXMLDOMDocument2);
@@ -12168,7 +11361,7 @@ static void test_get_namespaces(void)
     s = (void*)0xdeadbeef;
     hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 2, &s);
     EXPECT_HR(hr, E_FAIL);
-    ok(s == (void*)0xdeadbeef, "got %p\n", s);
+    ok(broken(s == (void*)0xdeadbeef) || (s == NULL), "got %p\n", s);
 
     /* enumerate */
     enumv = (void*)0xdeadbeef;
@@ -12215,11 +11408,13 @@ static void test_put_data(void)
     WCHAR buff[100], *data;
     IXMLDOMDocument *doc;
     DOMNodeType *type;
+    IXMLDOMText *text;
+    IXMLDOMNode *node;
+    VARIANT v;
     BSTR get_data;
     HRESULT hr;
 
     doc = create_document(&IID_IXMLDOMDocument);
-    if (!doc) return;
 
     memcpy(&buff[2], test_data, sizeof(test_data));
     /* just a big length */
@@ -12229,9 +11424,6 @@ static void test_put_data(void)
     type = put_data_types;
     while (*type != NODE_INVALID)
     {
-       IXMLDOMNode *node;
-       VARIANT v;
-
        V_VT(&v) = VT_I2;
        V_I2(&v) = *type;
 
@@ -12243,8 +11435,6 @@ static void test_put_data(void)
        {
            case NODE_TEXT:
            {
-              IXMLDOMText *text;
-
               hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
               EXPECT_HR(hr, S_OK);
               hr = IXMLDOMText_put_data(text, data);
@@ -12314,6 +11504,32 @@ static void test_put_data(void)
        type++;
     }
 
+    /* \r\n sequence is never escaped */
+    V_VT(&v) = VT_I2;
+    V_I2(&v) = NODE_TEXT;
+
+    hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
+
+    hr = IXMLDOMText_put_data(text, _bstr_("\r\n"));
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMText_get_data(text, &get_data);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+    ok(!lstrcmpW(get_data, _bstr_("\n")), "got %s\n", wine_dbgstr_w(get_data));
+    SysFreeString(get_data);
+
+    hr = IXMLDOMText_get_xml(text, &get_data);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(get_data, _bstr_("\r\n")), "got %s\n", wine_dbgstr_w(get_data));
+    SysFreeString(get_data);
+
+    IXMLDOMText_Release(text);
+    IXMLDOMNode_Release(node);
+
     IXMLDOMDocument_Release(doc);
     free_bstrs();
 }
@@ -12325,8 +11541,10 @@ static void test_putref_schemas(void)
     VARIANT schema;
     HRESULT hr;
 
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument2)) return;
+    if (!is_clsid_supported(&CLSID_XMLSchemaCache, &IID_IXMLDOMSchemaCollection)) return;
+
     doc = create_document(&IID_IXMLDOMDocument2);
-    if (!doc) return;
     cache = create_cache(&IID_IXMLDOMSchemaCollection);
 
     /* set to NULL iface when no schema is set */
@@ -12498,27 +11716,205 @@ static void test_namedmap_newenum(void)
     IXMLDOMDocument_Release(doc);
 }
 
-START_TEST(domdoc)
+static const char xsltext_xsl[] =
+"<?xml version=\"1.0\"?>"
+"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
+"<xsl:output method=\"html\" encoding=\"us-ascii\"/>"
+"<xsl:template match=\"/\">"
+"    <xsl:choose>"
+"        <xsl:when test=\"testkey\">"
+"            <xsl:text>testdata</xsl:text>"
+"        </xsl:when>"
+"    </xsl:choose>"
+"</xsl:template>"
+"</xsl:stylesheet>";
+
+static const char omitxmldecl_xsl[] =
+"<?xml version=\"1.0\"?>"
+"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
+"<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>"
+"<xsl:template match=\"/\">"
+"    <xsl:for-each select=\"/a/item\">"
+"        <xsl:element name=\"node\">"
+"            <xsl:value-of select=\"@name\"/>"
+"        </xsl:element>"
+"    </xsl:for-each>"
+"</xsl:template>"
+"</xsl:stylesheet>";
+
+static const char omitxmldecl_doc[] =
+"<?xml version=\"1.0\"?>"
+"<a>"
+"    <item name=\"item1\"/>"
+"    <item name=\"item2\"/>"
+"</a>";
+
+static void test_xsltext(void)
+{
+    IXMLDOMDocument *doc, *doc2;
+    VARIANT_BOOL b;
+    HRESULT hr;
+    BSTR ret;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+    doc2 = create_document(&IID_IXMLDOMDocument);
+
+    hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IXMLDOMDocument_loadXML(doc2, _bstr_("<testkey/>"), &b);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
+    EXPECT_HR(hr, S_OK);
+    ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret));
+    SysFreeString(ret);
+
+    /* omit-xml-declaration */
+    hr = IXMLDOMDocument_loadXML(doc, _bstr_(omitxmldecl_xsl), &b);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMDocument_loadXML(doc2, _bstr_(omitxmldecl_doc), &b);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(ret, _bstr_("<node>item1</node><node>item2</node>")), "transform result %s\n", wine_dbgstr_w(ret));
+    SysFreeString(ret);
+
+    IXMLDOMDocument_Release(doc2);
+    IXMLDOMDocument_Release(doc);
+    free_bstrs();
+}
+
+struct attrtest_t {
+    const char *name;
+    const char *uri;
+    const char *prefix;
+    const char *href;
+};
+
+static struct attrtest_t attrtests[] = {
+    { "xmlns", "http://www.w3.org/2000/xmlns/", "xmlns", "xmlns" },
+    { "xmlns", "nondefaulturi", "xmlns", "xmlns" },
+    { "c", "http://www.w3.org/2000/xmlns/", NULL, "http://www.w3.org/2000/xmlns/" },
+    { "c", "nsref1", NULL, "nsref1" },
+    { "ns:c", "nsref1", "ns", "nsref1" },
+    { "xmlns:c", "http://www.w3.org/2000/xmlns/", "xmlns", "" },
+    { "xmlns:c", "nondefaulturi", "xmlns", "" },
+    { 0 }
+};
+
+static void test_create_attribute(void)
 {
+    struct attrtest_t *ptr = attrtests;
+    IXMLDOMElement *el;
     IXMLDOMDocument *doc;
-    IUnknown *unk;
+    IXMLDOMNode *node, *node2;
+    VARIANT var;
+    HRESULT hr;
+    int i = 0;
+    BSTR str;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+
+    while (ptr->name)
+    {
+        V_VT(&var) = VT_I1;
+        V_I1(&var) = NODE_ATTRIBUTE;
+        hr = IXMLDOMDocument_createNode(doc, var, _bstr_(ptr->name), _bstr_(ptr->uri), &node);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        str = NULL;
+        hr = IXMLDOMNode_get_prefix(node, &str);
+        if (ptr->prefix)
+        {
+            ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
+            ok(!lstrcmpW(str, _bstr_(ptr->prefix)), "%d: got prefix %s, expected %s\n", i, wine_dbgstr_w(str), ptr->prefix);
+        }
+        else
+        {
+            ok(hr == S_FALSE, "%d: got 0x%08x\n", i, hr);
+            ok(str == NULL, "%d: got prefix %s\n", i, wine_dbgstr_w(str));
+        }
+        SysFreeString(str);
+
+        str = NULL;
+        hr = IXMLDOMNode_get_namespaceURI(node, &str);
+        ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
+        ok(!lstrcmpW(str, _bstr_(ptr->href)), "%d: got uri %s, expected %s\n", i, wine_dbgstr_w(str), ptr->href);
+        SysFreeString(str);
+
+        IXMLDOMNode_Release(node);
+        free_bstrs();
+
+        i++;
+        ptr++;
+    }
+
+    V_VT(&var) = VT_I1;
+    V_I1(&var) = NODE_ELEMENT;
+    hr = IXMLDOMDocument_createNode(doc, var, _bstr_("e"), NULL, &node2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMNode_QueryInterface(node2, &IID_IXMLDOMElement, (void**)&el);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IXMLDOMNode_Release(node2);
+
+    V_VT(&var) = VT_I1;
+    V_I1(&var) = NODE_ATTRIBUTE;
+    hr = IXMLDOMDocument_createNode(doc, var, _bstr_("xmlns:a"), _bstr_("http://www.w3.org/2000/xmlns/"), &node);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMElement_setAttributeNode(el, (IXMLDOMAttribute*)node, NULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    /* for some reason default namespace uri is not reported */
+    hr = IXMLDOMNode_get_namespaceURI(node, &str);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(str, _bstr_("")), "got uri %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    IXMLDOMNode_Release(node);
+    IXMLDOMElement_Release(el);
+    IXMLDOMDocument_Release(doc);
+    free_bstrs();
+}
+
+static void test_url(void)
+{
+    IXMLDOMDocument *doc;
+    HRESULT hr;
+    BSTR s;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+
+    hr = IXMLDOMDocument_get_url(doc, NULL);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    s = (BSTR)0x1;
+    hr = IXMLDOMDocument_get_url(doc, &s);
+    ok(hr == S_FALSE, "got 0x%08x\n", hr);
+    ok(s == NULL, "got %s\n", wine_dbgstr_w(s));
+
+    IXMLDOMDocument_Release(doc);
+}
+
+START_TEST(domdoc)
+{
     HRESULT hr;
 
     hr = CoInitialize( NULL );
     ok( hr == S_OK, "failed to init com\n");
     if (hr != S_OK) return;
 
-    test_XMLHTTP();
-
-    hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
-    if (hr != S_OK)
+    get_class_support_data(domdoc_support_data);
+    if (!is_clsid_supported(&CLSID_DOMDocument2, &IID_IXMLDOMDocument))
     {
-        win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
+        win_skip("DOMDocument2 is not supported. Skipping all tests.\n");
+        CoUninitialize();
         return;
     }
 
-    IXMLDOMDocument_Release(doc);
-
     test_domdoc();
     test_persiststreaminit();
     test_domnode();
@@ -12538,7 +11934,9 @@ START_TEST(domdoc)
     test_XSLPattern();
     test_cloneNode();
     test_xmlTypes();
+#if CORE_6738_IS_FIXED
     test_save();
+#endif
     test_testTransforms();
     test_namespaces_basic();
     test_namespaces_change();
@@ -12546,7 +11944,7 @@ START_TEST(domdoc)
     test_nodeTypedValue();
     test_TransformWithLoadingLocalFile();
     test_put_nodeValue();
-    test_document_IObjectSafety();
+    test_IObjectSafety();
     test_splitText();
     test_getQualifiedItem();
     test_removeQualifiedItem();
@@ -12554,6 +11952,7 @@ START_TEST(domdoc)
     test_setAttributeNode();
     test_put_dataType();
     test_createNode();
+    test_create_attribute();
     test_get_prefix();
     test_default_properties();
     test_selectSingleNode();
@@ -12579,20 +11978,17 @@ START_TEST(domdoc)
     test_put_data();
     test_putref_schemas();
     test_namedmap_newenum();
+    test_xmlns_attribute();
+    test_url();
 
     test_xsltemplate();
+    test_xsltext();
 
-    hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
-        &IID_IMXNamespaceManager, (void**)&unk);
-    if (hr == S_OK)
+    if (is_clsid_supported(&CLSID_MXNamespaceManager40, &IID_IMXNamespaceManager))
     {
         test_mxnamespacemanager();
         test_mxnamespacemanager_override();
-
-        IUnknown_Release(unk);
     }
-    else
-        win_skip("MXNamespaceManager is not available\n");
 
     CoUninitialize();
 }