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/wininet/tests/http.c | 72 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 9405991c3b0..705f89f28ba 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -529,11 +529,13 @@ typedef struct { HINTERNET request; } test_request_t;
-#define open_simple_request(a,b,c,d,e) _open_simple_request(__LINE__,a,b,c,d,e) +#define open_simple_request(a,b,c,d,e) _open_simple_request(__LINE__,a,b,c,d,e,FALSE) +#define open_simple_request_proxy(a,b,c,d,e) _open_simple_request(__LINE__,a,b,c,d,e,TRUE) static void _open_simple_request(unsigned line, test_request_t *req, const char *host, - int port, const char *verb, const char *url) + int port, const char *verb, const char *url, BOOL use_proxy) { - req->session = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + req->session = InternetOpenA(NULL, use_proxy ? INTERNET_OPEN_TYPE_PRECONFIG : INTERNET_OPEN_TYPE_DIRECT, + NULL, NULL, 0); ok_(__FILE__,line)(req->session != NULL, "InternetOpenA failed: %lu\n", GetLastError());
req->connection = InternetConnectA(req->session, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); @@ -2445,6 +2447,11 @@ static const char ok_with_length2[] = "Content-Length: 19\r\n\r\n" "HTTP/1.1 211 OK\r\n\r\n";
+static const char proxy_pac[] = +"function FindProxyForURL(url, host) {\r\n" +" return 'PROXY localhost:%d';\r\n" +"}\r\n\r\n"; + struct server_info { HANDLE hEvent; int port; @@ -2858,6 +2865,18 @@ static DWORD CALLBACK server_thread(LPVOID param) sprintf(msg, largemsg, content_length); send(c, msg, strlen(msg), 0); } + if (strstr(buffer, "GET /proxy.pac")) + { + char script[sizeof(proxy_pac) + 16]; + sprintf(script, proxy_pac, si->port); + send(c, okmsg, sizeof(okmsg)-1, 0); + send(c, script, strlen(script), 0); + } + if (strstr(buffer, "GET http://test.winehq.org/tests/hello.html")) + { + send(c, okmsg, sizeof(okmsg)-1, 0); + send(c, page1, sizeof(page1)-1, 0); + } shutdown(c, 2); closesocket(c); c = -1; @@ -6625,6 +6644,52 @@ static void test_header_length(int port) close_request(&req); }
+static void test_pac(int port) +{ + static const WCHAR autoconf_url_fmt[] = L"http://localhost:%d/proxy.pac?ver=1"; + INTERNET_PER_CONN_OPTION_LISTW option_list; + INTERNET_PER_CONN_OPTIONW options[2]; + WCHAR autoconf_url[64]; + test_request_t req; + char buf[1000]; + DWORD len; + BOOL r; + + open_simple_request_proxy(&req, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, "GET", "/tests/hello.html"); + + swprintf(autoconf_url, ARRAY_SIZE(autoconf_url), autoconf_url_fmt, port); + memset(&option_list, 0, sizeof(option_list)); + option_list.dwSize = sizeof(option_list); + option_list.dwOptionCount = ARRAY_SIZE(options); + option_list.pOptions = options; + options[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; + options[0].Value.pszValue = autoconf_url; + options[1].dwOption = INTERNET_PER_CONN_FLAGS; + options[1].Value.dwValue = PROXY_TYPE_AUTO_PROXY_URL; + r = InternetSetOptionW(req.session, INTERNET_OPTION_PER_CONNECTION_OPTION, (void*)&option_list, sizeof(option_list)); + ok(r, "InternetSetOptionW failed: %lu\n", GetLastError()); + + r = HttpSendRequestW(req.request, NULL, 0, NULL, 0); + ok(r, "HttpSendRequestW failed: %lu\n", GetLastError()); + + test_status_code(req.request, 200); + len = receive_simple_request(req.request, buf, sizeof(buf)); + todo_wine + ok(len == sizeof(page1) - 1, "unexpected buffer size\n"); + buf[len] = 0; + todo_wine + ok(!strcmp(buf, page1), "unexpected buffer content\n"); + + len = sizeof(option_list); + r = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, (void*)&option_list, &len); + ok(r, "InternetGetOptionW failed: %lu\n", GetLastError()); + r = InternetSetOptionW(req.session, INTERNET_OPTION_PER_CONNECTION_OPTION, (void*)&option_list, sizeof(option_list)); + ok(r, "InternetSetOptionW failed: %lu\n", GetLastError()); + GlobalFree(options[0].Value.pszValue); + + close_request(&req); +} + static void test_http_connection(void) { struct server_info si; @@ -6692,6 +6757,7 @@ static void test_http_connection(void) test_remove_dot_segments(si.port); test_large_content(si.port); test_header_length(si.port); + test_pac(si.port);
/* send the basic request again to shutdown the server thread */ test_basic_request(si.port, "GET", "/quit");
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)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143057
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/wininet/internet.c:89 error: patch failed: dlls/wininet/internet.c:643 error: patch failed: dlls/wininet/internet.c:446 error: patch failed: dlls/wininet/internet.c:2947 Task: Patch failed to apply
=== debian11 (build log) ===
error: patch failed: dlls/wininet/internet.c:89 error: patch failed: dlls/wininet/internet.c:643 error: patch failed: dlls/wininet/internet.c:446 error: patch failed: dlls/wininet/internet.c:2947 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/wininet/internet.c:89 error: patch failed: dlls/wininet/internet.c:643 error: patch failed: dlls/wininet/internet.c:446 error: patch failed: dlls/wininet/internet.c:2947 Task: Patch failed to apply
Windows CI failure seems related.