Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/wininet/Makefile.in | 4 +- dlls/wininet/internet.c | 201 +++++++++++++++++++++++++++++++++------ 2 files changed, 173 insertions(+), 32 deletions(-)
diff --git a/dlls/wininet/Makefile.in b/dlls/wininet/Makefile.in index 6eeb7cf85b..e1d4979d87 100644 --- a/dlls/wininet/Makefile.in +++ b/dlls/wininet/Makefile.in @@ -2,9 +2,9 @@ EXTRADEFS = -D_WINX32_ MODULE = wininet.dll IMPORTLIB = wininet IMPORTS = mpr shlwapi shell32 user32 ws2_32 advapi32 -DELAYIMPORTS = secur32 crypt32 cryptui +DELAYIMPORTS = secur32 crypt32 cryptui dhcpcsvc iphlpapi EXTRAINCL = $(Z_CFLAGS) -EXTRALIBS = $(CORESERVICES_LIBS) $(Z_LIBS) +EXTRALIBS = $(Z_LIBS)
C_SRCS = \ cookie.c \ diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 266100861d..3e8be9fa2b 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -28,14 +28,6 @@
#include "config.h"
-#ifdef HAVE_CORESERVICES_CORESERVICES_H -#define GetCurrentThread MacGetCurrentThread -#define LoadResource MacLoadResource -#include <CoreServices/CoreServices.h> -#undef GetCurrentThread -#undef LoadResource -#endif - #include "winsock2.h" #include "ws2ipdef.h"
@@ -56,6 +48,10 @@ #include "winerror.h" #define NO_SHLWAPI_STREAM #include "shlwapi.h" +#include "ws2tcpip.h" +#include "winternl.h" +#include "iphlpapi.h" +#include "dhcpcsdk.h"
#include "wine/exception.h"
@@ -2295,38 +2291,183 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, return res == ERROR_SUCCESS; }
-static WCHAR *get_proxy_autoconfig_url(void) +static IP_ADAPTER_ADDRESSES *get_adapters(void) { -#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + ULONG err, size = 1024, flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; + IP_ADAPTER_ADDRESSES *tmp, *ret;
- CFDictionaryRef settings = CFNetworkCopySystemProxySettings(); - WCHAR *ret = NULL; - SIZE_T len; - const void *ref; + if (!(ret = heap_alloc( size ))) return NULL; + err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size ); + while (err == ERROR_BUFFER_OVERFLOW) + { + if (!(tmp = heap_realloc( ret, size ))) break; + ret = tmp; + err = GetAdaptersAddresses( AF_UNSPEC, flags, NULL, ret, &size ); + } + if (err == ERROR_SUCCESS) return ret; + heap_free( ret ); + return NULL; +} + +static WCHAR *detect_proxy_autoconfig_url_dhcp(void) +{ + IP_ADAPTER_ADDRESSES *adapters, *ptr; + DHCPCAPI_PARAMS_ARRAY send_params, recv_params; + DHCPCAPI_PARAMS param; + WCHAR name[MAX_ADAPTER_NAME_LENGTH + 1], *ret = NULL; + DWORD err, size; + BYTE *tmp, *buf = NULL; + + if (!(adapters = get_adapters())) return NULL; + + memset( &send_params, 0, sizeof(send_params) ); + memset( ¶m, 0, sizeof(param) ); + param.OptionId = OPTION_MSFT_IE_PROXY; + recv_params.nParams = 1; + recv_params.Params = ¶m; + + for (ptr = adapters; ptr; ptr = ptr->Next) + { + MultiByteToWideChar( CP_ACP, 0, ptr->AdapterName, -1, name, ARRAY_SIZE(name) ); + TRACE( "adapter '%s' type %u dhcpv4 enabled %d\n", wine_dbgstr_w(name), ptr->IfType, ptr->Dhcpv4Enabled ); + + if (ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; + /* FIXME: also skip adapters where DHCP is disabled */ + + size = 256; + if (!(buf = heap_alloc( size ))) goto done; + err = DhcpRequestParams( DHCPCAPI_REQUEST_SYNCHRONOUS, NULL, name, NULL, send_params, recv_params, + buf, &size, NULL ); + while (err == ERROR_MORE_DATA) + { + if (!(tmp = heap_realloc( buf, size ))) goto done; + buf = tmp; + err = DhcpRequestParams( DHCPCAPI_REQUEST_SYNCHRONOUS, NULL, name, NULL, send_params, recv_params, + buf, &size, NULL ); + } + if (err == ERROR_SUCCESS && param.nBytesData) + { + int len = MultiByteToWideChar( CP_ACP, 0, (const char *)param.Data, param.nBytesData, NULL, 0 ); + if ((ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + MultiByteToWideChar( CP_ACP, 0, (const char *)param.Data, param.nBytesData, ret, len ); + ret[len] = 0; + } + TRACE("returning %s\n", debugstr_w(ret)); + break; + } + }
- if (!settings) return NULL; +done: + heap_free( buf ); + heap_free( adapters ); + return ret; +}
- if (!(ref = CFDictionaryGetValue( settings, kCFNetworkProxiesProxyAutoConfigURLString ))) +static char *get_computer_name( COMPUTER_NAME_FORMAT format ) +{ + char *ret; + DWORD size = 0; + + GetComputerNameExA( format, NULL, &size ); + if (GetLastError() != ERROR_MORE_DATA) return NULL; + if (!(ret = heap_alloc( size ))) return NULL; + if (!GetComputerNameExA( format, ret, &size )) { - CFRelease( settings ); + heap_free( ret ); return NULL; } - len = CFStringGetLength( ref ); - if (len) - ret = heap_alloc( (len+1) * sizeof(WCHAR) ); - if (ret) + return ret; +} + +static BOOL is_domain_suffix( const char *domain, const char *suffix ) +{ + int len_domain = strlen( domain ), len_suffix = strlen( suffix ); + + if (len_suffix > len_domain) return FALSE; + if (!_strnicmp( domain + len_domain - len_suffix, suffix, -1 )) return TRUE; + return FALSE; +} + +static int reverse_lookup( const struct addrinfo *ai, char *hostname, size_t len ) +{ + return getnameinfo( ai->ai_addr, ai->ai_addrlen, hostname, len, NULL, 0, 0 ); +} + +static WCHAR *build_wpad_url( const char *hostname, const struct addrinfo *ai ) +{ + static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; + static const WCHAR wpadW[] = {'/','w','p','a','d','.','d','a','t',0}; + char name[NI_MAXHOST]; + WCHAR *ret, *p; + int len; + + while (ai && ai->ai_family != AF_INET && ai->ai_family != AF_INET6) ai = ai->ai_next; + if (!ai) return NULL; + + if (!reverse_lookup( ai, name, sizeof(name) )) hostname = name; + + len = lstrlenW( httpW ) + strlen( hostname ) + lstrlenW( wpadW ); + if (!(ret = p = GlobalAlloc( 0, (len + 1) * sizeof(WCHAR) ))) return NULL; + lstrcpyW( p, httpW ); + p += lstrlenW( httpW ); + while (*hostname) { *p++ = *hostname++; } + lstrcpyW( p, wpadW ); + return ret; +} + +static WCHAR *detect_proxy_autoconfig_url_dns(void) +{ + char *fqdn, *domain, *p; + WCHAR *ret; + + if (!(fqdn = get_computer_name( ComputerNamePhysicalDnsFullyQualified ))) return NULL; + if (!(domain = get_computer_name( ComputerNamePhysicalDnsDomain ))) + { + heap_free( fqdn ); + return NULL; + } + p = fqdn; + while ((p = strchr( p, '.' )) && is_domain_suffix( p + 1, domain )) { - CFStringGetCharacters( ref, CFRangeMake(0, len), ret ); - ret[len] = 0; + char *name; + struct addrinfo *ai; + int res; + + if (!(name = heap_alloc( sizeof("wpad") + strlen(p) ))) + { + heap_free( fqdn ); + heap_free( domain ); + return NULL; + } + strcpy( name, "wpad" ); + strcat( name, p ); + res = getaddrinfo( name, NULL, NULL, &ai ); + if (!res) + { + ret = build_wpad_url( name, ai ); + freeaddrinfo( ai ); + if (ret) + { + TRACE("returning %s\n", debugstr_w(ret)); + heap_free( name ); + break; + } + } + heap_free( name ); + p++; } - TRACE( "returning %s\n", debugstr_w(ret) ); - CFRelease( settings ); + heap_free( domain ); + heap_free( fqdn ); + return ret; +} + +static WCHAR *get_proxy_autoconfig_url(void) +{ + WCHAR *ret = detect_proxy_autoconfig_url_dhcp(); + if (!ret) ret = detect_proxy_autoconfig_url_dns(); return ret; -#else - static int once; - if (!once++) FIXME( "no support on this platform\n" ); - return NULL; -#endif }
static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL unicode)