Module: wine Branch: master Commit: 402fce157901e0c51bf109a2c4b98632b3f74e58 URL: https://source.winehq.org/git/wine.git/?a=commit;h=402fce157901e0c51bf109a2c...
Author: Owen Rudge orudge@codeweavers.com Date: Mon Mar 19 21:46:38 2018 +0000
wsdapi: Store discovered namespaces and write xmlns attributes for them.
Signed-off-by: Owen Rudge orudge@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wsdapi/soap.c | 67 +++++++++++++++++++++++++++++++++++++++++-- dlls/wsdapi/tests/discovery.c | 8 ++++-- dlls/wsdapi/wsdapi_internal.h | 4 +++ dlls/wsdapi/xml.c | 2 +- 4 files changed, 74 insertions(+), 7 deletions(-)
diff --git a/dlls/wsdapi/soap.c b/dlls/wsdapi/soap.c index abea33c..40edd15 100644 --- a/dlls/wsdapi/soap.c +++ b/dlls/wsdapi/soap.c @@ -71,6 +71,13 @@ static const WCHAR relatesToString[] = { 'R','e','l','a','t','e','s','T','o', 0 static const WCHAR appSequenceString[] = { 'A','p','p','S','e','q','u','e','n','c','e', 0 }; static const WCHAR emptyString[] = { 0 };
+struct discovered_namespace +{ + struct list entry; + LPCWSTR prefix; + LPCWSTR uri; +}; + static char *wide_to_utf8(LPCWSTR wide_string, int *length) { char *new_string = NULL; @@ -252,6 +259,31 @@ static void populate_soap_header(WSD_SOAP_HEADER *header, LPCWSTR to, LPCWSTR ac /* TODO: Implement RelatesTo, ReplyTo, From, FaultTo */ }
+static BOOL add_discovered_namespace(struct list *namespaces, WSDXML_NAMESPACE *discovered_ns) +{ + struct discovered_namespace *ns; + + LIST_FOR_EACH_ENTRY(ns, namespaces, struct discovered_namespace, entry) + { + if (lstrcmpW(ns->uri, discovered_ns->Uri) == 0) + return TRUE; /* Already added */ + } + + ns = WSDAllocateLinkedMemory(namespaces, sizeof(struct discovered_namespace)); + + if (ns == NULL) + return FALSE; + + ns->prefix = duplicate_string(ns, discovered_ns->PreferredPrefix); + ns->uri = duplicate_string(ns, discovered_ns->Uri); + + if ((ns->prefix == NULL) || (ns->uri == NULL)) + return FALSE; + + list_add_tail(namespaces, &ns->entry); + return TRUE; +} + static WSDXML_ELEMENT *create_soap_header_xml_elements(IWSDXMLContext *xml_context, WSD_SOAP_HEADER *header) { WSDXML_ELEMENT *header_element = NULL, *app_sequence_element = NULL; @@ -309,9 +341,10 @@ cleanup: static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER *header, WSDXML_ELEMENT *body_element, WS_HEAP **heap, char **output_xml, ULONG *xml_length, struct list *discovered_namespaces) { - WS_XML_STRING *actual_envelope_prefix = NULL, *envelope_uri_xmlstr = NULL; + WS_XML_STRING *actual_envelope_prefix = NULL, *envelope_uri_xmlstr = NULL, *tmp_prefix = NULL, *tmp_uri = NULL; WSDXML_NAMESPACE *addressing_ns = NULL, *discovery_ns = NULL, *envelope_ns = NULL; WSDXML_ELEMENT *header_element = NULL; + struct discovered_namespace *ns; WS_XML_BUFFER *buffer = NULL; WS_XML_WRITER *writer = NULL; WS_XML_STRING envelope; @@ -320,10 +353,13 @@ static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER
/* Create the necessary XML prefixes */ if (FAILED(IWSDXMLContext_AddNamespace(xml_context, addressingNsUri, addressingPrefix, &addressing_ns))) goto cleanup; + if (!add_discovered_namespace(discovered_namespaces, addressing_ns)) goto cleanup;
if (FAILED(IWSDXMLContext_AddNamespace(xml_context, discoveryNsUri, discoveryPrefix, &discovery_ns))) goto cleanup; + if (!add_discovered_namespace(discovered_namespaces, discovery_ns)) goto cleanup;
if (FAILED(IWSDXMLContext_AddNamespace(xml_context, envelopeNsUri, envelopePrefix, &envelope_ns))) goto cleanup; + if (!add_discovered_namespace(discovered_namespaces, envelope_ns)) goto cleanup;
envelope.bytes = envelopeString; envelope.length = sizeof(envelopeString) - 1; @@ -356,6 +392,23 @@ static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER ret = WsWriteStartElement(writer, actual_envelope_prefix, &envelope, envelope_uri_xmlstr, NULL); if (FAILED(ret)) goto cleanup;
+ LIST_FOR_EACH_ENTRY(ns, discovered_namespaces, struct discovered_namespace, entry) + { + tmp_prefix = populate_xml_string(ns->prefix); + tmp_uri = populate_xml_string(ns->uri); + + if ((tmp_prefix == NULL) || (tmp_uri == NULL)) goto cleanup; + + ret = WsWriteXmlnsAttribute(writer, tmp_prefix, tmp_uri, FALSE, NULL); + if (FAILED(ret)) goto cleanup; + + free_xml_string(tmp_prefix); + free_xml_string(tmp_uri); + } + + tmp_prefix = NULL; + tmp_uri = NULL; + /* Write the header */ if (!write_xml_element(header_element, writer)) goto cleanup;
@@ -401,7 +454,7 @@ static HRESULT write_and_send_message(IWSDiscoveryPublisherImpl *impl, WSD_SOAP_ char *full_xml; HRESULT ret;
- ret = create_soap_envelope(impl->xmlContext, header, NULL, &heap, &xml, &xml_length, NULL); + ret = create_soap_envelope(impl->xmlContext, header, NULL, &heap, &xml, &xml_length, discovered_namespaces); if (ret != S_OK) return ret;
/* Prefix the XML header */ @@ -439,6 +492,7 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON const WSD_URI_LIST *xaddrs_list, const WSDXML_ELEMENT *hdr_any, const WSDXML_ELEMENT *ref_param_any, const WSDXML_ELEMENT *endpoint_ref_any, const WSDXML_ELEMENT *any) { + struct list *discoveredNamespaces = NULL; WSD_SOAP_HEADER soapHeader; WSD_APP_SEQUENCE sequence; WCHAR message_id[64]; @@ -450,13 +504,20 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON
if (!create_guid(message_id)) goto cleanup;
+ discoveredNamespaces = WSDAllocateLinkedMemory(NULL, sizeof(struct list)); + if (!discoveredNamespaces) goto cleanup; + + list_init(discoveredNamespaces); + populate_soap_header(&soapHeader, discoveryTo, actionHello, message_id, &sequence, hdr_any);
/* TODO: Populate message body */
/* Write and send the message */ - ret = write_and_send_message(impl, &soapHeader, NULL, NULL, NULL, APP_MAX_DELAY); + ret = write_and_send_message(impl, &soapHeader, NULL, discoveredNamespaces, NULL, APP_MAX_DELAY);
cleanup: + WSDFreeLinkedMemory(discoveredNamespaces); + return ret; } diff --git a/dlls/wsdapi/tests/discovery.c b/dlls/wsdapi/tests/discovery.c index d81dcdc..563c33c 100644 --- a/dlls/wsdapi/tests/discovery.c +++ b/dlls/wsdapi/tests/discovery.c @@ -506,6 +506,7 @@ static void Publish_tests(void) messageStorage *msgStorage; WSADATA wsaData; BOOL messageOK; + BOOL hello_message_seen = FALSE; int ret, i; HRESULT rc; ULONG ref; @@ -595,8 +596,8 @@ static void Publish_tests(void) msg = msgStorage->messages[i]; messageOK = FALSE;
- messageOK = (strstr(msg, "wsa:Actionhttp://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</wsa:Action>") != NULL); - messageOK = messageOK && (strstr(msg, endpointReferenceString) != NULL); + hello_message_seen = (strstr(msg, "wsa:Actionhttp://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</wsa:Action>") != NULL); + messageOK = hello_message_seen && (strstr(msg, endpointReferenceString) != NULL); messageOK = messageOK && (strstr(msg, "<wsd:AppSequence InstanceId="1" MessageNumber="1"></wsd:AppSequence>") != NULL); messageOK = messageOK && (strstr(msg, "wsd:MetadataVersion1</wsd:MetadataVersion>") != NULL);
@@ -610,7 +611,8 @@ static void Publish_tests(void)
heap_free(msgStorage);
- todo_wine ok(messageOK == TRUE, "Hello message not received\n"); + ok(hello_message_seen == TRUE, "Hello message not received\n"); + todo_wine ok(messageOK == TRUE, "Hello message metadata not received\n");
after_publish_test:
diff --git a/dlls/wsdapi/wsdapi_internal.h b/dlls/wsdapi/wsdapi_internal.h index 417eed9..47dde6b 100644 --- a/dlls/wsdapi/wsdapi_internal.h +++ b/dlls/wsdapi/wsdapi_internal.h @@ -62,4 +62,8 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON const WSD_URI_LIST *xaddrs_list, const WSDXML_ELEMENT *hdr_any, const WSDXML_ELEMENT *ref_param_any, const WSDXML_ELEMENT *endpoint_ref_any, const WSDXML_ELEMENT *any);
+/* xml.c */ + +LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value); + #endif diff --git a/dlls/wsdapi/xml.c b/dlls/wsdapi/xml.c index 4d6319c..fc02d8b 100644 --- a/dlls/wsdapi/xml.c +++ b/dlls/wsdapi/xml.c @@ -27,7 +27,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
-static LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value) +LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value) { int valueLen; LPWSTR dup;