| /* | 
 |  * Internet control panel applet: general propsheet | 
 |  * | 
 |  * Copyright 2010 Detlef Riekenberg | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  * | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  * Lesser General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU Lesser General Public | 
 |  * License along with this library; if not, write to the Free Software | 
 |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
 |  * | 
 |  */ | 
 |  | 
 | #define NONAMELESSUNION | 
 |  | 
 | #include <stdarg.h> | 
 | #include <windef.h> | 
 | #include <winbase.h> | 
 | #include <winuser.h> | 
 | #include <wininet.h> | 
 | #include <winreg.h> | 
 | #include <shlwapi.h> | 
 | #include <prsht.h> | 
 |  | 
 | #include "inetcpl.h" | 
 | #include "wine/debug.h" | 
 |  | 
 | WINE_DEFAULT_DEBUG_CHANNEL(inetcpl); | 
 |  | 
 | static const WCHAR about_blank[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; | 
 | static const WCHAR start_page[] = {'S','t','a','r','t',' ','P','a','g','e',0}; | 
 | static const WCHAR reg_ie_main[] = {'S','o','f','t','w','a','r','e','\\', | 
 |                                     'M','i','c','r','o','s','o','f','t','\\', | 
 |                                     'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\', | 
 |                                     'M','a','i','n',0}; | 
 |  | 
 | /* list of unimplemented buttons */ | 
 | static DWORD disabled_general_buttons[] = {IDC_HOME_CURRENT, | 
 |                                            IDC_HOME_DEFAULT, | 
 |                                            IDC_HISTORY_SETTINGS, | 
 |                                            0}; | 
 | static DWORD disabled_delhist_buttons[] = {IDC_DELETE_COOKIES, | 
 |                                            IDC_DELETE_HISTORY, | 
 |                                            IDC_DELETE_FORM_DATA, | 
 |                                            IDC_DELETE_PASSWORDS, | 
 |                                            0}; | 
 |  | 
 | /********************************************************************* | 
 |  * delhist_on_command [internal] | 
 |  * | 
 |  * handle WM_COMMAND in Delete browsing history dialog | 
 |  * | 
 |  */ | 
 | static INT_PTR delhist_on_command(HWND hdlg, WPARAM wparam) | 
 | { | 
 |     switch (wparam) | 
 |     { | 
 |         case MAKEWPARAM(IDOK, BN_CLICKED): | 
 |             if (!FreeUrlCacheSpaceW(NULL, 100, FCS_PERCENT_CACHE_SPACE)) | 
 |                 break;   /* Don't close the dialog. */ | 
 |             EndDialog(hdlg, IDOK); | 
 |             return TRUE; | 
 |  | 
 |         case MAKEWPARAM(IDCANCEL, BN_CLICKED): | 
 |             EndDialog(hdlg, IDCANCEL); | 
 |             return TRUE; | 
 |  | 
 |         case MAKEWPARAM(IDC_DELETE_TEMP_FILES, BN_CLICKED): | 
 |         case MAKEWPARAM(IDC_DELETE_COOKIES, BN_CLICKED): | 
 |         case MAKEWPARAM(IDC_DELETE_HISTORY, BN_CLICKED): | 
 |         case MAKEWPARAM(IDC_DELETE_FORM_DATA, BN_CLICKED): | 
 |         case MAKEWPARAM(IDC_DELETE_PASSWORDS, BN_CLICKED): | 
 |         { | 
 |             BOOL any = IsDlgButtonChecked(hdlg, IDC_DELETE_TEMP_FILES) || | 
 |                        IsDlgButtonChecked(hdlg, IDC_DELETE_COOKIES) || | 
 |                        IsDlgButtonChecked(hdlg, IDC_DELETE_HISTORY) || | 
 |                        IsDlgButtonChecked(hdlg, IDC_DELETE_FORM_DATA) || | 
 |                        IsDlgButtonChecked(hdlg, IDC_DELETE_PASSWORDS); | 
 |             EnableWindow(GetDlgItem(hdlg, IDOK), any); | 
 |             break; | 
 |         } | 
 |  | 
 |         default: | 
 |             break; | 
 |     } | 
 |     return FALSE; | 
 | } | 
 |  | 
 |  | 
 | /********************************************************************* | 
 |  * delhist_dlgproc [internal] | 
 |  * | 
 |  * Delete browsing history dialog procedure | 
 |  * | 
 |  */ | 
 | static INT_PTR CALLBACK delhist_dlgproc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) | 
 | { | 
 |     switch (msg) | 
 |     { | 
 |         case WM_COMMAND: | 
 |             return delhist_on_command(hdlg, wparam); | 
 |  | 
 |         case WM_INITDIALOG: | 
 |         { | 
 |             DWORD *ptr = disabled_delhist_buttons; | 
 |             while (*ptr) | 
 |             { | 
 |                 EnableWindow(GetDlgItem(hdlg, *ptr), FALSE); | 
 |                 ptr++; | 
 |             } | 
 |             CheckDlgButton(hdlg, IDC_DELETE_TEMP_FILES, BST_CHECKED); | 
 |             break; | 
 |         } | 
 |  | 
 |         default: | 
 |             break; | 
 |     } | 
 |     return FALSE; | 
 | } | 
 |  | 
 | /********************************************************************* | 
 |  * parse_url_from_outside [internal] | 
 |  * | 
 |  * Filter an URL, add a usable scheme, when needed | 
 |  * | 
 |  */ | 
 | static DWORD parse_url_from_outside(LPCWSTR url, LPWSTR out, DWORD maxlen) | 
 | { | 
 |     HMODULE hdll; | 
 |     DWORD (WINAPI *pParseURLFromOutsideSourceW)(LPCWSTR, LPWSTR, LPDWORD, LPDWORD); | 
 |     DWORD res; | 
 |  | 
 |     hdll = LoadLibraryA("shdocvw.dll"); | 
 |     pParseURLFromOutsideSourceW = (void *) GetProcAddress(hdll, (LPSTR) 170); | 
 |  | 
 |     if (pParseURLFromOutsideSourceW) | 
 |     { | 
 |         res = pParseURLFromOutsideSourceW(url, out, &maxlen, NULL); | 
 |         FreeLibrary(hdll); | 
 |         return res; | 
 |     } | 
 |  | 
 |     ERR("failed to get ordinal 170: %d\n", GetLastError()); | 
 |     FreeLibrary(hdll); | 
 |     return 0; | 
 | } | 
 |  | 
 | /********************************************************************* | 
 |  * general_on_command [internal] | 
 |  * | 
 |  * handle WM_COMMAND | 
 |  * | 
 |  */ | 
 | static INT_PTR general_on_command(HWND hwnd, WPARAM wparam) | 
 | { | 
 |  | 
 |     switch (wparam) | 
 |     { | 
 |         case MAKEWPARAM(IDC_HOME_EDIT, EN_CHANGE): | 
 |             /* enable apply button */ | 
 |             SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0); | 
 |             break; | 
 |  | 
 |         case MAKEWPARAM(IDC_HOME_BLANK, BN_CLICKED): | 
 |             SetDlgItemTextW(hwnd, IDC_HOME_EDIT, about_blank); | 
 |             break; | 
 |  | 
 |         case MAKEWPARAM(IDC_HISTORY_DELETE, BN_CLICKED): | 
 |             DialogBoxW(hcpl, MAKEINTRESOURCEW(IDD_DELETE_HISTORY), hwnd, | 
 |                        delhist_dlgproc); | 
 |             break; | 
 |  | 
 |         default: | 
 |             TRACE("not implemented for command: %d/%d\n", HIWORD(wparam),  LOWORD(wparam)); | 
 |             return FALSE; | 
 |     } | 
 |     return TRUE; | 
 | } | 
 |  | 
 | /********************************************************************* | 
 |  * general_on_initdialog [internal] | 
 |  * | 
 |  * handle WM_INITDIALOG | 
 |  * | 
 |  */ | 
 | static VOID general_on_initdialog(HWND hwnd) | 
 | { | 
 |     WCHAR buffer[INTERNET_MAX_URL_LENGTH]; | 
 |     DWORD len; | 
 |     DWORD type; | 
 |     LONG res; | 
 |     DWORD *ptr = disabled_general_buttons; | 
 |  | 
 |     /* disable unimplemented buttons */ | 
 |     while (*ptr) | 
 |     { | 
 |         EnableWindow(GetDlgItem(hwnd, *ptr), FALSE); | 
 |         ptr++; | 
 |     } | 
 |  | 
 |     /* read current homepage from the registry. Try HCU first, then HKLM */ | 
 |     *buffer = 0; | 
 |     len = sizeof(buffer); | 
 |     type = REG_SZ; | 
 |     res = SHRegGetUSValueW(reg_ie_main, start_page, &type, buffer, &len, FALSE, (LPBYTE) about_blank, sizeof(about_blank)); | 
 |  | 
 |     if (!res && (type == REG_SZ)) | 
 |     { | 
 |         SetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer); | 
 |     } | 
 | } | 
 |  | 
 | /********************************************************************* | 
 |  * general_on_notify [internal] | 
 |  * | 
 |  * handle WM_NOTIFY | 
 |  * | 
 |  */ | 
 | static INT_PTR general_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam) | 
 | { | 
 |     PSHNOTIFY *psn; | 
 |     WCHAR buffer[INTERNET_MAX_URL_LENGTH]; | 
 |     WCHAR parsed[INTERNET_MAX_URL_LENGTH]; | 
 |     LONG res; | 
 |  | 
 |     psn = (PSHNOTIFY *) lparam; | 
 |     TRACE("WM_NOTIFY (%p, 0x%lx, 0x%lx) from %p with code: %d\n", hwnd, wparam, lparam, | 
 |             psn->hdr.hwndFrom, psn->hdr.code); | 
 |  | 
 |     if (psn->hdr.code == PSN_APPLY) | 
 |     { | 
 |         *buffer = 0; | 
 |         GetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer, sizeof(buffer)/sizeof(WCHAR)); | 
 |         TRACE("EDITTEXT has %s\n", debugstr_w(buffer)); | 
 |  | 
 |         res = parse_url_from_outside(buffer, parsed, sizeof(parsed)/sizeof(WCHAR)); | 
 |         TRACE("got %d with %s\n", res, debugstr_w(parsed)); | 
 |  | 
 |         if (res) | 
 |         { | 
 |             HKEY hkey; | 
 |  | 
 |             /* update the dialog, when needed */ | 
 |             if (lstrcmpW(buffer, parsed)) | 
 |                 SetDlgItemTextW(hwnd, IDC_HOME_EDIT, parsed); | 
 |  | 
 |             /* update the registry */ | 
 |             res = RegOpenKeyW(HKEY_CURRENT_USER, reg_ie_main, &hkey); | 
 |             if (!res) | 
 |             { | 
 |                 res = RegSetValueExW(hkey, start_page, 0, REG_SZ, (const BYTE *)parsed, | 
 |                                     (lstrlenW(parsed) + 1) * sizeof(WCHAR)); | 
 |                 RegCloseKey(hkey); | 
 |                 return !res; | 
 |             } | 
 |         } | 
 |     } | 
 |     return FALSE; | 
 | } | 
 |  | 
 | /********************************************************************* | 
 |  * general_dlgproc [internal] | 
 |  * | 
 |  */ | 
 | INT_PTR CALLBACK general_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) | 
 | { | 
 |  | 
 |     switch (msg) | 
 |     { | 
 |         case WM_INITDIALOG: | 
 |             general_on_initdialog(hwnd); | 
 |             return TRUE; | 
 |  | 
 |         case WM_COMMAND: | 
 |             return general_on_command(hwnd, wparam); | 
 |  | 
 |         case WM_NOTIFY: | 
 |             return general_on_notify(hwnd, wparam, lparam); | 
 |  | 
 |         default: | 
 |             /* do not flood the log */ | 
 |             if ((msg == WM_SETCURSOR) || (msg == WM_NCHITTEST) || (msg == WM_MOUSEMOVE)) | 
 |                 return FALSE; | 
 |  | 
 |             TRACE("(%p, 0x%08x/%d, 0x%lx, 0x%lx)\n", hwnd, msg, msg, wparam, lparam); | 
 |  | 
 |     } | 
 |     return FALSE; | 
 | } |