-- v3: inetcpl.cpl: Use wininet functions to load and save proxy settings.
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 72 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index b74015146ea..4fe4a5d3984 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -89,6 +89,21 @@ typedef struct LPWSTR autoconf_url; } proxyinfo_t;
+#define CONNECTION_SETTINGS_VERSION 0x46 +typedef struct { + DWORD version; + DWORD id; + DWORD flags; + BYTE data[1]; + /* DWORD proxy_server_len; */ + /* UTF8 proxy_server[proxy_server_len]; */ + /* DWORD bypass_list_len; */ + /* UTF8 bypass_list[bypass_list_len]; */ + /* DWORD configuration_script_len; */ + /* UTF8 configuration_script[configuration_script_len]; */ + /* DWORD unk[8]; set to 0 */ +} connection_settings; + static ULONG max_conns = 2, max_1_0_conns = 4; static ULONG connect_timeout = 60000;
@@ -316,6 +331,48 @@ HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline) return S_OK; }
+static void connection_settings_write( connection_settings *settings, DWORD *pos, DWORD size, const WCHAR *str ) +{ + int len = 0; + + if (str) + { + len = wcslen( str ); + len = WideCharToMultiByte( CP_UTF8, 0, str, len, settings ? (char*)settings->data + *pos + sizeof(len) : NULL, + settings ? size - *pos - sizeof(len) : 0, NULL, NULL ); + } + if (settings) + memcpy(settings->data + *pos, &len, sizeof(len)); + *pos += sizeof(len) + len; +} + +static LONG save_connection_settings( HKEY key, const WCHAR *connection, proxyinfo_t *lpwpi ) +{ + connection_settings *settings; + DWORD size = 0, pos = 0; + LONG ret; + + connection_settings_write( NULL, &size, 0, lpwpi->proxy ); + connection_settings_write( NULL, &size, 0, lpwpi->proxyBypass ); + connection_settings_write( NULL, &size, 0, lpwpi->autoconf_url ); + size += sizeof(DWORD) * 10; /* unknown fields */ + + settings = calloc( 1, FIELD_OFFSET(connection_settings, data[size]) ); + if (!settings) + return ERROR_OUTOFMEMORY; + + settings->version = CONNECTION_SETTINGS_VERSION; + settings->flags = lpwpi->flags; + connection_settings_write( settings, &pos, size, lpwpi->proxy ); + connection_settings_write( settings, &pos, size, lpwpi->proxyBypass ); + connection_settings_write( settings, &pos, size, lpwpi->autoconf_url ); + + ret = RegSetValueExW(key, connection, 0, REG_BINARY, (BYTE*)settings, + FIELD_OFFSET(connection_settings, data[size])); + free(settings); + return ret; +} + /*********************************************************************** * INTERNET_SaveProxySettings * @@ -326,13 +383,26 @@ HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline) */ static LONG INTERNET_SaveProxySettings( proxyinfo_t *lpwpi ) { - HKEY key; + HKEY key, con; DWORD val; LONG ret;
if ((ret = RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key ))) return ret;
+ if ((ret = RegCreateKeyExW( key, L"Connections", 0, NULL, 0, KEY_WRITE, NULL, &con, NULL ))) + { + RegCloseKey( key ); + return ret; + } + ret = save_connection_settings( con, L"DefaultConnectionSettings", lpwpi ); + RegCloseKey( con ); + if (ret) + { + RegCloseKey( key ); + return ret; + } + val = !!(lpwpi->flags & PROXY_TYPE_PROXY); if ((ret = RegSetValueExW( key, L"ProxyEnable", 0, REG_DWORD, (BYTE*)&val, sizeof(DWORD)))) {
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 100 ++++++++++++++++++++++++++++++++-- dlls/wininet/tests/internet.c | 2 +- 2 files changed, 97 insertions(+), 5 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 4fe4a5d3984..36ee7639f26 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -643,6 +643,79 @@ static WCHAR *get_http_proxy( const WCHAR *proxy ) return ret; }
+static LONG connection_settings_read( const connection_settings *settings, DWORD *pos, DWORD size, WCHAR **str) +{ + int len, wlen; + + *str = NULL; + if (*pos + sizeof(int) >= size) + return ERROR_SUCCESS; + memcpy( &len, settings->data + *pos, sizeof(int) ); + *pos += sizeof(int); + + if (*pos + len >= size) + { + *pos = size; + return ERROR_SUCCESS; + } + wlen = MultiByteToWideChar( CP_UTF8, 0, (const char *)settings->data + *pos, len, NULL, 0 ); + if (wlen) + { + *str = malloc( (wlen + 1) * sizeof(WCHAR) ); + if (!*str) + { + *pos = size; + return ERROR_OUTOFMEMORY; + } + MultiByteToWideChar( CP_UTF8, 0, (const char *)settings->data + *pos, len, *str, wlen ); + (*str)[wlen] = 0; + *pos += len; + } + return ERROR_SUCCESS; +} + +static LONG load_connection_settings( HKEY key, const WCHAR *connection, proxyinfo_t *lpwpi ) +{ + connection_settings *settings = NULL; + DWORD type, pos, size = 0; + LONG res; + + while ((res = RegQueryValueExW( key, connection, NULL, &type, (BYTE*)settings, &size )) == ERROR_MORE_DATA || + (!res && !settings)) + { + connection_settings *new_settings = realloc(settings, size); + if(!new_settings) + { + free( settings ); + return ERROR_OUTOFMEMORY; + } + settings = new_settings; + } + + memset(lpwpi, 0, sizeof(*lpwpi)); + if (res || type != REG_BINARY || size < FIELD_OFFSET( connection_settings, data )) + { + lpwpi->flags |= PROXY_TYPE_DIRECT | PROXY_TYPE_AUTO_DETECT; + free( settings ); + return ERROR_SUCCESS; + } + + lpwpi->flags = settings->flags; + size -= FIELD_OFFSET( connection_settings, data ); + pos = 0; + res = connection_settings_read( settings, &pos, size, &lpwpi->proxy ); + if (!res) + res = connection_settings_read( settings, &pos, size, &lpwpi->proxyBypass ); + if (!res) + res = connection_settings_read( settings, &pos, size, &lpwpi->autoconf_url ); + if (res) + { + FreeProxyInfo( lpwpi ); + return res; + } + return ERROR_SUCCESS; +} + /*********************************************************************** * INTERNET_LoadProxySettings * @@ -657,7 +730,7 @@ static WCHAR *get_http_proxy( const WCHAR *proxy ) static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi ) { DWORD type, len, val; - HKEY key; + HKEY key, con; LONG ret;
memset( lpwpi, 0, sizeof(*lpwpi) ); @@ -665,19 +738,30 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi ) if ((ret = RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key ))) return ret;
+ if (!(ret = RegOpenKeyW( key, L"Connections", &con ))) + { + load_connection_settings( con, L"DefaultConnectionSettings", lpwpi ); + RegCloseKey( con ); + } + len = sizeof(DWORD); if (RegQueryValueExW( key, L"ProxyEnable", NULL, &type, (BYTE *)&val, &len ) || type != REG_DWORD) { - val = 0; + val = !!(lpwpi->flags & PROXY_TYPE_PROXY); if((ret = RegSetValueExW( key, L"ProxyEnable", 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD) ))) { RegCloseKey( key ); + FreeProxyInfo( lpwpi ); return ret; } } + else if (val) + { + lpwpi->flags |= PROXY_TYPE_PROXY; + } else { - lpwpi->flags |= (val ? PROXY_TYPE_PROXY : PROXY_TYPE_DIRECT); + lpwpi->flags &= ~PROXY_TYPE_PROXY; }
/* figure out how much memory the proxy setting takes */ @@ -688,12 +772,18 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi ) if (!(szProxy = malloc( len ))) { RegCloseKey( key ); + FreeProxyInfo( lpwpi ); return ERROR_OUTOFMEMORY; } RegQueryValueExW( key, L"ProxyServer", NULL, &type, (BYTE*)szProxy, &len );
+ free( lpwpi->proxy ); lpwpi->proxy = szProxy; - TRACE("proxy server (from registry%s) = %s\n", lpwpi->flags & PROXY_TYPE_PROXY ? "" : ", disabled", + } + + if (lpwpi->proxy) + { + TRACE("proxy (from registry%s) = %s\n", lpwpi->flags & PROXY_TYPE_PROXY ? "" : ", disabled", debugstr_w(lpwpi->proxy)); } else @@ -713,6 +803,7 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi ) } RegQueryValueExW( key, L"ProxyOverride", NULL, &type, (BYTE*)szProxy, &len );
+ free( lpwpi->proxyBypass ); lpwpi->proxyBypass = szProxy; TRACE("http proxy bypass (from registry) = %s\n", debugstr_w(lpwpi->proxyBypass)); } @@ -734,6 +825,7 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi ) RegQueryValueExW( key, L"AutoConfigURL", NULL, &type, (BYTE*)autoconf_url, &len );
lpwpi->flags |= PROXY_TYPE_AUTO_PROXY_URL; + free( lpwpi->autoconf_url ); lpwpi->autoconf_url = autoconf_url; TRACE("AutoConfigURL = %s\n", debugstr_w(lpwpi->autoconf_url)); } diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 495371d50a5..fe47c10b78b 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1394,7 +1394,7 @@ static void test_Option_PerConnectionOption(void) ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - todo_wine ok(list.pOptions[0].Value.dwValue == (PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT), + ok(list.pOptions[0].Value.dwValue == (PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT), "Retrieved flags should've been PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT, was: %ld\n", list.pOptions[0].Value.dwValue); verifyProxyEnable(1);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 36ee7639f26..fe49ff27b31 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -446,7 +446,7 @@ static LONG INTERNET_SaveProxySettings( proxyinfo_t *lpwpi ) } }
- if (lpwpi->autoconf_url) + if (lpwpi->autoconf_url && lpwpi->flags & PROXY_TYPE_AUTO_PROXY_URL) { if ((ret = RegSetValueExW( key, L"AutoConfigURL", 0, REG_SZ, (BYTE*)lpwpi->autoconf_url, sizeof(WCHAR) * (lstrlenW(lpwpi->autoconf_url) + 1)))) @@ -3395,6 +3395,10 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, break;
case INTERNET_PER_CONN_AUTOCONFIG_URL: + free(pi.autoconf_url); + pi.autoconf_url = wcsdup(option->Value.pszValue); + break; + case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index fe49ff27b31..fdea5c8c3c6 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -1150,6 +1150,53 @@ static DWORD APPINFO_SetOption(object_header_t *hdr, DWORD option, void *buf, DW case INTERNET_OPTION_REFRESH: FIXME("INTERNET_OPTION_REFRESH\n"); return ERROR_SUCCESS; + case INTERNET_OPTION_PER_CONNECTION_OPTION: { + INTERNET_PER_CONN_OPTION_LISTW *con = buf; + unsigned int i; + + EnterCriticalSection( &WININET_cs ); + for (i = 0; i < con->dwOptionCount; i++) { + INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i; + + switch (option->dwOption) { + case INTERNET_PER_CONN_PROXY_SERVER: + free(global_proxy.proxy); + global_proxy.proxy = wcsdup(option->Value.pszValue); + break; + + case INTERNET_PER_CONN_FLAGS: + if(option->Value.dwValue & ~(PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT)) + FIXME("Unhandled flags: 0x%lx\n", option->Value.dwValue); + global_proxy.flags = option->Value.dwValue; + break; + + case INTERNET_PER_CONN_PROXY_BYPASS: + free(global_proxy.proxyBypass); + global_proxy.proxyBypass = wcsdup(option->Value.pszValue); + break; + + case INTERNET_PER_CONN_AUTOCONFIG_URL: + free(global_proxy.autoconf_url); + global_proxy.autoconf_url = wcsdup(option->Value.pszValue); + break; + + case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: + case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: + case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: + FIXME("Unhandled dwOption %ld\n", option->dwOption); + break; + + default: + FIXME("Unknown dwOption %ld\n", option->dwOption); + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + } + LeaveCriticalSection( &WININET_cs ); + return ERROR_SUCCESS; + } }
return INET_SetOption(hdr, option, buf, size);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 165 +++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 44 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index fdea5c8c3c6..072c76ff7e3 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -110,6 +110,8 @@ static ULONG connect_timeout = 60000; static const WCHAR szInternetSettings[] = L"Software\Microsoft\Windows\CurrentVersion\Internet Settings";
+static WCHAR *get_proxy_autoconfig_url(void); + void *alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t size) { UINT_PTR handle = 0, num; @@ -985,6 +987,37 @@ static VOID APPINFO_Destroy(object_header_t *hdr) free(lpwai->proxyPassword); }
+static WCHAR *copy_optionW(WCHAR *value) +{ + DWORD len; + void *tmp; + + if (!value) + return NULL; + + len = (wcslen(value) + 1) * sizeof(WCHAR); + if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) + return NULL; + + return memcpy(tmp, value, len); +} + +static char *copy_optionA(WCHAR *value) +{ + DWORD len; + void *tmp; + + if (!value) + return NULL; + + len = wcslen(value) * 3 + 1; + if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) + return NULL; + + WideCharToMultiByte(CP_ACP, 0, value, -1, tmp, len, NULL, NULL); + return tmp; +} + static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { appinfo_t *ai = (appinfo_t*)hdr; @@ -1123,6 +1156,80 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe *size = sizeof(ULONG);
return ERROR_SUCCESS; + + case INTERNET_OPTION_PER_CONNECTION_OPTION: { + INTERNET_PER_CONN_OPTION_LISTW *con = buffer; + INTERNET_PER_CONN_OPTION_LISTA *conA = buffer; + LONG res = ERROR_SUCCESS; + WCHAR *url = NULL; + int i; + + if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) + return ERROR_INSUFFICIENT_BUFFER; + + EnterCriticalSection(&WININET_cs); + + if (global_proxy.flags & PROXY_TYPE_AUTO_DETECT) + url = get_proxy_autoconfig_url(); + + for (i = 0; i < con->dwOptionCount; i++) { + INTERNET_PER_CONN_OPTIONW *optionW = con->pOptions + i; + INTERNET_PER_CONN_OPTIONA *optionA = conA->pOptions + i; + + switch (optionW->dwOption) { + case INTERNET_PER_CONN_FLAGS: + optionW->Value.dwValue = global_proxy.flags; + break; + + case INTERNET_PER_CONN_PROXY_SERVER: + if (unicode) + optionW->Value.pszValue = copy_optionW(global_proxy.proxy); + else + optionA->Value.pszValue = copy_optionA(global_proxy.proxy); + break; + + case INTERNET_PER_CONN_PROXY_BYPASS: + if (unicode) + optionW->Value.pszValue = copy_optionW(global_proxy.proxyBypass); + else + optionA->Value.pszValue = copy_optionA(global_proxy.proxyBypass); + break; + + case INTERNET_PER_CONN_AUTOCONFIG_URL: + if (unicode) + optionW->Value.pszValue = copy_optionW(global_proxy.autoconf_url); + else + optionA->Value.pszValue = copy_optionA(global_proxy.autoconf_url); + break; + + case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: + optionW->Value.dwValue = AUTO_PROXY_FLAG_ALWAYS_DETECT; + break; + + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: + if (unicode) + optionW->Value.pszValue = copy_optionW(url); + else + optionA->Value.pszValue = copy_optionA(url); + break; + + case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: + case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: + case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: + FIXME("Unhandled dwOption %ld\n", optionW->dwOption); + memset(&optionW->Value, 0, sizeof(optionW->Value)); + break; + + default: + FIXME("Unknown dwOption %ld\n", optionW->dwOption); + res = ERROR_INVALID_PARAMETER; + break; + } + } + + LeaveCriticalSection(&WININET_cs); + return res; + } }
return INET_QueryOption(hdr, option, buffer, size, unicode); @@ -2806,37 +2913,6 @@ static WCHAR *get_proxy_autoconfig_url(void) return ret; }
-static WCHAR *copy_optionW(WCHAR *value) -{ - DWORD len; - void *tmp; - - if (!value) - return NULL; - - len = (wcslen(value) + 1) * sizeof(WCHAR); - if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) - return NULL; - - return memcpy(tmp, value, len); -} - -static char *copy_optionA(WCHAR *value) -{ - DWORD len; - void *tmp; - - if (!value) - return NULL; - - len = wcslen(value) * 3 + 1; - if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) - return NULL; - - WideCharToMultiByte(CP_ACP, 0, value, -1, tmp, len, NULL, NULL); - return tmp; -} - static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL unicode) { /* FIXME: This function currently handles more options than it should. Options requiring @@ -2920,25 +2996,25 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u }
case INTERNET_OPTION_PER_CONNECTION_OPTION: { - WCHAR *url; + WCHAR *url = NULL; INTERNET_PER_CONN_OPTION_LISTW *con = buffer; INTERNET_PER_CONN_OPTION_LISTA *conA = buffer; DWORD res = ERROR_SUCCESS, i; proxyinfo_t pi; LONG ret;
- TRACE("Getting global proxy info\n"); if((ret = INTERNET_LoadProxySettings(&pi))) return ret;
- FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n"); + TRACE("INTERNET_OPTION_PER_CONNECTION_OPTION\n");
if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) { FreeProxyInfo(&pi); return ERROR_INSUFFICIENT_BUFFER; }
- url = get_proxy_autoconfig_url(); + if (pi.flags & PROXY_TYPE_AUTO_DETECT) + url = get_proxy_autoconfig_url();
for (i = 0; i < con->dwOptionCount; i++) { INTERNET_PER_CONN_OPTIONW *optionW = con->pOptions + i; @@ -2947,9 +3023,6 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u switch (optionW->dwOption) { case INTERNET_PER_CONN_FLAGS: optionW->Value.dwValue = pi.flags; - if (url) - /* native includes PROXY_TYPE_DIRECT even if PROXY_TYPE_PROXY is set */ - optionW->Value.dwValue |= PROXY_TYPE_DIRECT|PROXY_TYPE_AUTO_PROXY_URL; break;
case INTERNET_PER_CONN_PROXY_SERVER: @@ -2967,22 +3040,26 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u break;
case INTERNET_PER_CONN_AUTOCONFIG_URL: - if (!url) - optionW->Value.pszValue = NULL; - else if (unicode) - optionW->Value.pszValue = copy_optionW(url); + if (unicode) + optionW->Value.pszValue = copy_optionW(pi.autoconf_url); else - optionA->Value.pszValue = copy_optionA(url); + optionA->Value.pszValue = copy_optionA(pi.autoconf_url); break;
case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: optionW->Value.dwValue = AUTO_PROXY_FLAG_ALWAYS_DETECT; break;
+ case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: + if (unicode) + optionW->Value.pszValue = copy_optionW(url); + else + optionA->Value.pszValue = copy_optionA(url); + break; + case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: - case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: FIXME("Unhandled dwOption %ld\n", optionW->dwOption); memset(&optionW->Value, 0, sizeof(optionW->Value)); break;
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/tests/internet.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index fe47c10b78b..da47fcd9cac 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1286,8 +1286,10 @@ static void test_Option_PerConnectionOption(void) BOOL ret; DWORD size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); INTERNET_PER_CONN_OPTION_LISTW list = {size}; - INTERNET_PER_CONN_OPTIONW *orig_settings; + INTERNET_PER_CONN_OPTIONW *orig_settings, opt; static WCHAR proxy_srvW[] = {'p','r','o','x','y','.','e','x','a','m','p','l','e',0}; + DWORD proxy_flags; + HINTERNET session;
/* get the global IE proxy server info, to restore later */ list.dwOptionCount = 2; @@ -1301,6 +1303,22 @@ static void test_Option_PerConnectionOption(void) ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); orig_settings = list.pOptions;
+ /* store process proxy settings */ + session = InternetOpenW(L"", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + ok(session != NULL,"InternetOpen failed\n"); + + list.dwOptionCount = 1; + list.pOptions = &opt; + opt.dwOption = INTERNET_PER_CONN_FLAGS; + ret = InternetQueryOptionW(session, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); + ok(ret, "InternetQueryOption failed\n"); + proxy_flags = opt.Value.dwValue; + + /* disable process proxy */ + opt.Value.dwValue = PROXY_TYPE_DIRECT; + ret = InternetSetOptionW(session, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list)); + ok(ret, "InternetSetOption failed\n"); + /* set the global IE proxy server */ list.dwOptionCount = 2; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); @@ -1341,8 +1359,14 @@ static void test_Option_PerConnectionOption(void) HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
- /* disable the proxy server */ + /* verify that process proxy was not changed */ list.dwOptionCount = 1; + list.pOptions = &opt; + ret = InternetQueryOptionW(session, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); + ok(ret, "InternetQueryOption failed\n"); + ok(opt.Value.dwValue == PROXY_TYPE_DIRECT, "process proxy flags: %lx\n", opt.Value.dwValue); + + /* disable the proxy server */ list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW));
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; @@ -1410,6 +1434,13 @@ static void test_Option_PerConnectionOption(void) ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); + + list.dwOptionCount = 1; + list.pOptions = &opt; + opt.Value.dwValue = proxy_flags; + ret = InternetSetOptionW(session, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list)); + ok(ret, "InternetSetOption failed\n"); + InternetCloseHandle(session); }
static void test_Option_PerConnectionOptionA(void)
From: Piotr Caban piotr@codeweavers.com
--- dlls/inetcpl.cpl/connections.c | 272 ++++++++------------------------- 1 file changed, 64 insertions(+), 208 deletions(-)
diff --git a/dlls/inetcpl.cpl/connections.c b/dlls/inetcpl.cpl/connections.c index 842f154bd8c..cf10f728652 100644 --- a/dlls/inetcpl.cpl/connections.c +++ b/dlls/inetcpl.cpl/connections.c @@ -30,93 +30,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
-static const WCHAR internet_settings[] = L"Software\Microsoft\Windows\CurrentVersion\Internet Settings"; - static BOOL initdialog_done;
-#define CONNECTION_SETTINGS_VERSION 0x46 -#define CONNECTION_SETTINGS_MANUAL_PROXY 0x2 -#define CONNECTION_SETTINGS_PAC_SCRIPT 0x4 -#define CONNECTION_SETTINGS_WPAD 0x8 - -typedef struct { - DWORD version; - DWORD id; - DWORD flags; - BYTE data[1]; - /* DWORD proxy_server_len; */ - /* UTF8 proxy_server[proxy_server_len]; */ - /* DWORD bypass_list_len; */ - /* UTF8 bypass_list[bypass_list_len]; */ - /* DWORD configuration_script_len; */ - /* UTF8 configuration_script[configuration_script_len]; */ - /* DWORD unk[8]; set to 0 */ -} connection_settings; - -static DWORD create_connection_settings(BOOL manual_proxy, const WCHAR *proxy_server, - BOOL use_wpad, BOOL use_pac_script, const WCHAR *pac_url, connection_settings **ret) -{ - DWORD size = FIELD_OFFSET(connection_settings, data), pos; - DWORD proxy_server_len; - DWORD pac_url_len; - - size += sizeof(DWORD); - if(proxy_server) - { - proxy_server_len = WideCharToMultiByte(CP_UTF8, 0, proxy_server, -1, - NULL, 0, NULL, NULL); - if(!proxy_server_len) return 0; - proxy_server_len--; - } - else - proxy_server_len = 0; - size += proxy_server_len; - if(pac_url) - { - pac_url_len = WideCharToMultiByte(CP_UTF8, 0, pac_url, -1, - NULL, 0, NULL, NULL); - if(!pac_url_len) return 0; - pac_url_len--; - } - else - pac_url_len = 0; - size += sizeof(DWORD)*10; - - *ret = calloc(1, size); - if(!*ret) return 0; - - (*ret)->version = CONNECTION_SETTINGS_VERSION; - (*ret)->flags = 1; - if(manual_proxy) (*ret)->flags |= CONNECTION_SETTINGS_MANUAL_PROXY; - if(use_pac_script) (*ret)->flags |= CONNECTION_SETTINGS_PAC_SCRIPT; - if(use_wpad) (*ret)->flags |= CONNECTION_SETTINGS_WPAD; - ((DWORD*)(*ret)->data)[0] = proxy_server_len; - pos = sizeof(DWORD); - if(proxy_server_len) - { - WideCharToMultiByte(CP_UTF8, 0, proxy_server, -1, - (char*)(*ret)->data+pos, proxy_server_len, NULL, NULL); - pos += proxy_server_len; - } - pos += sizeof(DWORD); /* skip proxy bypass list */ - ((DWORD*)((*ret)->data+pos))[0] = pac_url_len; - pos += sizeof(DWORD); - if(pac_url_len) - { - WideCharToMultiByte(CP_UTF8, 0, pac_url, -1, - (char*)(*ret)->data+pos, pac_url_len, NULL, NULL); - pos += pac_url_len; - } - return size; -} - static void connections_on_initdialog(HWND hwnd) { - DWORD type, size, enabled; - WCHAR address[INTERNET_MAX_URL_LENGTH], *port; - WCHAR pac_url[INTERNET_MAX_URL_LENGTH]; - HKEY hkey, con; - LONG res; + INTERNET_PER_CONN_OPTION_LISTW list; + INTERNET_PER_CONN_OPTIONW options[3]; + WCHAR *address, *port, *pac_url; + DWORD size, flags;
SendMessageW(GetDlgItem(hwnd, IDC_EDIT_PAC_SCRIPT), EM_LIMITTEXT, INTERNET_MAX_URL_LENGTH, 0); @@ -124,82 +45,59 @@ static void connections_on_initdialog(HWND hwnd) EM_LIMITTEXT, INTERNET_MAX_URL_LENGTH-10, 0); SendMessageW(GetDlgItem(hwnd, IDC_EDIT_PROXY_PORT), EM_LIMITTEXT, 8, 0);
- res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings, &hkey); - if(res) - return; - - size = sizeof(enabled); - res = RegQueryValueExW(hkey, L"ProxyEnable", NULL, &type, (BYTE*)&enabled, &size); - if(res || type != REG_DWORD) - enabled = 0; - size = sizeof(address); - res = RegQueryValueExW(hkey, L"ProxyServer", NULL, &type, (BYTE*)address, &size); - if(res || type != REG_SZ) - address[0] = 0; - size = sizeof(pac_url); - res = RegQueryValueExW(hkey, L"AutoConfigURL", NULL, &type, (BYTE*)pac_url, &size); - if(res || type != REG_SZ) - pac_url[0] = 0; - - res = RegOpenKeyW(hkey, L"Connections", &con); - RegCloseKey(hkey); - if(!res) - { - connection_settings *settings = NULL; - size = 0; + list.dwSize = sizeof(list); + list.pszConnection = NULL; + list.dwOptionCount = ARRAY_SIZE(options); + list.pOptions = options;
- while((res = RegQueryValueExW(con, L"DefaultConnectionSettings", NULL, &type, - (BYTE*)settings, &size)) == ERROR_MORE_DATA || !settings) - { - connection_settings *new_settings = realloc(settings, size); - if(!new_settings) - { - RegCloseKey(con); - free(settings); - return; - } - settings = new_settings; - } - RegCloseKey(con); + options[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[2].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; + size = sizeof(list); + if(!InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size)) + return;
- if(!res && type == REG_BINARY) - { - if(settings->version != CONNECTION_SETTINGS_VERSION) - FIXME("unexpected structure version (%lx)\n", settings->version); - else if(settings->flags & CONNECTION_SETTINGS_WPAD) - CheckDlgButton(hwnd, IDC_USE_WPAD, BST_CHECKED); - } - free(settings); - } + flags = options[0].Value.dwValue; + address = options[1].Value.pszValue; + pac_url = options[2].Value.pszValue;
- TRACE("ProxyEnable = %lx\n", enabled); + TRACE("flags = %lx\n", flags); TRACE("ProxyServer = %s\n", wine_dbgstr_w(address)); TRACE("AutoConfigURL = %s\n", wine_dbgstr_w(pac_url));
- if(enabled) + if (flags & PROXY_TYPE_AUTO_DETECT) + CheckDlgButton(hwnd, IDC_USE_WPAD, BST_CHECKED); + + if(flags & PROXY_TYPE_PROXY) { CheckDlgButton(hwnd, IDC_USE_PROXY_SERVER, BST_CHECKED); EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_SERVER), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_PORT), TRUE); }
- port = wcschr(address, ':'); - if(port) + if(address) { - *port = 0; - port++; + port = wcschr(address, ':'); + if(port) + { + *port = 0; + port++; + } + SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_SERVER, address); + if(port) + SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_PORT, port); } - SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_SERVER, address); - if(port) - SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_PORT, port);
- if(pac_url[0]) + if(flags & PROXY_TYPE_AUTO_PROXY_URL) { CheckDlgButton(hwnd, IDC_USE_PAC_SCRIPT, BST_CHECKED); EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PAC_SCRIPT), TRUE); - SetDlgItemTextW(hwnd, IDC_EDIT_PAC_SCRIPT, pac_url); } + if(pac_url) + SetDlgItemTextW(hwnd, IDC_EDIT_PAC_SCRIPT, pac_url);
+ GlobalFree(address); + GlobalFree(pac_url); return; }
@@ -237,31 +135,18 @@ static INT_PTR connections_on_command(HWND hwnd, WPARAM wparam)
static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam) { - connection_settings *default_connection; WCHAR proxy[INTERNET_MAX_URL_LENGTH]; WCHAR pac_script[INTERNET_MAX_URL_LENGTH]; PSHNOTIFY *psn = (PSHNOTIFY*)lparam; DWORD proxy_len, port_len, pac_script_len; - DWORD use_proxy, use_pac_script, use_wpad, size; - LRESULT res; - HKEY hkey, con; + INTERNET_PER_CONN_OPTION_LISTW list; + INTERNET_PER_CONN_OPTIONW options[3]; + DWORD flags;
if(psn->hdr.code != PSN_APPLY) return FALSE;
- res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings, &hkey); - if(res) - return FALSE; - - use_proxy = IsDlgButtonChecked(hwnd, IDC_USE_PROXY_SERVER); - res = RegSetValueExW(hkey, L"ProxyEnable", 0, REG_DWORD, - (BYTE*)&use_proxy, sizeof(use_proxy)); - if(res) - { - RegCloseKey(hkey); - return FALSE; - } - TRACE("ProxyEnable set to %lx\n", use_proxy); + flags = IsDlgButtonChecked(hwnd, IDC_USE_PROXY_SERVER) ? PROXY_TYPE_PROXY : PROXY_TYPE_DIRECT;
proxy_len = GetDlgItemTextW(hwnd, IDC_EDIT_PROXY_SERVER, proxy, ARRAY_SIZE(proxy)); if(proxy_len) @@ -275,65 +160,36 @@ static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam) proxy[proxy_len++] = '0'; proxy[proxy_len] = 0; } - - res = RegSetValueExW(hkey, L"ProxyServer", 0, REG_SZ, - (BYTE*)proxy, (proxy_len+port_len)*sizeof(WCHAR)); } else { - res = RegDeleteValueW(hkey, L"ProxyServer"); - if(res == ERROR_FILE_NOT_FOUND) - res = ERROR_SUCCESS; + flags = PROXY_TYPE_DIRECT; } - if(res) - { - RegCloseKey(hkey); - return FALSE; - } - TRACE("ProxyServer set to %s\n", wine_dbgstr_w(proxy));
- use_pac_script = IsDlgButtonChecked(hwnd, IDC_USE_PAC_SCRIPT); pac_script_len = GetDlgItemTextW(hwnd, IDC_EDIT_PAC_SCRIPT, pac_script, ARRAY_SIZE(pac_script)); - if(!pac_script_len) use_pac_script = FALSE; - if(use_pac_script) - { - res = RegSetValueExW(hkey, L"AutoConfigURL", 0, REG_SZ, - (BYTE*)pac_script, pac_script_len*sizeof(WCHAR)); - } - else - { - res = RegDeleteValueW(hkey, L"AutoConfigURL"); - if(res == ERROR_FILE_NOT_FOUND) - res = ERROR_SUCCESS; - } - if(res) - { - RegCloseKey(hkey); - return FALSE; - } - TRACE("AutoConfigURL set to %s\n", wine_dbgstr_w(use_pac_script ? pac_script : NULL)); - - use_wpad = IsDlgButtonChecked(hwnd, IDC_USE_WPAD); - - res = RegCreateKeyExW(hkey, L"Connections", 0, NULL, 0, KEY_WRITE, NULL, &con, NULL); - RegCloseKey(hkey); - if(res) - return FALSE; - - size = create_connection_settings(use_proxy, proxy, use_wpad, - use_pac_script, pac_script, &default_connection); - if(!size) - { - RegCloseKey(con); - return FALSE; - } - - res = RegSetValueExW(con, L"DefaultConnectionSettings", 0, REG_BINARY, - (BYTE*)default_connection, size); - free(default_connection); - RegCloseKey(con); - return !res; + if(pac_script_len && IsDlgButtonChecked(hwnd, IDC_USE_PAC_SCRIPT)) + flags |= PROXY_TYPE_AUTO_PROXY_URL; + + if(IsDlgButtonChecked(hwnd, IDC_USE_WPAD)) + flags |= PROXY_TYPE_AUTO_DETECT; + + TRACE("flags = %lx\n", flags); + TRACE("ProxyServer = %s\n", wine_dbgstr_w(proxy)); + TRACE("AutoConfigURL = %s\n", wine_dbgstr_w(pac_script)); + + list.dwSize = sizeof(list); + list.pszConnection = NULL; + list.dwOptionCount = ARRAY_SIZE(options); + list.pOptions = options; + + options[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.dwValue = flags; + options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[1].Value.pszValue = proxy; + options[2].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; + options[2].Value.pszValue = pac_script; + return InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list)); }
INT_PTR CALLBACK connections_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)