diff --git a/reactos/dll/win32/ws2_32/CMakeLists.txt b/reactos/dll/win32/ws2_32/CMakeLists.txt index a7ad9645cde..6015ff08589 100644 --- a/reactos/dll/win32/ws2_32/CMakeLists.txt +++ b/reactos/dll/win32/ws2_32/CMakeLists.txt @@ -19,7 +19,8 @@ list(APPEND SOURCE add_library(ws2_32 SHARED ${SOURCE} - misc/async.c + wine/async.c + wine/socket.c ws2_32.rc ${CMAKE_CURRENT_BINARY_DIR}/ws2_32.def) diff --git a/reactos/dll/win32/ws2_32/misc/stubs.c b/reactos/dll/win32/ws2_32/misc/stubs.c index c0cb392c8f1..256facf5a98 100644 --- a/reactos/dll/win32/ws2_32/misc/stubs.c +++ b/reactos/dll/win32/ws2_32/misc/stubs.c @@ -930,39 +930,4 @@ BOOL EXPORT WSApSetPostRoutine(PVOID Routine) return FALSE; } -/* - * @unimplemented - */ -INT -EXPORT -GetAddrInfoW(IN PCWSTR pszNodeName, - IN PCWSTR pszServiceName, - IN const ADDRINFOW *ptHints, - OUT PADDRINFOW *pptResult) -{ - UNIMPLEMENTED - - WSASetLastError(EAI_FAIL); - return EAI_FAIL; -} - -/* - * @unimplemented - */ -INT -EXPORT -GetNameInfoW(IN CONST SOCKADDR *pSockaddr, - IN socklen_t SockaddrLength, - OUT PWCHAR pNodeBuffer, - IN DWORD NodeBufferSize, - OUT PWCHAR pServiceBuffer, - IN DWORD ServiceBufferSize, - IN INT Flags) -{ - UNIMPLEMENTED - - WSASetLastError(EAI_FAIL); - return EAI_FAIL; -} - /* EOF */ diff --git a/reactos/dll/win32/ws2_32/misc/async.c b/reactos/dll/win32/ws2_32/wine/async.c similarity index 100% rename from reactos/dll/win32/ws2_32/misc/async.c rename to reactos/dll/win32/ws2_32/wine/async.c diff --git a/reactos/dll/win32/ws2_32/wine/socket.c b/reactos/dll/win32/ws2_32/wine/socket.c new file mode 100644 index 00000000000..5f28c922a4c --- /dev/null +++ b/reactos/dll/win32/ws2_32/wine/socket.c @@ -0,0 +1,198 @@ +/* + * 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))) + { + 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; +}