| /* | |
| * Web Services on Devices | |
| * | |
| * Copyright 2017 Owen Rudge for CodeWeavers | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include <stdarg.h> | |
| #define COBJMACROS | |
| #define INITGUID | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "wine/debug.h" | |
| #include "wine/list.h" | |
| #include "objbase.h" | |
| #include "guiddef.h" | |
| #include "wsdapi.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(wsdapi); | |
| struct notificationSink | |
| { | |
| struct list entry; | |
| IWSDiscoveryPublisherNotify *notificationSink; | |
| }; | |
| typedef struct IWSDiscoveryPublisherImpl { | |
| IWSDiscoveryPublisher IWSDiscoveryPublisher_iface; | |
| LONG ref; | |
| IWSDXMLContext *xmlContext; | |
| DWORD addressFamily; | |
| struct list notificationSinks; | |
| } IWSDiscoveryPublisherImpl; | |
| static inline IWSDiscoveryPublisherImpl *impl_from_IWSDiscoveryPublisher(IWSDiscoveryPublisher *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IWSDiscoveryPublisherImpl, IWSDiscoveryPublisher_iface); | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_QueryInterface(IWSDiscoveryPublisher *iface, REFIID riid, void **ppv) | |
| { | |
| IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface); | |
| TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppv); | |
| if (!ppv) | |
| { | |
| WARN("Invalid parameter\n"); | |
| return E_INVALIDARG; | |
| } | |
| *ppv = NULL; | |
| if (IsEqualIID(riid, &IID_IUnknown) || | |
| IsEqualIID(riid, &IID_IWSDiscoveryPublisher)) | |
| { | |
| *ppv = &This->IWSDiscoveryPublisher_iface; | |
| } | |
| else | |
| { | |
| WARN("Unknown IID %s\n", debugstr_guid(riid)); | |
| return E_NOINTERFACE; | |
| } | |
| IUnknown_AddRef((IUnknown*)*ppv); | |
| return S_OK; | |
| } | |
| static ULONG WINAPI IWSDiscoveryPublisherImpl_AddRef(IWSDiscoveryPublisher *iface) | |
| { | |
| IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface); | |
| ULONG ref = InterlockedIncrement(&This->ref); | |
| TRACE("(%p) ref=%d\n", This, ref); | |
| return ref; | |
| } | |
| static ULONG WINAPI IWSDiscoveryPublisherImpl_Release(IWSDiscoveryPublisher *iface) | |
| { | |
| IWSDiscoveryPublisherImpl *This = impl_from_IWSDiscoveryPublisher(iface); | |
| ULONG ref = InterlockedDecrement(&This->ref); | |
| struct notificationSink *sink, *cursor; | |
| TRACE("(%p) ref=%d\n", This, ref); | |
| if (ref == 0) | |
| { | |
| if (This->xmlContext != NULL) | |
| { | |
| IWSDXMLContext_Release(This->xmlContext); | |
| } | |
| LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->notificationSinks, struct notificationSink, entry) | |
| { | |
| IWSDiscoveryPublisherNotify_Release(sink->notificationSink); | |
| list_remove(&sink->entry); | |
| HeapFree(GetProcessHeap(), 0, sink); | |
| } | |
| HeapFree(GetProcessHeap(), 0, This); | |
| } | |
| return ref; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_SetAddressFamily(IWSDiscoveryPublisher *This, DWORD dwAddressFamily) | |
| { | |
| IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This); | |
| TRACE("(%p, %d)\n", This, dwAddressFamily); | |
| /* Has the address family already been set? */ | |
| if (impl->addressFamily != 0) | |
| { | |
| return STG_E_INVALIDFUNCTION; | |
| } | |
| if ((dwAddressFamily == WSDAPI_ADDRESSFAMILY_IPV4) || (dwAddressFamily == WSDAPI_ADDRESSFAMILY_IPV6) || | |
| (dwAddressFamily == (WSDAPI_ADDRESSFAMILY_IPV4 | WSDAPI_ADDRESSFAMILY_IPV6))) | |
| { | |
| /* TODO: Check that the address family is supported by the system */ | |
| impl->addressFamily = dwAddressFamily; | |
| return S_OK; | |
| } | |
| return E_INVALIDARG; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_RegisterNotificationSink(IWSDiscoveryPublisher *This, IWSDiscoveryPublisherNotify *pSink) | |
| { | |
| IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This); | |
| struct notificationSink *sink; | |
| TRACE("(%p, %p)\n", This, pSink); | |
| if (pSink == NULL) | |
| { | |
| return E_INVALIDARG; | |
| } | |
| sink = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sink)); | |
| if (!sink) | |
| { | |
| return E_OUTOFMEMORY; | |
| } | |
| sink->notificationSink = pSink; | |
| IWSDiscoveryPublisherNotify_AddRef(pSink); | |
| list_add_tail(&impl->notificationSinks, &sink->entry); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnRegisterNotificationSink(IWSDiscoveryPublisher *This, IWSDiscoveryPublisherNotify *pSink) | |
| { | |
| IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This); | |
| struct notificationSink *sink; | |
| TRACE("(%p, %p)\n", This, pSink); | |
| if (pSink == NULL) | |
| { | |
| return E_INVALIDARG; | |
| } | |
| LIST_FOR_EACH_ENTRY(sink, &impl->notificationSinks, struct notificationSink, entry) | |
| { | |
| if (sink->notificationSink == pSink) | |
| { | |
| IWSDiscoveryPublisherNotify_Release(pSink); | |
| list_remove(&sink->entry); | |
| HeapFree(GetProcessHeap(), 0, sink); | |
| return S_OK; | |
| } | |
| } | |
| /* Notification sink is not registered */ | |
| return E_FAIL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_Publish(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullMetadataVersion, ULONGLONG ullInstanceId, | |
| ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, const WSD_NAME_LIST *pTypesList, | |
| const WSD_URI_LIST *pScopesList, const WSD_URI_LIST *pXAddrsList) | |
| { | |
| FIXME("(%p, %s, %s, %s, %s, %s, %p, %p, %p)\n", This, debugstr_w(pszId), wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), | |
| wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), pTypesList, pScopesList, pXAddrsList); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnPublish(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, | |
| LPCWSTR pszSessionId, const WSDXML_ELEMENT *pAny) | |
| { | |
| FIXME("(%p, %s, %s, %s, %s, %p)\n", This, debugstr_w(pszId), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), | |
| debugstr_w(pszSessionId), pAny); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchProbe(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pProbeMessage, | |
| IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion, | |
| ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, | |
| const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList, | |
| const WSD_URI_LIST *pXAddrsList) | |
| { | |
| FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p)\n", This, pProbeMessage, pMessageParameters, debugstr_w(pszId), | |
| wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), | |
| pTypesList, pScopesList, pXAddrsList); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchResolve(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pResolveMessage, | |
| IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion, | |
| ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, | |
| const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList, | |
| const WSD_URI_LIST *pXAddrsList) | |
| { | |
| FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p)\n", This, pResolveMessage, pMessageParameters, debugstr_w(pszId), | |
| wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), | |
| pTypesList, pScopesList, pXAddrsList); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_PublishEx(IWSDiscoveryPublisher *This, LPCWSTR pszId, ULONGLONG ullMetadataVersion, | |
| ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, | |
| const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList, | |
| const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny, | |
| const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny, | |
| const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny) | |
| { | |
| FIXME("(%p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, debugstr_w(pszId), wine_dbgstr_longlong(ullMetadataVersion), | |
| wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), pTypesList, pScopesList, pXAddrsList, | |
| pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchProbeEx(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pProbeMessage, | |
| IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion, | |
| ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, | |
| const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList, | |
| const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny, | |
| const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny, | |
| const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny) | |
| { | |
| FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, pProbeMessage, pMessageParameters, debugstr_w(pszId), | |
| wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), | |
| pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_MatchResolveEx(IWSDiscoveryPublisher *This, const WSD_SOAP_MESSAGE *pResolveMessage, | |
| IWSDMessageParameters *pMessageParameters, LPCWSTR pszId, ULONGLONG ullMetadataVersion, | |
| ULONGLONG ullInstanceId, ULONGLONG ullMessageNumber, LPCWSTR pszSessionId, | |
| const WSD_NAME_LIST *pTypesList, const WSD_URI_LIST *pScopesList, | |
| const WSD_URI_LIST *pXAddrsList, const WSDXML_ELEMENT *pHeaderAny, | |
| const WSDXML_ELEMENT *pReferenceParameterAny, const WSDXML_ELEMENT *pPolicyAny, | |
| const WSDXML_ELEMENT *pEndpointReferenceAny, const WSDXML_ELEMENT *pAny) | |
| { | |
| FIXME("(%p, %p, %p, %s, %s, %s, %s, %s, %p, %p, %p, %p, %p, %p, %p, %p)\n", This, pResolveMessage, pMessageParameters, debugstr_w(pszId), | |
| wine_dbgstr_longlong(ullMetadataVersion), wine_dbgstr_longlong(ullInstanceId), wine_dbgstr_longlong(ullMessageNumber), debugstr_w(pszSessionId), | |
| pTypesList, pScopesList, pXAddrsList, pHeaderAny, pReferenceParameterAny, pPolicyAny, pEndpointReferenceAny, pAny); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_RegisterScopeMatchingRule(IWSDiscoveryPublisher *This, IWSDScopeMatchingRule *pScopeMatchingRule) | |
| { | |
| FIXME("(%p, %p)\n", This, pScopeMatchingRule); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_UnRegisterScopeMatchingRule(IWSDiscoveryPublisher *This, IWSDScopeMatchingRule *pScopeMatchingRule) | |
| { | |
| FIXME("(%p, %p)\n", This, pScopeMatchingRule); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IWSDiscoveryPublisherImpl_GetXMLContext(IWSDiscoveryPublisher *This, IWSDXMLContext **ppContext) | |
| { | |
| IWSDiscoveryPublisherImpl *impl = impl_from_IWSDiscoveryPublisher(This); | |
| TRACE("%p, %p)\n", This, ppContext); | |
| if (ppContext == NULL) | |
| return E_INVALIDARG; | |
| if (impl->xmlContext != NULL) | |
| { | |
| IWSDXMLContext_AddRef(impl->xmlContext); | |
| } | |
| *ppContext = impl->xmlContext; | |
| return S_OK; | |
| } | |
| static const IWSDiscoveryPublisherVtbl publisher_vtbl = | |
| { | |
| IWSDiscoveryPublisherImpl_QueryInterface, | |
| IWSDiscoveryPublisherImpl_AddRef, | |
| IWSDiscoveryPublisherImpl_Release, | |
| IWSDiscoveryPublisherImpl_SetAddressFamily, | |
| IWSDiscoveryPublisherImpl_RegisterNotificationSink, | |
| IWSDiscoveryPublisherImpl_UnRegisterNotificationSink, | |
| IWSDiscoveryPublisherImpl_Publish, | |
| IWSDiscoveryPublisherImpl_UnPublish, | |
| IWSDiscoveryPublisherImpl_MatchProbe, | |
| IWSDiscoveryPublisherImpl_MatchResolve, | |
| IWSDiscoveryPublisherImpl_PublishEx, | |
| IWSDiscoveryPublisherImpl_MatchProbeEx, | |
| IWSDiscoveryPublisherImpl_MatchResolveEx, | |
| IWSDiscoveryPublisherImpl_RegisterScopeMatchingRule, | |
| IWSDiscoveryPublisherImpl_UnRegisterScopeMatchingRule, | |
| IWSDiscoveryPublisherImpl_GetXMLContext | |
| }; | |
| HRESULT WINAPI WSDCreateDiscoveryPublisher(IWSDXMLContext *pContext, IWSDiscoveryPublisher **ppPublisher) | |
| { | |
| IWSDiscoveryPublisherImpl *obj; | |
| TRACE("(%p, %p)\n", pContext, ppPublisher); | |
| if (ppPublisher == NULL) | |
| { | |
| WARN("Invalid parameter: ppPublisher == NULL\n"); | |
| return E_POINTER; | |
| } | |
| *ppPublisher = NULL; | |
| obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj)); | |
| if (!obj) | |
| { | |
| WARN("Out of memory\n"); | |
| return E_OUTOFMEMORY; | |
| } | |
| obj->IWSDiscoveryPublisher_iface.lpVtbl = &publisher_vtbl; | |
| obj->ref = 1; | |
| if (pContext == NULL) | |
| { | |
| if (FAILED(WSDXMLCreateContext(&obj->xmlContext))) | |
| { | |
| WARN("Unable to create XML context\n"); | |
| HeapFree (GetProcessHeap(), 0, obj); | |
| return E_OUTOFMEMORY; | |
| } | |
| } | |
| else | |
| { | |
| obj->xmlContext = pContext; | |
| IWSDXMLContext_AddRef(pContext); | |
| } | |
| list_init(&obj->notificationSinks); | |
| *ppPublisher = &obj->IWSDiscoveryPublisher_iface; | |
| TRACE("Returning iface %p\n", *ppPublisher); | |
| return S_OK; | |
| } |