Hans Leidekker : winhttp: Implement WinHttpDetectAutoProxyConfigUrl.
Alexandre Julliard
julliard at winehq.org
Tue Nov 15 13:17:32 CST 2011
Module: wine
Branch: master
Commit: 96f2e7139cb14b1711c0dc22fea1f9eb47802df5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=96f2e7139cb14b1711c0dc22fea1f9eb47802df5
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Nov 15 09:11:05 2011 +0100
winhttp: Implement WinHttpDetectAutoProxyConfigUrl.
---
dlls/winhttp/session.c | 107 ++++++++++++++++++++++++++++++++++++++++-
dlls/winhttp/tests/winhttp.c | 39 +++++++++++++++
include/winhttp.h | 3 +
3 files changed, 146 insertions(+), 3 deletions(-)
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index b7cc31b..c187079 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -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[] = {
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index acf88dc..f481a82 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -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;
diff --git a/include/winhttp.h b/include/winhttp.h
index 68bec0a..36f8b9d 100644
--- a/include/winhttp.h
+++ b/include/winhttp.h
@@ -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;
More information about the wine-cvs
mailing list