From: Owen Rudge Subject: [PATCH 1/6] wsdapi: Ignore duplicate messages. Message-Id: Date: Wed, 19 Sep 2018 21:29:05 +0100 Dropped unrequired critical section -> SRW changes. Signed-off-by: Owen Rudge --- 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 7456f90372..a016e8deac 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 c8f260c765..c7af2c3dfa 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 bfa4f3b0cd..e2746b9833 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 7dd08f9f0d..3c9390a899 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