wusa: Fix double free on error path in read_update_package (scan-build).
[wine.git] / dlls / inetcpl.cpl / general.c
blob516689bcdab34ca4ad0bb92374fd8d708d4d4549
1 /*
2 * Internet control panel applet: general propsheet
4 * Copyright 2010 Detlef Riekenberg
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winuser.h>
26 #include <wininet.h>
27 #include <winreg.h>
28 #include <shlwapi.h>
29 #include <prsht.h>
30 #include <shlobj.h>
32 #include "inetcpl.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
36 static const WCHAR reg_ie_main[] = L"Software\\Microsoft\\Internet Explorer\\Main";
38 /* list of unimplemented buttons */
39 static DWORD disabled_general_buttons[] = {IDC_HOME_CURRENT,
40 IDC_HISTORY_SETTINGS,
41 0};
42 static DWORD disabled_delhist_buttons[] = {IDC_DELETE_FORM_DATA,
43 IDC_DELETE_PASSWORDS,
44 0};
46 /*********************************************************************
47 * delhist_on_command [internal]
49 * handle WM_COMMAND in Delete browsing history dialog
52 static INT_PTR delhist_on_command(HWND hdlg, WPARAM wparam)
54 switch (wparam)
56 case MAKEWPARAM(IDOK, BN_CLICKED):
57 if (IsDlgButtonChecked(hdlg, IDC_DELETE_TEMP_FILES))
58 FreeUrlCacheSpaceW(NULL, 100, 0);
60 if (IsDlgButtonChecked(hdlg, IDC_DELETE_COOKIES))
62 WCHAR pathW[MAX_PATH];
64 if(SHGetSpecialFolderPathW(NULL, pathW, CSIDL_COOKIES, TRUE))
65 FreeUrlCacheSpaceW(pathW, 100, 0);
68 if (IsDlgButtonChecked(hdlg, IDC_DELETE_HISTORY))
70 WCHAR pathW[MAX_PATH];
72 if(SHGetSpecialFolderPathW(NULL, pathW, CSIDL_HISTORY, TRUE))
73 FreeUrlCacheSpaceW(pathW, 100, 0);
76 EndDialog(hdlg, IDOK);
77 return TRUE;
79 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
80 EndDialog(hdlg, IDCANCEL);
81 return TRUE;
83 case MAKEWPARAM(IDC_DELETE_TEMP_FILES, BN_CLICKED):
84 case MAKEWPARAM(IDC_DELETE_COOKIES, BN_CLICKED):
85 case MAKEWPARAM(IDC_DELETE_HISTORY, BN_CLICKED):
86 case MAKEWPARAM(IDC_DELETE_FORM_DATA, BN_CLICKED):
87 case MAKEWPARAM(IDC_DELETE_PASSWORDS, BN_CLICKED):
89 BOOL any = IsDlgButtonChecked(hdlg, IDC_DELETE_TEMP_FILES) ||
90 IsDlgButtonChecked(hdlg, IDC_DELETE_COOKIES) ||
91 IsDlgButtonChecked(hdlg, IDC_DELETE_HISTORY) ||
92 IsDlgButtonChecked(hdlg, IDC_DELETE_FORM_DATA) ||
93 IsDlgButtonChecked(hdlg, IDC_DELETE_PASSWORDS);
94 EnableWindow(GetDlgItem(hdlg, IDOK), any);
95 break;
98 default:
99 break;
101 return FALSE;
105 /*********************************************************************
106 * delhist_dlgproc [internal]
108 * Delete browsing history dialog procedure
111 static INT_PTR CALLBACK delhist_dlgproc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
113 switch (msg)
115 case WM_COMMAND:
116 return delhist_on_command(hdlg, wparam);
118 case WM_INITDIALOG:
120 DWORD *ptr = disabled_delhist_buttons;
121 while (*ptr)
123 EnableWindow(GetDlgItem(hdlg, *ptr), FALSE);
124 ptr++;
126 CheckDlgButton(hdlg, IDC_DELETE_TEMP_FILES, BST_CHECKED);
127 break;
130 default:
131 break;
133 return FALSE;
136 /*********************************************************************
137 * parse_url_from_outside [internal]
139 * Filter an URL, add a usable scheme, when needed
142 static DWORD parse_url_from_outside(LPCWSTR url, LPWSTR out, DWORD maxlen)
144 HMODULE hdll;
145 DWORD (WINAPI *pParseURLFromOutsideSourceW)(LPCWSTR, LPWSTR, LPDWORD, LPDWORD);
146 DWORD res;
148 hdll = LoadLibraryA("shdocvw.dll");
149 pParseURLFromOutsideSourceW = (void *) GetProcAddress(hdll, (LPSTR) 170);
151 if (pParseURLFromOutsideSourceW)
153 res = pParseURLFromOutsideSourceW(url, out, &maxlen, NULL);
154 FreeLibrary(hdll);
155 return res;
158 ERR("failed to get ordinal 170: %ld\n", GetLastError());
159 FreeLibrary(hdll);
160 return 0;
163 /*********************************************************************
164 * general_on_command [internal]
166 * handle WM_COMMAND
169 static INT_PTR general_on_command(HWND hwnd, WPARAM wparam)
171 WCHAR buffer[INTERNET_MAX_URL_LENGTH];
172 DWORD len;
173 DWORD type;
174 LONG res;
176 switch (wparam)
178 case MAKEWPARAM(IDC_HOME_EDIT, EN_CHANGE):
179 /* enable apply button */
180 SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
181 break;
183 case MAKEWPARAM(IDC_HOME_BLANK, BN_CLICKED):
184 SetDlgItemTextW(hwnd, IDC_HOME_EDIT, L"about:blank");
185 break;
187 case MAKEWPARAM(IDC_HOME_DEFAULT, BN_CLICKED):
188 len = sizeof(buffer);
189 type = REG_SZ;
190 res = SHRegGetUSValueW(reg_ie_main, L"Default_Page_URL", &type, buffer, &len, FALSE,
191 (BYTE *)L"about:blank", sizeof(L"about:blank"));
192 if (!res && (type == REG_SZ)) SetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer);
193 break;
195 case MAKEWPARAM(IDC_HISTORY_DELETE, BN_CLICKED):
196 DialogBoxW(hcpl, MAKEINTRESOURCEW(IDD_DELETE_HISTORY), hwnd,
197 delhist_dlgproc);
198 break;
200 default:
201 TRACE("not implemented for command: %d/%d\n", HIWORD(wparam), LOWORD(wparam));
202 return FALSE;
204 return TRUE;
207 /*********************************************************************
208 * general_on_initdialog [internal]
210 * handle WM_INITDIALOG
213 static VOID general_on_initdialog(HWND hwnd)
215 WCHAR buffer[INTERNET_MAX_URL_LENGTH];
216 DWORD len;
217 DWORD type;
218 LONG res;
219 DWORD *ptr = disabled_general_buttons;
221 /* disable unimplemented buttons */
222 while (*ptr)
224 EnableWindow(GetDlgItem(hwnd, *ptr), FALSE);
225 ptr++;
228 /* read current homepage from the registry. Try HCU first, then HKLM */
229 *buffer = 0;
230 len = sizeof(buffer);
231 type = REG_SZ;
232 res = SHRegGetUSValueW(reg_ie_main, L"Start Page", &type, buffer, &len, FALSE,
233 (BYTE *)L"about:blank", sizeof(L"about:blank"));
235 if (!res && (type == REG_SZ))
237 SetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer);
241 /*********************************************************************
242 * general_on_notify [internal]
244 * handle WM_NOTIFY
247 static INT_PTR general_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
249 PSHNOTIFY *psn;
250 WCHAR buffer[INTERNET_MAX_URL_LENGTH];
251 WCHAR parsed[INTERNET_MAX_URL_LENGTH];
252 LONG res;
254 psn = (PSHNOTIFY *) lparam;
255 TRACE("WM_NOTIFY (%p, 0x%Ix, 0x%Ix) from %p with code: %d\n", hwnd, wparam, lparam,
256 psn->hdr.hwndFrom, psn->hdr.code);
258 if (psn->hdr.code == PSN_APPLY)
260 *buffer = 0;
261 GetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer, ARRAY_SIZE(buffer));
262 TRACE("EDITTEXT has %s\n", debugstr_w(buffer));
264 res = parse_url_from_outside(buffer, parsed, ARRAY_SIZE(parsed));
265 TRACE("got %ld with %s\n", res, debugstr_w(parsed));
267 if (res)
269 HKEY hkey;
271 /* update the dialog, when needed */
272 if (lstrcmpW(buffer, parsed))
273 SetDlgItemTextW(hwnd, IDC_HOME_EDIT, parsed);
275 /* update the registry */
276 res = RegOpenKeyW(HKEY_CURRENT_USER, reg_ie_main, &hkey);
277 if (!res)
279 res = RegSetValueExW(hkey, L"Start Page", 0, REG_SZ, (const BYTE *)parsed,
280 (lstrlenW(parsed) + 1) * sizeof(WCHAR));
281 RegCloseKey(hkey);
282 return !res;
286 return FALSE;
289 /*********************************************************************
290 * general_dlgproc [internal]
293 INT_PTR CALLBACK general_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
296 switch (msg)
298 case WM_INITDIALOG:
299 general_on_initdialog(hwnd);
300 return TRUE;
302 case WM_COMMAND:
303 return general_on_command(hwnd, wparam);
305 case WM_NOTIFY:
306 return general_on_notify(hwnd, wparam, lparam);
308 default:
309 /* do not flood the log */
310 if ((msg == WM_SETCURSOR) || (msg == WM_NCHITTEST) || (msg == WM_MOUSEMOVE))
311 return FALSE;
313 TRACE("(%p, 0x%08x/%d, 0x%Ix, 0x%Ix)\n", hwnd, msg, msg, wparam, lparam);
316 return FALSE;