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
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
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
;
64 size
+= sizeof(DWORD
);
67 proxy_server_len
= WideCharToMultiByte(CP_UTF8
, 0, proxy_server
, -1,
69 if(!proxy_server_len
) return 0;
74 size
+= proxy_server_len
;
77 pac_url_len
= WideCharToMultiByte(CP_UTF8
, 0, pac_url
, -1,
79 if(!pac_url_len
) return 0;
84 size
+= sizeof(DWORD
)*10;
86 *ret
= heap_alloc_zero(size
);
89 (*ret
)->version
= CONNECTION_SETTINGS_VERSION
;
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
;
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
);
107 WideCharToMultiByte(CP_UTF8
, 0, pac_url
, -1,
108 (char*)(*ret
)->data
+pos
, pac_url_len
, NULL
, NULL
);
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
];
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
);
132 size
= sizeof(enabled
);
133 res
= RegQueryValueExW(hkey
, L
"ProxyEnable", NULL
, &type
, (BYTE
*)&enabled
, &size
);
134 if(res
|| type
!= REG_DWORD
)
136 size
= sizeof(address
);
137 res
= RegQueryValueExW(hkey
, L
"ProxyServer", NULL
, &type
, (BYTE
*)address
, &size
);
138 if(res
|| type
!= REG_SZ
)
140 size
= sizeof(pac_url
);
141 res
= RegQueryValueExW(hkey
, L
"AutoConfigURL", NULL
, &type
, (BYTE
*)pac_url
, &size
);
142 if(res
|| type
!= REG_SZ
)
145 res
= RegOpenKeyW(hkey
, L
"Connections", &con
);
149 connection_settings
*settings
= NULL
;
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
);
162 settings
= new_settings
;
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
);
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
));
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
, ':');
193 SetDlgItemTextW(hwnd
, IDC_EDIT_PROXY_SERVER
, address
);
195 SetDlgItemTextW(hwnd
, IDC_EDIT_PROXY_PORT
, port
);
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
);
207 static INT_PTR
connections_on_command(HWND hwnd
, WPARAM wparam
)
213 case IDC_USE_PAC_SCRIPT
:
214 checked
= IsDlgButtonChecked(hwnd
, IDC_USE_PAC_SCRIPT
);
215 EnableWindow(GetDlgItem(hwnd
, IDC_EDIT_PAC_SCRIPT
), checked
);
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
);
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
):
232 SendMessageW(GetParent(hwnd
), PSM_CHANGED
, (WPARAM
)hwnd
, 0);
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
;
250 if(psn
->hdr
.code
!= PSN_APPLY
)
253 res
= RegOpenKeyW(HKEY_CURRENT_USER
, internet_settings
, &hkey
);
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
));
265 TRACE("ProxyEnable set to %x\n", use_proxy
);
267 proxy_len
= GetDlgItemTextW(hwnd
, IDC_EDIT_PROXY_SERVER
, proxy
, ARRAY_SIZE(proxy
));
270 proxy
[proxy_len
++] = ':';
271 port_len
= GetDlgItemTextW(hwnd
, IDC_EDIT_PROXY_PORT
, proxy
+proxy_len
,
272 ARRAY_SIZE(proxy
)-proxy_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
));
285 res
= RegDeleteValueW(hkey
, L
"ProxyServer");
286 if(res
== ERROR_FILE_NOT_FOUND
)
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
;
302 res
= RegSetValueExW(hkey
, L
"AutoConfigURL", 0, REG_SZ
,
303 (BYTE
*)pac_script
, pac_script_len
*sizeof(WCHAR
));
307 res
= RegDeleteValueW(hkey
, L
"AutoConfigURL");
308 if(res
== ERROR_FILE_NOT_FOUND
)
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
);
325 size
= create_connection_settings(use_proxy
, proxy
, use_wpad
,
326 use_pac_script
, pac_script
, &default_connection
);
333 res
= RegSetValueExW(con
, L
"DefaultConnectionSettings", 0, REG_BINARY
,
334 (BYTE
*)default_connection
, size
);
335 heap_free(default_connection
);
340 INT_PTR CALLBACK
connections_dlgproc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
345 connections_on_initdialog(hwnd
);
346 initdialog_done
= TRUE
;
349 return connections_on_command(hwnd
, wparam
);
351 return connections_on_notify(hwnd
, wparam
, lparam
);