msxml4/tests: Copy namespaces as attributes tests.
[wine.git] / dlls / wsdapi / discovery.c
blob837db483ce62cb572a1e81ffe17a3e140deafa21
1 /*
2 * Web Services on Devices
4 * Copyright 2017 Owen Rudge for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define INITGUID
26 #include "wsdapi_internal.h"
27 #include "wine/debug.h"
28 #include "guiddef.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
32 static inline IWSDiscoveryPublisherImpl *impl_from_IWSDiscoveryPublisher(IWSDiscoveryPublisher *iface)
34 return CONTAINING_RECORD(iface, IWSDiscoveryPublisherImpl, IWSDiscoveryPublisher_iface);
37 static HRESULT WINAPI IWSDiscoveryPublisherImpl_QueryInterface(IWSDiscoveryPublisher *iface, REFIID riid, void **ppv)
39 IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface);
41 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppv);
43 if (!ppv)
45 WARN("Invalid parameter\n");
46 return E_INVALIDARG;
49 *ppv = NULL;
51 if (IsEqualIID(riid, &IID_IUnknown) ||
52 IsEqualIID(riid, &IID_IWSDiscoveryPublisher))
54 *ppv = &This->IWSDiscoveryPublisher_iface;
56 else
58 WARN("Unknown IID %s\n", debugstr_guid(riid));
59 return E_NOINTERFACE;
62 IUnknown_AddRef((IUnknown*)*ppv);
63 return S_OK;
66 static ULONG WINAPI IWSDiscoveryPublisherImpl_AddRef(IWSDiscoveryPublisher *iface)
68 IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface);
69 ULONG ref = InterlockedIncrement(&This->ref);
71 TRACE("(%p) ref=%ld\n", This, ref);
72 return ref;
75 static ULONG WINAPI IWSDiscoveryPublisherImpl_Release(IWSDiscoveryPublisher *iface)
77 IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface);
78 ULONG ref = InterlockedDecrement(&This->ref);
79 struct notificationSink *sink, *cursor;
80 struct message_id *msg_id, *msg_id_cursor;
82 TRACE("(%p) ref=%ld\n", This, ref);
84 if (ref == 0)
86 terminate_networking(This);
88 if (This->xmlContext != NULL)
90 IWSDXMLContext_Release(This->xmlContext);
93 LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->notificationSinks, struct notificationSink, entry)
95 IWSDiscoveryPublisherNotify_Release(sink->notificationSink);
96 list_remove(&sink->entry);
97 free(sink);
100 DeleteCriticalSection(&This->notification_sink_critical_section);
102 LIST_FOR_EACH_ENTRY_SAFE(msg_id, msg_id_cursor, &This->message_ids, struct message_id, entry)
104 free(msg_id->id);
105 list_remove(&msg_id->entry);
106 free(msg_id);
109 DeleteCriticalSection(&This->message_ids_critical_section);
110 free(This);
113 return ref;
116 static HRESULT WINAPI IWSDiscoveryPublisherImpl_SetAddressFamily(IWSDiscoveryPublisher *This, DWORD dwAddressFamily)
118 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
120 TRACE("(%p, %ld)\n", This, dwAddressFamily);
122 /* Has the address family already been set? */
123 if (impl->addressFamily != 0)
125 return STG_E_INVALIDFUNCTION;
128 if ((dwAddressFamily == WSDAPI_ADDRESSFAMILY_IPV4) || (dwAddressFamily == WSDAPI_ADDRESSFAMILY_IPV6) ||
129 (dwAddressFamily == (WSDAPI_ADDRESSFAMILY_IPV4 | WSDAPI_ADDRESSFAMILY_IPV6)))
131 /* TODO: Check that the address family is supported by the system */
132 impl->addressFamily = dwAddressFamily;
133 return S_OK;
136 return E_INVALIDARG;
139 static HRESULT WINAPI IWSDiscoveryPublisherImpl_RegisterNotificationSink(IWSDiscoveryPublisher *This, IWSDiscoveryPublisherNotify *pSink)
141 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
142 struct notificationSink *sink;
144 TRACE("(%p, %p)\n", This, pSink);
146 if (pSink == NULL)
148 return E_INVALIDARG;
151 sink = calloc(1, sizeof(*sink));
153 if (!sink)
155 return E_OUTOFMEMORY;
158 sink->notificationSink = pSink;
159 IWSDiscoveryPublisherNotify_AddRef(pSink);
161 EnterCriticalSection(&impl->notification_sink_critical_section);
162 list_add_tail(&impl->notificationSinks, &sink->entry);
163 LeaveCriticalSection(&impl->notification_sink_critical_section);
165 if ((!impl->publisherStarted) && (!init_networking(impl)))
166 return E_FAIL;
168 return S_OK;
171 static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnRegisterNotificationSink(IWSDiscoveryPublisher *This, IWSDiscoveryPublisherNotify *pSink)
173 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
174 struct notificationSink *sink;
176 TRACE("(%p, %p)\n", This, pSink);
178 if (pSink == NULL)
180 return E_INVALIDARG;
183 EnterCriticalSection(&impl->notification_sink_critical_section);
185 LIST_FOR_EACH_ENTRY(sink, &impl->notificationSinks, struct notificationSink, entry)
187 if (sink->notificationSink == pSink)
189 IWSDiscoveryPublisherNotify_Release(pSink);
190 list_remove(&sink->entry);
191 free(sink);
193 LeaveCriticalSection(&impl->notification_sink_critical_section);
194 return S_OK;
198 LeaveCriticalSection(&impl->notification_sink_critical_section);
200 /* Notification sink is not registered */
201 return E_FAIL;
204 static HRESULT WINAPI IWSDiscoveryPublisherImpl_Publish(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullMetadataVersion, ULONGLONG ullInstanceId,
205 ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, const WSD_NAME_LIST *pTypesList,
206 const WSD_URI_LIST *pScopesList, const WSD_URI_LIST *pXAddrsList)
208 return IWSDiscoveryPublisher_PublishEx(This, pszId, ullMetadataVersion, ullInstanceId, ullMessageNumber,
209 pszSessionId, pTypesList, pScopesList, pXAddrsList, NULL, NULL, NULL, NULL, NULL);
212 static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnPublish(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber,
213 LPCWSTR pszSessionId, const WSDXML_ELEMENT *pAny)
215 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
217 TRACE("(%p, %s, %s, %s, %s, %p)\n", This, debugstr_w(pszId), wine_dbgstr_longlong(ullInstanceId),
218 wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), pAny);
220 if ((!impl->publisherStarted) || (pszId == NULL) || (lstrlenW(pszId) > WSD_MAX_TEXT_LENGTH) ||
221 ((pszSessionId != NULL) && (lstrlenW(pszSessionId) > WSD_MAX_TEXT_LENGTH)))
223 return E_INVALIDARG;
226 return send_bye_message(impl, pszId, ullInstanceId, ullMessageNumber, pszSessionId, pAny);
229 static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchProbe(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pProbeMessage,
230 IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion,
231 ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId,
232 const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList,
233 const WSD_URI_LIST *pXAddrsList)
235 TRACE("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p)\n", This, pProbeMessage, pMessageParameters, debugstr_w(pszId),
236 wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId),
237 pTypesList, pScopesList, pXAddrsList);
239 return IWSDiscoveryPublisher_MatchProbeEx(This, pProbeMessage, pMessageParameters, pszId, ullMetadataVersion,
240 ullInstanceId, ullMessageNumber, pszSessionId, pTypesList, pScopesList, pXAddrsList, NULL, NULL, NULL, NULL,
241 NULL);
244 static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchResolve(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pResolveMessage,
245 IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion,
246 ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId,
247 const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList,
248 const WSD_URI_LIST *pXAddrsList)
250 FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p)\n", This, pResolveMessage, pMessageParameters, debugstr_w(pszId),
251 wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId),
252 pTypesList, pScopesList, pXAddrsList);
254 return E_NOTIMPL;
257 static HRESULT WINAPI IWSDiscoveryPublisherImpl_PublishEx(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullMetadataVersion,
258 ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId,
259 const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList,
260 const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny,
261 const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny,
262 const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny)
264 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
266 TRACE("(%p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, debugstr_w(pszId), wine_dbgstr_longlong(ullMetadataVersion),
267 wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), pTypesList, pScopesList, pXAddrsList,
268 pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny);
270 if ((!impl->publisherStarted) || (pszId == NULL) || (lstrlenW(pszId) > WSD_MAX_TEXT_LENGTH) ||
271 ((pszSessionId != NULL) && (lstrlenW(pszSessionId) > WSD_MAX_TEXT_LENGTH)))
273 return E_INVALIDARG;
276 return send_hello_message(impl, pszId, ullMetadataVersion, ullInstanceId, ullMessageNumber, pszSessionId,
277 pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny, pEndpointReferenceAny, pAny);
280 static BOOL is_name_in_list(WSDXML_NAME *name, const WSD_NAME_LIST *list)
282 const WSD_NAME_LIST *next = list;
284 while (next != NULL)
286 if ((lstrcmpW(next->Element->LocalName, name->LocalName) == 0) &&
287 (lstrcmpW(next->Element->Space->PreferredPrefix, name->Space->PreferredPrefix) == 0))
289 return TRUE;
292 next = next->Next;
295 return FALSE;
298 static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchProbeEx(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pProbeMessage,
299 IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion,
300 ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId,
301 const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList,
302 const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny,
303 const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny,
304 const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny)
306 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
307 WSD_NAME_LIST *next_name;
308 WSD_PROBE *probe_msg;
310 TRACE("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, pProbeMessage, pMessageParameters, debugstr_w(pszId),
311 wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId),
312 pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny);
314 if (!impl->publisherStarted) return E_ABORT;
316 if ((pszId == NULL) || (lstrlenW(pszId) > WSD_MAX_TEXT_LENGTH) ||
317 ((pszSessionId != NULL) && (lstrlenW(pszSessionId) > WSD_MAX_TEXT_LENGTH)) || (pProbeMessage == NULL) ||
318 (pProbeMessage->Body == NULL))
320 return E_INVALIDARG;
323 probe_msg = (WSD_PROBE *) pProbeMessage->Body;
324 next_name = probe_msg->Types;
326 /* Verify that all names in the probe message are present in the types list */
327 while (next_name != NULL)
329 /* If a name isn't present, return success; we simply don't send a Probe Match message */
330 if (!is_name_in_list(next_name->Element, pTypesList)) return S_OK;
332 next_name = next_name->Next;
335 if ((probe_msg->Scopes != NULL) && (probe_msg->Scopes->Scopes != NULL))
336 FIXME("Scopes matching currently unimplemented\n");
338 return send_probe_matches_message(impl, pProbeMessage, pMessageParameters, pszId, ullMetadataVersion, ullInstanceId,
339 ullMessageNumber, pszSessionId, pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny,
340 pEndpointReferenceAny, pAny);
343 static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchResolveEx(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pResolveMessage,
344 IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion,
345 ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId,
346 const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList,
347 const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny,
348 const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny,
349 const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny)
351 FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, pResolveMessage, pMessageParameters, debugstr_w(pszId),
352 wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId),
353 pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny);
355 return E_NOTIMPL;
358 static HRESULT WINAPI IWSDiscoveryPublisherImpl_RegisterScopeMatchingRule(IWSDiscoveryPublisher *This, IWSDScopeMatchingRule *pScopeMatchingRule)
360 FIXME("(%p, %p)\n", This, pScopeMatchingRule);
361 return E_NOTIMPL;
364 static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnRegisterScopeMatchingRule(IWSDiscoveryPublisher *This, IWSDScopeMatchingRule *pScopeMatchingRule)
366 FIXME("(%p, %p)\n", This, pScopeMatchingRule);
367 return E_NOTIMPL;
370 static HRESULT WINAPI IWSDiscoveryPublisherImpl_GetXMLContext(IWSDiscoveryPublisher *This, IWSDXMLContext **ppContext)
372 IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This);
374 TRACE("%p, %p)\n", This, ppContext);
376 if (ppContext == NULL)
377 return E_INVALIDARG;
379 if (impl->xmlContext != NULL)
381 IWSDXMLContext_AddRef(impl->xmlContext);
384 *ppContext = impl->xmlContext;
385 return S_OK;
388 static const IWSDiscoveryPublisherVtbl publisher_vtbl =
390 IWSDiscoveryPublisherImpl_QueryInterface,
391 IWSDiscoveryPublisherImpl_AddRef,
392 IWSDiscoveryPublisherImpl_Release,
393 IWSDiscoveryPublisherImpl_SetAddressFamily,
394 IWSDiscoveryPublisherImpl_RegisterNotificationSink,
395 IWSDiscoveryPublisherImpl_UnRegisterNotificationSink,
396 IWSDiscoveryPublisherImpl_Publish,
397 IWSDiscoveryPublisherImpl_UnPublish,
398 IWSDiscoveryPublisherImpl_MatchProbe,
399 IWSDiscoveryPublisherImpl_MatchResolve,
400 IWSDiscoveryPublisherImpl_PublishEx,
401 IWSDiscoveryPublisherImpl_MatchProbeEx,
402 IWSDiscoveryPublisherImpl_MatchResolveEx,
403 IWSDiscoveryPublisherImpl_RegisterScopeMatchingRule,
404 IWSDiscoveryPublisherImpl_UnRegisterScopeMatchingRule,
405 IWSDiscoveryPublisherImpl_GetXMLContext
408 HRESULT WINAPI WSDCreateDiscoveryPublisher(IWSDXMLContext *pContext, IWSDiscoveryPublisher **ppPublisher)
410 IWSDiscoveryPublisherImpl *obj;
411 HRESULT ret;
413 TRACE("(%p, %p)\n", pContext, ppPublisher);
415 if (ppPublisher == NULL)
417 WARN("Invalid parameter: ppPublisher == NULL\n");
418 return E_POINTER;
421 *ppPublisher = NULL;
423 obj = calloc(1, sizeof(*obj));
425 if (!obj)
427 WARN("Out of memory\n");
428 return E_OUTOFMEMORY;
431 obj->IWSDiscoveryPublisher_iface.lpVtbl = &publisher_vtbl;
432 obj->ref = 1;
434 if (pContext == NULL)
436 ret = WSDXMLCreateContext(&obj->xmlContext);
438 if (FAILED(ret))
440 WARN("Unable to create XML context\n");
441 free(obj);
442 return ret;
445 else
447 obj->xmlContext = pContext;
448 IWSDXMLContext_AddRef(pContext);
451 ret = register_namespaces(obj->xmlContext);
453 if (FAILED(ret))
455 WARN("Unable to register default namespaces\n");
456 free(obj);
458 return ret;
461 InitializeCriticalSection(&obj->notification_sink_critical_section);
462 list_init(&obj->notificationSinks);
464 InitializeCriticalSection(&obj->message_ids_critical_section);
465 list_init(&obj->message_ids);
467 *ppPublisher = &obj->IWSDiscoveryPublisher_iface;
468 TRACE("Returning iface %p\n", *ppPublisher);
470 return S_OK;
473 HRESULT WINAPI WSDCreateDiscoveryProvider(IWSDXMLContext *context, IWSDiscoveryProvider **provider)
475 FIXME("(%p, %p) stub\n", context, provider);
477 return E_NOTIMPL;