X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdll%2Fwin32%2Fwininet%2Futility.c;h=66fbecdd653bd0d901938e073489a3d522fd6ac2;hp=b0d9c9c91c66e9074f3036a2ea30b587b16ad0f7;hb=3e4b8ea4f14df0fe879a2524a28d33a18c37d396;hpb=f9d93024457a87da14e2ca2146ae51ec48d8e5b9 diff --git a/reactos/dll/win32/wininet/utility.c b/reactos/dll/win32/wininet/utility.c index b0d9c9c91c6..66fbecdd653 100644 --- a/reactos/dll/win32/wininet/utility.c +++ b/reactos/dll/win32/wininet/utility.c @@ -25,6 +25,10 @@ #include "config.h" #include "wine/port.h" +#if defined(__MINGW32__) || defined (_MSC_VER) +#include +#endif + #include #include #include @@ -40,6 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); +#ifndef HAVE_GETADDRINFO + /* critical section to protect non-reentrant gethostbyname() */ static CRITICAL_SECTION cs_gethostbyname; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -50,6 +56,8 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 }; +#endif + #define TIME_STRING_LEN 30 time_t ConvertTimeString(LPCWSTR asctime) @@ -137,12 +145,18 @@ time_t ConvertTimeString(LPCWSTR asctime) BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr_in *psa) + struct sockaddr *psa, socklen_t *sa_len) { WCHAR *found; char *name; int len, sz; +#ifdef HAVE_GETADDRINFO + struct addrinfo *res, hints; + int ret; +#else struct hostent *phe; + struct sockaddr_in *sin = (struct sockaddr_in *)psa; +#endif TRACE("%s\n", debugstr_w(lpszServerName)); @@ -158,27 +172,75 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, len = strlenW(lpszServerName); sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL ); - name = HeapAlloc(GetProcessHeap(), 0, sz+1); + if (!(name = HeapAlloc( GetProcessHeap(), 0, sz + 1 ))) return FALSE; WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL ); name[sz] = 0; +#ifdef HAVE_GETADDRINFO + memset( &hints, 0, sizeof(struct addrinfo) ); + /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on + * their IPv6 addresses even though they have IPv6 addresses in the DNS. + */ + hints.ai_family = AF_INET; + + ret = getaddrinfo( name, NULL, &hints, &res ); + HeapFree( GetProcessHeap(), 0, name ); + if (ret != 0) + { + TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret)); + hints.ai_family = AF_INET6; + ret = getaddrinfo( name, NULL, &hints, &res ); + if (ret != 0) + { + TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret)); + return FALSE; + } + } + if (*sa_len < res->ai_addrlen) + { + WARN("address too small\n"); + freeaddrinfo( res ); + return FALSE; + } + *sa_len = res->ai_addrlen; + memcpy( psa, res->ai_addr, res->ai_addrlen ); + /* Copy port */ + switch (res->ai_family) + { + case AF_INET: + ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort); + break; + case AF_INET6: + ((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort); + break; + } + + freeaddrinfo( res ); +#else EnterCriticalSection( &cs_gethostbyname ); phe = gethostbyname(name); HeapFree( GetProcessHeap(), 0, name ); if (NULL == phe) { - TRACE("Failed to get hostname: (%s)\n", debugstr_w(lpszServerName) ); + TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno); LeaveCriticalSection( &cs_gethostbyname ); return FALSE; } - - memset(psa,0,sizeof(struct sockaddr_in)); - memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length); - psa->sin_family = phe->h_addrtype; - psa->sin_port = htons(nServerPort); + if (*sa_len < sizeof(struct sockaddr_in)) + { + WARN("address too small\n"); + LeaveCriticalSection( &cs_gethostbyname ); + return FALSE; + } + *sa_len = sizeof(struct sockaddr_in); + memset(sin,0,sizeof(struct sockaddr_in)); + memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length); + sin->sin_family = phe->h_addrtype; + sin->sin_port = htons(nServerPort); LeaveCriticalSection( &cs_gethostbyname ); +#endif return TRUE; } @@ -224,7 +286,7 @@ static const char *get_callback_name(DWORD dwInternetStatus) { return "Unknown"; } -VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, +VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) { @@ -244,11 +306,11 @@ VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, case INTERNET_STATUS_NAME_RESOLVED: case INTERNET_STATUS_CONNECTING_TO_SERVER: case INTERNET_STATUS_CONNECTED_TO_SERVER: - lpvNewInfo = WININET_strdup_AtoW(lpvStatusInfo); + lpvNewInfo = heap_strdupAtoW(lpvStatusInfo); break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: - lpvNewInfo = WININET_strdupW(lpvStatusInfo); + lpvNewInfo = heap_strdupW(lpvStatusInfo); break; } }else { @@ -262,7 +324,7 @@ VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: - lpvNewInfo = WININET_strdup_WtoA(lpvStatusInfo); + lpvNewInfo = heap_strdupWtoA(lpvStatusInfo); break; } } @@ -294,7 +356,7 @@ static void SendAsyncCallbackProc(WORKREQUEST *workRequest) HeapFree(GetProcessHeap(), 0, req->lpvStatusInfo); } -VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, +void SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) {