1 /*
2  * PROJECT:     ReactOS Applications Manager
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Settings Dialog
5  * COPYRIGHT:   Copyright 2009 Dmitry Chapyshev           (dmitry@reactos.org)
6  *              Copyright 2017 Alexander Shaposhnikov     (sanchaez@reactos.org)
7  */
8 #include "rapps.h"
9 
10 SETTINGS_INFO NewSettingsInfo;
11 
12 BOOL ChooseFolder(HWND hwnd)
13 {
14     BOOL bRet = FALSE;
15     BROWSEINFOW bi;
16     ATL::CStringW szChooseFolderText;
17 
18     szChooseFolderText.LoadStringW(IDS_CHOOSE_FOLDER_TEXT);
19 
20     ZeroMemory(&bi, sizeof(bi));
21     bi.hwndOwner = hwnd;
22     bi.pidlRoot = NULL;
23     bi.lpszTitle = szChooseFolderText.GetString();
24     bi.ulFlags = BIF_USENEWUI | BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | /* BIF_BROWSEFILEJUNCTIONS | */ BIF_VALIDATE;
25 
26     if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
27     {
28         ATL::CStringW szBuf;
29 
30         LPITEMIDLIST lpItemList = SHBrowseForFolderW(&bi);
31         if (lpItemList && SHGetPathFromIDListW(lpItemList, szBuf.GetBuffer(MAX_PATH)))
32         {
33             szBuf.ReleaseBuffer();
34             if (!szBuf.IsEmpty())
35             {
36                 SetDlgItemTextW(hwnd, IDC_DOWNLOAD_DIR_EDIT, szBuf.GetString());
37                 bRet = TRUE;
38             }
39         }
40         else
41         {
42             szBuf.ReleaseBuffer();
43         }
44 
45         CoTaskMemFree(lpItemList);
46         CoUninitialize();
47     }
48 
49     return bRet;
50 }
51 
52 BOOL IsUrlValid(const WCHAR * Url)
53 {
54     URL_COMPONENTSW UrlComponmentInfo = { 0 };
55     UrlComponmentInfo.dwStructSize = sizeof(UrlComponmentInfo);
56     UrlComponmentInfo.dwSchemeLength = 1;
57 
58     BOOL bSuccess = InternetCrackUrlW(Url, wcslen(Url), 0, &UrlComponmentInfo);
59     if(!bSuccess)
60     {
61         return FALSE;
62     }
63 
64     switch(UrlComponmentInfo.nScheme)
65     {
66         case INTERNET_SCHEME_HTTP:
67         case INTERNET_SCHEME_HTTPS:
68         case INTERNET_SCHEME_FTP:
69         case INTERNET_SCHEME_FILE:
70         // supported
71             return TRUE;
72 
73         default:
74             return FALSE;
75     }
76 }
77 
78 namespace
79 {
80     inline BOOL IsCheckedDlgItem(HWND hDlg, INT nIDDlgItem)
81     {
82         return (SendDlgItemMessageW(hDlg, nIDDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? TRUE : FALSE;
83     }
84 
85     VOID InitSettingsControls(HWND hDlg, PSETTINGS_INFO Info)
86     {
87         SendDlgItemMessageW(hDlg, IDC_SAVE_WINDOW_POS, BM_SETCHECK, Info->bSaveWndPos, 0);
88         SendDlgItemMessageW(hDlg, IDC_UPDATE_AVLIST, BM_SETCHECK, Info->bUpdateAtStart, 0);
89         SendDlgItemMessageW(hDlg, IDC_LOG_ENABLED, BM_SETCHECK, Info->bLogEnabled, 0);
90         SendDlgItemMessageW(hDlg, IDC_DEL_AFTER_INSTALL, BM_SETCHECK, Info->bDelInstaller, 0);
91 
92         SetWindowTextW(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT),
93                        Info->szDownloadDir);
94 
95         CheckRadioButton(hDlg, IDC_PROXY_DEFAULT, IDC_USE_PROXY, IDC_PROXY_DEFAULT + Info->Proxy);
96 
97         if (Info->Proxy == 2)
98         {
99             EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), TRUE);
100             EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), TRUE);
101         }
102         else
103         {
104             EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
105             EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
106         }
107 
108         CheckRadioButton(hDlg, IDC_SOURCE_DEFAULT, IDC_USE_SOURCE, Info->bUseSource ? IDC_USE_SOURCE : IDC_SOURCE_DEFAULT);
109 
110         EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), Info->bUseSource);
111 
112         SetWindowTextW(GetDlgItem(hDlg, IDC_SOURCE_URL), Info->szSourceURL);
113         SetWindowTextW(GetDlgItem(hDlg, IDC_PROXY_SERVER), Info->szProxyServer);
114         SetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), Info->szNoProxyFor);
115     }
116 
117     INT_PTR CALLBACK SettingsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
118     {
119         switch (Msg)
120         {
121         case WM_INITDIALOG:
122         {
123             NewSettingsInfo = SettingsInfo;
124             InitSettingsControls(hDlg, &SettingsInfo);
125         }
126         break;
127 
128         case WM_COMMAND:
129         {
130             switch (LOWORD(wParam))
131             {
132             case IDC_CHOOSE:
133                 ChooseFolder(hDlg);
134                 break;
135 
136             case IDC_SAVE_WINDOW_POS:
137                 NewSettingsInfo.bSaveWndPos = IsCheckedDlgItem(hDlg, IDC_SAVE_WINDOW_POS);
138                 break;
139 
140             case IDC_UPDATE_AVLIST:
141                 NewSettingsInfo.bUpdateAtStart = IsCheckedDlgItem(hDlg, IDC_UPDATE_AVLIST);
142                 break;
143 
144             case IDC_LOG_ENABLED:
145                 NewSettingsInfo.bLogEnabled = IsCheckedDlgItem(hDlg, IDC_LOG_ENABLED);
146                 break;
147 
148             case IDC_DEL_AFTER_INSTALL:
149                 NewSettingsInfo.bDelInstaller = IsCheckedDlgItem(hDlg, IDC_DEL_AFTER_INSTALL);
150                 break;
151 
152             case IDC_SOURCE_DEFAULT:
153                 NewSettingsInfo.bUseSource = FALSE;
154                 EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
155                 break;
156 
157             case IDC_USE_SOURCE:
158                 NewSettingsInfo.bUseSource = TRUE;
159                 EnableWindow(GetDlgItem(hDlg, IDC_SOURCE_URL), NewSettingsInfo.bUseSource);
160                 break;
161 
162             case IDC_PROXY_DEFAULT:
163                 NewSettingsInfo.Proxy = 0;
164                 EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
165                 EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
166                 break;
167 
168             case IDC_NO_PROXY:
169                 NewSettingsInfo.Proxy = 1;
170                 EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), FALSE);
171                 EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), FALSE);
172                 break;
173 
174             case IDC_USE_PROXY:
175                 NewSettingsInfo.Proxy = 2;
176                 EnableWindow(GetDlgItem(hDlg, IDC_PROXY_SERVER), TRUE);
177                 EnableWindow(GetDlgItem(hDlg, IDC_NO_PROXY_FOR), TRUE);
178                 break;
179 
180             case IDC_DEFAULT_SETTINGS:
181                 FillDefaultSettings(&NewSettingsInfo);
182                 InitSettingsControls(hDlg, &NewSettingsInfo);
183                 break;
184 
185             case IDOK:
186             {
187                 ATL::CStringW szDir;
188                 ATL::CStringW szSource;
189                 ATL::CStringW szProxy;
190                 ATL::CStringW szNoProxy;
191                 DWORD dwAttr;
192 
193                 GetWindowTextW(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT),
194                                szDir.GetBuffer(MAX_PATH), MAX_PATH);
195                 szDir.ReleaseBuffer();
196 
197                 GetWindowTextW(GetDlgItem(hDlg, IDC_SOURCE_URL),
198                                szSource.GetBuffer(INTERNET_MAX_URL_LENGTH), INTERNET_MAX_URL_LENGTH);
199                 szSource.ReleaseBuffer();
200 
201                 GetWindowTextW(GetDlgItem(hDlg, IDC_PROXY_SERVER),
202                                szProxy.GetBuffer(MAX_PATH), MAX_PATH);
203                 szProxy.ReleaseBuffer();
204                 ATL::CStringW::CopyChars(NewSettingsInfo.szProxyServer,
205                                          _countof(NewSettingsInfo.szProxyServer),
206                                          szProxy.GetString(),
207                                          szProxy.GetLength() + 1);
208 
209                 GetWindowTextW(GetDlgItem(hDlg, IDC_NO_PROXY_FOR),
210                                szNoProxy.GetBuffer(MAX_PATH), MAX_PATH);
211                 szNoProxy.ReleaseBuffer();
212                 ATL::CStringW::CopyChars(NewSettingsInfo.szNoProxyFor,
213                                          _countof(NewSettingsInfo.szNoProxyFor),
214                                          szNoProxy.GetString(),
215                                          szNoProxy.GetLength() + 1);
216 
217                 dwAttr = GetFileAttributesW(szDir.GetString());
218                 if (dwAttr != INVALID_FILE_ATTRIBUTES &&
219                     (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
220                 {
221                     ATL::CStringW::CopyChars(NewSettingsInfo.szDownloadDir,
222                                              _countof(NewSettingsInfo.szDownloadDir),
223                                              szDir.GetString(),
224                                              szDir.GetLength() + 1);
225                 }
226                 else
227                 {
228                     ATL::CStringW szMsgText;
229                     szMsgText.LoadStringW(IDS_CHOOSE_FOLDER_ERROR);
230 
231                     if (MessageBoxW(hDlg, szMsgText.GetString(), NULL, MB_YESNO) == IDYES)
232                     {
233                         if (CreateDirectoryW(szDir.GetString(), NULL))
234                         {
235                             EndDialog(hDlg, LOWORD(wParam));
236                         }
237                     }
238                     else
239                     {
240                         SetFocus(GetDlgItem(hDlg, IDC_DOWNLOAD_DIR_EDIT));
241                         break;
242                     }
243                 }
244 
245 
246                 if(NewSettingsInfo.bUseSource && !IsUrlValid(szSource.GetString()))
247                 {
248                     ATL::CStringW szMsgText;
249                     szMsgText.LoadStringW(IDS_URL_INVALID);
250 
251                     MessageBoxW(hDlg, szMsgText.GetString(), NULL, 0);
252                     SetFocus(GetDlgItem(hDlg, IDC_SOURCE_URL));
253                     break;
254                 }
255                 else
256                 {
257                     ATL::CStringW::CopyChars(NewSettingsInfo.szSourceURL,
258                                          _countof(NewSettingsInfo.szSourceURL),
259                                          szSource.GetString(),
260                                          szSource.GetLength() + 1);
261                 }
262 
263                 SettingsInfo = NewSettingsInfo;
264                 SaveSettings(GetParent(hDlg), &SettingsInfo);
265                 EndDialog(hDlg, LOWORD(wParam));
266             }
267             break;
268 
269             case IDCANCEL:
270                 EndDialog(hDlg, LOWORD(wParam));
271                 break;
272             }
273         }
274         break;
275         }
276 
277         return FALSE;
278     }
279 }
280 
281 VOID CreateSettingsDlg(HWND hwnd)
282 {
283     DialogBoxW(hInst,
284                MAKEINTRESOURCEW(IDD_SETTINGS_DIALOG),
285                hwnd,
286                SettingsDlgProc);
287 }
288