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
24 #define NONAMELESSUNION
26 #define WIN32_NO_STATUS
28 #define COM_NO_WINDOWS_H
35 //#include "commctrl.h"
39 //#include "initguid.h"
44 #include <wine/debug.h>
46 WINE_DEFAULT_DEBUG_CHANNEL(inetcpl
);
48 typedef struct secdlg_data_s
{
49 HWND hsec
; /* security propsheet */
50 HWND hlv
; /* listview */
51 HWND htb
; /* trackbar */
52 IInternetSecurityManager
*sec_mgr
;
53 IInternetZoneManager
*zone_mgr
;
54 DWORD zone_enumerator
;
56 ZONEATTRIBUTES
*zone_attr
;
64 #define NUM_TRACKBAR_POS 5
66 static WCHAR spaceW
[] = {' ',0};
67 static DWORD url_templates
[] = {URLTEMPLATE_CUSTOM
,
74 /*********************************************************************
75 * index_from_urltemplate [internal]
78 static DWORD
index_from_urltemplate(URLTEMPLATE value
)
81 DWORD index
= sizeof(url_templates
) / sizeof(url_templates
[0]);
83 while((index
> 0) && (url_templates
[index
-1] != value
))
86 index
--; /* table entries are 0 based */
88 FIXME("URLTEMPLATE 0x%x not supported\n", value
);
90 TRACE("URLTEMPLATE 0x%08x=> Level %d\n", value
, index
);
94 /*********************************************************************
95 * update_security_level [internal]
98 static void update_security_level(secdlg_data
*sd
, DWORD lv_index
, DWORD tb_index
)
103 TRACE("(%p, lv_index: %u, tb_index: %u)\n", sd
, lv_index
, tb_index
);
105 if ((sd
->levels
[lv_index
] != sd
->last_level
) || (tb_index
> 0)) {
106 /* show or hide the trackbar */
107 if (!sd
->levels
[lv_index
] || !sd
->last_level
)
108 ShowWindow(sd
->htb
, sd
->levels
[lv_index
] ? SW_NORMAL
: SW_HIDE
);
110 current_index
= (tb_index
> 0) ? tb_index
: index_from_urltemplate(sd
->levels
[lv_index
]);
113 LoadStringW(hcpl
, IDS_SEC_LEVEL0
+ current_index
, name
, sizeof(name
)/sizeof(name
[0]));
114 TRACE("new level #%d: %s\n", current_index
, debugstr_w(name
));
115 SetWindowTextW(GetDlgItem(sd
->hsec
, IDC_SEC_LEVEL
), name
);
118 LoadStringW(hcpl
, IDS_SEC_LEVEL0_INFO
+ (current_index
* 0x10), name
, sizeof(name
)/sizeof(name
[0]));
119 TRACE("new level info: %s\n", debugstr_w(name
));
120 SetWindowTextW(GetDlgItem(sd
->hsec
, IDC_SEC_LEVEL_INFO
), name
);
123 SendMessageW(sd
->htb
, TBM_SETPOS
, TRUE
, NUM_TRACKBAR_POS
- current_index
);
125 sd
->last_level
= sd
->levels
[lv_index
];
130 /*********************************************************************
131 * update_zone_info [internal]
134 static void update_zone_info(secdlg_data
*sd
, DWORD lv_index
)
136 ZONEATTRIBUTES
*za
= &sd
->zone_attr
[lv_index
];
137 WCHAR name
[MAX_PATH
];
140 SetWindowTextW(GetDlgItem(sd
->hsec
, IDC_SEC_ZONE_INFO
), za
->szDescription
);
145 LoadStringW(hcpl
, IDS_SEC_SETTINGS
, &name
[1], sizeof(name
)/sizeof(name
[0]) - 3);
146 len
= lstrlenW(name
);
147 lstrcpynW(&name
[len
], za
->szDisplayName
, sizeof(name
)/sizeof(name
[0]) - len
- 3);
148 lstrcatW(name
, spaceW
);
150 TRACE("new title: %s\n", debugstr_w(name
));
151 SetWindowTextW(GetDlgItem(sd
->hsec
, IDC_SEC_GROUP
), name
);
153 update_security_level(sd
, lv_index
, 0);
154 sd
->last_lv_index
= lv_index
;
157 /*********************************************************************
158 * add_zone_to_listview [internal]
161 static void add_zone_to_listview(secdlg_data
*sd
, DWORD
*pindex
, DWORD zone
)
163 DWORD lv_index
= *pindex
;
164 ZONEATTRIBUTES
*za
= &sd
->zone_attr
[lv_index
];
172 TRACE("item %d (zone %d)\n", lv_index
, zone
);
174 sd
->zones
[lv_index
] = zone
;
176 memset(&lvitem
, 0, sizeof(LVITEMW
));
177 memset(za
, 0, sizeof(ZONEATTRIBUTES
));
178 za
->cbSize
= sizeof(ZONEATTRIBUTES
);
179 hr
= IInternetZoneManager_GetZoneAttributes(sd
->zone_mgr
, zone
, za
);
181 TRACE("displayname: %s\n", debugstr_w(za
->szDisplayName
));
182 TRACE("description: %s\n", debugstr_w(za
->szDescription
));
183 TRACE("minlevel: 0x%x, recommended: 0x%x, current: 0x%x (flags: 0x%x)\n", za
->dwTemplateMinLevel
,
184 za
->dwTemplateRecommended
, za
->dwTemplateCurrentLevel
, za
->dwFlags
);
186 if (za
->dwFlags
& ZAFLAGS_NO_UI
) {
187 TRACE("item %d (zone %d): UI disabled for %s\n", lv_index
, zone
, debugstr_w(za
->szDisplayName
));
191 sd
->levels
[lv_index
] = za
->dwTemplateCurrentLevel
;
193 lvitem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
;
194 lvitem
.iItem
= lv_index
;
196 lvitem
.pszText
= za
->szDisplayName
;
197 lvitem
.lParam
= (LPARAM
) zone
;
199 /* format is "filename.ext#iconid" */
200 ptr
= StrChrW(za
->szIconPath
, '#');
204 iconid
= StrToIntW(ptr
);
205 hdll
= LoadLibraryExW(za
->szIconPath
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
206 TRACE("%p: icon #%d from %s\n", hdll
, iconid
, debugstr_w(za
->szIconPath
));
208 icon
= LoadImageW(hdll
, MAKEINTRESOURCEW(iconid
), IMAGE_ICON
, GetSystemMetrics(SM_CXICON
),
209 GetSystemMetrics(SM_CYICON
), LR_SHARED
);
212 FIXME("item %d (zone %d): missing icon #%d in %s\n", lv_index
, zone
, iconid
, debugstr_w(za
->szIconPath
));
215 /* the failure result (NULL) from LoadImageW let ImageList_AddIcon fail
216 with -1, which is reused in ListView_InsertItemW to disable the image */
217 lvitem
.iImage
= ImageList_AddIcon(sd
->himages
, icon
);
220 FIXME("item %d (zone %d): malformed szIconPath %s\n", lv_index
, zone
, debugstr_w(za
->szIconPath
));
222 if (ListView_InsertItemW(sd
->hlv
, &lvitem
) >= 0) {
223 /* activate first item in the listview */
225 lvitem
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
226 lvitem
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
227 SendMessageW(sd
->hlv
, LVM_SETITEMSTATE
, 0, (LPARAM
) &lvitem
);
229 update_zone_info(sd
, lv_index
);
236 FIXME("item %d (zone %d): GetZoneAttributes failed with 0x%x\n", lv_index
, zone
, hr
);
239 /*********************************************************************
240 * security_cleanup_zones [internal]
243 static void security_cleanup_zones(secdlg_data
*sd
)
245 if (sd
->zone_enumerator
) {
246 IInternetZoneManager_DestroyZoneEnumerator(sd
->zone_mgr
, sd
->zone_enumerator
);
250 IInternetZoneManager_Release(sd
->zone_mgr
);
254 IInternetSecurityManager_Release(sd
->sec_mgr
);
258 /*********************************************************************
259 * security_enum_zones [internal]
262 static HRESULT
security_enum_zones(secdlg_data
* sd
)
266 hr
= CoInternetCreateSecurityManager(NULL
, &sd
->sec_mgr
, 0);
268 hr
= CoInternetCreateZoneManager(NULL
, &sd
->zone_mgr
, 0);
270 hr
= IInternetZoneManager_CreateZoneEnumerator(sd
->zone_mgr
, &sd
->zone_enumerator
, &sd
->num_zones
, 0);
276 /*********************************************************************
277 * security_on_destroy [internal]
279 * handle WM_NCDESTROY
282 static INT_PTR
security_on_destroy(secdlg_data
* sd
)
286 heap_free(sd
->zone_attr
);
287 heap_free(sd
->zones
);
289 SendMessageW(sd
->hlv
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, 0);
290 ImageList_Destroy(sd
->himages
);
293 security_cleanup_zones(sd
);
294 SetWindowLongPtrW(sd
->hsec
, DWLP_USER
, 0);
299 /*********************************************************************
300 * security_on_initdialog [internal]
302 * handle WM_INITDIALOG
305 static INT_PTR
security_on_initdialog(HWND hsec
)
313 sd
= heap_alloc_zero(sizeof(secdlg_data
));
314 SetWindowLongPtrW(hsec
, DWLP_USER
, (LONG_PTR
) sd
);
320 sd
->hlv
= GetDlgItem(hsec
, IDC_SEC_LISTVIEW
);
321 sd
->htb
= GetDlgItem(hsec
, IDC_SEC_TRACKBAR
);
323 EnableWindow(sd
->htb
, FALSE
); /* not changeable yet */
325 TRACE("(%p) (data: %p, listview: %p, trackbar: %p)\n", hsec
, sd
, sd
->hlv
, sd
->htb
);
327 SendMessageW(sd
->htb
, TBM_SETRANGE
, FALSE
, MAKELONG(0, NUM_TRACKBAR_POS
- 1));
328 SendMessageW(sd
->htb
, TBM_SETTICFREQ
, 1, 0 );
330 /* Create the image lists for the listview */
331 sd
->himages
= ImageList_Create(GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
), ILC_COLOR32
| ILC_MASK
, 1, 1);
333 TRACE("using imagelist: %p\n", sd
->himages
);
335 ERR("ImageList_Create failed!\n");
338 SendMessageW(sd
->hlv
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)sd
->himages
);
340 hr
= security_enum_zones(sd
);
342 ERR("got 0x%x\n", hr
);
343 security_on_destroy(sd
);
347 TRACE("found %d zones\n", sd
->num_zones
);
349 /* remember ZONEATTRIBUTES for a listview entry */
350 sd
->zone_attr
= heap_alloc(sizeof(ZONEATTRIBUTES
) * sd
->num_zones
);
351 if (!sd
->zone_attr
) {
352 security_on_destroy(sd
);
356 /* remember zone number and current security level for a listview entry */
357 sd
->zones
= heap_alloc((sizeof(DWORD
) + sizeof(DWORD
)) * sd
->num_zones
);
359 security_on_destroy(sd
);
362 sd
->levels
= &sd
->zones
[sd
->num_zones
];
364 /* use the same order as visible with native inetcpl.cpl */
365 add_zone_to_listview(sd
, &lv_index
, URLZONE_INTERNET
);
366 add_zone_to_listview(sd
, &lv_index
, URLZONE_INTRANET
);
367 add_zone_to_listview(sd
, &lv_index
, URLZONE_TRUSTED
);
368 add_zone_to_listview(sd
, &lv_index
, URLZONE_UNTRUSTED
);
370 for (i
= 0; i
< sd
->num_zones
; i
++)
372 hr
= IInternetZoneManager_GetZoneAt(sd
->zone_mgr
, sd
->zone_enumerator
, i
, ¤t_zone
);
373 if (SUCCEEDED(hr
) && (current_zone
!= (DWORD
)URLZONE_INVALID
)) {
374 if (!current_zone
|| (current_zone
> URLZONE_UNTRUSTED
)) {
375 add_zone_to_listview(sd
, &lv_index
, current_zone
);
382 /*********************************************************************
383 * security_on_notify [internal]
388 static INT_PTR
security_on_notify(secdlg_data
*sd
, WPARAM wparam
, LPARAM lparam
)
392 nm
= (NMLISTVIEW
*) lparam
;
393 switch (nm
->hdr
.code
)
395 case LVN_ITEMCHANGED
:
396 TRACE("LVN_ITEMCHANGED (0x%lx, 0x%lx) from %p with code: %d (item: %d, uNewState: %u)\n",
397 wparam
, lparam
, nm
->hdr
.hwndFrom
, nm
->hdr
.code
, nm
->iItem
, nm
->uNewState
);
398 if ((nm
->uNewState
& LVIS_SELECTED
) == LVIS_SELECTED
) {
399 update_zone_info(sd
, nm
->iItem
);
404 TRACE("PSN_APPLY (0x%lx, 0x%lx) from %p with code: %d\n", wparam
, lparam
,
405 nm
->hdr
.hwndFrom
, nm
->hdr
.code
);
409 TRACE("WM_NOTIFY (0x%lx, 0x%lx) from %p with code: %d\n", wparam
, lparam
,
410 nm
->hdr
.hwndFrom
, nm
->hdr
.code
);
416 /*********************************************************************
417 * security_dlgproc [internal]
420 INT_PTR CALLBACK
security_dlgproc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
424 if (msg
== WM_INITDIALOG
) {
425 return security_on_initdialog(hwnd
);
428 sd
= (secdlg_data
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
433 return security_on_notify(sd
, wparam
, lparam
);
436 return security_on_destroy(sd
);
439 /* do not flood the log */
440 if ((msg
== WM_SETCURSOR
) || (msg
== WM_NCHITTEST
) ||
441 (msg
== WM_MOUSEMOVE
) || (msg
== WM_MOUSEACTIVATE
) || (msg
== WM_PARENTNOTIFY
))
444 TRACE("(%p, 0x%08x/%03d, 0x%08lx, 0x%08lx)\n", hwnd
, msg
, msg
, wparam
, lparam
);