mfplay: Implement GetCharacteristics().
[wine/zf.git] / dlls / wsdapi / address.c
blob7f11f48ce7c70ee2b70fcb50be8dc19973c7b46e
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 "wsdapi_internal.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
30 typedef struct IWSDUdpAddressImpl {
31 IWSDUdpAddress IWSDUdpAddress_iface;
32 LONG ref;
33 SOCKADDR_STORAGE sockAddr;
34 WCHAR ipv4Address[25];
35 WCHAR ipv6Address[64];
36 WORD port;
37 WSDUdpMessageType messageType;
38 } IWSDUdpAddressImpl;
40 static inline IWSDUdpAddressImpl *impl_from_IWSDUdpAddress(IWSDUdpAddress *iface)
42 return CONTAINING_RECORD(iface, IWSDUdpAddressImpl, IWSDUdpAddress_iface);
45 static HRESULT WINAPI IWSDUdpAddressImpl_QueryInterface(IWSDUdpAddress *iface, REFIID riid, void **ppv)
47 IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);
49 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppv);
51 if (!ppv)
53 WARN("Invalid parameter\n");
54 return E_INVALIDARG;
57 *ppv = NULL;
59 if (IsEqualIID(riid, &IID_IUnknown) ||
60 IsEqualIID(riid, &IID_IWSDUdpAddress) ||
61 IsEqualIID(riid, &IID_IWSDTransportAddress) ||
62 IsEqualIID(riid, &IID_IWSDAddress))
64 *ppv = &This->IWSDUdpAddress_iface;
66 else
68 WARN("Unknown IID %s\n", debugstr_guid(riid));
69 return E_NOINTERFACE;
72 IUnknown_AddRef((IUnknown*)*ppv);
73 return S_OK;
76 static ULONG WINAPI IWSDUdpAddressImpl_AddRef(IWSDUdpAddress *iface)
78 IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);
79 ULONG ref = InterlockedIncrement(&This->ref);
81 TRACE("(%p) ref=%d\n", This, ref);
82 return ref;
85 static ULONG WINAPI IWSDUdpAddressImpl_Release(IWSDUdpAddress *iface)
87 IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);
88 ULONG ref = InterlockedDecrement(&This->ref);
90 TRACE("(%p) ref=%d\n", This, ref);
92 if (ref == 0)
94 HeapFree(GetProcessHeap(), 0, This);
97 return ref;
100 static HRESULT WINAPI IWSDUdpAddressImpl_Serialize(IWSDUdpAddress *This, LPWSTR pszBuffer, DWORD cchLength, BOOL fSafe)
102 FIXME("(%p, %p, %d, %d)\n", This, pszBuffer, cchLength, fSafe);
103 return E_NOTIMPL;
106 static HRESULT WINAPI IWSDUdpAddressImpl_Deserialize(IWSDUdpAddress *This, LPCWSTR pszBuffer)
108 FIXME("(%p, %s)\n", This, debugstr_w(pszBuffer));
109 return E_NOTIMPL;
112 static HRESULT WINAPI IWSDUdpAddressImpl_GetPort(IWSDUdpAddress *This, WORD *pwPort)
114 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
116 TRACE("(%p, %p)\n", This, pwPort);
118 if (pwPort == NULL)
120 return E_POINTER;
123 *pwPort = impl->port;
124 return S_OK;
127 static HRESULT WINAPI IWSDUdpAddressImpl_SetPort(IWSDUdpAddress *This, WORD wPort)
129 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
131 TRACE("(%p, %d)\n", This, wPort);
133 impl->port = wPort;
134 return S_OK;
137 static HRESULT WINAPI IWSDUdpAddressImpl_GetTransportAddressEx(IWSDUdpAddress *This, BOOL fSafe, LPCWSTR *ppszAddress)
139 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
140 SOCKADDR_STORAGE storage;
141 DWORD size;
143 TRACE("(%p, %d, %p)\n", This, fSafe, ppszAddress);
145 if (ppszAddress == NULL)
146 return E_POINTER;
148 *ppszAddress = NULL;
150 switch (((SOCKADDR_IN *) &impl->sockAddr)->sin_family)
152 case AF_INET:
153 size = ARRAY_SIZE(impl->ipv4Address);
155 if (WSAAddressToStringW((LPSOCKADDR) &impl->sockAddr, sizeof(SOCKADDR_IN), NULL, impl->ipv4Address, &size) == 0)
157 *ppszAddress = impl->ipv4Address;
158 return S_OK;
161 break;
163 case AF_INET6:
164 size = ARRAY_SIZE(impl->ipv6Address);
166 /* Copy the SOCKADDR structure so we can remove the scope ID if not required */
167 memcpy(&storage, &impl->sockAddr, sizeof(SOCKADDR_IN6));
169 if (!fSafe)
170 ((SOCKADDR_IN6 *) &storage)->sin6_scope_id = 0;
172 if (WSAAddressToStringW((LPSOCKADDR) &storage, sizeof(SOCKADDR_IN6), NULL, impl->ipv6Address, &size) == 0)
174 *ppszAddress = impl->ipv6Address;
175 return S_OK;
178 break;
180 default:
181 return S_OK;
184 return HRESULT_FROM_WIN32(WSAGetLastError());
187 static HRESULT WINAPI IWSDUdpAddressImpl_GetTransportAddress(IWSDUdpAddress *This, LPCWSTR *ppszAddress)
189 return IWSDUdpAddressImpl_GetTransportAddressEx(This, FALSE, ppszAddress);
192 static HRESULT WINAPI IWSDUdpAddressImpl_SetTransportAddress(IWSDUdpAddress *This, LPCWSTR pszAddress)
194 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
195 ADDRINFOW *addrInfo = NULL;
196 ADDRINFOW hints;
197 int ret;
199 TRACE("(%p, %s)\n", impl, debugstr_w(pszAddress));
201 if (pszAddress == NULL)
202 return E_INVALIDARG;
204 ZeroMemory(&hints, sizeof(hints));
205 hints.ai_family = AF_UNSPEC;
207 ret = GetAddrInfoW(pszAddress, NULL, &hints, &addrInfo);
209 if (ret == 0)
211 ZeroMemory(&impl->sockAddr, sizeof(SOCKADDR_STORAGE));
212 memcpy(&impl->sockAddr, addrInfo->ai_addr, addrInfo->ai_addrlen);
215 if (addrInfo != NULL)
216 FreeAddrInfoW(addrInfo);
218 return HRESULT_FROM_WIN32(ret);
221 static HRESULT WINAPI IWSDUdpAddressImpl_SetSockaddr(IWSDUdpAddress *This, const SOCKADDR_STORAGE *pSockAddr)
223 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
225 TRACE("(%p, %p)\n", This, pSockAddr);
227 if (pSockAddr == NULL)
229 return E_POINTER;
232 memcpy(&impl->sockAddr, pSockAddr, sizeof(SOCKADDR_STORAGE));
233 return S_OK;
236 static HRESULT WINAPI IWSDUdpAddressImpl_GetSockaddr(IWSDUdpAddress *This, SOCKADDR_STORAGE *pSockAddr)
238 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
239 SOCKADDR_IN *sockAddr = (SOCKADDR_IN *) &impl->sockAddr;
241 TRACE("(%p, %p)\n", This, pSockAddr);
243 if (pSockAddr == NULL)
245 return E_POINTER;
248 /* Ensure the sockaddr is initialised correctly */
249 if ((sockAddr->sin_family != AF_INET) && (sockAddr->sin_family != AF_INET6))
251 return E_FAIL;
254 memcpy(pSockAddr, &impl->sockAddr, sizeof(SOCKADDR_STORAGE));
255 return S_OK;
258 static HRESULT WINAPI IWSDUdpAddressImpl_SetExclusive(IWSDUdpAddress *This, BOOL fExclusive)
260 FIXME("(%p, %d)\n", This, fExclusive);
261 return E_NOTIMPL;
264 static HRESULT WINAPI IWSDUdpAddressImpl_GetExclusive(IWSDUdpAddress *This)
266 FIXME("(%p)\n", This);
267 return E_NOTIMPL;
270 static HRESULT WINAPI IWSDUdpAddressImpl_SetMessageType(IWSDUdpAddress *This, WSDUdpMessageType messageType)
272 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
274 TRACE("(%p, %d)\n", This, messageType);
276 impl->messageType = messageType;
277 return S_OK;
280 static HRESULT WINAPI IWSDUdpAddressImpl_GetMessageType(IWSDUdpAddress *This, WSDUdpMessageType *pMessageType)
282 IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
284 TRACE("(%p, %p)\n", This, pMessageType);
286 if (pMessageType == NULL)
288 return E_POINTER;
291 *pMessageType = impl->messageType;
292 return S_OK;
295 static HRESULT WINAPI IWSDUdpAddressImpl_SetTTL(IWSDUdpAddress *This, DWORD dwTTL)
297 FIXME("(%p, %d)\n", This, dwTTL);
298 return E_NOTIMPL;
301 static HRESULT WINAPI IWSDUdpAddressImpl_GetTTL(IWSDUdpAddress *This, DWORD *pdwTTL)
303 FIXME("(%p, %p)\n", This, pdwTTL);
304 return E_NOTIMPL;
307 static HRESULT WINAPI IWSDUdpAddressImpl_SetAlias(IWSDUdpAddress *This, const GUID *pAlias)
309 FIXME("(%p, %s)\n", This, debugstr_guid(pAlias));
310 return E_NOTIMPL;
313 static HRESULT WINAPI IWSDUdpAddressImpl_GetAlias(IWSDUdpAddress *This, GUID *pAlias)
315 FIXME("(%p, %p)\n", This, pAlias);
316 return E_NOTIMPL;
319 static const IWSDUdpAddressVtbl udpAddressVtbl =
321 IWSDUdpAddressImpl_QueryInterface,
322 IWSDUdpAddressImpl_AddRef,
323 IWSDUdpAddressImpl_Release,
324 IWSDUdpAddressImpl_Serialize,
325 IWSDUdpAddressImpl_Deserialize,
326 IWSDUdpAddressImpl_GetPort,
327 IWSDUdpAddressImpl_SetPort,
328 IWSDUdpAddressImpl_GetTransportAddress,
329 IWSDUdpAddressImpl_GetTransportAddressEx,
330 IWSDUdpAddressImpl_SetTransportAddress,
331 IWSDUdpAddressImpl_SetSockaddr,
332 IWSDUdpAddressImpl_GetSockaddr,
333 IWSDUdpAddressImpl_SetExclusive,
334 IWSDUdpAddressImpl_GetExclusive,
335 IWSDUdpAddressImpl_SetMessageType,
336 IWSDUdpAddressImpl_GetMessageType,
337 IWSDUdpAddressImpl_SetTTL,
338 IWSDUdpAddressImpl_GetTTL,
339 IWSDUdpAddressImpl_SetAlias,
340 IWSDUdpAddressImpl_GetAlias
343 HRESULT WINAPI WSDCreateUdpAddress(IWSDUdpAddress **ppAddress)
345 IWSDUdpAddressImpl *obj;
347 TRACE("(%p)\n", ppAddress);
349 if (ppAddress == NULL)
351 WARN("Invalid parameter: ppAddress == NULL\n");
352 return E_POINTER;
355 *ppAddress = NULL;
357 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
359 if (!obj)
361 WARN("Out of memory\n");
362 return E_OUTOFMEMORY;
365 obj->IWSDUdpAddress_iface.lpVtbl = &udpAddressVtbl;
366 obj->ref = 1;
368 *ppAddress = &obj->IWSDUdpAddress_iface;
369 TRACE("Returning iface %p\n", *ppAddress);
371 return S_OK;