Release 2.16.
[wine.git] / dlls / wsdapi / address.c
blob8e9d475118bca46a2fd93717d178e8d0039752bb
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
25 #include "winsock2.h"
26 #include "ws2tcpip.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/debug.h"
30 #include "wsdapi.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
34 typedef struct IWSDUdpAddressImpl {
35 IWSDUdpAddress IWSDUdpAddress_iface;
36 LONG ref;
37 SOCKADDR_STORAGE sockAddr;
38 WCHAR ipv4Address[25];
39 WCHAR ipv6Address[64];
40 WORD port;
41 WSDUdpMessageType messageType;
42 } IWSDUdpAddressImpl;
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);
55 if (!ppv)
57 WARN("Invalid parameter\n");
58 return E_INVALIDARG;
61 *ppv = NULL;
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;
70 else
72 WARN("Unknown IID %s\n", debugstr_guid(riid));
73 return E_NOINTERFACE;
76 IUnknown_AddRef((IUnknown*)*ppv);
77 return S_OK;
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);
86 return 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);
96 if (ref == 0)
98 HeapFree(GetProcessHeap(), 0, This);
101 return ref;
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);
107 return E_NOTIMPL;
110 static HRESULT WINAPI IWSDUdpAddressImpl_Deserialize(IWSDUdpAddress *This, LPCWSTR pszBuffer)
112 FIXME("(%p, %s)\n", This, debugstr_w(pszBuffer));
113 return E_NOTIMPL;
116 static HRESULT WINAPI IWSDUdpAddressImpl_GetPort(IWSDUdpAddress *This, WORD *pwPort)
118 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
120 TRACE("(%p, %p)\n", This, pwPort);
122 if (pwPort == NULL)
124 return E_POINTER;
127 *pwPort = impl->port;
128 return S_OK;
131 static HRESULT WINAPI IWSDUdpAddressImpl_SetPort(IWSDUdpAddress *This, WORD wPort)
133 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
135 TRACE("(%p, %d)\n", This, wPort);
137 impl->port = wPort;
138 return S_OK;
141 static HRESULT WINAPI IWSDUdpAddressImpl_GetTransportAddressEx(IWSDUdpAddress *This, BOOL fSafe, LPCWSTR *ppszAddress)
143 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
144 SOCKADDR_STORAGE storage;
145 DWORD size;
147 TRACE("(%p, %d, %p)\n", This, fSafe, ppszAddress);
149 if (ppszAddress == NULL)
150 return E_POINTER;
152 *ppszAddress = NULL;
154 switch (((SOCKADDR_IN *) &impl->sockAddr)->sin_family)
156 case AF_INET:
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;
162 return S_OK;
165 break;
167 case AF_INET6:
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));
173 if (!fSafe)
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;
179 return S_OK;
182 break;
184 default:
185 return S_OK;
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;
200 ADDRINFOW hints;
201 int ret;
203 TRACE("(%p, %s)\n", impl, debugstr_w(pszAddress));
205 if (pszAddress == NULL)
206 return E_INVALIDARG;
208 ZeroMemory(&hints, sizeof(hints));
209 hints.ai_family = AF_UNSPEC;
211 ret = GetAddrInfoW(pszAddress, NULL, &hints, &addrInfo);
213 if (ret == 0)
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)
233 return E_POINTER;
236 memcpy(&impl->sockAddr, pSockAddr, sizeof(SOCKADDR_STORAGE));
237 return S_OK;
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)
249 return E_POINTER;
252 /* Ensure the sockaddr is initialised correctly */
253 if ((sockAddr->sin_family != AF_INET) && (sockAddr->sin_family != AF_INET6))
255 return E_FAIL;
258 memcpy(pSockAddr, &impl->sockAddr, sizeof(SOCKADDR_STORAGE));
259 return S_OK;
262 static HRESULT WINAPI IWSDUdpAddressImpl_SetExclusive(IWSDUdpAddress *This, BOOL fExclusive)
264 FIXME("(%p, %d)\n", This, fExclusive);
265 return E_NOTIMPL;
268 static HRESULT WINAPI IWSDUdpAddressImpl_GetExclusive(IWSDUdpAddress *This)
270 FIXME("(%p)\n", This);
271 return E_NOTIMPL;
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;
281 return S_OK;
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)
292 return E_POINTER;
295 *pMessageType = impl->messageType;
296 return S_OK;
299 static HRESULT WINAPI IWSDUdpAddressImpl_SetTTL(IWSDUdpAddress *This, DWORD dwTTL)
301 FIXME("(%p, %d)\n", This, dwTTL);
302 return E_NOTIMPL;
305 static HRESULT WINAPI IWSDUdpAddressImpl_GetTTL(IWSDUdpAddress *This, DWORD *pdwTTL)
307 FIXME("(%p, %p)\n", This, pdwTTL);
308 return E_NOTIMPL;
311 static HRESULT WINAPI IWSDUdpAddressImpl_SetAlias(IWSDUdpAddress *This, const GUID *pAlias)
313 FIXME("(%p, %s)\n", This, debugstr_guid(pAlias));
314 return E_NOTIMPL;
317 static HRESULT WINAPI IWSDUdpAddressImpl_GetAlias(IWSDUdpAddress *This, GUID *pAlias)
319 FIXME("(%p, %p)\n", This, pAlias);
320 return E_NOTIMPL;
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");
356 return E_POINTER;
359 *ppAddress = NULL;
361 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
363 if (!obj)
365 WARN("Out of memory\n");
366 return E_OUTOFMEMORY;
369 obj->IWSDUdpAddress_iface.lpVtbl = &udpAddressVtbl;
370 obj->ref = 1;
372 *ppAddress = &obj->IWSDUdpAddress_iface;
373 TRACE("Returning iface %p\n", *ppAddress);
375 return S_OK;