Hans Leidekker : winhttp: Implement WinHttpGetIEProxyConfigForCurrentUser.

Alexandre Julliard julliard at winehq.org
Wed Nov 16 12:46:45 CST 2011


Module: wine
Branch: master
Commit: f6c46dd0743def8e015bc0390924ab1980206805
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f6c46dd0743def8e015bc0390924ab1980206805

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Nov 16 09:42:17 2011 +0100

winhttp: Implement WinHttpGetIEProxyConfigForCurrentUser.

---

 dlls/winhttp/session.c       |  109 ++++++++++++++++++++++++++++++++---------
 dlls/winhttp/tests/winhttp.c |   26 ++++++++++
 2 files changed, 111 insertions(+), 24 deletions(-)

diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index c187079..42ef85b 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -1234,15 +1234,18 @@ static const WCHAR Connections[] = {
     'C','o','n','n','e','c','t','i','o','n','s',0 };
 static const WCHAR WinHttpSettings[] = {
     'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
-static const DWORD WINHTTPSETTINGS_MAGIC = 0x18;
-static const DWORD WINHTTP_PROXY_TYPE_DIRECT = 1;
-static const DWORD WINHTTP_PROXY_TYPE_PROXY = 2;
-
-struct winhttp_settings_header
+static const DWORD WINHTTP_SETTINGS_MAGIC = 0x18;
+static const DWORD WININET_SETTINGS_MAGIC = 0x46;
+static const DWORD PROXY_TYPE_DIRECT         = 1;
+static const DWORD PROXY_TYPE_PROXY          = 2;
+static const DWORD PROXY_USE_PAC_SCRIPT      = 4;
+static const DWORD PROXY_AUTODETECT_SETTINGS = 8;
+
+struct connection_settings_header
 {
     DWORD magic;
     DWORD unknown; /* always zero? */
-    DWORD flags;   /* one of WINHTTP_PROXY_TYPE_* */
+    DWORD flags;   /* one or more of PROXY_* */
 };
 
 static inline void copy_char_to_wchar_sz(const BYTE *src, DWORD len, WCHAR *dst)
@@ -1273,22 +1276,22 @@ BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
 
         l = RegQueryValueExW( key, WinHttpSettings, NULL, &type, NULL, &size );
         if (!l && type == REG_BINARY &&
-            size >= sizeof(struct winhttp_settings_header) + 2 * sizeof(DWORD))
+            size >= sizeof(struct connection_settings_header) + 2 * sizeof(DWORD))
         {
             BYTE *buf = heap_alloc( size );
 
             if (buf)
             {
-                struct winhttp_settings_header *hdr =
-                    (struct winhttp_settings_header *)buf;
+                struct connection_settings_header *hdr =
+                    (struct connection_settings_header *)buf;
                 DWORD *len = (DWORD *)(hdr + 1);
 
                 l = RegQueryValueExW( key, WinHttpSettings, NULL, NULL, buf,
                     &size );
-                if (!l && hdr->magic == WINHTTPSETTINGS_MAGIC &&
+                if (!l && hdr->magic == WINHTTP_SETTINGS_MAGIC &&
                     hdr->unknown == 0)
                 {
-                    if (hdr->flags & WINHTTP_PROXY_TYPE_PROXY)
+                    if (hdr->flags & PROXY_TYPE_PROXY)
                     {
                        BOOL sane = FALSE;
                        LPWSTR proxy = NULL;
@@ -1394,6 +1397,13 @@ BOOL WINAPI WinHttpGetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
  */
 BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser( WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *config )
 {
+    static const WCHAR settingsW[] =
+        {'D','e','f','a','u','l','t','C','o','n','n','e','c','t','i','o','n','S','e','t','t','i','n','g','s',0};
+    HKEY hkey = NULL;
+    struct connection_settings_header *hdr = NULL;
+    DWORD type, offset, len, size = 0;
+    BOOL ret = FALSE;
+
     TRACE("%p\n", config);
 
     if (!config)
@@ -1401,16 +1411,67 @@ BOOL WINAPI WinHttpGetIEProxyConfigForCurrentUser( WINHTTP_CURRENT_USER_IE_PROXY
         set_last_error( ERROR_INVALID_PARAMETER );
         return FALSE;
     }
+    memset( config, 0, sizeof(*config) );
+    config->fAutoDetect = TRUE;
 
-    /* FIXME: read from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings */
+    if (RegOpenKeyExW( HKEY_CURRENT_USER, Connections, 0, KEY_READ, &hkey ) ||
+        RegQueryValueExW( hkey, settingsW, NULL, &type, NULL, &size ) ||
+        type != REG_BINARY || size < sizeof(struct connection_settings_header))
+    {
+        ret = TRUE;
+        goto done;
+    }
+    if (!(hdr = heap_alloc( size ))) goto done;
+    if (RegQueryValueExW( hkey, settingsW, NULL, &type, (BYTE *)hdr, &size ) ||
+        hdr->magic != WININET_SETTINGS_MAGIC)
+    {
+        ret = TRUE;
+        goto done;
+    }
 
-    FIXME("returning no proxy used\n");
-    config->fAutoDetect       = FALSE;
-    config->lpszAutoConfigUrl = NULL;
-    config->lpszProxy         = NULL;
-    config->lpszProxyBypass   = NULL;
+    config->fAutoDetect = (hdr->flags & PROXY_AUTODETECT_SETTINGS) != 0;
+    offset = sizeof(*hdr);
+    if (offset + sizeof(DWORD) > size) goto done;
+    len = *(DWORD *)((char *)hdr + offset);
+    offset += sizeof(DWORD);
+    if (len && hdr->flags & PROXY_TYPE_PROXY)
+    {
+        if (!(config->lpszProxy = GlobalAlloc( 0, (len + 1) * sizeof(WCHAR) ))) goto done;
+        copy_char_to_wchar_sz( (const BYTE *)hdr + offset , len, config->lpszProxy );
+    }
+    offset += len;
+    if (offset + sizeof(DWORD) > size) goto done;
+    len = *(DWORD *)((char *)hdr + offset);
+    offset += sizeof(DWORD);
+    if (len && (hdr->flags & PROXY_TYPE_PROXY))
+    {
+        if (!(config->lpszProxyBypass = GlobalAlloc( 0, (len + 1) * sizeof(WCHAR) ))) goto done;
+        copy_char_to_wchar_sz( (const BYTE *)hdr + offset , len, config->lpszProxyBypass );
+    }
+    offset += len;
+    if (offset + sizeof(DWORD) > size) goto done;
+    len = *(DWORD *)((char *)hdr + offset);
+    offset += sizeof(DWORD);
+    if (len && (hdr->flags & PROXY_USE_PAC_SCRIPT))
+    {
+        if (!(config->lpszAutoConfigUrl = GlobalAlloc( 0, (len + 1) * sizeof(WCHAR) ))) goto done;
+        copy_char_to_wchar_sz( (const BYTE *)hdr + offset , len, config->lpszAutoConfigUrl );
+    }
+    ret = TRUE;
 
-    return TRUE;
+done:
+    RegCloseKey( hkey );
+    heap_free( hdr );
+    if (!ret)
+    {
+        heap_free( config->lpszAutoConfigUrl );
+        config->lpszAutoConfigUrl = NULL;
+        heap_free( config->lpszProxy );
+        config->lpszProxy = NULL;
+        heap_free( config->lpszProxyBypass );
+        config->lpszProxyBypass = NULL;
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -1478,7 +1539,7 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
         KEY_WRITE, NULL, &key, NULL );
     if (!l)
     {
-        DWORD size = sizeof(struct winhttp_settings_header) + 2 * sizeof(DWORD);
+        DWORD size = sizeof(struct connection_settings_header) + 2 * sizeof(DWORD);
         BYTE *buf;
 
         if (info->dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
@@ -1490,17 +1551,17 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
         buf = heap_alloc( size );
         if (buf)
         {
-            struct winhttp_settings_header *hdr =
-                (struct winhttp_settings_header *)buf;
+            struct connection_settings_header *hdr =
+                (struct connection_settings_header *)buf;
             DWORD *len = (DWORD *)(hdr + 1);
 
-            hdr->magic = WINHTTPSETTINGS_MAGIC;
+            hdr->magic = WINHTTP_SETTINGS_MAGIC;
             hdr->unknown = 0;
             if (info->dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
             {
                 BYTE *dst;
 
-                hdr->flags = WINHTTP_PROXY_TYPE_PROXY;
+                hdr->flags = PROXY_TYPE_PROXY;
                 *len++ = strlenW( info->lpszProxy );
                 for (dst = (BYTE *)len, src = info->lpszProxy; *src;
                     src++, dst++)
@@ -1518,7 +1579,7 @@ BOOL WINAPI WinHttpSetDefaultProxyConfiguration( WINHTTP_PROXY_INFO *info )
             }
             else
             {
-                hdr->flags = WINHTTP_PROXY_TYPE_DIRECT;
+                hdr->flags = PROXY_TYPE_DIRECT;
                 *len++ = 0;
                 *len++ = 0;
             }
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index f481a82..5e4892c 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -2556,6 +2556,31 @@ static void test_WinHttpDetectAutoProxyConfigUrl(void)
     }
 }
 
+static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
+{
+    BOOL ret;
+    DWORD error;
+    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
+
+    memset( &cfg, 0, sizeof(cfg) );
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
+    error = GetLastError();
+    ok( !ret, "expected failure\n" );
+    ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
+
+    ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
+    ok( ret, "expected success\n" );
+    trace("%d\n", cfg.fAutoDetect);
+    trace("%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
+    trace("%s\n", wine_dbgstr_w(cfg.lpszProxy));
+    trace("%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
+    GlobalFree( cfg.lpszAutoConfigUrl );
+    GlobalFree( cfg.lpszProxy );
+    GlobalFree( cfg.lpszProxyBypass );
+}
+
 START_TEST (winhttp)
 {
     static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
@@ -2579,6 +2604,7 @@ START_TEST (winhttp)
     test_credentials();
     test_IWinHttpRequest();
     test_WinHttpDetectAutoProxyConfigUrl();
+    test_WinHttpGetIEProxyConfigForCurrentUser();
 
     si.event = CreateEvent(NULL, 0, 0, NULL);
     si.port = 7532;




More information about the wine-cvs mailing list