user32/tests: Test pending redraw state with owner-drawn list box.
[wine.git] / dlls / inetcpl.cpl / connections.c
blob4327c33b420aacb6b892d2153a388bc44464b4d5
1 /*
2 * Copyright 2018 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
21 #include <windef.h>
22 #include <winbase.h>
23 #include <winnls.h>
24 #include <wininet.h>
25 #include <winuser.h>
26 #include <winreg.h>
28 #include "inetcpl.h"
29 #include "wine/debug.h"
30 #include "wine/heap.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
34 static const WCHAR internet_settings[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
36 static BOOL initdialog_done;
38 #define CONNECTION_SETTINGS_VERSION 0x46
39 #define CONNECTION_SETTINGS_MANUAL_PROXY 0x2
40 #define CONNECTION_SETTINGS_PAC_SCRIPT 0x4
41 #define CONNECTION_SETTINGS_WPAD 0x8
43 typedef struct {
44 DWORD version;
45 DWORD id;
46 DWORD flags;
47 BYTE data[1];
48 /* DWORD proxy_server_len; */
49 /* UTF8 proxy_server[proxy_server_len]; */
50 /* DWORD bypass_list_len; */
51 /* UTF8 bypass_list[bypass_list_len]; */
52 /* DWORD configuration_script_len; */
53 /* UTF8 configuration_script[configuration_script_len]; */
54 /* DWORD unk[8]; set to 0 */
55 } connection_settings;
57 static DWORD create_connection_settings(BOOL manual_proxy, const WCHAR *proxy_server,
58 BOOL use_wpad, BOOL use_pac_script, const WCHAR *pac_url, connection_settings **ret)
60 DWORD size = FIELD_OFFSET(connection_settings, data), pos;
61 DWORD proxy_server_len;
62 DWORD pac_url_len;
64 size += sizeof(DWORD);
65 if(L"ProxyServer")
67 proxy_server_len = WideCharToMultiByte(CP_UTF8, 0, proxy_server, -1,
68 NULL, 0, NULL, NULL);
69 if(!proxy_server_len) return 0;
70 proxy_server_len--;
72 else
73 proxy_server_len = 0;
74 size += proxy_server_len;
75 if(pac_url)
77 pac_url_len = WideCharToMultiByte(CP_UTF8, 0, pac_url, -1,
78 NULL, 0, NULL, NULL);
79 if(!pac_url_len) return 0;
80 pac_url_len--;
82 else
83 pac_url_len = 0;
84 size += sizeof(DWORD)*10;
86 *ret = heap_alloc_zero(size);
87 if(!*ret) return 0;
89 (*ret)->version = CONNECTION_SETTINGS_VERSION;
90 (*ret)->flags = 1;
91 if(manual_proxy) (*ret)->flags |= CONNECTION_SETTINGS_MANUAL_PROXY;
92 if(use_pac_script) (*ret)->flags |= CONNECTION_SETTINGS_PAC_SCRIPT;
93 if(use_wpad) (*ret)->flags |= CONNECTION_SETTINGS_WPAD;
94 ((DWORD*)(*ret)->data)[0] = proxy_server_len;
95 pos = sizeof(DWORD);
96 if(proxy_server_len)
98 WideCharToMultiByte(CP_UTF8, 0, proxy_server, -1,
99 (char*)(*ret)->data+pos, proxy_server_len, NULL, NULL);
100 pos += proxy_server_len;
102 pos += sizeof(DWORD); /* skip proxy bypass list */
103 ((DWORD*)((*ret)->data+pos))[0] = pac_url_len;
104 pos += sizeof(DWORD);
105 if(pac_url_len)
107 WideCharToMultiByte(CP_UTF8, 0, pac_url, -1,
108 (char*)(*ret)->data+pos, pac_url_len, NULL, NULL);
109 pos += pac_url_len;
111 return size;
114 static void connections_on_initdialog(HWND hwnd)
116 DWORD type, size, enabled;
117 WCHAR address[INTERNET_MAX_URL_LENGTH], *port;
118 WCHAR pac_url[INTERNET_MAX_URL_LENGTH];
119 HKEY hkey, con;
120 LONG res;
122 SendMessageW(GetDlgItem(hwnd, IDC_EDIT_PAC_SCRIPT),
123 EM_LIMITTEXT, INTERNET_MAX_URL_LENGTH, 0);
124 SendMessageW(GetDlgItem(hwnd, IDC_EDIT_PROXY_SERVER),
125 EM_LIMITTEXT, INTERNET_MAX_URL_LENGTH-10, 0);
126 SendMessageW(GetDlgItem(hwnd, IDC_EDIT_PROXY_PORT), EM_LIMITTEXT, 8, 0);
128 res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings, &hkey);
129 if(res)
130 return;
132 size = sizeof(enabled);
133 res = RegQueryValueExW(hkey, L"ProxyEnable", NULL, &type, (BYTE*)&enabled, &size);
134 if(res || type != REG_DWORD)
135 enabled = 0;
136 size = sizeof(address);
137 res = RegQueryValueExW(hkey, L"ProxyServer", NULL, &type, (BYTE*)address, &size);
138 if(res || type != REG_SZ)
139 address[0] = 0;
140 size = sizeof(pac_url);
141 res = RegQueryValueExW(hkey, L"AutoConfigURL", NULL, &type, (BYTE*)pac_url, &size);
142 if(res || type != REG_SZ)
143 pac_url[0] = 0;
145 res = RegOpenKeyW(hkey, L"Connections", &con);
146 RegCloseKey(hkey);
147 if(!res)
149 connection_settings *settings = NULL;
150 size = 0;
152 while((res = RegQueryValueExW(con, L"DefaultConnectionSettings", NULL, &type,
153 (BYTE*)settings, &size)) == ERROR_MORE_DATA || !settings)
155 connection_settings *new_settings = heap_realloc(settings, size);
156 if(!new_settings)
158 RegCloseKey(con);
159 heap_free(settings);
160 return;
162 settings = new_settings;
164 RegCloseKey(con);
166 if(!res && type == REG_BINARY)
168 if(settings->version != CONNECTION_SETTINGS_VERSION)
169 FIXME("unexpected structure version (%x)\n", settings->version);
170 else if(settings->flags & CONNECTION_SETTINGS_WPAD)
171 CheckDlgButton(hwnd, IDC_USE_WPAD, BST_CHECKED);
173 heap_free(settings);
176 TRACE("ProxyEnable = %x\n", enabled);
177 TRACE("ProxyServer = %s\n", wine_dbgstr_w(address));
178 TRACE("AutoConfigURL = %s\n", wine_dbgstr_w(pac_url));
180 if(enabled)
182 CheckDlgButton(hwnd, IDC_USE_PROXY_SERVER, BST_CHECKED);
183 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_SERVER), TRUE);
184 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_PORT), TRUE);
187 port = wcschr(address, ':');
188 if(port)
190 *port = 0;
191 port++;
193 SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_SERVER, address);
194 if(port)
195 SetDlgItemTextW(hwnd, IDC_EDIT_PROXY_PORT, port);
197 if(pac_url[0])
199 CheckDlgButton(hwnd, IDC_USE_PAC_SCRIPT, BST_CHECKED);
200 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PAC_SCRIPT), TRUE);
201 SetDlgItemTextW(hwnd, IDC_EDIT_PAC_SCRIPT, pac_url);
204 return;
207 static INT_PTR connections_on_command(HWND hwnd, WPARAM wparam)
209 BOOL checked;
211 switch (wparam)
213 case IDC_USE_PAC_SCRIPT:
214 checked = IsDlgButtonChecked(hwnd, IDC_USE_PAC_SCRIPT);
215 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PAC_SCRIPT), checked);
216 break;
217 case IDC_USE_PROXY_SERVER:
218 checked = IsDlgButtonChecked(hwnd, IDC_USE_PROXY_SERVER);
219 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_SERVER), checked);
220 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_PROXY_PORT), checked);
223 switch (wparam)
225 case IDC_USE_WPAD:
226 case IDC_USE_PAC_SCRIPT:
227 case IDC_USE_PROXY_SERVER:
228 case MAKEWPARAM(IDC_EDIT_PAC_SCRIPT, EN_CHANGE):
229 case MAKEWPARAM(IDC_EDIT_PROXY_SERVER, EN_CHANGE):
230 case MAKEWPARAM(IDC_EDIT_PROXY_PORT, EN_CHANGE):
231 if(initdialog_done)
232 SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
233 return TRUE;
236 return FALSE;
239 static INT_PTR connections_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
241 connection_settings *default_connection;
242 WCHAR proxy[INTERNET_MAX_URL_LENGTH];
243 WCHAR pac_script[INTERNET_MAX_URL_LENGTH];
244 PSHNOTIFY *psn = (PSHNOTIFY*)lparam;
245 DWORD proxy_len, port_len, pac_script_len;
246 DWORD use_proxy, use_pac_script, use_wpad, size;
247 LRESULT res;
248 HKEY hkey, con;
250 if(psn->hdr.code != PSN_APPLY)
251 return FALSE;
253 res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings, &hkey);
254 if(res)
255 return FALSE;
257 use_proxy = IsDlgButtonChecked(hwnd, IDC_USE_PROXY_SERVER);
258 res = RegSetValueExW(hkey, L"ProxyEnable", 0, REG_DWORD,
259 (BYTE*)&use_proxy, sizeof(use_proxy));
260 if(res)
262 RegCloseKey(hkey);
263 return FALSE;
265 TRACE("ProxyEnable set to %x\n", use_proxy);
267 proxy_len = GetDlgItemTextW(hwnd, IDC_EDIT_PROXY_SERVER, proxy, ARRAY_SIZE(proxy));
268 if(proxy_len)
270 proxy[proxy_len++] = ':';
271 port_len = GetDlgItemTextW(hwnd, IDC_EDIT_PROXY_PORT, proxy+proxy_len,
272 ARRAY_SIZE(proxy)-proxy_len);
273 if(!port_len)
275 proxy[proxy_len++] = '8';
276 proxy[proxy_len++] = '0';
277 proxy[proxy_len] = 0;
280 res = RegSetValueExW(hkey, L"ProxyServer", 0, REG_SZ,
281 (BYTE*)proxy, (proxy_len+port_len)*sizeof(WCHAR));
283 else
285 res = RegDeleteValueW(hkey, L"ProxyServer");
286 if(res == ERROR_FILE_NOT_FOUND)
287 res = ERROR_SUCCESS;
289 if(res)
291 RegCloseKey(hkey);
292 return FALSE;
294 TRACE("ProxtServer set to %s\n", wine_dbgstr_w(proxy));
296 use_pac_script = IsDlgButtonChecked(hwnd, IDC_USE_PAC_SCRIPT);
297 pac_script_len = GetDlgItemTextW(hwnd, IDC_EDIT_PAC_SCRIPT,
298 pac_script, ARRAY_SIZE(pac_script));
299 if(!pac_script_len) use_pac_script = FALSE;
300 if(use_pac_script)
302 res = RegSetValueExW(hkey, L"AutoConfigURL", 0, REG_SZ,
303 (BYTE*)pac_script, pac_script_len*sizeof(WCHAR));
305 else
307 res = RegDeleteValueW(hkey, L"AutoConfigURL");
308 if(res == ERROR_FILE_NOT_FOUND)
309 res = ERROR_SUCCESS;
311 if(res)
313 RegCloseKey(hkey);
314 return FALSE;
316 TRACE("AutoConfigURL set to %s\n", wine_dbgstr_w(use_pac_script ? pac_script : NULL));
318 use_wpad = IsDlgButtonChecked(hwnd, IDC_USE_WPAD);
320 res = RegCreateKeyExW(hkey, L"Connections", 0, NULL, 0, KEY_WRITE, NULL, &con, NULL);
321 RegCloseKey(hkey);
322 if(res)
323 return FALSE;
325 size = create_connection_settings(use_proxy, proxy, use_wpad,
326 use_pac_script, pac_script, &default_connection);
327 if(!size)
329 RegCloseKey(con);
330 return FALSE;
333 res = RegSetValueExW(con, L"DefaultConnectionSettings", 0, REG_BINARY,
334 (BYTE*)default_connection, size);
335 heap_free(default_connection);
336 RegCloseKey(con);
337 return !res;
340 INT_PTR CALLBACK connections_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
342 switch (msg)
344 case WM_INITDIALOG:
345 connections_on_initdialog(hwnd);
346 initdialog_done = TRUE;
347 break;
348 case WM_COMMAND:
349 return connections_on_command(hwnd, wparam);
350 case WM_NOTIFY:
351 return connections_on_notify(hwnd, wparam, lparam);
353 return FALSE;