[PATCH 4/4] Properly set default value for SelectionLanguage property

Nikolay Sivov nsivov at codeweavers.com
Tue Sep 14 00:15:31 CDT 2010


---
 dlls/msxml3/domdoc.c        |   20 ++++--
 dlls/msxml3/factory.c       |  147 ++++++++++++++++++++++++++++++++-----------
 dlls/msxml3/msxml_private.h |   10 ++--
 dlls/msxml3/tests/domdoc.c  |   48 ++++++++++++++-
 4 files changed, 176 insertions(+), 49 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 9053a7d..8aa5332 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -77,7 +77,7 @@ typedef struct _domdoc
     VARIANT_BOOL validating;
     VARIANT_BOOL resolving;
     VARIANT_BOOL preserving;
-    BOOL bUseXPath;
+    BOOL XPath;
     IXMLDOMSchemaCollection *schema;
     bsc_t *bsc;
     HRESULT error;
@@ -2139,9 +2139,9 @@ static HRESULT WINAPI domdoc_setProperty(
 
         hr = S_OK;
         if (lstrcmpiW(bstr, PropValueXPathW) == 0)
-            This->bUseXPath = TRUE;
+            This->XPath = TRUE;
         else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
-            This->bUseXPath = FALSE;
+            This->XPath = FALSE;
         else
             hr = E_FAIL;
 
@@ -2180,7 +2180,7 @@ static HRESULT WINAPI domdoc_getProperty(
     if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
     {
         V_VT(var) = VT_BSTR;
-        if (This->bUseXPath)
+        if (This->XPath)
             V_BSTR(var) = SysAllocString(PropValueXPathW);
         else
             V_BSTR(var) = SysAllocString(PropValueXSLPatternW);
@@ -2461,7 +2461,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
     doc->validating = 0;
     doc->resolving = 0;
     doc->preserving = 0;
-    doc->bUseXPath = FALSE;
+    doc->XPath = FALSE;
     doc->error = S_OK;
     doc->schema = NULL;
     doc->stream = NULL;
@@ -2477,7 +2477,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **docu
     return S_OK;
 }
 
-HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
+HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
 {
     xmlDocPtr xmldoc;
     HRESULT hr;
@@ -2494,6 +2494,14 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
     if(FAILED(hr))
         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;
 }
 
diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index 5e2039f..5c7d015 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -43,26 +43,30 @@
 
 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
  */
-typedef struct _xmlcf
+typedef struct
 {
     const struct IClassFactoryVtbl *lpVtbl;
-    fnCreateInstance pfnCreateInstance;
-} xmlcf;
+    ClassFactoryCreateInstanceFunc pCreateInstance;
+} 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,
     REFIID riid,
-    LPVOID *ppobj )
+    void **ppobj )
 {
     if (IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IClassFactory))
@@ -76,28 +80,26 @@ static HRESULT WINAPI xmlcf_QueryInterface(
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI xmlcf_AddRef(
-    IClassFactory *iface )
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface )
 {
     return 2;
 }
 
-static ULONG WINAPI xmlcf_Release(
-    IClassFactory *iface )
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface )
 {
     return 1;
 }
 
-static HRESULT WINAPI xmlcf_CreateInstance(
+static HRESULT WINAPI ClassFactory_CreateInstance(
     IClassFactory *iface,
-    LPUNKNOWN pOuter,
+    IUnknown *pOuter,
     REFIID riid,
-    LPVOID *ppobj )
+    void **ppobj )
 {
-    xmlcf *This = impl_from_IClassFactory( iface );
-    HRESULT r;
+    ClassFactory *This = (ClassFactory*)iface;
     IUnknown *punk;
-    
+    HRESULT r;
+
     TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj );
 
     *ppobj = NULL;
@@ -105,7 +107,7 @@ static HRESULT WINAPI xmlcf_CreateInstance(
     if (pOuter)
         return CLASS_E_NOAGGREGATION;
 
-    r = This->pfnCreateInstance( pOuter, (LPVOID*) &punk );
+    r = This->pCreateInstance( pOuter, (void**) &punk );
     if (FAILED(r))
         return r;
 
@@ -114,7 +116,7 @@ static HRESULT WINAPI xmlcf_CreateInstance(
     return r;
 }
 
-static HRESULT WINAPI xmlcf_LockServer(
+static HRESULT WINAPI ClassFactory_LockServer(
     IClassFactory *iface,
     BOOL dolock)
 {
@@ -122,29 +124,100 @@ static HRESULT WINAPI xmlcf_LockServer(
     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,
-    xmlcf_AddRef,
-    xmlcf_Release,
-    xmlcf_CreateInstance,
-    xmlcf_LockServer
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+    ClassFactory_CreateInstance,
+    ClassFactory_LockServer
 };
 
-static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create };
-static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create };
-static xmlcf xmldoccf = { &xmlcf_vtbl, XMLDocument_create };
-static xmlcf saxreadcf = { &xmlcf_vtbl, SAXXMLReader_create };
-static xmlcf httpreqcf = { &xmlcf_vtbl, XMLHTTPRequest_create };
+static const struct IClassFactoryVtbl DOMClassFactoryVtbl =
+{
+    ClassFactory_QueryInterface,
+    DOMClassFactory_AddRef,
+    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.@)
  */
-HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
+HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
 {
     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 */
         IsEqualCLSID( rclsid, &CLSID_DOMDocument2 ) ||  /* Version indep. v 3.0 */
@@ -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_DOMDocument60 ))   /* Version dep.   v 6.0 */
     {
-        cf = (IClassFactory*) &domdoccf.lpVtbl;
+        return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
     }
     else if( IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache )   ||
              IsEqualCLSID( rclsid, &CLSID_XMLSchemaCache30 ) ||
@@ -171,7 +244,7 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument40 ) ||
              IsEqualCLSID( rclsid, &CLSID_FreeThreadedDOMDocument60 ))
     {
-        cf = (IClassFactory*) &domdoccf.lpVtbl;
+        return DOMClassFactory_Create(rclsid, riid, ppv, DOMDocument_create);
     }
     else if( IsEqualCLSID( rclsid, &CLSID_SAXXMLReader) ||
              IsEqualCLSID( rclsid, &CLSID_SAXXMLReader30 ) ||
@@ -188,5 +261,5 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv )
     if ( !cf )
         return CLASS_E_CLASSNOTAVAILABLE;
 
-    return IClassFactory_QueryInterface( cf, iid, ppv );
+    return IClassFactory_QueryInterface( cf, riid, ppv );
 }
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 830e45c..a1b3b9d 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -244,11 +244,11 @@ 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( IUnknown *pUnkOuter, LPVOID *ppObj );
-extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj );
-extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj );
-extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj );
-extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj);
+extern HRESULT DOMDocument_create( const GUID *clsid, IUnknown *pUnkOuter, void **ppObj );
+extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, void **pObj );
+extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, void **pObj );
+extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, void **pObj );
+extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, void **pObj);
 
 typedef struct bsc_t bsc_t;
 
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index cd789e5..0ed8f33 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -37,6 +37,7 @@
 #include "initguid.h"
 
 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 szIncomplete[] = {
@@ -5617,6 +5618,50 @@ static void test_document_IObjectSafety(void)
     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)
 {
     IXMLDOMDocument2 *doc;
@@ -5630,7 +5675,7 @@ static void test_XSLPattern(void)
     ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
     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")));
 
     /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
@@ -6229,6 +6274,7 @@ START_TEST(domdoc)
     test_put_dataType();
     test_createNode();
     test_get_prefix();
+    test_default_properties();
 
     CoUninitialize();
 }
-- 
1.5.6.5



--------------080508080707030504050507--



More information about the wine-patches mailing list