-- v4: wininet: Add support for reading connection settings binary blobs from registry. wininet: Add support for writing connection settings binary blobs from registry. wininet/tests: Cleanup INTERNET_OPTION_PER_CONNECTION_OPTION tests. wininet: Use GlobalAlloc in InternetQueryOption(INTERNET_OPTION_PER_CONNECTION_OPTION). wininet: Fix buffer size calculation in InternetQueryOption(INTERNET_OPTION_PER_CONNECTION_OPTION). wininet: Test INTERNET_OPTION_PER_CONNECTION_OPTION on process settings.
From: Piotr Caban piotr@codeweavers.com
Setting invalid proxy server has some side effects. --- dlls/wininet/tests/internet.c | 91 +++++++++++++---------------------- 1 file changed, 34 insertions(+), 57 deletions(-)
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 495371d50a5..715b03f95fb 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1260,27 +1260,6 @@ static void test_end_browser_session(void) ok(!len, "len = %lu\n", len); }
-#define verifyProxyEnable(e) r_verifyProxyEnable(__LINE__, e) -static void r_verifyProxyEnable(LONG l, DWORD exp) -{ - HKEY hkey; - DWORD type, val, size = sizeof(DWORD); - LONG ret; - static const CHAR szInternetSettings[] = "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; - static const CHAR szProxyEnable[] = "ProxyEnable"; - - ret = RegOpenKeyA(HKEY_CURRENT_USER, szInternetSettings, &hkey); - ok_(__FILE__,l) (!ret, "RegOpenKeyA failed: 0x%08lx\n", ret); - - ret = RegQueryValueExA(hkey, szProxyEnable, 0, &type, (BYTE*)&val, &size); - ok_(__FILE__,l) (!ret, "RegQueryValueExA failed: 0x%08lx\n", ret); - ok_(__FILE__,l) (type == REG_DWORD, "Expected regtype to be REG_DWORD, was: %ld\n", type); - ok_(__FILE__,l) (val == exp, "Expected ProxyEnabled to be %ld, got: %ld\n", exp, val); - - ret = RegCloseKey(hkey); - ok_(__FILE__,l) (!ret, "RegCloseKey failed: 0x%08lx\n", ret); -} - static void test_Option_PerConnectionOption(void) { BOOL ret; @@ -1288,20 +1267,23 @@ static void test_Option_PerConnectionOption(void) INTERNET_PER_CONN_OPTION_LISTW list = {size}; INTERNET_PER_CONN_OPTIONW *orig_settings; static WCHAR proxy_srvW[] = {'p','r','o','x','y','.','e','x','a','m','p','l','e',0}; + HINTERNET ses; + + ses = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(ses != 0, "InternetOpen failed: 0x%08lx\n", GetLastError());
- /* get the global IE proxy server info, to restore later */ + /* get the process IE proxy server info, to restore later */ list.dwOptionCount = 2; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW));
list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, &size); + ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); orig_settings = list.pOptions;
- /* set the global IE proxy server */ + /* set the process IE proxy server */ list.dwOptionCount = 2; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW));
@@ -1310,13 +1292,12 @@ static void test_Option_PerConnectionOption(void) list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY;
- ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, size); + ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions);
- /* get & verify the global IE proxy server */ + /* get & verify the process IE proxy server */ list.dwOptionCount = 2; list.dwOptionError = 0; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); @@ -1324,8 +1305,7 @@ static void test_Option_PerConnectionOption(void) list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, &size); + ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); ok(!lstrcmpW(list.pOptions[0].Value.pszValue, proxy_srvW), "Retrieved proxy server should've been %s, was: %s\n", @@ -1333,7 +1313,6 @@ static void test_Option_PerConnectionOption(void) ok(list.pOptions[1].Value.dwValue == PROXY_TYPE_PROXY, "Retrieved flags should've been PROXY_TYPE_PROXY, was: %ld\n", list.pOptions[1].Value.dwValue); - verifyProxyEnable(1);
ret = HeapValidate(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); ok(ret, "HeapValidate failed, last error %lu\n", GetLastError()); @@ -1348,8 +1327,7 @@ static void test_Option_PerConnectionOption(void) list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT;
- ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, size); + ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); @@ -1361,13 +1339,11 @@ static void test_Option_PerConnectionOption(void)
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, &size); + ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); ok(list.pOptions[0].Value.dwValue == PROXY_TYPE_DIRECT, "Retrieved flags should've been PROXY_TYPE_DIRECT, was: %ld\n", list.pOptions[0].Value.dwValue); - verifyProxyEnable(0);
HeapFree(GetProcessHeap(), 0, list.pOptions);
@@ -1378,8 +1354,7 @@ static void test_Option_PerConnectionOption(void) list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; list.pOptions[0].Value.dwValue = PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT;
- ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, size); + ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); @@ -1391,13 +1366,11 @@ static void test_Option_PerConnectionOption(void)
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, &size); + ret = InternetQueryOptionW(ses, 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), - "Retrieved flags should've been PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT, was: %ld\n", + todo_wine ok(list.pOptions[0].Value.dwValue == PROXY_TYPE_DIRECT, + "Retrieved flags should've been PROXY_TYPE_DIRECT, was: %ld\n", list.pOptions[0].Value.dwValue); - verifyProxyEnable(1);
HeapFree(GetProcessHeap(), 0, list.pOptions);
@@ -1405,11 +1378,12 @@ static void test_Option_PerConnectionOption(void) list.dwOptionCount = 2; list.pOptions = orig_settings;
- ret = InternetSetOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, size); + ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); + + InternetCloseHandle(ses); }
static void test_Option_PerConnectionOptionA(void) @@ -1419,20 +1393,24 @@ static void test_Option_PerConnectionOptionA(void) INTERNET_PER_CONN_OPTION_LISTA list = {size}; INTERNET_PER_CONN_OPTIONA *orig_settings; char proxy_srv[] = "proxy.example"; + HINTERNET ses;
- /* get the global IE proxy server info, to restore later */ + ses = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(ses != 0, "InternetOpen failed: 0x%08lx\n", GetLastError()); + + /* get the process IE proxy server info, to restore later */ list.dwOptionCount = 2; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA));
list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); orig_settings = list.pOptions;
- /* set the global IE proxy server */ + /* set the process IE proxy server */ list.dwOptionCount = 2; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA));
@@ -1441,13 +1419,13 @@ static void test_Option_PerConnectionOptionA(void) list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY;
- ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions);
- /* get & verify the global IE proxy server */ + /* get & verify the process IE proxy server */ list.dwOptionCount = 2; list.dwOptionError = 0; list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); @@ -1455,7 +1433,7 @@ static void test_Option_PerConnectionOptionA(void) list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS;
- ret = InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); ok(!lstrcmpA(list.pOptions[0].Value.pszValue, "proxy.example"), @@ -1474,10 +1452,7 @@ static void test_Option_PerConnectionOptionA(void) list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[0].Value.pszValue = NULL;
- ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); + ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); @@ -1488,7 +1463,7 @@ static void test_Option_PerConnectionOptionA(void) list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONA)); list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
- ret = InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); + ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); ok(!list.pOptions[0].Value.pszValue, "Retrieved proxy server should've been NULL, was: "%s"\n", @@ -1501,11 +1476,13 @@ static void test_Option_PerConnectionOptionA(void) list.dwOptionCount = 2; list.pOptions = orig_settings;
- ret = InternetSetOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, + ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
HeapFree(GetProcessHeap(), 0, list.pOptions); + + InternetCloseHandle(ses); }
#define FLAG_NEEDREQ 0x1
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/internet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index b74015146ea..fe11cb6f501 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -2620,7 +2620,7 @@ static char *copy_optionA(WCHAR *value) if (!value) return NULL;
- len = wcslen(value) * 3 + 1; + len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL); if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) return NULL;
From: Piotr Caban piotr@codeweavers.com
So the allocator matches with documentation. --- dlls/wininet/internet.c | 4 ++-- dlls/wininet/tests/internet.c | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index fe11cb6f501..22f0023bba2 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -2606,7 +2606,7 @@ static WCHAR *copy_optionW(WCHAR *value) return NULL;
len = (wcslen(value) + 1) * sizeof(WCHAR); - if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) + if (!(tmp = GlobalAlloc(0, len))) return NULL;
return memcpy(tmp, value, len); @@ -2621,7 +2621,7 @@ static char *copy_optionA(WCHAR *value) return NULL;
len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL); - if (!(tmp = HeapAlloc(GetProcessHeap(), 0, len))) + if (!(tmp = GlobalAlloc(0, len))) return NULL;
WideCharToMultiByte(CP_ACP, 0, value, -1, tmp, len, NULL, NULL); diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 715b03f95fb..32504382477 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1317,7 +1317,7 @@ static void test_Option_PerConnectionOption(void) ret = HeapValidate(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); ok(ret, "HeapValidate failed, last error %lu\n", GetLastError());
- HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + GlobalFree(list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
/* disable the proxy server */ @@ -1381,6 +1381,7 @@ static void test_Option_PerConnectionOption(void) ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
+ GlobalFree(list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
InternetCloseHandle(ses); @@ -1443,7 +1444,7 @@ static void test_Option_PerConnectionOptionA(void) "Retrieved flags should've been PROXY_TYPE_PROXY, was: %ld\n", list.pOptions[1].Value.dwValue);
- HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + GlobalFree(list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
/* test with NULL as proxy server */ @@ -1469,7 +1470,7 @@ static void test_Option_PerConnectionOptionA(void) "Retrieved proxy server should've been NULL, was: "%s"\n", list.pOptions[0].Value.pszValue);
- HeapFree(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + GlobalFree(list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
/* restore original settings */ @@ -1480,6 +1481,7 @@ static void test_Option_PerConnectionOptionA(void) &list, size); ok(ret == TRUE, "InternetSetOption should've succeeded\n");
+ GlobalFree(list.pOptions[0].Value.pszValue); HeapFree(GetProcessHeap(), 0, list.pOptions);
InternetCloseHandle(ses);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wininet/tests/internet.c | 190 ++++++++++++---------------------- 1 file changed, 66 insertions(+), 124 deletions(-)
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 32504382477..1475d2161ce 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1265,8 +1265,8 @@ 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; - static WCHAR proxy_srvW[] = {'p','r','o','x','y','.','e','x','a','m','p','l','e',0}; + INTERNET_PER_CONN_OPTIONW orig_settings[2], options[2]; + static WCHAR proxy_srvW[] = L"proxy.example"; HINTERNET ses;
ses = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); @@ -1274,116 +1274,81 @@ static void test_Option_PerConnectionOption(void)
/* get the process IE proxy server info, to restore later */ list.dwOptionCount = 2; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions = orig_settings; + orig_settings[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + orig_settings[1].dwOption = INTERNET_PER_CONN_FLAGS;
ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - orig_settings = list.pOptions; + ok(ret, "InternetQueryOption should've succeeded\n");
/* set the process IE proxy server */ - list.dwOptionCount = 2; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[0].Value.pszValue = proxy_srvW; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; - list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY; + list.pOptions = options; + options[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[0].Value.pszValue = proxy_srvW; + options[1].dwOption = INTERNET_PER_CONN_FLAGS; + options[1].Value.dwValue = PROXY_TYPE_PROXY;
ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
/* get & verify the process IE proxy server */ - list.dwOptionCount = 2; - list.dwOptionError = 0; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.pszValue = NULL; + options[1].Value.dwValue = 0;
ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - ok(!lstrcmpW(list.pOptions[0].Value.pszValue, proxy_srvW), + ok(ret, "InternetQueryOption should've succeeded\n"); + ok(!lstrcmpW(options[0].Value.pszValue, proxy_srvW), "Retrieved proxy server should've been %s, was: %s\n", - wine_dbgstr_w(proxy_srvW), wine_dbgstr_w(list.pOptions[0].Value.pszValue)); - ok(list.pOptions[1].Value.dwValue == PROXY_TYPE_PROXY, + wine_dbgstr_w(proxy_srvW), wine_dbgstr_w(options[0].Value.pszValue)); + ok(options[1].Value.dwValue == PROXY_TYPE_PROXY, "Retrieved flags should've been PROXY_TYPE_PROXY, was: %ld\n", - list.pOptions[1].Value.dwValue); + options[1].Value.dwValue);
- ret = HeapValidate(GetProcessHeap(), 0, list.pOptions[0].Value.pszValue); + ret = HeapValidate(GetProcessHeap(), 0, options[0].Value.pszValue); ok(ret, "HeapValidate failed, last error %lu\n", GetLastError()); - - GlobalFree(list.pOptions[0].Value.pszValue); - HeapFree(GetProcessHeap(), 0, list.pOptions); + GlobalFree(options[0].Value.pszValue);
/* disable the proxy server */ list.dwOptionCount = 1; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; - list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT; + options[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.dwValue = PROXY_TYPE_DIRECT;
ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
/* verify that the proxy is disabled */ - list.dwOptionCount = 1; - list.dwOptionError = 0; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.dwValue = 0;
ret = InternetQueryOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - ok(list.pOptions[0].Value.dwValue == PROXY_TYPE_DIRECT, + ok(ret, "InternetQueryOption should've succeeded\n"); + ok(options[0].Value.dwValue == PROXY_TYPE_DIRECT, "Retrieved flags should've been PROXY_TYPE_DIRECT, was: %ld\n", - list.pOptions[0].Value.dwValue); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + options[0].Value.dwValue);
/* set the proxy flags to 'invalid' value */ - list.dwOptionCount = 1; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; - list.pOptions[0].Value.dwValue = PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT; + options[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.dwValue = PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT;
ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
/* verify that the proxy is enabled */ - list.dwOptionCount = 1; - list.dwOptionError = 0; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONW)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.dwValue = 0;
ret = InternetQueryOptionW(ses, 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_DIRECT, + ok(ret, "InternetQueryOption should've succeeded\n"); + todo_wine ok(options[0].Value.dwValue == PROXY_TYPE_DIRECT, "Retrieved flags should've been PROXY_TYPE_DIRECT, was: %ld\n", - list.pOptions[0].Value.dwValue); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + options[0].Value.dwValue);
/* restore original settings */ list.dwOptionCount = 2; list.pOptions = orig_settings;
ret = InternetSetOptionW(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - GlobalFree(list.pOptions[0].Value.pszValue); - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
+ GlobalFree(orig_settings[0].Value.pszValue); InternetCloseHandle(ses); }
@@ -1392,7 +1357,7 @@ static void test_Option_PerConnectionOptionA(void) BOOL ret; DWORD size = sizeof(INTERNET_PER_CONN_OPTION_LISTA); INTERNET_PER_CONN_OPTION_LISTA list = {size}; - INTERNET_PER_CONN_OPTIONA *orig_settings; + INTERNET_PER_CONN_OPTIONA orig_settings[2], options[2]; char proxy_srv[] = "proxy.example"; HINTERNET ses;
@@ -1401,89 +1366,66 @@ static void test_Option_PerConnectionOptionA(void)
/* get the process IE proxy server info, to restore later */ list.dwOptionCount = 2; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + list.pOptions = orig_settings; + orig_settings[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + orig_settings[1].dwOption = INTERNET_PER_CONN_FLAGS;
ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - orig_settings = list.pOptions; + ok(ret, "InternetQueryOption should've succeeded\n");
/* set the process IE proxy server */ - list.dwOptionCount = 2; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[0].Value.pszValue = proxy_srv; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; - list.pOptions[1].Value.dwValue = PROXY_TYPE_PROXY; + list.pOptions = options; + options[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[0].Value.pszValue = proxy_srv; + options[1].dwOption = INTERNET_PER_CONN_FLAGS; + options[1].Value.dwValue = PROXY_TYPE_PROXY;
ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
/* get & verify the process IE proxy server */ - list.dwOptionCount = 2; - list.dwOptionError = 0; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(INTERNET_PER_CONN_OPTIONA)); - - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[1].dwOption = INTERNET_PER_CONN_FLAGS; + options[0].Value.pszValue = NULL; + options[1].Value.dwValue = 0;
ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - ok(!lstrcmpA(list.pOptions[0].Value.pszValue, "proxy.example"), + ok(ret, "InternetQueryOption should've succeeded\n"); + ok(!lstrcmpA(options[0].Value.pszValue, "proxy.example"), "Retrieved proxy server should've been "%s", was: "%s"\n", - proxy_srv, list.pOptions[0].Value.pszValue); - ok(list.pOptions[1].Value.dwValue == PROXY_TYPE_PROXY, + proxy_srv, options[0].Value.pszValue); + ok(options[1].Value.dwValue == PROXY_TYPE_PROXY, "Retrieved flags should've been PROXY_TYPE_PROXY, was: %ld\n", - list.pOptions[1].Value.dwValue); + options[1].Value.dwValue);
- GlobalFree(list.pOptions[0].Value.pszValue); - HeapFree(GetProcessHeap(), 0, list.pOptions); + GlobalFree(options[0].Value.pszValue);
/* test with NULL as proxy server */ list.dwOptionCount = 1; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONA)); - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; - list.pOptions[0].Value.pszValue = NULL; + options[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[0].Value.pszValue = NULL;
ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - HeapFree(GetProcessHeap(), 0, list.pOptions); + ok(ret, "InternetSetOption should've succeeded\n");
/* get & verify the proxy server */ - list.dwOptionCount = 1; - list.dwOptionError = 0; - list.pOptions = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNET_PER_CONN_OPTIONA)); - list.pOptions[0].dwOption = INTERNET_PER_CONN_PROXY_SERVER; + options[0].Value.dwValue = 0xdeadbeef;
ret = InternetQueryOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &size); - ok(ret == TRUE, "InternetQueryOption should've succeeded\n"); - ok(!list.pOptions[0].Value.pszValue, + ok(ret, "InternetQueryOption should've succeeded\n"); + ok(!options[0].Value.pszValue, "Retrieved proxy server should've been NULL, was: "%s"\n", - list.pOptions[0].Value.pszValue); - - GlobalFree(list.pOptions[0].Value.pszValue); - HeapFree(GetProcessHeap(), 0, list.pOptions); + options[0].Value.pszValue);
/* restore original settings */ list.dwOptionCount = 2; list.pOptions = orig_settings;
- ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, - &list, size); - ok(ret == TRUE, "InternetSetOption should've succeeded\n"); - - GlobalFree(list.pOptions[0].Value.pszValue); - HeapFree(GetProcessHeap(), 0, list.pOptions); + ret = InternetSetOptionA(ses, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, size); + ok(ret, "InternetSetOption should've succeeded\n");
+ GlobalFree(orig_settings[0].Value.pszValue); InternetCloseHandle(ses); }
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 22f0023bba2..b8c45355d9d 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 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index b8c45355d9d..54063a25b7e 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)); }
On Wed Feb 14 13:42:53 2024 +0000, Piotr Caban wrote:
It looks like there's something strange happening because of PAC script tests. I'm still looking into it.
It turns out that it was caused by current INTERNET_OPTION_PER_CONNECTION_OPTION. In general WinHTTP Web Proxy Auto-Discovery Service doesn't like when non-working proxy server is set. This causes discrepancy between proxy set in registry and used by the service.
I've pushed new patches that are changing existing INTERNET_OPTION_PER_CONNECTION_OPTION tests to work on process settings instead of global.
This merge request was approved by Jacek Caban.