[MSXML3] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / reactos / dll / win32 / msxml3 / domdoc.c
index 36d6573..670741e 100644 (file)
@@ -33,8 +33,6 @@
 #include <olectl.h>
 #include <objsafe.h>
 
-#include <wine/list.h>
-
 #ifdef HAVE_LIBXML2
 
 /* not defined in older versions */
@@ -66,6 +64,7 @@ typedef struct {
     xmlChar const* selectNsStr;
     LONG selectNsStr_len;
     BOOL XPath;
+    WCHAR *url;
 } domdoc_properties;
 
 typedef struct ConnectionPoint ConnectionPoint;
@@ -109,10 +108,9 @@ struct domdoc
     VARIANT_BOOL validating;
     VARIANT_BOOL resolving;
     domdoc_properties* properties;
-    bsc_t *bsc;
     HRESULT error;
 
-    /* IObjectWithSite*/
+    /* IObjectWithSite */
     IUnknown *site;
 
     /* IObjectSafety */
@@ -278,6 +276,9 @@ static domdoc_properties *create_properties(MSXML_VERSION version)
     properties->version = version;
     properties->XPath = (version == MSXML4 || version == MSXML6);
 
+    /* document url */
+    properties->url = NULL;
+
     return properties;
 }
 
@@ -312,6 +313,16 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties)
             list_add_tail(&pcopy->selectNsList, &new_ns->entry);
         }
 
+        if (properties->url)
+        {
+            int len = strlenW(properties->url);
+
+            pcopy->url = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
+            memcpy(pcopy->url, properties->url, len*sizeof(WCHAR));
+            pcopy->url[len] = 0;
+        }
+        else
+            pcopy->url = NULL;
     }
 
     return pcopy;
@@ -325,6 +336,7 @@ static void free_properties(domdoc_properties* properties)
             IXMLDOMSchemaCollection2_Release(properties->schemaCache);
         clear_selectNsList(&properties->selectNsList);
         heap_free((xmlChar*)properties->selectNsStr);
+        CoTaskMemFree(properties->url);
         heap_free(properties);
     }
 }
@@ -920,9 +932,6 @@ static ULONG WINAPI domdoc_Release( IXMLDOMDocument3 *iface )
     {
         int eid;
 
-        if(This->bsc)
-            detach_bsc(This->bsc);
-
         if (This->site)
             IUnknown_Release( This->site );
         destroy_xmlnode(&This->node);
@@ -1816,12 +1825,18 @@ static HRESULT WINAPI domdoc_createEntityReference(
 xmlChar* tagName_to_XPath(const BSTR tagName)
 {
     xmlChar *query, *tmp;
+    static const xmlChar everything[] = "/descendant::node()";
     static const xmlChar mod_pre[] = "*[local-name()='";
     static const xmlChar mod_post[] = "']";
     static const xmlChar prefix[] = "descendant::";
     const WCHAR *tokBegin, *tokEnd;
     int len;
 
+    /* Special case - empty tagname - means select all nodes,
+       except document itself. */
+    if (!*tagName)
+        return xmlStrdup(everything);
+
     query = xmlStrdup(prefix);
 
     tokBegin = tagName;
@@ -1930,7 +1945,7 @@ static HRESULT WINAPI domdoc_createNode(
     }
 
     xml_name = xmlchar_from_wchar(name);
-    /* prevent empty href to be allocated */
+    /* prevent empty href from being allocated */
     href = namespaceURI ? xmlchar_from_wchar(namespaceURI) : NULL;
 
     switch(node_type)
@@ -1943,7 +1958,7 @@ static HRESULT WINAPI domdoc_createNode(
 
         xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
 
-        /* allow to create default namespace xmlns= */
+        /* allow creating the default namespace xmlns= */
         if (local || (href && *href))
         {
             xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
@@ -2047,7 +2062,7 @@ static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
         return attach_xmldoc(This, xmldoc);
     }
 
-    return S_OK;
+    return E_FAIL;
 }
 
 static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon)
@@ -2059,14 +2074,7 @@ static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon)
     if(FAILED(hr))
         return hr;
 
-    if(This->bsc) {
-        hr = detach_bsc(This->bsc);
-        if(FAILED(hr))
-            return hr;
-    }
-
-    This->bsc = bsc;
-    return S_OK;
+    return detach_bsc(bsc);
 }
 
 static HRESULT WINAPI domdoc_load(
@@ -2112,7 +2120,13 @@ static HRESULT WINAPI domdoc_load(
             case 1:
                 /* Only takes UTF-8 strings.
                  * NOT NULL-terminated. */
-                SafeArrayAccessData(psa, (void**)&str);
+                hr = SafeArrayAccessData(psa, (void**)&str);
+                if (FAILED(hr))
+                {
+                    This->error = hr;
+                    WARN("failed to access array data, 0x%08x\n", hr);
+                    break;
+                }
                 SafeArrayGetUBound(psa, 1, &len);
 
                 if ((xmldoc = doparse(This, str, ++len, XML_CHAR_ENCODING_UTF8)))
@@ -2190,10 +2204,15 @@ static HRESULT WINAPI domdoc_load(
     {
         IMoniker *mon;
 
+        CoTaskMemFree(This->properties->url);
+        This->properties->url = NULL;
+
         hr = create_moniker_from_url( filename, &mon);
         if ( SUCCEEDED(hr) )
         {
             hr = domdoc_load_moniker( This, mon );
+            if (hr == S_OK)
+                IMoniker_GetDisplayName(mon, NULL, NULL, &This->properties->url);
             IMoniker_Release(mon);
         }
 
@@ -2256,11 +2275,25 @@ static HRESULT WINAPI domdoc_get_parseError(
 
 static HRESULT WINAPI domdoc_get_url(
     IXMLDOMDocument3 *iface,
-    BSTR* urlString )
+    BSTR* url )
 {
     domdoc *This = impl_from_IXMLDOMDocument3(iface);
-    FIXME("(%p)->(%p)\n", This, urlString);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p)\n", This, url);
+
+    if (!url)
+        return E_INVALIDARG;
+
+    if (This->properties->url)
+    {
+        *url = SysAllocString(This->properties->url);
+        if (!*url)
+            return E_OUTOFMEMORY;
+
+        return S_OK;
+    }
+    else
+        return return_null_bstr(url);
 }
 
 
@@ -2583,7 +2616,7 @@ static HRESULT WINAPI domdoc_get_namespaces(
 
     if (!This->namespaces)
     {
-        hr = SchemaCache_create(This->properties->version, NULL, (void**)&This->namespaces);
+        hr = SchemaCache_create(This->properties->version, (void**)&This->namespaces);
         if (hr != S_OK) return hr;
 
         hr = cache_from_doc_ns(This->namespaces, &This->node);
@@ -3535,7 +3568,6 @@ HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
     doc->error = S_OK;
     doc->site = NULL;
     doc->safeopt = 0;
-    doc->bsc = NULL;
     doc->cp_list = NULL;
     doc->namespaces = NULL;
     memset(doc->events, 0, sizeof(doc->events));
@@ -3554,12 +3586,12 @@ HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
     return S_OK;
 }
 
-HRESULT DOMDocument_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **ppObj)
+HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
 {
     xmlDocPtr xmldoc;
     HRESULT hr;
 
-    TRACE("(%d, %p, %p)\n", version, pUnkOuter, ppObj);
+    TRACE("(%d, %p)\n", version, ppObj);
 
     xmldoc = xmlNewDoc(NULL);
     if(!xmldoc)
@@ -3595,7 +3627,7 @@ IUnknown* create_domdoc( xmlNodePtr document )
 
 #else
 
-HRESULT DOMDocument_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **ppObj)
+HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
 {
     MESSAGE("This program tried to use a DOMDocument object, but\n"
             "libxml2 support was not present at compile time.\n");