/* * 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 */ #include #define COBJMACROS #include "initguid.h" #include "windows.h" #include "ole2.h" #include "xmldom.h" #include "msxml2.h" #include "dispex.h" #include "wine/test.h" 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 }; static 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); V_VT(&v) = VT_INT; r = IXMLDOMDocument2_get_schemas(doc, &v); ok(r == S_FALSE, "ret %08x\n", r); ok(V_VT(&v) == VT_NULL, "vt %x\n", V_VT(&v)); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 2, "ref %d\n", ref); V_VT(&v) = VT_DISPATCH; V_DISPATCH(&v) = (IDispatch*)schema; /* check that putref_schemas takes a ref */ r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == S_OK, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 4, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); VariantClear(&v); /* refs now 2 */ V_VT(&v) = VT_INT; /* check that get_schemas adds a ref */ r = IXMLDOMDocument2_get_schemas(doc, &v); ok(r == S_OK, "ret %08x\n", r); ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v)); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 4, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); /* refs now 3 */ /* get_schemas doesn't release a ref if passed VT_DISPATCH - ie it doesn't call VariantClear() */ r = IXMLDOMDocument2_get_schemas(doc, &v); ok(r == S_OK, "ret %08x\n", r); ok(V_VT(&v) == VT_DISPATCH, "vt %x\n", V_VT(&v)); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 5, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); /* refs now 4 */ /* release the two refs returned by get_schemas */ IXMLDOMSchemaCollection_Release(schema); IXMLDOMSchemaCollection_Release(schema); /* refs now 2 */ /* check that taking another ref on the document doesn't change the schema's ref count */ IXMLDOMDocument2_AddRef(doc); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 3, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); IXMLDOMDocument2_Release(doc); /* refs now 2 */ /* call putref_schema with some odd variants */ V_VT(&v) = VT_INT; r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == E_FAIL, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 3, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); /* refs now 2 */ /* calling with VT_EMPTY releases the schema */ V_VT(&v) = VT_EMPTY; r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == S_OK, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 2, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); /* refs now 1 */ /* try setting with VT_UNKNOWN */ IXMLDOMSchemaCollection_AddRef(schema); V_VT(&v) = VT_UNKNOWN; V_UNKNOWN(&v) = (IUnknown*)schema; r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == S_OK, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 4, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); VariantClear(&v); /* refs now 2 */ /* calling with VT_NULL releases the schema */ V_VT(&v) = VT_NULL; r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == S_OK, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 2, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); /* refs now 1 */ /* set again */ IXMLDOMSchemaCollection_AddRef(schema); V_VT(&v) = VT_UNKNOWN; V_UNKNOWN(&v) = (IUnknown*)schema; r = IXMLDOMDocument2_putref_schemas(doc, v); ok(r == S_OK, "ret %08x\n", r); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 4, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); VariantClear(&v); /* refs now 2 */ /* release the final ref on the doc which should release its ref on the schema */ IXMLDOMDocument2_Release(doc); ref = IXMLDOMSchemaCollection_AddRef(schema); ok(ref == 2, "ref %d\n", ref); IXMLDOMSchemaCollection_Release(schema); IXMLDOMSchemaCollection_Release(schema); } START_TEST(schema) { HRESULT r; r = CoInitialize( NULL ); ok( r == S_OK, "failed to init com\n"); test_schema_refs(); CoUninitialize(); }