Owen Rudge : wsdapi: Build types list when parsing Probe message.

Alexandre Julliard julliard at winehq.org
Thu Jun 14 16:53:23 CDT 2018


Module: wine
Branch: master
Commit: c6a2afc8b24c89d7b2075d8d0da7a250978f1982
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c6a2afc8b24c89d7b2075d8d0da7a250978f1982

Author: Owen Rudge <orudge at codeweavers.com>
Date:   Wed Jun 13 19:11:30 2018 +0100

wsdapi: Build types list when parsing Probe message.

Signed-off-by: Owen Rudge <orudge at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wsdapi/soap.c            | 91 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/wsdapi/tests/discovery.c |  2 +-
 dlls/wsdapi/wsdapi_internal.h |  1 +
 dlls/wsdapi/xml.c             | 16 ++++++++
 4 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/dlls/wsdapi/soap.c b/dlls/wsdapi/soap.c
index 85a5fba..5b40cac 100644
--- a/dlls/wsdapi/soap.c
+++ b/dlls/wsdapi/soap.c
@@ -1347,6 +1347,86 @@ static void remove_element(WSDXML_ELEMENT *element)
     WSDFreeLinkedMemory(element);
 }
 
+static WSD_NAME_LIST *build_types_list_from_string(IWSDXMLContext *context, LPCWSTR buffer, void *parent)
+{
+    WSD_NAME_LIST *list = NULL, *cur_list = NULL, *prev_list = NULL;
+    LPWSTR name_start = NULL, temp_buffer = NULL;
+    LPCWSTR prefix_start = buffer;
+    WSDXML_NAMESPACE *ns;
+    WSDXML_NAME *name;
+    int buffer_len, i;
+
+    if (buffer == NULL)
+        return NULL;
+
+    temp_buffer = duplicate_string(parent, buffer);
+    if (temp_buffer == NULL) goto cleanup;
+
+    buffer_len = lstrlenW(temp_buffer);
+
+    list = WSDAllocateLinkedMemory(parent, sizeof(WSD_NAME_LIST));
+    if (list == NULL) goto cleanup;
+
+    ZeroMemory(list, sizeof(WSD_NAME_LIST));
+    prefix_start = temp_buffer;
+
+    for (i = 0; i < buffer_len; i++)
+    {
+        if (temp_buffer[i] == ':')
+        {
+            temp_buffer[i] = 0;
+            name_start = &temp_buffer[i + 1];
+        }
+        else if ((temp_buffer[i] == ' ') || (i == buffer_len - 1))
+        {
+            WSDXML_NAMESPACE *known_ns;
+
+            if (temp_buffer[i] == ' ')
+                temp_buffer[i] = 0;
+
+            if (cur_list == NULL)
+                cur_list = list;
+            else
+            {
+                cur_list = WSDAllocateLinkedMemory(parent, sizeof(WSD_NAME_LIST));
+                if (cur_list == NULL) goto cleanup;
+
+                prev_list->Next = cur_list;
+            }
+
+            name = WSDAllocateLinkedMemory(cur_list, sizeof(WSDXML_NAME));
+            if (name == NULL) goto cleanup;
+
+            ns = WSDAllocateLinkedMemory(cur_list, sizeof(WSDXML_NAMESPACE));
+            if (ns == NULL) goto cleanup;
+
+            ZeroMemory(ns, sizeof(WSDXML_NAMESPACE));
+            ns->PreferredPrefix = duplicate_string(ns, prefix_start);
+
+            known_ns = xml_context_find_namespace_by_prefix(context, ns->PreferredPrefix);
+
+            if (known_ns != NULL)
+                ns->Uri = duplicate_string(ns, known_ns->Uri);
+
+            name->Space = ns;
+            name->LocalName = duplicate_string(name, name_start);
+
+            cur_list->Element = name;
+            prefix_start = &temp_buffer[i + 1];
+            name_start = NULL;
+        }
+    }
+
+    WSDFreeLinkedMemory(temp_buffer);
+    return list;
+
+cleanup:
+    WSDFreeLinkedMemory(list);
+    WSDFreeLinkedMemory(temp_buffer);
+
+    return NULL;
+}
+
 static WSDXML_TYPE *generate_type(LPCWSTR uri, void *parent)
 {
     WSDXML_TYPE *type = WSDAllocateLinkedMemory(parent, sizeof(WSDXML_TYPE));
@@ -1516,7 +1596,16 @@ HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg
 
         ZeroMemory(probe, sizeof(WSD_PROBE));
 
-        /* TODO: Check for the "types" element */
+        /* Check for the "types" element */
+        ret = WSDXMLGetValueFromAny(discoveryNsUri, typesString, (WSDXML_ELEMENT *) probe_element->FirstChild, &value);
+
+        if (FAILED(ret))
+        {
+            WARN("Unable to find Types element in received Probe message\n");
+            goto cleanup;
+        }
+
+        probe->Types = build_types_list_from_string(context, value, probe);
 
         /* Now detach and free known headers to leave the "any" elements */
         remove_element(find_element(probe_element, typesString, discoveryNsUri));
diff --git a/dlls/wsdapi/tests/discovery.c b/dlls/wsdapi/tests/discovery.c
index 94a5ebf..84aa67d 100644
--- a/dlls/wsdapi/tests/discovery.c
+++ b/dlls/wsdapi/tests/discovery.c
@@ -564,7 +564,7 @@ static HRESULT WINAPI IWSDiscoveryPublisherNotifyImpl_ProbeHandler(IWSDiscoveryP
             static const WCHAR lager[] = {'L','a','g','e','r',0};
             static const WCHAR more_info[] = {'M','o','r','e','I','n','f','o',0};
 
-            todo_wine ok(probe_msg->Types != NULL, "Probe message Types == NULL\n");
+            ok(probe_msg->Types != NULL, "Probe message Types == NULL\n");
 
             if (probe_msg->Types != NULL)
             {
diff --git a/dlls/wsdapi/wsdapi_internal.h b/dlls/wsdapi/wsdapi_internal.h
index dc4fc4d..7dd08f9 100644
--- a/dlls/wsdapi/wsdapi_internal.h
+++ b/dlls/wsdapi/wsdapi_internal.h
@@ -81,5 +81,6 @@ HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg
 
 LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value);
 WSDXML_NAME *duplicate_name(void *parentMemoryBlock, WSDXML_NAME *name);
+WSDXML_NAMESPACE *xml_context_find_namespace_by_prefix(IWSDXMLContext *context, LPCWSTR prefix);
 
 #endif
diff --git a/dlls/wsdapi/xml.c b/dlls/wsdapi/xml.c
index 968b217..98bdec6 100644
--- a/dlls/wsdapi/xml.c
+++ b/dlls/wsdapi/xml.c
@@ -672,3 +672,19 @@ HRESULT WINAPI WSDXMLCreateContext(IWSDXMLContext **ppContext)
 
     return S_OK;
 }
+
+WSDXML_NAMESPACE *xml_context_find_namespace_by_prefix(IWSDXMLContext *context, LPCWSTR prefix)
+{
+    IWSDXMLContextImpl *impl = impl_from_IWSDXMLContext(context);
+    struct xmlNamespace *ns;
+
+    if (prefix == NULL) return NULL;
+
+    LIST_FOR_EACH_ENTRY(ns, impl->namespaces, struct xmlNamespace, entry)
+    {
+        if (lstrcmpW(ns->namespace->PreferredPrefix, prefix) == 0)
+            return ns->namespace;
+    }
+
+    return NULL;
+}




More information about the wine-cvs mailing list