/* * based on Windows Sockets 1.1 specs * * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka. * Copyright (C) 2001 Stefan Leichter * Copyright (C) 2004 Hans Leidekker * Copyright (C) 2005 Marcus Meissner * Copyright (C) 2006-2008 Kai Blin * * 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 * * NOTE: If you make any changes to fix a particular app, make sure * they don't break something else like Netscape or telnet and ftp * clients and servers (www.winsite.com got a lot of those). */ #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H #include #include #include #include static inline void FreeAddrInfoW_(struct addrinfoW *pAddrInfo) { freeaddrinfo((struct addrinfo *)pAddrInfo); } #define FreeAddrInfoW FreeAddrInfoW_ static struct addrinfoW *addrinfo_AtoW(const struct addrinfo *ai) { struct addrinfoW *ret; if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct addrinfoW)))) return NULL; ret->ai_flags = ai->ai_flags; ret->ai_family = ai->ai_family; ret->ai_socktype = ai->ai_socktype; ret->ai_protocol = ai->ai_protocol; ret->ai_addrlen = ai->ai_addrlen; ret->ai_canonname = NULL; ret->ai_addr = NULL; ret->ai_next = NULL; if (ai->ai_canonname) { int len = MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0); if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)))) { HeapFree(GetProcessHeap(), 0, ret); return NULL; } MultiByteToWideChar(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len); } if (ai->ai_addr) { if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, ai->ai_addrlen))) { HeapFree(GetProcessHeap(), 0, ret->ai_canonname); HeapFree(GetProcessHeap(), 0, ret); return NULL; } memcpy(ret->ai_addr, ai->ai_addr, ai->ai_addrlen); } return ret; } static struct addrinfoW *addrinfo_list_AtoW(const struct addrinfo *info) { struct addrinfoW *ret, *infoW; if (!(ret = infoW = addrinfo_AtoW(info))) return NULL; while (info->ai_next) { if (!(infoW->ai_next = addrinfo_AtoW(info->ai_next))) { FreeAddrInfoW(ret); return NULL; } infoW = infoW->ai_next; info = info->ai_next; } return ret; } static struct addrinfo *addrinfo_WtoA(const struct addrinfoW *ai) { struct addrinfo *ret; if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct addrinfo)))) return NULL; ret->ai_flags = ai->ai_flags; ret->ai_family = ai->ai_family; ret->ai_socktype = ai->ai_socktype; ret->ai_protocol = ai->ai_protocol; ret->ai_addrlen = ai->ai_addrlen; ret->ai_canonname = NULL; ret->ai_addr = NULL; ret->ai_next = NULL; if (ai->ai_canonname) { int len = WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, NULL, 0, NULL, NULL); if (!(ret->ai_canonname = HeapAlloc(GetProcessHeap(), 0, len))) { HeapFree(GetProcessHeap(), 0, ret); return NULL; } WideCharToMultiByte(CP_ACP, 0, ai->ai_canonname, -1, ret->ai_canonname, len, NULL, NULL); } if (ai->ai_addr) { if (!(ret->ai_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sockaddr)))) { HeapFree(GetProcessHeap(), 0, ret->ai_canonname); HeapFree(GetProcessHeap(), 0, ret); return NULL; } memcpy(ret->ai_addr, ai->ai_addr, sizeof(struct sockaddr)); } return ret; } /*********************************************************************** * GetAddrInfoW (WS2_32.@) */ int WINAPI GetAddrInfoW(LPCWSTR nodename, LPCWSTR servname, const ADDRINFOW *hints, PADDRINFOW *res) { int ret, len; char *nodenameA = NULL, *servnameA = NULL; struct addrinfo *resA, *hintsA = NULL; *res = NULL; if (nodename) { len = WideCharToMultiByte(CP_ACP, 0, nodename, -1, NULL, 0, NULL, NULL); if (!(nodenameA = HeapAlloc(GetProcessHeap(), 0, len))) return EAI_MEMORY; WideCharToMultiByte(CP_ACP, 0, nodename, -1, nodenameA, len, NULL, NULL); } if (servname) { len = WideCharToMultiByte(CP_ACP, 0, servname, -1, NULL, 0, NULL, NULL); if (!(servnameA = HeapAlloc(GetProcessHeap(), 0, len))) { HeapFree(GetProcessHeap(), 0, nodenameA); return EAI_MEMORY; } WideCharToMultiByte(CP_ACP, 0, servname, -1, servnameA, len, NULL, NULL); } if (hints) hintsA = addrinfo_WtoA(hints); ret = getaddrinfo(nodenameA, servnameA, hintsA, &resA); freeaddrinfo(hintsA); if (!ret) { *res = addrinfo_list_AtoW(resA); freeaddrinfo(resA); } HeapFree(GetProcessHeap(), 0, nodenameA); HeapFree(GetProcessHeap(), 0, servnameA); return ret; } int WINAPI GetNameInfoW(const SOCKADDR *sa, socklen_t salen, PWCHAR host, DWORD hostlen, PWCHAR serv, DWORD servlen, INT flags) { int ret; char *hostA = NULL, *servA = NULL; if (host && (!(hostA = HeapAlloc(GetProcessHeap(), 0, hostlen)))) return EAI_MEMORY; if (serv && (!(servA = HeapAlloc(GetProcessHeap(), 0, servlen)))) { HeapFree(GetProcessHeap(), 0, hostA); return EAI_MEMORY; } ret = getnameinfo(sa, salen, hostA, hostlen, servA, servlen, flags); if (!ret) { if (host) MultiByteToWideChar(CP_ACP, 0, hostA, -1, host, hostlen); if (serv) MultiByteToWideChar(CP_ACP, 0, servA, -1, serv, servlen); } HeapFree(GetProcessHeap(), 0, hostA); HeapFree(GetProcessHeap(), 0, servA); return ret; }