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
29 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wsdapi
);
34 typedef struct IWSDUdpAddressImpl
{
35 IWSDUdpAddress IWSDUdpAddress_iface
;
37 SOCKADDR_STORAGE sockAddr
;
38 WCHAR ipv4Address
[25];
39 WCHAR ipv6Address
[64];
41 WSDUdpMessageType messageType
;
44 static inline IWSDUdpAddressImpl
*impl_from_IWSDUdpAddress(IWSDUdpAddress
*iface
)
46 return CONTAINING_RECORD(iface
, IWSDUdpAddressImpl
, IWSDUdpAddress_iface
);
49 static HRESULT WINAPI
IWSDUdpAddressImpl_QueryInterface(IWSDUdpAddress
*iface
, REFIID riid
, void **ppv
)
51 IWSDUdpAddressImpl
*This
= impl_from_IWSDUdpAddress(iface
);
53 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppv
);
57 WARN("Invalid parameter\n");
63 if (IsEqualIID(riid
, &IID_IUnknown
) ||
64 IsEqualIID(riid
, &IID_IWSDUdpAddress
) ||
65 IsEqualIID(riid
, &IID_IWSDTransportAddress
) ||
66 IsEqualIID(riid
, &IID_IWSDAddress
))
68 *ppv
= &This
->IWSDUdpAddress_iface
;
72 WARN("Unknown IID %s\n", debugstr_guid(riid
));
76 IUnknown_AddRef((IUnknown
*)*ppv
);
80 static ULONG WINAPI
IWSDUdpAddressImpl_AddRef(IWSDUdpAddress
*iface
)
82 IWSDUdpAddressImpl
*This
= impl_from_IWSDUdpAddress(iface
);
83 ULONG ref
= InterlockedIncrement(&This
->ref
);
85 TRACE("(%p) ref=%d\n", This
, ref
);
89 static ULONG WINAPI
IWSDUdpAddressImpl_Release(IWSDUdpAddress
*iface
)
91 IWSDUdpAddressImpl
*This
= impl_from_IWSDUdpAddress(iface
);
92 ULONG ref
= InterlockedDecrement(&This
->ref
);
94 TRACE("(%p) ref=%d\n", This
, ref
);
98 HeapFree(GetProcessHeap(), 0, This
);
104 static HRESULT WINAPI
IWSDUdpAddressImpl_Serialize(IWSDUdpAddress
*This
, LPWSTR pszBuffer
, DWORD cchLength
, BOOL fSafe
)
106 FIXME("(%p, %p, %d, %d)\n", This
, pszBuffer
, cchLength
, fSafe
);
110 static HRESULT WINAPI
IWSDUdpAddressImpl_Deserialize(IWSDUdpAddress
*This
, LPCWSTR pszBuffer
)
112 FIXME("(%p, %s)\n", This
, debugstr_w(pszBuffer
));
116 static HRESULT WINAPI
IWSDUdpAddressImpl_GetPort(IWSDUdpAddress
*This
, WORD
*pwPort
)
118 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
120 TRACE("(%p, %p)\n", This
, pwPort
);
127 *pwPort
= impl
->port
;
131 static HRESULT WINAPI
IWSDUdpAddressImpl_SetPort(IWSDUdpAddress
*This
, WORD wPort
)
133 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
135 TRACE("(%p, %d)\n", This
, wPort
);
141 static HRESULT WINAPI
IWSDUdpAddressImpl_GetTransportAddressEx(IWSDUdpAddress
*This
, BOOL fSafe
, LPCWSTR
*ppszAddress
)
143 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
144 SOCKADDR_STORAGE storage
;
147 TRACE("(%p, %d, %p)\n", This
, fSafe
, ppszAddress
);
149 if (ppszAddress
== NULL
)
154 switch (((SOCKADDR_IN
*) &impl
->sockAddr
)->sin_family
)
157 size
= sizeof(impl
->ipv4Address
) / sizeof(WCHAR
);
159 if (WSAAddressToStringW((LPSOCKADDR
) &impl
->sockAddr
, sizeof(SOCKADDR_IN
), NULL
, impl
->ipv4Address
, &size
) == 0)
161 *ppszAddress
= impl
->ipv4Address
;
168 size
= sizeof(impl
->ipv6Address
) / sizeof(WCHAR
);
170 /* Copy the SOCKADDR structure so we can remove the scope ID if not required */
171 memcpy(&storage
, &impl
->sockAddr
, sizeof(SOCKADDR_IN6
));
174 ((SOCKADDR_IN6
*) &storage
)->sin6_scope_id
= 0;
176 if (WSAAddressToStringW((LPSOCKADDR
) &storage
, sizeof(SOCKADDR_IN6
), NULL
, impl
->ipv6Address
, &size
) == 0)
178 *ppszAddress
= impl
->ipv6Address
;
188 return HRESULT_FROM_WIN32(WSAGetLastError());
191 static HRESULT WINAPI
IWSDUdpAddressImpl_GetTransportAddress(IWSDUdpAddress
*This
, LPCWSTR
*ppszAddress
)
193 return IWSDUdpAddressImpl_GetTransportAddressEx(This
, FALSE
, ppszAddress
);
196 static HRESULT WINAPI
IWSDUdpAddressImpl_SetTransportAddress(IWSDUdpAddress
*This
, LPCWSTR pszAddress
)
198 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
199 ADDRINFOW
*addrInfo
= NULL
;
203 TRACE("(%p, %s)\n", impl
, debugstr_w(pszAddress
));
205 if (pszAddress
== NULL
)
208 ZeroMemory(&hints
, sizeof(hints
));
209 hints
.ai_family
= AF_UNSPEC
;
211 ret
= GetAddrInfoW(pszAddress
, NULL
, &hints
, &addrInfo
);
215 ZeroMemory(&impl
->sockAddr
, sizeof(SOCKADDR_STORAGE
));
216 memcpy(&impl
->sockAddr
, addrInfo
->ai_addr
, addrInfo
->ai_addrlen
);
219 if (addrInfo
!= NULL
)
220 FreeAddrInfoW(addrInfo
);
222 return HRESULT_FROM_WIN32(ret
);
225 static HRESULT WINAPI
IWSDUdpAddressImpl_SetSockaddr(IWSDUdpAddress
*This
, const SOCKADDR_STORAGE
*pSockAddr
)
227 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
229 TRACE("(%p, %p)\n", This
, pSockAddr
);
231 if (pSockAddr
== NULL
)
236 memcpy(&impl
->sockAddr
, pSockAddr
, sizeof(SOCKADDR_STORAGE
));
240 static HRESULT WINAPI
IWSDUdpAddressImpl_GetSockaddr(IWSDUdpAddress
*This
, SOCKADDR_STORAGE
*pSockAddr
)
242 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
243 SOCKADDR_IN
*sockAddr
= (SOCKADDR_IN
*) &impl
->sockAddr
;
245 TRACE("(%p, %p)\n", This
, pSockAddr
);
247 if (pSockAddr
== NULL
)
252 /* Ensure the sockaddr is initialised correctly */
253 if ((sockAddr
->sin_family
!= AF_INET
) && (sockAddr
->sin_family
!= AF_INET6
))
258 memcpy(pSockAddr
, &impl
->sockAddr
, sizeof(SOCKADDR_STORAGE
));
262 static HRESULT WINAPI
IWSDUdpAddressImpl_SetExclusive(IWSDUdpAddress
*This
, BOOL fExclusive
)
264 FIXME("(%p, %d)\n", This
, fExclusive
);
268 static HRESULT WINAPI
IWSDUdpAddressImpl_GetExclusive(IWSDUdpAddress
*This
)
270 FIXME("(%p)\n", This
);
274 static HRESULT WINAPI
IWSDUdpAddressImpl_SetMessageType(IWSDUdpAddress
*This
, WSDUdpMessageType messageType
)
276 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
278 TRACE("(%p, %d)\n", This
, messageType
);
280 impl
->messageType
= messageType
;
284 static HRESULT WINAPI
IWSDUdpAddressImpl_GetMessageType(IWSDUdpAddress
*This
, WSDUdpMessageType
*pMessageType
)
286 IWSDUdpAddressImpl
*impl
= impl_from_IWSDUdpAddress(This
);
288 TRACE("(%p, %p)\n", This
, pMessageType
);
290 if (pMessageType
== NULL
)
295 *pMessageType
= impl
->messageType
;
299 static HRESULT WINAPI
IWSDUdpAddressImpl_SetTTL(IWSDUdpAddress
*This
, DWORD dwTTL
)
301 FIXME("(%p, %d)\n", This
, dwTTL
);
305 static HRESULT WINAPI
IWSDUdpAddressImpl_GetTTL(IWSDUdpAddress
*This
, DWORD
*pdwTTL
)
307 FIXME("(%p, %p)\n", This
, pdwTTL
);
311 static HRESULT WINAPI
IWSDUdpAddressImpl_SetAlias(IWSDUdpAddress
*This
, const GUID
*pAlias
)
313 FIXME("(%p, %s)\n", This
, debugstr_guid(pAlias
));
317 static HRESULT WINAPI
IWSDUdpAddressImpl_GetAlias(IWSDUdpAddress
*This
, GUID
*pAlias
)
319 FIXME("(%p, %p)\n", This
, pAlias
);
323 static const IWSDUdpAddressVtbl udpAddressVtbl
=
325 IWSDUdpAddressImpl_QueryInterface
,
326 IWSDUdpAddressImpl_AddRef
,
327 IWSDUdpAddressImpl_Release
,
328 IWSDUdpAddressImpl_Serialize
,
329 IWSDUdpAddressImpl_Deserialize
,
330 IWSDUdpAddressImpl_GetPort
,
331 IWSDUdpAddressImpl_SetPort
,
332 IWSDUdpAddressImpl_GetTransportAddress
,
333 IWSDUdpAddressImpl_GetTransportAddressEx
,
334 IWSDUdpAddressImpl_SetTransportAddress
,
335 IWSDUdpAddressImpl_SetSockaddr
,
336 IWSDUdpAddressImpl_GetSockaddr
,
337 IWSDUdpAddressImpl_SetExclusive
,
338 IWSDUdpAddressImpl_GetExclusive
,
339 IWSDUdpAddressImpl_SetMessageType
,
340 IWSDUdpAddressImpl_GetMessageType
,
341 IWSDUdpAddressImpl_SetTTL
,
342 IWSDUdpAddressImpl_GetTTL
,
343 IWSDUdpAddressImpl_SetAlias
,
344 IWSDUdpAddressImpl_GetAlias
347 HRESULT WINAPI
WSDCreateUdpAddress(IWSDUdpAddress
**ppAddress
)
349 IWSDUdpAddressImpl
*obj
;
351 TRACE("(%p)\n", ppAddress
);
353 if (ppAddress
== NULL
)
355 WARN("Invalid parameter: ppAddress == NULL\n");
361 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*obj
));
365 WARN("Out of memory\n");
366 return E_OUTOFMEMORY
;
369 obj
->IWSDUdpAddress_iface
.lpVtbl
= &udpAddressVtbl
;
372 *ppAddress
= &obj
->IWSDUdpAddress_iface
;
373 TRACE("Returning iface %p\n", *ppAddress
);