Owen Rudge : wsdapi: Ignore duplicate messages.

Alexandre Julliard julliard at winehq.org
Thu Sep 20 13:45:32 CDT 2018


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

Author: Owen Rudge <orudge at codeweavers.com>
Date:   Wed Sep 19 21:29:05 2018 +0100

wsdapi: Ignore duplicate messages.

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/discovery.c       | 13 ++++++++++++
 dlls/wsdapi/network.c         |  2 +-
 dlls/wsdapi/soap.c            | 47 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/wsdapi/wsdapi_internal.h | 11 +++++++++-
 4 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/dlls/wsdapi/discovery.c b/dlls/wsdapi/discovery.c
index 7456f90..a016e8d 100644
--- a/dlls/wsdapi/discovery.c
+++ b/dlls/wsdapi/discovery.c
@@ -78,6 +78,7 @@ static ULONG WINAPI IWSDiscoveryPublisherImpl_Release(IWSDiscoveryPublisher *ifa
     IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
     struct notificationSink *sink, *cursor;
+    struct message_id *msg_id, *msg_id_cursor;
 
     TRACE("(%p) ref=%d\n", This, ref);
 
@@ -98,6 +99,15 @@ static ULONG WINAPI IWSDiscoveryPublisherImpl_Release(IWSDiscoveryPublisher *ifa
         }
 
         DeleteCriticalSection(&This->notification_sink_critical_section);
+
+        LIST_FOR_EACH_ENTRY_SAFE(msg_id, msg_id_cursor, &This->message_ids, struct message_id, entry)
+        {
+            heap_free(msg_id->id);
+            list_remove(&msg_id->entry);
+            heap_free(msg_id);
+        }
+
+        DeleteCriticalSection(&This->message_ids_critical_section);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -402,6 +412,9 @@ HRESULT WINAPI WSDCreateDiscoveryPublisher(IWSDXMLContext *pContext, IWSDiscover
     InitializeCriticalSection(&obj->notification_sink_critical_section);
     list_init(&obj->notificationSinks);
 
+    InitializeCriticalSection(&obj->message_ids_critical_section);
+    list_init(&obj->message_ids);
+
     *ppPublisher = &obj->IWSDiscoveryPublisher_iface;
     TRACE("Returning iface %p\n", *ppPublisher);
 
diff --git a/dlls/wsdapi/network.c b/dlls/wsdapi/network.c
index c8f260c..c7af2c3 100644
--- a/dlls/wsdapi/network.c
+++ b/dlls/wsdapi/network.c
@@ -302,7 +302,7 @@ static HRESULT process_received_message(listener_thread_params *params, char *me
     int msg_type;
     HRESULT ret;
 
-    ret = read_message(message, message_len, &msg, &msg_type);
+    ret = read_message(params->impl, message, message_len, &msg, &msg_type);
     if (FAILED(ret)) return ret;
 
     switch (msg_type)
diff --git a/dlls/wsdapi/soap.c b/dlls/wsdapi/soap.c
index bfa4f3b..e2746b9 100644
--- a/dlls/wsdapi/soap.c
+++ b/dlls/wsdapi/soap.c
@@ -1488,7 +1488,44 @@ static WSDXML_TYPE *generate_type(LPCWSTR uri, void *parent)
     return type;
 }
 
-HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg, int *msg_type)
+static BOOL is_duplicate_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id)
+{
+    struct message_id *msg_id, *msg_id_cursor;
+    BOOL ret = FALSE;
+    int len;
+
+    EnterCriticalSection(&impl->message_ids_critical_section);
+
+    LIST_FOR_EACH_ENTRY_SAFE(msg_id, msg_id_cursor, &impl->message_ids, struct message_id, entry)
+    {
+        if (lstrcmpW(msg_id->id, id) == 0)
+        {
+            ret = TRUE;
+            goto end;
+        }
+    }
+
+    msg_id = heap_alloc(sizeof(*msg_id));
+    if (!msg_id) goto end;
+
+    len = (lstrlenW(id) + 1) * sizeof(WCHAR);
+    msg_id->id = heap_alloc(len);
+
+    if (!msg_id->id)
+    {
+        heap_free(msg_id);
+        goto end;
+    }
+
+    memcpy(msg_id->id, id, len);
+    list_add_tail(&impl->message_ids, &msg_id->entry);
+
+end:
+    LeaveCriticalSection(&impl->message_ids_critical_section);
+    return ret;
+}
+
+HRESULT read_message(IWSDiscoveryPublisherImpl *impl, const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg, int *msg_type)
 {
     WSDXML_ELEMENT *envelope = NULL, *header_element, *appsequence_element, *body_element;
     WS_XML_READER_TEXT_ENCODING encoding;
@@ -1606,6 +1643,14 @@ HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg
 
     ret = WSDXMLGetValueFromAny(addressingNsUri, messageIdString, (WSDXML_ELEMENT *) header_element->FirstChild, &value);
     if (FAILED(ret)) goto cleanup;
+
+    /* Detect duplicate messages */
+    if (is_duplicate_message(impl, value))
+    {
+        ret = E_FAIL;
+        goto cleanup;
+    }
+
     soap_msg->Header.MessageID = duplicate_string(soap_msg, value);
     if (soap_msg->Header.MessageID == NULL) goto outofmemory;
 
diff --git a/dlls/wsdapi/wsdapi_internal.h b/dlls/wsdapi/wsdapi_internal.h
index 7dd08f9..3c9390a 100644
--- a/dlls/wsdapi/wsdapi_internal.h
+++ b/dlls/wsdapi/wsdapi_internal.h
@@ -40,6 +40,12 @@ struct notificationSink
     IWSDiscoveryPublisherNotify *notificationSink;
 };
 
+struct message_id
+{
+    struct list entry;
+    LPWSTR id;
+};
+
 #define MAX_WSD_THREADS        20
 
 typedef struct IWSDiscoveryPublisherImpl {
@@ -52,6 +58,8 @@ typedef struct IWSDiscoveryPublisherImpl {
     BOOL                  publisherStarted;
     HANDLE                thread_handles[MAX_WSD_THREADS];
     int                   num_thread_handles;
+    struct list           message_ids;
+    CRITICAL_SECTION      message_ids_critical_section;
 } IWSDiscoveryPublisherImpl;
 
 /* network.c */
@@ -72,7 +80,8 @@ HRESULT send_bye_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLONG
 
 HRESULT register_namespaces(IWSDXMLContext *xml_context);
 
-HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg, int *msg_type);
+HRESULT read_message(IWSDiscoveryPublisherImpl *impl, const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg,
+    int *msg_type);
 
 #define MSGTYPE_UNKNOWN     0
 #define MSGTYPE_PROBE       1




More information about the wine-cvs mailing list