From 459c29ba3451b9f0b973cea3235f7d43ee31db44 Mon Sep 17 00:00:00 2001 From: Adam Martinson Date: Wed, 24 Nov 2010 13:53:47 -0600 Subject: [PATCH] msxml3: Store the DOMDocument/XMLSchemaCache object version. --- dlls/msxml3/domdoc.c | 36 ++++++++++++++++++-------- dlls/msxml3/factory.c | 3 +-- dlls/msxml3/msxml_private.h | 51 ++++++++++++++++++++++++++++++++++++- dlls/msxml3/schema.c | 38 +++++++++++++++++---------- 4 files changed, 100 insertions(+), 28 deletions(-) diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index e06b03d3ab2..27f6a9f4203 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -75,6 +75,7 @@ static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r' * We need to preserve this when reloading a document, * and also need access to it from the libxml backend. */ typedef struct _domdoc_properties { + MSXML_VERSION version; VARIANT_BOOL preserving; IXMLDOMSchemaCollection2* schemaCache; struct list selectNsList; @@ -249,20 +250,31 @@ static domdoc_properties * create_properties(const GUID *clsid) { domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties)); - list_init( &properties->selectNsList ); + list_init(&properties->selectNsList); properties->preserving = VARIANT_FALSE; properties->schemaCache = NULL; properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar)); properties->selectNsStr_len = 0; /* properties that are dependent on object versions */ - if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) || - IsEqualCLSID( clsid, &CLSID_DOMDocument60 )) + if (IsEqualCLSID(clsid, &CLSID_DOMDocument30)) { + properties->version = MSXML3; + properties->XPath = FALSE; + } + else if (IsEqualCLSID(clsid, &CLSID_DOMDocument40)) + { + properties->version = MSXML4; + properties->XPath = TRUE; + } + else if (IsEqualCLSID(clsid, &CLSID_DOMDocument60)) + { + properties->version = MSXML6; properties->XPath = TRUE; } else { + properties->version = MSXML_DEFAULT; properties->XPath = FALSE; } @@ -279,6 +291,7 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties) if (pcopy) { + pcopy->version = properties->version; pcopy->preserving = properties->preserving; pcopy->schemaCache = properties->schemaCache; pcopy->XPath = properties->XPath; @@ -630,33 +643,34 @@ static inline domdoc *impl_from_IConnectionPointContainer(IConnectionPointContai static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface( IPersistStreamInit *iface, REFIID riid, void **ppvObj) { - domdoc *this = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj); + domdoc* This = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3*)&This->lpVtbl, riid, ppvObj); } static ULONG WINAPI domdoc_IPersistStreamInit_AddRef( IPersistStreamInit *iface) { - domdoc *this = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this); + domdoc* This = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_AddRef((IXMLDOMDocument3*)&This->lpVtbl); } static ULONG WINAPI domdoc_IPersistStreamInit_Release( IPersistStreamInit *iface) { - domdoc *this = impl_from_IPersistStreamInit(iface); - return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this); + domdoc* This = impl_from_IPersistStreamInit(iface); + return IXMLDOMDocument3_Release((IXMLDOMDocument3*)&This->lpVtbl); } static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID( IPersistStreamInit *iface, CLSID *classid) { - TRACE("(%p,%p): stub!\n", iface, classid); + domdoc* This = impl_from_IPersistStreamInit(iface); + TRACE("(%p)->(%p)\n", This, classid); if(!classid) return E_POINTER; - *classid = CLSID_DOMDocument2; + *classid = *DOMDocument_version(This->properties->version); return S_OK; } diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c index cc287ced59d..4e7d29e919e 100644 --- a/dlls/msxml3/factory.c +++ b/dlls/msxml3/factory.c @@ -204,7 +204,6 @@ static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv return hres; } -static ClassFactory schemacf = { &ClassFactoryVtbl, SchemaCache_create }; static ClassFactory xmldoccf = { &ClassFactoryVtbl, XMLDocument_create }; static ClassFactory saxreadcf = { &ClassFactoryVtbl, SAXXMLReader_create }; static ClassFactory httpreqcf = { &ClassFactoryVtbl, XMLHTTPRequest_create }; @@ -231,7 +230,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv ) IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache40 ) || IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache60 )) { - cf = (IClassFactory*) &schemacf.lpVtbl; + return DOMClassFactory_Create(rclsid, riid, ppv, SchemaCache_create); } else if( IsEqualCLSID( rclsid, &CLSID_XMLDocument ) ) { diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 8a2b1b59e09..0e7971e94e3 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -29,6 +29,13 @@ # error You must include config.h to use this header #endif +typedef enum { + MSXML_DEFAULT = 0, + MSXML3 = 30, + MSXML4 = 40, + MSXML6 = 60 +} MSXML_VERSION; + /* typelibs */ typedef enum tid_t { IXMLDOMAttribute_tid, @@ -371,11 +378,53 @@ MAKE_FUNCPTR(xsltParseStylesheetDoc); extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos ); extern HRESULT DOMDocument_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj ); -extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, void **pObj ); +extern HRESULT SchemaCache_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj ); extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, void **pObj ); extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, void **pObj ); extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, void **pObj); +static inline const CLSID* DOMDocument_version(const MSXML_VERSION v) +{ + CLSID const* clsid; + switch (v) + { + case MSXML_DEFAULT: + clsid = &CLSID_DOMDocument; + break; + case MSXML3: + clsid = &CLSID_DOMDocument30; + break; + case MSXML4: + clsid = &CLSID_DOMDocument40; + break; + case MSXML6: + clsid = &CLSID_DOMDocument60; + break; + } + return clsid; +} + +static inline const CLSID* SchemaCache_version(const MSXML_VERSION v) +{ + CLSID const* clsid; + switch (v) + { + case MSXML_DEFAULT: + clsid = &CLSID_XMLSchemaCache; + break; + case MSXML3: + clsid = &CLSID_XMLSchemaCache30; + break; + case MSXML4: + clsid = &CLSID_XMLSchemaCache40; + break; + case MSXML6: + clsid = &CLSID_XMLSchemaCache60; + break; + } + return clsid; +} + typedef struct bsc_t bsc_t; HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**); diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c index eb6b6d3eb09..cddbc5c82a6 100644 --- a/dlls/msxml3/schema.c +++ b/dlls/msxml3/schema.c @@ -85,6 +85,7 @@ typedef enum _SCHEMA_TYPE { typedef struct _schema_cache { const struct IXMLDOMSchemaCollection2Vtbl* lpVtbl; + MSXML_VERSION version; xmlHashTablePtr cache; LONG ref; } schema_cache; @@ -818,7 +819,7 @@ static BOOL link_datatypes(xmlDocPtr schema) return TRUE; } -static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI) +static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI, MSXML_VERSION v) { cache_entry* entry = heap_alloc(sizeof(cache_entry)); xmlSchemaParserCtxtPtr spctx; @@ -834,7 +835,7 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI if ((entry->schema = Schema_parse(spctx))) { - xmldoc_init(entry->schema->doc, &CLSID_DOMDocument40); + xmldoc_init(entry->schema->doc, DOMDocument_version(v)); entry->doc = entry->schema->doc; xmldoc_add_ref(entry->doc); } @@ -849,7 +850,7 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc, xmlChar const* nsURI return entry; } -static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI) +static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI, MSXML_VERSION v) { cache_entry* entry = heap_alloc(sizeof(cache_entry)); xmlSchemaParserCtxtPtr spctx; @@ -864,8 +865,8 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI if ((entry->schema = Schema_parse(spctx))) { entry->doc = new_doc; - xmldoc_init(entry->schema->doc, &CLSID_DOMDocument30); - xmldoc_init(entry->doc, &CLSID_DOMDocument30); + xmldoc_init(entry->schema->doc, DOMDocument_version(v)); + xmldoc_init(entry->doc, DOMDocument_version(v)); xmldoc_add_ref(entry->doc); xmldoc_add_ref(entry->schema->doc); } @@ -882,12 +883,12 @@ static cache_entry* cache_entry_from_xdr_doc(xmlDocPtr doc, xmlChar const* nsURI return entry; } -static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI) +static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI, MSXML_VERSION v) { cache_entry* entry; IXMLDOMDocument3* domdoc = NULL; xmlDocPtr doc = NULL; - HRESULT hr = DOMDocument_create(&CLSID_DOMDocument, NULL, (void**)&domdoc); + HRESULT hr = DOMDocument_create(DOMDocument_version(v), NULL, (void**)&domdoc); VARIANT_BOOL b = VARIANT_FALSE; SCHEMA_TYPE type = SCHEMA_TYPE_INVALID; @@ -916,10 +917,10 @@ static cache_entry* cache_entry_from_url(VARIANT url, xmlChar const* nsURI) switch (type) { case SCHEMA_TYPE_XSD: - entry = cache_entry_from_xsd_doc(doc, nsURI); + entry = cache_entry_from_xsd_doc(doc, nsURI, v); break; case SCHEMA_TYPE_XDR: - entry = cache_entry_from_xdr_doc(doc, nsURI); + entry = cache_entry_from_xdr_doc(doc, nsURI, v); break; case SCHEMA_TYPE_INVALID: entry = NULL; @@ -1073,7 +1074,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri case VT_BSTR: { - cache_entry* entry = cache_entry_from_url(var, name); + cache_entry* entry = cache_entry_from_url(var, name, This->version); if (entry) { @@ -1111,11 +1112,11 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri if (type == SCHEMA_TYPE_XSD) { - entry = cache_entry_from_xsd_doc(doc, name); + entry = cache_entry_from_xsd_doc(doc, name, This->version); } else if (type == SCHEMA_TYPE_XDR) { - entry = cache_entry_from_xdr_doc(doc, name); + entry = cache_entry_from_xdr_doc(doc, name, This->version); } else { @@ -1405,7 +1406,7 @@ XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node) return dt; } -HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj) +HRESULT SchemaCache_create(const GUID *clsid, IUnknown* pUnkOuter, void** ppObj) { schema_cache* This = heap_alloc(sizeof(schema_cache)); if (!This) @@ -1415,13 +1416,22 @@ HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj) This->cache = xmlHashCreate(DEFAULT_HASHTABLE_SIZE); This->ref = 1; + if (IsEqualCLSID(clsid, &CLSID_XMLSchemaCache30)) + This->version = MSXML3; + else if (IsEqualCLSID(clsid, &CLSID_DOMDocument40)) + This->version = MSXML4; + else if (IsEqualCLSID(clsid, &CLSID_DOMDocument60)) + This->version = MSXML6; + else + This->version = MSXML_DEFAULT; + *ppObj = &This->lpVtbl; return S_OK; } #else -HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj) +HRESULT SchemaCache_create(const GUID *clsid, IUnknown* pUnkOuter, void** ppObj) { MESSAGE("This program tried to use a SchemaCache object, but\n" "libxml2 support was not present at compile time.\n");