Commit 9c951e75 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

msxml3: Properly set default value for SelectionLanguage property.

parent 4e94abd7
...@@ -77,7 +77,7 @@ typedef struct _domdoc ...@@ -77,7 +77,7 @@ typedef struct _domdoc
VARIANT_BOOL validating; VARIANT_BOOL validating;
VARIANT_BOOL resolving; VARIANT_BOOL resolving;
VARIANT_BOOL preserving; VARIANT_BOOL preserving;
BOOL bUseXPath; BOOL XPath;
IXMLDOMSchemaCollection *schema; IXMLDOMSchemaCollection *schema;
bsc_t *bsc; bsc_t *bsc;
HRESULT error; HRESULT error;
...@@ -2139,9 +2139,9 @@ static HRESULT WINAPI domdoc_setProperty( ...@@ -2139,9 +2139,9 @@ static HRESULT WINAPI domdoc_setProperty(
hr = S_OK; hr = S_OK;
if (lstrcmpiW(bstr, PropValueXPathW) == 0) if (lstrcmpiW(bstr, PropValueXPathW) == 0)
This->bUseXPath = TRUE; This->XPath = TRUE;
else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0) else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
This->bUseXPath = FALSE; This->XPath = FALSE;
else else
hr = E_FAIL; hr = E_FAIL;
...@@ -2180,7 +2180,7 @@ static HRESULT WINAPI domdoc_getProperty( ...@@ -2180,7 +2180,7 @@ static HRESULT WINAPI domdoc_getProperty(
if (lstrcmpiW(p, PropertySelectionLanguageW) == 0) if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
{ {
V_VT(var) = VT_BSTR; V_VT(var) = VT_BSTR;
if (This->bUseXPath) if (This->XPath)
V_BSTR(var) = SysAllocString(PropValueXPathW); V_BSTR(var) = SysAllocString(PropValueXPathW);
else else
V_BSTR(var) = SysAllocString(PropValueXSLPatternW); V_BSTR(var) = SysAllocString(PropValueXSLPatternW);
...@@ -2461,7 +2461,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu ...@@ -2461,7 +2461,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
doc->validating = 0; doc->validating = 0;
doc->resolving = 0; doc->resolving = 0;
doc->preserving = 0; doc->preserving = 0;
doc->bUseXPath = FALSE; doc->XPath = FALSE;
doc->error = S_OK; doc->error = S_OK;
doc->schema = NULL; doc->schema = NULL;
doc->stream = NULL; doc->stream = NULL;
...@@ -2477,7 +2477,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu ...@@ -2477,7 +2477,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
return S_OK; return S_OK;
} }
HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj) HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
{ {
xmlDocPtr xmldoc; xmlDocPtr xmldoc;
HRESULT hr; HRESULT hr;
...@@ -2494,6 +2494,14 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj) ...@@ -2494,6 +2494,14 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
if(FAILED(hr)) if(FAILED(hr))
xmlFreeDoc(xmldoc); xmlFreeDoc(xmldoc);
/* properties that are dependent on object versions */
if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
IsEqualCLSID( clsid, &CLSID_DOMDocument60 ))
{
domdoc *This = impl_from_IXMLDOMDocument3(*ppObj);
This->XPath = TRUE;
}
return hr; return hr;
} }
......
...@@ -43,26 +43,30 @@ ...@@ -43,26 +43,30 @@
WINE_DEFAULT_DEBUG_CHANNEL(msxml); WINE_DEFAULT_DEBUG_CHANNEL(msxml);
typedef HRESULT (*fnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); typedef HRESULT (*ClassFactoryCreateInstanceFunc)(IUnknown *pUnkOuter, LPVOID *ppObj);
typedef HRESULT (*DOMFactoryCreateInstanceFunc)(const GUID *clsid, IUnknown *pUnkOuter, LPVOID *ppObj);
/****************************************************************************** /******************************************************************************
* MSXML ClassFactory * MSXML ClassFactory
*/ */
typedef struct _xmlcf typedef struct
{ {
const struct IClassFactoryVtbl *lpVtbl; const struct IClassFactoryVtbl *lpVtbl;
fnCreateInstance pfnCreateInstance; ClassFactoryCreateInstanceFunc pCreateInstance;
} xmlcf; } ClassFactory;
static inline xmlcf *impl_from_IClassFactory( IClassFactory *iface ) typedef struct
{ {
return (xmlcf *)((char*)iface - FIELD_OFFSET(xmlcf, lpVtbl)); const struct IClassFactoryVtbl *lpVtbl;
} LONG ref;
DOMFactoryCreateInstanceFunc pCreateInstance;
GUID clsid;
} DOMFactory;
static HRESULT WINAPI xmlcf_QueryInterface( static HRESULT WINAPI ClassFactory_QueryInterface(
IClassFactory *iface, IClassFactory *iface,
REFIID riid, REFIID riid,
LPVOID *ppobj ) void **ppobj )
{ {
if (IsEqualGUID(riid, &IID_IUnknown) || if (IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IClassFactory)) IsEqualGUID(riid, &IID_IClassFactory))
...@@ -76,28 +80,26 @@ static HRESULT WINAPI xmlcf_QueryInterface( ...@@ -76,28 +80,26 @@ static HRESULT WINAPI xmlcf_QueryInterface(
return E_NOINTERFACE; return E_NOINTERFACE;
} }
static ULONG WINAPI xmlcf_AddRef( static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface )
IClassFactory *iface )
{ {
return 2; return 2;
} }
static ULONG WINAPI xmlcf_Release( static ULONG WINAPI ClassFactory_Release(IClassFactory *iface )
IClassFactory *iface )
{ {
return 1; return 1;
} }
static HRESULT WINAPI xmlcf_CreateInstance( static HRESULT WINAPI ClassFactory_CreateInstance(
IClassFactory *iface, IClassFactory *iface,
LPUNKNOWN pOuter, IUnknown *pOuter,
REFIID riid, REFIID riid,
LPVOID *ppobj ) void **ppobj )
{ {
xmlcf *This = impl_from_IClassFactory( iface ); ClassFactory *This = (ClassFactory*)iface;
HRESULT r;
IUnknown *punk; IUnknown *punk;
HRESULT r;
TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj ); TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
*ppobj = NULL; *ppobj = NULL;
...@@ -105,7 +107,7 @@ static HRESULT WINAPI xmlcf_CreateInstance( ...@@ -105,7 +107,7 @@ static HRESULT WINAPI xmlcf_CreateInstance(
if (pOuter) if (pOuter)
return CLASS_E_NOAGGREGATION; return CLASS_E_NOAGGREGATION;
r = This->pfnCreateInstance( pOuter, (LPVOID*) &punk ); r = This->pCreateInstance( pOuter, (void**) &punk );
if (FAILED(r)) if (FAILED(r))
return r; return r;
...@@ -114,7 +116,7 @@ static HRESULT WINAPI xmlcf_CreateInstance( ...@@ -114,7 +116,7 @@ static HRESULT WINAPI xmlcf_CreateInstance(
return r; return r;
} }
static HRESULT WINAPI xmlcf_LockServer( static HRESULT WINAPI ClassFactory_LockServer(
IClassFactory *iface, IClassFactory *iface,
BOOL dolock) BOOL dolock)
{ {
...@@ -122,29 +124,100 @@ static HRESULT WINAPI xmlcf_LockServer( ...@@ -122,29 +124,100 @@ static HRESULT WINAPI xmlcf_LockServer(
return S_OK; return S_OK;
} }
static const struct IClassFactoryVtbl xmlcf_vtbl = static ULONG WINAPI DOMClassFactory_AddRef(IClassFactory *iface )
{
DOMFactory *This = (DOMFactory*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref = %u\n", This, ref);
return ref;
}
static ULONG WINAPI DOMClassFactory_Release(IClassFactory *iface )
{
DOMFactory *This = (DOMFactory*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref = %u\n", This, ref);
if(!ref) {
heap_free(This);
}
return ref;
}
static HRESULT WINAPI DOMClassFactory_CreateInstance(
IClassFactory *iface,
IUnknown *pOuter,
REFIID riid,
void **ppobj )
{
DOMFactory *This = (DOMFactory*)iface;
IUnknown *punk;
HRESULT r;
TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
*ppobj = NULL;
if (pOuter)
return CLASS_E_NOAGGREGATION;
r = This->pCreateInstance( &This->clsid, pOuter, (void**) &punk );
if (FAILED(r))
return r;
r = IUnknown_QueryInterface( punk, riid, ppobj );
IUnknown_Release( punk );
return r;
}
static const struct IClassFactoryVtbl ClassFactoryVtbl =
{ {
xmlcf_QueryInterface, ClassFactory_QueryInterface,
xmlcf_AddRef, ClassFactory_AddRef,
xmlcf_Release, ClassFactory_Release,
xmlcf_CreateInstance, ClassFactory_CreateInstance,
xmlcf_LockServer ClassFactory_LockServer
}; };
static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create }; static const struct IClassFactoryVtbl DOMClassFactoryVtbl =
static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create }; {
static xmlcf xmldoccf = { &xmlcf_vtbl, XMLDocument_create }; ClassFactory_QueryInterface,
static xmlcf saxreadcf = { &xmlcf_vtbl, SAXXMLReader_create }; DOMClassFactory_AddRef,
static xmlcf httpreqcf = { &xmlcf_vtbl, XMLHTTPRequest_create }; DOMClassFactory_Release,
DOMClassFactory_CreateInstance,
ClassFactory_LockServer
};
static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv, DOMFactoryCreateInstanceFunc fnCreateInstance)
{
DOMFactory *ret = heap_alloc(sizeof(DOMFactory));
HRESULT hres;
ret->lpVtbl = &DOMClassFactoryVtbl;
ret->ref = 0;
ret->clsid = *clsid;
ret->pCreateInstance = fnCreateInstance;
hres = IClassFactory_QueryInterface((IClassFactory*)ret, riid, ppv);
if(FAILED(hres)) {
heap_free(ret);
*ppv = NULL;
}
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 };
/****************************************************************** /******************************************************************
* DllGetClassObject (MSXML3.@) * DllGetClassObject (MSXML3.@)
*/ */
HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
{ {
IClassFactory *cf = NULL; IClassFactory *cf = NULL;
TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv ); TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv );
if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */ if( IsEqualCLSID( rclsid, &CLSID_DOMDocument ) || /* Version indep. v 2.x */
IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */ IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) || /* Version indep. v 3.0 */
...@@ -152,7 +225,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) ...@@ -152,7 +225,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
IsEqualCLSID( rclsid, &CLSID_DOMDocument40 )|| /* Version dep. v 4.0 */ IsEqualCLSID( rclsid, &CLSID_DOMDocument40 )|| /* Version dep. v 4.0 */
IsEqualCLSID( rclsid, &CLSID_DOMDocument60 )) /* Version dep. v 6.0 */ IsEqualCLSID( rclsid, &CLSID_DOMDocument60 )) /* Version dep. v 6.0 */
{ {
cf = (IClassFactory*) &domdoccf.lpVtbl; return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
} }
else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) || else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache ) ||
IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) || IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ||
...@@ -171,7 +244,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) ...@@ -171,7 +244,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) || IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) ||
IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 )) IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 ))
{ {
cf = (IClassFactory*) &domdoccf.lpVtbl; return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
} }
else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) || else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) || IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
...@@ -188,5 +261,5 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) ...@@ -188,5 +261,5 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
if ( !cf ) if ( !cf )
return CLASS_E_CLASSNOTAVAILABLE; return CLASS_E_CLASSNOTAVAILABLE;
return IClassFactory_QueryInterface( cf, iid, ppv ); return IClassFactory_QueryInterface( cf, riid, ppv );
} }
...@@ -244,11 +244,11 @@ MAKE_FUNCPTR(xsltParseStylesheetDoc); ...@@ -244,11 +244,11 @@ MAKE_FUNCPTR(xsltParseStylesheetDoc);
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText, extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
LONG line, LONG linepos, LONG filepos ); LONG line, LONG linepos, LONG filepos );
extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT DOMDocument_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj );
extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, void **pObj );
extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, void **pObj );
extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, void **pObj );
extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj); extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, void **pObj);
typedef struct bsc_t bsc_t; typedef struct bsc_t bsc_t;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "initguid.h" #include "initguid.h"
DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f,0x20, 0x00,0x80,0x5f,0x2c,0xd0,0x64); DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f,0x20, 0x00,0x80,0x5f,0x2c,0xd0,0x64);
DEFINE_GUID(CLSID_DOMDocument60, 0x88d96a05, 0xf192, 0x11d4, 0xa6,0x5f, 0x00,0x40,0x96,0x32,0x51,0xe5);
static const WCHAR szEmpty[] = { 0 }; static const WCHAR szEmpty[] = { 0 };
static const WCHAR szIncomplete[] = { static const WCHAR szIncomplete[] = {
...@@ -5617,6 +5618,50 @@ static void test_document_IObjectSafety(void) ...@@ -5617,6 +5618,50 @@ static void test_document_IObjectSafety(void)
IXMLDOMDocument_Release(doc); IXMLDOMDocument_Release(doc);
} }
typedef struct _property_test_t {
const GUID *guid;
const char *clsid;
const char *property;
const char *value;
} property_test_t;
static const property_test_t properties_test_data[] = {
{ &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
{ &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
{ &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
{ &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
{ &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
{ 0 }
};
static void test_default_properties(void)
{
const property_test_t *entry = properties_test_data;
IXMLDOMDocument2 *doc;
VARIANT var;
HRESULT hr;
while (entry->guid)
{
hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
if (hr != S_OK)
{
win_skip("can't create %s instance\n", entry->clsid);
continue;
}
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",
entry->value, entry->clsid);
VariantClear(&var);
IXMLDOMDocument2_Release(doc);
entry++;
}
}
static void test_XSLPattern(void) static void test_XSLPattern(void)
{ {
IXMLDOMDocument2 *doc; IXMLDOMDocument2 *doc;
...@@ -5630,7 +5675,7 @@ static void test_XSLPattern(void) ...@@ -5630,7 +5675,7 @@ static void test_XSLPattern(void)
ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b)); ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
ok(b == VARIANT_TRUE, "failed to load XML string\n"); ok(b == VARIANT_TRUE, "failed to load XML string\n");
/* switch to XPath */ /* switch to XSLPattern */
ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern"))); ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
/* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */ /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
...@@ -6229,6 +6274,7 @@ START_TEST(domdoc) ...@@ -6229,6 +6274,7 @@ START_TEST(domdoc)
test_put_dataType(); test_put_dataType();
test_createNode(); test_createNode();
test_get_prefix(); test_get_prefix();
test_default_properties();
CoUninitialize(); CoUninitialize();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment