winhttp: Implement WinHttpDetectAutoProxyConfigUrl.

This commit is contained in:
Hans Leidekker 2011-11-15 09:11:05 +01:00 committed by Alexandre Julliard
parent 75be2284e1
commit 96f2e7139c
3 changed files with 146 additions and 3 deletions

View File

@ -1113,15 +1113,116 @@ BOOL WINAPI WinHttpSetOption( HINTERNET handle, DWORD option, LPVOID buffer, DWO
return ret;
}
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 ))
{
heap_free( ret );
return NULL;
}
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 (!strcasecmp( domain + len_domain - len_suffix, suffix )) return TRUE;
return FALSE;
}
static WCHAR *build_wpad_url( const struct addrinfo *ai )
{
static const WCHAR fmtW[] =
{'h','t','t','p',':','/','/','%','u','.','%','u','.','%','u','.','%','u',
'/','w','p','a','d','.','d','a','t',0};
struct sockaddr_in *addr;
WCHAR *ret;
while (ai && ai->ai_family != AF_INET) ai = ai->ai_next;
if (!ai) return NULL;
if (!(ret = GlobalAlloc( 0, sizeof(fmtW) + 12 * sizeof(WCHAR) ))) return NULL;
addr = (struct sockaddr_in *)ai->ai_addr;
sprintfW( ret, fmtW,
(unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 24 & 0xff),
(unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 16 & 0xff),
(unsigned int)(ntohl( addr->sin_addr.s_addr ) >> 8 & 0xff),
(unsigned int)(ntohl( addr->sin_addr.s_addr ) & 0xff) );
return ret;
}
/***********************************************************************
* WinHttpDetectAutoProxyConfigUrl (winhttp.@)
*/
BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url )
{
FIXME("0x%08x, %p\n", flags, url);
BOOL ret = FALSE;
set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED );
return FALSE;
TRACE("0x%08x, %p\n", flags, url);
if (!flags || !url)
{
set_last_error( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (flags & WINHTTP_AUTO_DETECT_TYPE_DHCP) FIXME("discovery via DHCP not supported\n");
if (flags & WINHTTP_AUTO_DETECT_TYPE_DNS_A)
{
#ifdef HAVE_GETADDRINFO
char *fqdn, *domain, *p;
if (!(fqdn = get_computer_name( ComputerNamePhysicalDnsFullyQualified ))) return FALSE;
if (!(domain = get_computer_name( ComputerNamePhysicalDnsDomain )))
{
heap_free( fqdn );
return FALSE;
}
p = fqdn;
while ((p = strchr( p, '.' )) && is_domain_suffix( p + 1, domain ))
{
struct addrinfo *ai;
char *name;
int res;
if (!(name = heap_alloc( sizeof("wpad") + strlen(p) )))
{
heap_free( fqdn );
heap_free( domain );
return FALSE;
}
strcpy( name, "wpad" );
strcat( name, p );
res = getaddrinfo( name, NULL, NULL, &ai );
heap_free( name );
if (!res)
{
*url = build_wpad_url( ai );
freeaddrinfo( ai );
if (*url)
{
TRACE("returning %s\n", debugstr_w(*url));
ret = TRUE;
break;
}
}
p++;
}
heap_free( domain );
heap_free( fqdn );
#else
FIXME("getaddrinfo not found at build time\n");
#endif
}
if (!ret) set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED );
return ret;
}
static const WCHAR Connections[] = {

View File

@ -2518,6 +2518,44 @@ static void test_IWinHttpRequest(void)
CoUninitialize();
}
static void test_WinHttpDetectAutoProxyConfigUrl(void)
{
BOOL ret;
WCHAR *url;
DWORD error;
SetLastError(0xdeadbeef);
ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
error = GetLastError();
ok( !ret, "expected failure\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
url = NULL;
SetLastError(0xdeadbeef);
ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
error = GetLastError();
ok( !ret, "expected failure\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
SetLastError(0xdeadbeef);
ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
error = GetLastError();
ok( !ret, "expected failure\n" );
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
url = NULL;
SetLastError(0xdeadbeef);
ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
error = GetLastError();
if (!ret)
ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
else
{
trace("%s\n", wine_dbgstr_w(url));
GlobalFree( url );
}
}
START_TEST (winhttp)
{
static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
@ -2540,6 +2578,7 @@ START_TEST (winhttp)
test_resolve_timeout();
test_credentials();
test_IWinHttpRequest();
test_WinHttpDetectAutoProxyConfigUrl();
si.event = CreateEvent(NULL, 0, 0, NULL);
si.port = 7532;

View File

@ -503,6 +503,9 @@ typedef struct
typedef VOID (CALLBACK *WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD_PTR,DWORD,LPVOID,DWORD);
#define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001
#define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002
typedef struct
{
DWORD dwFlags;