diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in index d79e71c63ba..17f723f1a46 100644 --- a/dlls/msxml3/Makefile.in +++ b/dlls/msxml3/Makefile.in @@ -21,6 +21,7 @@ C_SRCS = \ parseerror.c \ pi.c \ regsvr.c \ + schema.c \ text.c \ uuid.c diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c index f4dc2cc0161..ebc342f86f4 100644 --- a/dlls/msxml3/factory.c +++ b/dlls/msxml3/factory.c @@ -133,6 +133,7 @@ static const struct IClassFactoryVtbl xmlcf_vtbl = }; static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create }; +static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create }; /****************************************************************** * DllGetClassObject (MSXML3.@) @@ -143,11 +144,15 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv ); - if( IsEqualGUID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */ - IsEqualGUID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */ - IsEqualGUID( rclsid, &CLSID_DOMDocument30 ) ) /* Version dep. v 3.0 */ + if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */ + IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */ + IsEqualCLSID( rclsid, &CLSID_DOMDocument30 ) ) /* Version dep. v 3.0 */ cf = (IClassFactory*) &domdoccf.lpVtbl; + else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) || + IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ) + cf = (IClassFactory*) &schemacf.lpVtbl; + if ( !cf ) return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 9fb96cae4d9..4f459b9bd93 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -61,5 +61,6 @@ extern LONG xmldoc_release( xmlDocPtr doc ); extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos ); extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); +extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj ); #endif /* __MSXML_PRIVATE__ */ diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c new file mode 100644 index 00000000000..f823e78d672 --- /dev/null +++ b/dlls/msxml3/schema.c @@ -0,0 +1,204 @@ +/* + * Schema cache implementation + * + * Copyright 2007 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "ole2.h" +#include "msxml2.h" + +#include "wine/debug.h" + +#include "msxml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + + +typedef struct +{ + const struct IXMLDOMSchemaCollectionVtbl *lpVtbl; + LONG ref; +} schema_t; + +static inline schema_t *impl_from_IXMLDOMSchemaCollection( IXMLDOMSchemaCollection *iface ) +{ + return (schema_t *)((char*)iface - FIELD_OFFSET(schema_t, lpVtbl)); +} + +static HRESULT WINAPI schema_cache_QueryInterface( IXMLDOMSchemaCollection *iface, REFIID riid, void** ppvObject ) +{ + schema_t *This = impl_from_IXMLDOMSchemaCollection( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualIID( riid, &IID_IUnknown ) || + IsEqualIID( riid, &IID_IXMLDOMSchemaCollection ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLDOMSchemaCollection_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI schema_cache_AddRef( IXMLDOMSchemaCollection *iface ) +{ + schema_t *This = impl_from_IXMLDOMSchemaCollection( iface ); + LONG ref = InterlockedIncrement( &This->ref ); + TRACE("%p new ref %d\n", This, ref); + return ref; +} + +static ULONG WINAPI schema_cache_Release( IXMLDOMSchemaCollection *iface ) +{ + schema_t *This = impl_from_IXMLDOMSchemaCollection( iface ); + LONG ref = InterlockedDecrement( &This->ref ); + TRACE("%p new ref %d\n", This, ref); + + if ( ref == 0 ) + { + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI schema_cache_GetTypeInfoCount( IXMLDOMSchemaCollection *iface, UINT* pctinfo ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_GetTypeInfo( IXMLDOMSchemaCollection *iface, + UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_GetIDsOfNames( IXMLDOMSchemaCollection *iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_Invoke( IXMLDOMSchemaCollection *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_add( IXMLDOMSchemaCollection *iface, BSTR uri, VARIANT var ) +{ + FIXME("(%p)->(%s, var(vt %x)): stub\n", iface, debugstr_w(uri), V_VT(&var)); + return S_OK; +} + +static HRESULT WINAPI schema_cache_get( IXMLDOMSchemaCollection *iface, BSTR uri, IXMLDOMNode **node ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_remove( IXMLDOMSchemaCollection *iface, BSTR uri ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_get_length( IXMLDOMSchemaCollection *iface, long *length ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_get_namespaceURI( IXMLDOMSchemaCollection *iface, long index, BSTR *len ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_addCollection( IXMLDOMSchemaCollection *iface, IXMLDOMSchemaCollection *otherCollection ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI schema_cache_get__newEnum( IXMLDOMSchemaCollection *iface, IUnknown **ppUnk ) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static const struct IXMLDOMSchemaCollectionVtbl schema_vtbl = +{ + schema_cache_QueryInterface, + schema_cache_AddRef, + schema_cache_Release, + schema_cache_GetTypeInfoCount, + schema_cache_GetTypeInfo, + schema_cache_GetIDsOfNames, + schema_cache_Invoke, + schema_cache_add, + schema_cache_get, + schema_cache_remove, + schema_cache_get_length, + schema_cache_get_namespaceURI, + schema_cache_addCollection, + schema_cache_get__newEnum +}; + +HRESULT SchemaCache_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + schema_t *schema = HeapAlloc( GetProcessHeap(), 0, sizeof (*schema) ); + if( !schema ) + return E_OUTOFMEMORY; + + schema->lpVtbl = &schema_vtbl; + schema->ref = 1; + + *ppObj = &schema->lpVtbl; + return S_OK; +} diff --git a/dlls/msxml3/tests/Makefile.in b/dlls/msxml3/tests/Makefile.in index 477c89827ec..2aabdb6efa4 100644 --- a/dlls/msxml3/tests/Makefile.in +++ b/dlls/msxml3/tests/Makefile.in @@ -7,7 +7,8 @@ IMPORTS = oleaut32 ole32 kernel32 EXTRALIBS = -luuid CTESTS = \ - domdoc.c + domdoc.c \ + schema.c @MAKE_TEST_RULES@ diff --git a/dlls/msxml3/tests/schema.c b/dlls/msxml3/tests/schema.c new file mode 100644 index 00000000000..8651aa99818 --- /dev/null +++ b/dlls/msxml3/tests/schema.c @@ -0,0 +1,103 @@ +/* + * Schema test + * + * Copyright 2007 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "windows.h" +#include "ole2.h" +#include "xmldom.h" +#include "msxml2.h" +#include + +#include "wine/test.h" + +const CLSID CLSID_XMLSchemaCache = {0x373984c9, 0xb845, 0x449b, {0x91, 0xe7, 0x45, 0xac, 0x83, 0x03, 0x6a, 0xde}}; +const IID IID_IXMLDOMSchemaCollection = {0x373984c8, 0xb845, 0x449b, {0x91, 0xe7, 0x45, 0xac, 0x83, 0x03, 0x6a, 0xde}}; + +static const WCHAR schema_uri[] = {'x','-','s','c','h','e','m','a',':','t','e','s','t','.','x','m','l',0}; + +static const WCHAR schema_xml[] = { + '<','S','c','h','e','m','a',' ','x','m','l','n','s','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','x','m','l','-','d','a','t','a','\"','\n', + 'x','m','l','n','s',':','d','t','=','\"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','d','a','t','a','t','y','p','e','s','\"','>','\n', + '<','/','S','c','h','e','m','a','>','\n',0 +}; + +void test_schema_refs(void) +{ + IXMLDOMDocument2 *doc; + IXMLDOMSchemaCollection *schema; + HRESULT r; + LONG ref; + VARIANT v; + VARIANT_BOOL b; + BSTR str; + + r = CoCreateInstance( &CLSID_DOMDocument, NULL, + CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc ); + if( r != S_OK ) + return; + + r = CoCreateInstance( &CLSID_XMLSchemaCache, NULL, + CLSCTX_INPROC_SERVER, &IID_IXMLDOMSchemaCollection, (LPVOID*)&schema ); + if( r != S_OK ) + { + IXMLDOMDocument2_Release(doc); + return; + } + + str = SysAllocString(schema_xml); + r = IXMLDOMDocument2_loadXML(doc, str, &b); + ok(r == S_OK, "ret %08x\n", r); + ok(b == VARIANT_TRUE, "b %04x\n", b); + SysFreeString(str); + + ref = IXMLDOMDocument2_AddRef(doc); + ok(ref == 2, "ref %d\n", ref); + VariantInit(&v); + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)doc; + + str = SysAllocString(schema_uri); + r = IXMLDOMSchemaCollection_add(schema, str, v); + ok(r == S_OK, "ret %08x\n", r); + + /* IXMLDOMSchemaCollection_add doesn't add a ref on doc */ + ref = IXMLDOMDocument2_AddRef(doc); + ok(ref == 3, "ref %d\n", ref); + IXMLDOMDocument2_Release(doc); + + SysFreeString(str); + VariantClear(&v); + + IXMLDOMSchemaCollection_Release(schema); + IXMLDOMDocument2_Release(doc); +} + +START_TEST(schema) +{ + HRESULT r; + + r = CoInitialize( NULL ); + ok( r == S_OK, "failed to init com\n"); + + test_schema_refs(); + + CoUninitialize(); +}