inetcpl: Fill the security listview with zones.
[wine/multimedia.git] / dlls / inetcpl.cpl / security.c
blob1aa29a5be49ea9be95bd44aaa6b4f4c1ada86b70
1 /*
2 * Internet control panel applet: security propsheet
4 * Copyright 2011 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 #define COBJMACROS
23 #define CONST_VTABLE
24 #define NONAMELESSUNION
26 #include <stdarg.h>
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winuser.h>
30 #include <prsht.h>
31 #include "commctrl.h"
33 #include "ole2.h"
34 #include "urlmon.h"
35 #include "initguid.h"
36 #include "winreg.h"
37 #include "shlwapi.h"
39 #include "inetcpl.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
44 typedef struct secdlg_data_s {
45 HWND hsec; /* security propsheet */
46 HWND hlv; /* listview */
47 IInternetSecurityManager *sec_mgr;
48 IInternetZoneManager *zone_mgr;
49 DWORD zone_enumerator;
50 DWORD num_zones;
51 ZONEATTRIBUTES *zone_attr;
52 DWORD *zones;
53 HIMAGELIST himages;
54 } secdlg_data;
56 /*********************************************************************
57 * add_zone_to_listview [internal]
60 static void add_zone_to_listview(secdlg_data *sd, DWORD *pindex, DWORD zone)
62 DWORD lv_index = *pindex;
63 ZONEATTRIBUTES *za = &sd->zone_attr[lv_index];
64 LVITEMW lvitem;
65 HRESULT hr;
66 INT iconid = 0;
67 HMODULE hdll = NULL;
68 WCHAR * ptr;
69 HICON icon;
71 TRACE("item %d (zone %d)\n", lv_index, zone);
73 sd->zones[lv_index] = zone;
75 memset(&lvitem, 0, sizeof(LVITEMW));
76 memset(za, 0, sizeof(ZONEATTRIBUTES));
77 za->cbSize = sizeof(ZONEATTRIBUTES);
78 hr = IInternetZoneManager_GetZoneAttributes(sd->zone_mgr, zone, za);
79 if (SUCCEEDED(hr)) {
80 TRACE("displayname: %s\n", debugstr_w(za->szDisplayName));
81 TRACE("description: %s\n", debugstr_w(za->szDescription));
82 TRACE("minlevel: 0x%x, recommended: 0x%x, current: 0x%x (flags: 0x%x)\n", za->dwTemplateMinLevel,
83 za->dwTemplateRecommended, za->dwTemplateCurrentLevel, za->dwFlags);
85 if (za->dwFlags & ZAFLAGS_NO_UI ) {
86 TRACE("item %d (zone %d): UI disabled for %s\n", lv_index, zone, debugstr_w(za->szDisplayName));
87 return;
90 lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
91 lvitem.iItem = lv_index;
92 lvitem.iSubItem = 0;
93 lvitem.pszText = za->szDisplayName;
94 lvitem.lParam = (LPARAM) zone;
96 /* format is "filename.ext#iconid" */
97 ptr = StrChrW(za->szIconPath, '#');
98 if (ptr) {
99 *ptr = 0;
100 ptr++;
101 iconid = StrToIntW(ptr);
102 hdll = LoadLibraryExW(za->szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
103 TRACE("%p: icon #%d from %s\n", hdll, iconid, debugstr_w(za->szIconPath));
105 icon = LoadImageW(hdll, MAKEINTRESOURCEW(iconid), IMAGE_ICON, GetSystemMetrics(SM_CXICON),
106 GetSystemMetrics(SM_CYICON), LR_SHARED);
108 if (!icon) {
109 FIXME("item %d (zone %d): missing icon #%d in %s\n", lv_index, zone, iconid, debugstr_w(za->szIconPath));
112 /* the failure result (NULL) from LoadImageW let ImageList_AddIcon fail
113 with -1, which is reused in ListView_InsertItemW to disable the image */
114 lvitem.iImage = ImageList_AddIcon(sd->himages, icon);
116 else
117 FIXME("item %d (zone %d): malformed szIconPath %s\n", lv_index, zone, debugstr_w(za->szIconPath));
119 if (ListView_InsertItemW(sd->hlv, &lvitem) >= 0) {
120 /* activate first item in the listview */
121 if (! lv_index) {
122 lvitem.state = LVIS_FOCUSED | LVIS_SELECTED;
123 lvitem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
124 SendMessageW(sd->hlv, LVM_SETITEMSTATE, 0, (LPARAM) &lvitem);
126 (*pindex)++;
128 FreeLibrary(hdll);
130 else
131 FIXME("item %d (zone %d): GetZoneAttributes failed with 0x%x\n", lv_index, zone, hr);
134 /*********************************************************************
135 * security_cleanup_zones [internal]
138 static void security_cleanup_zones(secdlg_data *sd)
140 if (sd->zone_enumerator) {
141 IInternetZoneManager_DestroyZoneEnumerator(sd->zone_mgr, sd->zone_enumerator);
144 if (sd->zone_mgr) {
145 IInternetZoneManager_Release(sd->zone_mgr);
148 if (sd->sec_mgr) {
149 IInternetSecurityManager_Release(sd->sec_mgr);
153 /*********************************************************************
154 * security_enum_zones [internal]
157 static HRESULT security_enum_zones(secdlg_data * sd)
159 HRESULT hr;
161 hr = CoInternetCreateSecurityManager(NULL, &sd->sec_mgr, 0);
162 if (SUCCEEDED(hr)) {
163 hr = CoInternetCreateZoneManager(NULL, &sd->zone_mgr, 0);
164 if (SUCCEEDED(hr)) {
165 hr = IInternetZoneManager_CreateZoneEnumerator(sd->zone_mgr, &sd->zone_enumerator, &sd->num_zones, 0);
168 return hr;
171 /*********************************************************************
172 * security_on_destroy [internal]
174 * handle WM_NCDESTROY
177 static INT_PTR security_on_destroy(secdlg_data * sd)
179 TRACE("(%p)\n", sd);
181 heap_free(sd->zone_attr);
182 heap_free(sd->zones);
183 if (sd->himages) {
184 SendMessageW(sd->hlv, LVM_SETIMAGELIST, LVSIL_NORMAL, 0);
185 ImageList_Destroy(sd->himages);
188 security_cleanup_zones(sd);
189 SetWindowLongPtrW(sd->hsec, DWLP_USER, 0);
190 heap_free(sd);
191 return TRUE;
194 /*********************************************************************
195 * security_on_initdialog [internal]
197 * handle WM_INITDIALOG
200 static INT_PTR security_on_initdialog(HWND hsec)
202 secdlg_data *sd;
203 HRESULT hr;
204 DWORD current_zone;
205 DWORD lv_index = 0;
206 DWORD i;
208 sd = heap_alloc_zero(sizeof(secdlg_data));
209 SetWindowLongPtrW(hsec, DWLP_USER, (LONG_PTR) sd);
210 if (!sd) {
211 return FALSE;
214 sd->hsec = hsec;
215 sd->hlv = GetDlgItem(hsec, IDC_SEC_LISTVIEW);
217 /* Create the image lists for the listview */
218 sd->himages = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32 | ILC_MASK, 1, 1);
220 TRACE("using imagelist: %p\n", sd->himages);
221 if (!sd->himages) {
222 ERR("ImageList_Create failed!\n");
223 return FALSE;
225 SendMessageW(sd->hlv, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)sd->himages);
227 hr = security_enum_zones(sd);
228 if (FAILED(hr)) {
229 ERR("got 0x%x\n", hr);
230 security_on_destroy(sd);
231 return FALSE;
234 TRACE("found %d zones\n", sd->num_zones);
236 /* remember ZONEATTRIBUTES for a listview entry */
237 sd->zone_attr = heap_alloc(sizeof(ZONEATTRIBUTES) * sd->num_zones);
238 if (!sd->zone_attr) {
239 security_on_destroy(sd);
240 return FALSE;
243 /* remember zone number for a listview entry */
244 sd->zones = heap_alloc(sizeof(DWORD) * sd->num_zones);
245 if (!sd->zones) {
246 security_on_destroy(sd);
247 return FALSE;
250 /* use the same order as visible with native inetcpl.cpl */
251 add_zone_to_listview(sd, &lv_index, URLZONE_INTERNET);
252 add_zone_to_listview(sd, &lv_index, URLZONE_INTRANET);
253 add_zone_to_listview(sd, &lv_index, URLZONE_TRUSTED);
254 add_zone_to_listview(sd, &lv_index, URLZONE_UNTRUSTED);
256 for (i = 0; i < sd->num_zones; i++)
258 hr = IInternetZoneManager_GetZoneAt(sd->zone_mgr, sd->zone_enumerator, i, &current_zone);
259 if (SUCCEEDED(hr) && (current_zone != (DWORD)URLZONE_INVALID)) {
260 if (!current_zone || (current_zone > URLZONE_UNTRUSTED)) {
261 add_zone_to_listview(sd, &lv_index, current_zone);
265 return TRUE;
268 /*********************************************************************
269 * security_on_notify [internal]
271 * handle WM_NOTIFY
274 static INT_PTR security_on_notify(WPARAM wparam, LPARAM lparam)
276 NMLISTVIEW *nm;
278 nm = (NMLISTVIEW *) lparam;
279 switch (nm->hdr.code)
281 case PSN_APPLY:
282 TRACE("PSN_APPLY (0x%lx, 0x%lx) from %p with code: %d\n", wparam, lparam,
283 nm->hdr.hwndFrom, nm->hdr.code);
284 break;
286 default:
287 TRACE("WM_NOTIFY (0x%lx, 0x%lx) from %p with code: %d\n", wparam, lparam,
288 nm->hdr.hwndFrom, nm->hdr.code);
291 return FALSE;
294 /*********************************************************************
295 * security_dlgproc [internal]
298 INT_PTR CALLBACK security_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
300 secdlg_data *sd;
302 if (msg == WM_INITDIALOG) {
303 return security_on_initdialog(hwnd);
306 sd = (secdlg_data *)GetWindowLongPtrW(hwnd, DWLP_USER);
307 if (sd) {
308 switch (msg)
310 case WM_NOTIFY:
311 return security_on_notify(wparam, lparam);
313 case WM_NCDESTROY:
314 return security_on_destroy(sd);
316 default:
317 /* do not flood the log */
318 if ((msg == WM_SETCURSOR) || (msg == WM_NCHITTEST) ||
319 (msg == WM_MOUSEMOVE) || (msg == WM_MOUSEACTIVATE) || (msg == WM_PARENTNOTIFY))
320 return FALSE;
322 TRACE("(%p, 0x%08x/%03d, 0x%08lx, 0x%08lx)\n", hwnd, msg, msg, wparam, lparam);
325 return FALSE;