| /* | 
 |  * 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 <stdio.h> | 
 | #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(); | 
 | } |