Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1592 lines
51 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1995 **
  4. //*********************************************************************
  5. //
  6. // PRIVACY.cpp - "Privacy" Property Sheet and support dialogs
  7. //
  8. // HISTORY:
  9. //
  10. // 2/26/2001 darrenmi new code
  11. // 4/05/2001 jeffdav did per-site cookie dialog ui stuff
  12. #include "inetcplp.h"
  13. #include <urlmon.h>
  14. #include <mluisupp.h>
  15. #include <htmlhelp.h>
  16. BOOL DeleteCacheCookies();
  17. INT_PTR CALLBACK EmptyCacheCookiesDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
  18. #define REGSTR_PATH_SETTINGS TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")
  19. #define REGSTR_VAL_PRIVADV TEXT("PrivacyAdvanced")
  20. #define REGSTR_PRIVACYPS_PATHEDIT TEXT("Software\\Policies\\Microsoft\\Internet Explorer")
  21. #define REGSTR_PRIVACYPS_VALUEDIT TEXT("PrivacyAddRemoveSites") // this key is duplicated in shdocvw\privacyui.cpp
  22. #define REGSTR_PRIVACYPS_PATHPANE TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
  23. #define REGSTR_PRIVACYPS_VALUPANE TEXT("Privacy Settings") // this key is duplicated in shdocvw\privacyui.cpp
  24. ///////////////////////////////////////////////////////////////////////////////////////
  25. //
  26. // Per-site list dialog
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////////////
  29. ///////////////////////////////////////////////////////////////////////////////////////
  30. //
  31. // Per-site list utility function to minimize the domain name
  32. //
  33. WCHAR *GetMinCookieDomainFromUrl(WCHAR *bstrFullUrl)
  34. {
  35. WCHAR *pMinimizedDomain = NULL;
  36. if(bstrFullUrl == NULL)
  37. goto doneGetMinimizedCookieDomain;
  38. if(bstrFullUrl[0] == '\0')
  39. goto doneGetMinimizedCookieDomain;
  40. WCHAR *pBeginUrl = bstrFullUrl;
  41. WCHAR *pEndUrl = pBeginUrl; // pEndUrl will find the '/path/path..' and clip it from pBeginUrl
  42. while(*pEndUrl != L'\0' && *pEndUrl != L'/')
  43. pEndUrl++;
  44. *pEndUrl = L'\0';
  45. pMinimizedDomain = pEndUrl;
  46. do
  47. {
  48. pMinimizedDomain--;
  49. while(pBeginUrl < pMinimizedDomain
  50. && *(pMinimizedDomain-1) != L'.')
  51. {
  52. pMinimizedDomain--;
  53. }
  54. } while(!IsDomainLegalCookieDomain( pMinimizedDomain, pBeginUrl)
  55. && pBeginUrl < pMinimizedDomain);
  56. doneGetMinimizedCookieDomain:
  57. return pMinimizedDomain;
  58. }
  59. ///////////////////////////////////////////////////////////////////////////////////////
  60. //
  61. // Per-site list sorting function and data structure
  62. //
  63. struct LVCOMPAREINFO
  64. {
  65. HWND hwndLV; //hwnd for listview
  66. int iCol; //column (0 based)
  67. BOOL fAscending; //true if ascending, false if descending
  68. };
  69. int CALLBACK CompareByAlpha(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  70. {
  71. struct LVCOMPAREINFO *plvci = (struct LVCOMPAREINFO *)lParamSort;
  72. WCHAR wz1[INTERNET_MAX_URL_LENGTH];
  73. WCHAR wz2[INTERNET_MAX_URL_LENGTH];
  74. ListView_GetItemText(plvci->hwndLV, lParam1, plvci->iCol, wz1, ARRAYSIZE(wz1));
  75. ListView_GetItemText(plvci->hwndLV, lParam2, plvci->iCol, wz2, ARRAYSIZE(wz2));
  76. int iVal = _wcsicmp(wz1, wz2);
  77. if (iVal < 0)
  78. return (plvci->fAscending ? -1 : 1);
  79. if (iVal == 0)
  80. return (0);
  81. // only thing left is if (iVal > 0)...
  82. return (plvci->fAscending ? 1 : -1);
  83. }
  84. ///////////////////////////////////////////////////////////////////////////////////////
  85. //
  86. // Per-site list defines and prototypes
  87. //
  88. #define PRIVACYPS_ACTION_ACCEPT 0
  89. #define PRIVACYPS_ACTION_REJECT 1
  90. #define PRIVACYPS_ACTION_NOACTION 2
  91. void OnContextMenu(HWND hDlg, LPARAM lParam);
  92. void OnInvalidDomain(HWND hDlg);
  93. void OnSiteSet(HWND hDlg);
  94. void OnSiteDelete(HWND hDlg);
  95. void OnSiteClear(HWND hDlg);
  96. void PerSiteInit(HWND hDlg);
  97. LRESULT CALLBACK PrivPerSiteEBProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam);
  98. ///////////////////////////////////////////////////////////////////////////////////////
  99. //
  100. // Per-site list functions
  101. //
  102. void OnContextMenu(HWND hWnd, int iIndex, POINT pointClick)
  103. {
  104. HMENU hMenu0 = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(IDR_PERSITE_CONTEXT_MENU));
  105. HMENU hMenu1 = GetSubMenu(hMenu0, 0);
  106. DWORD dwAction = PRIVACYPS_ACTION_NOACTION;
  107. WCHAR wzUrl[INTERNET_MAX_URL_LENGTH];
  108. WCHAR wzAction[32];
  109. LVITEM lvi;
  110. if(!hMenu1)
  111. return;
  112. if(pointClick.x == -1 && pointClick.y == -1)
  113. {
  114. RECT rectListRect;
  115. RECT rectSelectionRect;
  116. if( 0 != GetWindowRect(hWnd, &rectListRect) &&
  117. TRUE == ListView_GetItemRect(hWnd, iIndex, &rectSelectionRect, LVIR_LABEL))
  118. {
  119. pointClick.x = rectListRect.left + (rectSelectionRect.left + rectSelectionRect.right) / 2;
  120. pointClick.y = rectListRect.top + (rectSelectionRect.top + rectSelectionRect.bottom) / 2;
  121. }
  122. else
  123. return;
  124. }
  125. // display it, get choice (if any)
  126. int iPick = TrackPopupMenu(hMenu1,
  127. TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
  128. pointClick.x,
  129. pointClick.y,
  130. 0,
  131. hWnd,
  132. (RECT *)NULL);
  133. DestroyMenu(hMenu0);
  134. DestroyMenu(hMenu1);
  135. if (iPick)
  136. {
  137. switch(iPick)
  138. {
  139. case IDM_PRIVACYPS_CTXM_ACCEPT:
  140. // set the action...
  141. dwAction = PRIVACYPS_ACTION_ACCEPT;
  142. MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAction, ARRAYSIZE(wzAction));
  143. // then fall-through...
  144. case IDM_PRIVACYPS_CTXM_REJECT:
  145. // set the action IFF its reject
  146. if (PRIVACYPS_ACTION_NOACTION == dwAction)
  147. {
  148. dwAction = PRIVACYPS_ACTION_REJECT;
  149. MLLoadString(IDS_PRIVACYPS_REJECT, wzAction, ARRAYSIZE(wzAction));
  150. }
  151. // update the ui...
  152. lvi.iItem = iIndex;
  153. lvi.iSubItem = 1;
  154. lvi.mask = LVIF_TEXT;
  155. lvi.pszText = wzAction;
  156. ListView_SetItem(hWnd, &lvi);
  157. // get the text...
  158. ListView_GetItemText(hWnd, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl));
  159. // update the internal list...
  160. InternetSetPerSiteCookieDecisionW(
  161. wzUrl,
  162. ((PRIVACYPS_ACTION_ACCEPT == dwAction) ? COOKIE_STATE_ACCEPT : COOKIE_STATE_REJECT)
  163. );
  164. break;
  165. case IDM_PRIVACYPS_CTXM_DELETE:
  166. OnSiteDelete(GetParent(hWnd));
  167. break;
  168. default:
  169. break;
  170. }
  171. }
  172. }
  173. void OnInvalidDomain(HWND hDlg)
  174. {
  175. WCHAR szError[256];
  176. WCHAR szTitle[64];
  177. // error message here
  178. MLLoadString(IDS_PRIVACYPS_ERRORTTL, szTitle, ARRAYSIZE(szTitle));
  179. MLLoadString(IDS_PRIVACYPS_ERRORTXT, szError, ARRAYSIZE(szError));
  180. MessageBox(hDlg, szError, szTitle, MB_ICONEXCLAMATION | MB_OK);
  181. // select the editbox text so the user can try again...
  182. SendMessage(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), EM_SETSEL, (WPARAM)0, (LPARAM)-1);
  183. }
  184. void AutosizeStatusColumnWidth(HWND hwndList)
  185. {
  186. int iColWidth = 0;
  187. RECT rc;
  188. if (0 == ListView_GetItemCount(hwndList))
  189. {
  190. // auto size it based on header text...
  191. ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER);
  192. }
  193. else
  194. {
  195. // auto size it based on content...
  196. ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
  197. }
  198. // see how big that was...
  199. iColWidth = ListView_GetColumnWidth(hwndList, 1);
  200. // size the 1st col...
  201. GetClientRect(hwndList, &rc);
  202. ListView_SetColumnWidth(hwndList, 0, rc.right-rc.left-iColWidth-GetSystemMetrics(SM_CXVSCROLL));
  203. }
  204. void OnSiteSet(HWND hDlg, UINT uiChoice)
  205. {
  206. WCHAR wzUrl[INTERNET_MAX_URL_LENGTH];
  207. WCHAR wzUrlDomain[INTERNET_MAX_URL_LENGTH];
  208. WCHAR wzUrlMinimized[INTERNET_MAX_URL_LENGTH];
  209. WCHAR wzSchema[INTERNET_MAX_URL_LENGTH];
  210. WCHAR wzAction[32];
  211. LVFINDINFO lvfi;
  212. LVITEM lvi;
  213. DWORD dwAction = 0;
  214. DWORD dwCount = 0;
  215. int iIndex;
  216. HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX);
  217. // the enter key and dbl click should do the same thing, so if the listbox has focus
  218. // and we got called, then they hit enter in the listbox, so let the listbox process
  219. // a WM_KEYDOWN/VK_RETURN message.
  220. if (GetFocus() == hwndList)
  221. {
  222. INT_PTR iIndx = ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX));
  223. if (-1 != iIndx)
  224. {
  225. SendMessage(hwndList, WM_KEYDOWN, VK_RETURN, NULL);
  226. return;
  227. }
  228. }
  229. // read url and setting from ui
  230. GetWindowText(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), wzUrl, INTERNET_MAX_URL_LENGTH);
  231. // if it came from AutoComplete it'll have an http:// or https:// in it...
  232. if(wcsstr(_wcslwr(wzUrl), TEXT("http://")) ||
  233. wcsstr(_wcslwr(wzUrl), TEXT("https://")))
  234. {
  235. // ...and we found it, so get just the domain name...
  236. if(S_OK != CoInternetParseUrl(wzUrl, PARSE_DOMAIN, NULL, wzUrlDomain, ARRAYSIZE(wzUrlDomain), &dwCount, 0))
  237. {
  238. OnInvalidDomain(hDlg);
  239. return;
  240. }
  241. else if(wcslen(wzUrlDomain) < 2)
  242. {
  243. OnInvalidDomain(hDlg);
  244. return;
  245. }
  246. }
  247. else if (wcslen(wzUrl) < 2)
  248. {
  249. // we don't want null strings. in fact, the smallest a domain could theoretically be would be something like "f."
  250. // so, to avoid null strings and stuff we check...
  251. OnInvalidDomain(hDlg);
  252. return;
  253. }
  254. else
  255. {
  256. // ...otherwise just use it
  257. wcsncpy(wzUrlDomain, wzUrl, wcslen(wzUrl)+1);
  258. }
  259. // only http:// or https:// domains in the internet zone are valid, so if we still have a schema after asking for just
  260. // the domain (see above) then we must have something like file:/// or some junk like that.
  261. CoInternetParseUrl(wzUrlDomain, PARSE_SCHEMA, NULL, wzSchema, ARRAYSIZE(wzSchema), &dwCount, 0);
  262. if (wcslen(wzSchema) != 0)
  263. {
  264. OnInvalidDomain(hDlg);
  265. return;
  266. }
  267. // minimize the domain
  268. wcsncpy(wzUrlMinimized, GetMinCookieDomainFromUrl(wzUrlDomain), wcslen(wzUrlDomain)+1);
  269. for (unsigned int i=0;i<wcslen(wzUrlMinimized);i++)
  270. {
  271. if (iswalnum(wzUrlMinimized[i]))
  272. {
  273. continue;
  274. }
  275. else
  276. {
  277. switch(wzUrlMinimized[i])
  278. {
  279. case L'.':
  280. if (i >= 1)
  281. if (L'.' == wzUrlMinimized[i-1]) //prevent duplicate periods like "www..net"
  282. break;
  283. // (fallthrough)
  284. case L'-':
  285. if (i == 0) // first character cannot be a dash
  286. break;
  287. // (fallthrough)
  288. case L'/':
  289. continue;
  290. default:
  291. break;
  292. }
  293. OnInvalidDomain(hDlg);
  294. return;
  295. }
  296. }
  297. if (!wcschr(_wcslwr(wzUrlMinimized), L'.'))
  298. {
  299. OnInvalidDomain(hDlg);
  300. return;
  301. }
  302. // valid domain?
  303. if(FALSE == IsDomainLegalCookieDomainW(wzUrlMinimized, wzUrlMinimized))
  304. {
  305. OnInvalidDomain(hDlg);
  306. return;
  307. }
  308. // are we accepting or rejecting this site?
  309. if (IDC_PRIVACYPS_ACCEPTBTN == uiChoice)
  310. {
  311. dwAction = PRIVACYPS_ACTION_ACCEPT;
  312. MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAction, ARRAYSIZE(wzAction));
  313. }
  314. else
  315. if (IDC_PRIVACYPS_REJECTBTN == uiChoice)
  316. {
  317. dwAction = PRIVACYPS_ACTION_REJECT;
  318. MLLoadString(IDS_PRIVACYPS_REJECT, wzAction, ARRAYSIZE(wzAction));
  319. }
  320. else
  321. {
  322. return;
  323. }
  324. // update UI...
  325. lvfi.flags = LVFI_STRING;
  326. lvfi.psz = wzUrlMinimized;
  327. iIndex = ListView_FindItem(hwndList, -1, &lvfi);
  328. if(iIndex != -1)
  329. {
  330. // found it, ensure correct subitem...
  331. lvi.iItem = iIndex;
  332. lvi.iSubItem = 1;
  333. lvi.pszText = wzAction;
  334. lvi.mask = LVIF_TEXT;
  335. ListView_SetItem(hwndList, &lvi);
  336. AutosizeStatusColumnWidth(hwndList);
  337. }
  338. else
  339. {
  340. // add a new item...
  341. lvi.iItem = 0;
  342. lvi.iSubItem = 0;
  343. lvi.mask = LVIF_TEXT;
  344. lvi.pszText = wzUrlMinimized;
  345. iIndex = ListView_InsertItem(hwndList, &lvi);
  346. lvi.iItem = iIndex;
  347. lvi.iSubItem = 1;
  348. lvi.mask = LVIF_TEXT;
  349. lvi.pszText = wzAction;
  350. ListView_SetItem(hwndList, &lvi);
  351. AutosizeStatusColumnWidth(hwndList);
  352. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), TRUE);
  353. }
  354. // update internal list...
  355. InternetSetPerSiteCookieDecisionW(
  356. wzUrlMinimized,
  357. ((PRIVACYPS_ACTION_ACCEPT == dwAction) ? COOKIE_STATE_ACCEPT : COOKIE_STATE_REJECT)
  358. );
  359. // clear the edit box...
  360. SetWindowText(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), TEXT(""));
  361. SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET));
  362. }
  363. void OnSiteDelete(HWND hDlg)
  364. {
  365. WCHAR wzUrl[INTERNET_MAX_URL_LENGTH];
  366. HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX);
  367. INT_PTR iIndex;
  368. // get the current selection in the list view...
  369. iIndex = ListView_GetSelectionMark(hwndList);
  370. // if we got something get the URL and delete it...
  371. if(iIndex != -1)
  372. {
  373. // remove from listview...
  374. ListView_GetItemText(hwndList, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl));
  375. ListView_DeleteItem(hwndList, iIndex);
  376. // disable buttons if the listbox is now empty...
  377. if(0 == ListView_GetItemCount(hwndList))
  378. {
  379. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  380. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE);
  381. }
  382. InternetSetPerSiteCookieDecisionW(wzUrl, COOKIE_STATE_UNKNOWN);
  383. // clear selection
  384. SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX));
  385. iIndex = ListView_GetSelectionMark(hwndList);
  386. ListView_SetItemState(hwndList, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED);
  387. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  388. }
  389. }
  390. void OnSiteClear(HWND hDlg)
  391. {
  392. // empty the list...
  393. ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX));
  394. InternetClearAllPerSiteCookieDecisions();
  395. // disable the remove buttons...
  396. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  397. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE);
  398. // set focus back to the edit box so they can add more if they feel like it...
  399. SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET));
  400. }
  401. void PerSiteInit(HWND hDlg)
  402. {
  403. HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX);
  404. LVITEM lviEntry;
  405. DWORD dwSizeOfBuffer = 0; // in bytes
  406. DWORD dwDecision = 0;
  407. DWORD dwIndex = 0;
  408. WCHAR wzSiteNameBuffer[INTERNET_MAX_URL_LENGTH];
  409. LONG_PTR wndprocOld = NULL;
  410. WCHAR wzTitle[64];
  411. WCHAR wzAccept[32];
  412. WCHAR wzReject[32];
  413. int iItem;
  414. DWORD dwRet, dwType, dwValue, dwSize;
  415. // subclass the editbox
  416. wndprocOld = SetWindowLongPtr(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), GWLP_WNDPROC, (LONG_PTR)PrivPerSiteEBProc);
  417. // put a pointer to the old proc in GWLP_USERDATA so we can call it...
  418. SetWindowLongPtr(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), GWLP_USERDATA, wndprocOld);
  419. if (!hwndList)
  420. return;
  421. // empty the listview...
  422. ListView_DeleteAllItems(hwndList);
  423. // initialize domain column in the listview...
  424. LV_COLUMN lvColumn;
  425. RECT rc;
  426. // load the accept and reject strings...
  427. MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAccept, ARRAYSIZE(wzAccept));
  428. MLLoadString(IDS_PRIVACYPS_REJECT, wzReject, ARRAYSIZE(wzReject));
  429. lvColumn.mask = LVCF_FMT | LVCF_TEXT;
  430. lvColumn.fmt = LVCFMT_LEFT;
  431. if( 0 != GetClientRect( hwndList, &rc))
  432. {
  433. lvColumn.cx = rc.right - rc.left - GetSystemMetrics(SM_CXVSCROLL) - 75;
  434. lvColumn.mask |= LVCF_WIDTH;
  435. }
  436. MLLoadString(IDS_PRIVACYPS_COLSITE, wzTitle, ARRAYSIZE(wzTitle));
  437. lvColumn.pszText = wzTitle;
  438. ListView_InsertColumn(hwndList, 0, &lvColumn);
  439. // initialize setting column
  440. lvColumn.mask = LVCF_FMT | LVCF_TEXT;
  441. lvColumn.fmt = LVCFMT_LEFT;
  442. if( 0 != GetClientRect( hwndList, &rc))
  443. {
  444. lvColumn.cx = 75;
  445. lvColumn.mask |= LVCF_WIDTH;
  446. }
  447. MLLoadString(IDS_PRIVACYPS_COLSET, wzTitle, ARRAYSIZE(wzTitle));
  448. lvColumn.pszText = wzTitle;
  449. ListView_InsertColumn(hwndList, 1, &lvColumn);
  450. // enumerate elements...
  451. while((dwSizeOfBuffer = ARRAYSIZE(wzSiteNameBuffer)) &&
  452. InternetEnumPerSiteCookieDecision(wzSiteNameBuffer,&dwSizeOfBuffer,&dwDecision,dwIndex))
  453. {
  454. lviEntry.iItem = dwIndex;
  455. lviEntry.iSubItem = 0;
  456. lviEntry.mask = LVIF_TEXT /*| LVIF_IMAGE*/;
  457. lviEntry.pszText = wzSiteNameBuffer;
  458. // don't display crap users may hack into the registry themselves, or hosed entries we may write :)
  459. if(FALSE == IsDomainLegalCookieDomainW(wzSiteNameBuffer, wzSiteNameBuffer))
  460. {
  461. dwIndex++;
  462. continue;
  463. }
  464. iItem = ListView_InsertItem(hwndList, &lviEntry);
  465. lviEntry.iItem = iItem;
  466. lviEntry.iSubItem = 1;
  467. lviEntry.mask = LVIF_TEXT;
  468. if (dwDecision == COOKIE_STATE_ACCEPT)
  469. lviEntry.pszText = wzAccept;
  470. else if (dwDecision == COOKIE_STATE_REJECT)
  471. lviEntry.pszText = wzReject;
  472. else
  473. {
  474. dwIndex++;
  475. continue;
  476. }
  477. ListView_SetItem(hwndList, &lviEntry);
  478. dwIndex++;
  479. }
  480. AutosizeStatusColumnWidth(hwndList);
  481. // enable the remove all button if we enumerated anything...
  482. if (dwIndex > 0)
  483. {
  484. ListView_SetItemState(hwndList, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  485. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), TRUE);
  486. }
  487. // enable autocomplete for the editbox...
  488. SHAutoComplete(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), SHACF_DEFAULT);
  489. // check for policy to make this dialog read-only...
  490. dwSize = sizeof(dwValue);
  491. dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHPANE, REGSTR_PRIVACYPS_VALUPANE, &dwType, &dwValue, &dwSize);
  492. if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
  493. {
  494. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)TRUE);
  495. // disable all buttons and stuff...
  496. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), FALSE);
  497. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REJECTBTN), FALSE);
  498. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_ACCEPTBTN), FALSE);
  499. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  500. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE);
  501. }
  502. }
  503. void OnDoubleClick(HWND hWnd)
  504. {
  505. int iIndex = ListView_GetSelectionMark(hWnd);
  506. WCHAR wzUrl[INTERNET_MAX_URL_LENGTH];
  507. // on dbl clicks we want to enter the item in the edit box so the user can edit it, or cut & paste, or whatever
  508. // but only if we actually have a selected item...
  509. if (-1 == iIndex)
  510. return;
  511. // get the current selection...
  512. ListView_GetItemText(hWnd, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl));
  513. // enter the text into the edit box...
  514. SetDlgItemText(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET, wzUrl);
  515. // select it for the user...
  516. SendMessage(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET), EM_SETSEL, (WPARAM)0, (LPARAM)-1);
  517. // set focus to the edit box...
  518. SetFocus(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET));
  519. // unselect the listview item...
  520. ListView_SetItemState(hWnd, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED);
  521. }
  522. ///////////////////////////////////////////////////////////////////////////////////////
  523. //
  524. // Per-site list window proc's
  525. //
  526. LRESULT CALLBACK PrivPerSiteEBProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
  527. {
  528. HWND hDlg = GetParent(hWnd);
  529. HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX);
  530. int iIndex = ListView_GetSelectionMark(hwndList);
  531. switch (uMsg)
  532. {
  533. case WM_SETFOCUS:
  534. // disable the remove button and unselect whatever in the listview...
  535. EnableWindow(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_REMOVEBTN), FALSE);
  536. ListView_SetItemState(hwndList, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED);
  537. break;
  538. default:
  539. break;
  540. }
  541. return (CallWindowProc((WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA), hWnd, uMsg, wParam, lParam));
  542. }
  543. INT_PTR CALLBACK PrivPerSiteDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  544. {
  545. HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX);
  546. switch (uMsg)
  547. {
  548. case WM_INITDIALOG:
  549. PerSiteInit(hDlg);
  550. if( IsOS(OS_WHISTLERORGREATER))
  551. {
  552. HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
  553. if( hIcon != NULL)
  554. SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  555. // icons loaded with LoadIcon never need to be released
  556. }
  557. return TRUE;
  558. case WM_COMMAND:
  559. switch(LOWORD(wParam))
  560. {
  561. case IDCANCEL:
  562. case IDOK:
  563. return EndDialog(hDlg, 0);
  564. case IDC_PRIVACYPS_REMOVEALLBTN:
  565. OnSiteClear(hDlg);
  566. return TRUE;
  567. case IDC_PRIVACYPS_REMOVEBTN:
  568. OnSiteDelete(hDlg);
  569. return TRUE;
  570. case IDC_PRIVACYPS_ACCEPTBTN:
  571. OnSiteSet(hDlg, IDC_PRIVACYPS_ACCEPTBTN);
  572. return TRUE;
  573. case IDC_PRIVACYPS_REJECTBTN:
  574. OnSiteSet(hDlg, IDC_PRIVACYPS_REJECTBTN);
  575. return TRUE;
  576. }
  577. break;
  578. case WM_NOTIFY:
  579. if (IDC_PRIVACYPS_LISTBOX == ((LPNMHDR)lParam)->idFrom)
  580. {
  581. switch (((LPNMHDR)lParam)->code)
  582. {
  583. case NM_KILLFOCUS:
  584. // lost focus, turn off remove button
  585. if ((GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN) != GetFocus()) ||
  586. (-1 == ListView_GetSelectionMark(hwndList)))
  587. {
  588. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  589. }
  590. return TRUE;
  591. case NM_SETFOCUS:
  592. {
  593. // if there is nothing in the list we have nothing to do
  594. if (0 == ListView_GetItemCount(hwndList))
  595. break;
  596. // if this is true a policy has been set making per-site list read-only, so do nothing...
  597. if ((BOOL)GetWindowLongPtr(hDlg, DWLP_USER))
  598. break;
  599. int iIndex = ListView_GetSelectionMark(hwndList);
  600. if (-1 == iIndex)
  601. {
  602. iIndex = 0;
  603. }
  604. // select|focus the correct item...
  605. ListView_SetItemState(hwndList, iIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  606. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), TRUE);
  607. }
  608. return TRUE;
  609. case NM_CLICK:
  610. if (-1 != ListView_GetSelectionMark(hwndList) &&
  611. !((BOOL)GetWindowLongPtr(hDlg, DWLP_USER)))
  612. {
  613. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), TRUE);
  614. }
  615. else
  616. {
  617. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE);
  618. }
  619. return TRUE;
  620. case NM_DBLCLK:
  621. OnDoubleClick(hwndList);
  622. return TRUE;
  623. case NM_RCLICK:
  624. {
  625. // if this is true a policy has been set making per-site list read-only, so don't show the context menu,
  626. // since all it does is allow you to change or remove things...
  627. if ((BOOL)GetWindowLongPtr(hDlg, DWLP_USER))
  628. break;
  629. int iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
  630. if (-1 != iItem)
  631. {
  632. POINT pointClick = ((LPNMITEMACTIVATE)lParam)->ptAction;
  633. RECT rc;
  634. if(0 != GetWindowRect(hwndList, &rc))
  635. {
  636. pointClick.x += rc.left;
  637. pointClick.y += rc.top;
  638. }
  639. else
  640. {
  641. pointClick.x = -1;
  642. pointClick.y = -1;
  643. }
  644. OnContextMenu(hwndList, iItem, pointClick);
  645. }
  646. return TRUE;
  647. }
  648. case LVN_KEYDOWN:
  649. switch (((LPNMLVKEYDOWN)lParam)->wVKey)
  650. {
  651. case VK_DELETE:
  652. OnSiteDelete(hDlg);
  653. return TRUE;
  654. case VK_RETURN:
  655. OnDoubleClick(hwndList);
  656. return TRUE;
  657. default:
  658. break;
  659. }
  660. break;
  661. case LVN_COLUMNCLICK:
  662. {
  663. struct LVCOMPAREINFO lvci;
  664. static BOOL fAscending = TRUE;
  665. fAscending = !fAscending;
  666. lvci.fAscending = fAscending;
  667. lvci.hwndLV = hwndList;
  668. lvci.iCol = ((LPNMLISTVIEW)lParam)->iSubItem;
  669. return ListView_SortItemsEx(hwndList, CompareByAlpha, &lvci);
  670. }
  671. default:
  672. break;
  673. }
  674. }
  675. break;
  676. case WM_HELP: // F1
  677. ResWinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  678. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  679. break;
  680. case WM_CONTEXTMENU: // right mouse click
  681. if ((HWND)wParam != hwndList)
  682. {
  683. ResWinHelp((HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  684. }
  685. else if (-1 == GET_X_LPARAM(lParam) && -1 == GET_Y_LPARAM(lParam))
  686. {
  687. POINT pointClick;
  688. pointClick.x = -1; pointClick.y = -1;
  689. OnContextMenu(hwndList, ListView_GetSelectionMark(hwndList), pointClick);
  690. }
  691. break;
  692. }
  693. return FALSE;
  694. }
  695. ///////////////////////////////////////////////////////////////////////////////////////
  696. //
  697. // Advanced privacy settings dialog
  698. //
  699. ///////////////////////////////////////////////////////////////////////////////////////
  700. BOOL IsAdvancedMode(void)
  701. {
  702. DWORD dwTemplate, dwError;
  703. BOOL fAdvanced = FALSE;
  704. dwError = PrivacyGetZonePreferenceW(
  705. URLZONE_INTERNET,
  706. PRIVACY_TYPE_FIRST_PARTY,
  707. &dwTemplate,
  708. NULL,
  709. NULL);
  710. if(ERROR_SUCCESS == dwError && PRIVACY_TEMPLATE_ADVANCED == dwTemplate)
  711. {
  712. fAdvanced = TRUE;
  713. }
  714. return fAdvanced;
  715. }
  716. DWORD MapPrefToIndex(WCHAR wcPref)
  717. {
  718. switch(wcPref)
  719. {
  720. case 'r': return 1; // reject
  721. case 'p': return 2; // prompt
  722. default: return 0; // default is accept
  723. }
  724. }
  725. WCHAR MapRadioToPref(HWND hDlg, DWORD dwResource)
  726. {
  727. if(IsDlgButtonChecked(hDlg, dwResource + 1)) // deny
  728. {
  729. return 'r';
  730. }
  731. if(IsDlgButtonChecked(hDlg, dwResource + 2)) // prompt
  732. {
  733. return 'p';
  734. }
  735. // deafult is accept
  736. return 'a';
  737. }
  738. void OnAdvancedInit(HWND hDlg)
  739. {
  740. BOOL fSession = FALSE;
  741. DWORD dwFirst = IDC_FIRST_ACCEPT;
  742. DWORD dwThird = IDC_THIRD_ACCEPT;
  743. if(IsAdvancedMode())
  744. {
  745. WCHAR szBuffer[MAX_PATH];
  746. // MAX_PATH is sufficent for advanced mode setting strings, MaxPrivacySettings is overkill.
  747. WCHAR *pszAlways;
  748. DWORD dwBufferSize, dwTemplate;
  749. DWORD dwError;
  750. //
  751. // turn on advanced check box
  752. //
  753. CheckDlgButton(hDlg, IDC_USE_ADVANCED, TRUE);
  754. //
  755. // Figure out first party setting and session
  756. //
  757. dwBufferSize = ARRAYSIZE( szBuffer);
  758. dwError = PrivacyGetZonePreferenceW(
  759. URLZONE_INTERNET,
  760. PRIVACY_TYPE_FIRST_PARTY,
  761. &dwTemplate,
  762. szBuffer,
  763. &dwBufferSize);
  764. if(ERROR_SUCCESS == dwError)
  765. {
  766. pszAlways = StrStrW(szBuffer, L"always=");
  767. if(pszAlways)
  768. {
  769. dwFirst = IDC_FIRST_ACCEPT + MapPrefToIndex(*(pszAlways + 7));
  770. }
  771. if(StrStrW(szBuffer, L"session"))
  772. {
  773. fSession = TRUE;
  774. }
  775. }
  776. //
  777. // Figure out third party setting
  778. //
  779. dwBufferSize = ARRAYSIZE( szBuffer);
  780. dwError = PrivacyGetZonePreferenceW(
  781. URLZONE_INTERNET,
  782. PRIVACY_TYPE_THIRD_PARTY,
  783. &dwTemplate,
  784. szBuffer,
  785. &dwBufferSize);
  786. if(ERROR_SUCCESS == dwError)
  787. {
  788. WCHAR *pszAlways;
  789. pszAlways = StrStrW(szBuffer, L"always=");
  790. if(pszAlways)
  791. {
  792. dwThird = IDC_THIRD_ACCEPT + MapPrefToIndex(*(pszAlways + 7));
  793. }
  794. }
  795. }
  796. CheckRadioButton(hDlg, IDC_FIRST_ACCEPT, IDC_FIRST_PROMPT, dwFirst);
  797. CheckRadioButton(hDlg, IDC_THIRD_ACCEPT, IDC_THIRD_PROMPT, dwThird);
  798. CheckDlgButton( hDlg, IDC_SESSION_OVERRIDE, fSession);
  799. }
  800. void OnAdvancedOk(HWND hDlg)
  801. {
  802. BOOL fWasAdvanced = IsAdvancedMode();
  803. BOOL fAdvanced = IsDlgButtonChecked(hDlg, IDC_USE_ADVANCED);
  804. // if advanced, build first and third party strings
  805. if(fAdvanced)
  806. {
  807. WCHAR szBuffer[MAX_PATH];
  808. wnsprintf(szBuffer, ARRAYSIZE( szBuffer), L"IE6-P3PV1/settings: always=%c%s",
  809. MapRadioToPref(hDlg, IDC_FIRST_ACCEPT),
  810. IsDlgButtonChecked(hDlg, IDC_SESSION_OVERRIDE) ? L" session=a" : L""
  811. );
  812. PrivacySetZonePreferenceW(
  813. URLZONE_INTERNET,
  814. PRIVACY_TYPE_FIRST_PARTY,
  815. PRIVACY_TEMPLATE_ADVANCED,
  816. szBuffer);
  817. wnsprintf(szBuffer, ARRAYSIZE( szBuffer), L"IE6-P3PV1/settings: always=%c%s",
  818. MapRadioToPref(hDlg, IDC_THIRD_ACCEPT),
  819. IsDlgButtonChecked(hDlg, IDC_SESSION_OVERRIDE) ? L" session=a" : L""
  820. );
  821. PrivacySetZonePreferenceW(
  822. URLZONE_INTERNET,
  823. PRIVACY_TYPE_THIRD_PARTY,
  824. PRIVACY_TEMPLATE_ADVANCED,
  825. szBuffer);
  826. // tell wininet to refresh itself
  827. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  828. }
  829. else if ( fWasAdvanced && !fAdvanced)
  830. {
  831. PrivacySetZonePreferenceW(
  832. URLZONE_INTERNET,
  833. PRIVACY_TYPE_FIRST_PARTY,
  834. PRIVACY_TEMPLATE_MEDIUM, NULL);
  835. PrivacySetZonePreferenceW(
  836. URLZONE_INTERNET,
  837. PRIVACY_TYPE_THIRD_PARTY,
  838. PRIVACY_TEMPLATE_MEDIUM, NULL);
  839. // tell wininet to refresh itself
  840. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  841. }
  842. }
  843. void OnAdvancedEnable(HWND hDlg)
  844. {
  845. BOOL fEnabled = IsDlgButtonChecked(hDlg, IDC_USE_ADVANCED);
  846. // if restricted, disable checkbox and force all others disabled
  847. if(g_restrict.fPrivacySettings)
  848. {
  849. EnableWindow(GetDlgItem(hDlg, IDC_USE_ADVANCED), FALSE);
  850. fEnabled = FALSE;
  851. }
  852. EnableWindow(GetDlgItem(hDlg, IDC_FIRST_ACCEPT), fEnabled);
  853. EnableWindow(GetDlgItem(hDlg, IDC_FIRST_DENY), fEnabled);
  854. EnableWindow(GetDlgItem(hDlg, IDC_FIRST_PROMPT), fEnabled);
  855. EnableWindow(GetDlgItem(hDlg, IDC_THIRD_ACCEPT), fEnabled);
  856. EnableWindow(GetDlgItem(hDlg, IDC_THIRD_DENY), fEnabled);
  857. EnableWindow(GetDlgItem(hDlg, IDC_THIRD_PROMPT), fEnabled);
  858. EnableWindow(GetDlgItem(hDlg, IDC_SESSION_OVERRIDE), fEnabled);
  859. EnableWindow(GetDlgItem(hDlg, IDC_TX_FIRST), fEnabled);
  860. EnableWindow(GetDlgItem(hDlg, IDC_TX_THIRD), fEnabled);
  861. }
  862. INT_PTR CALLBACK PrivAdvancedDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  863. {
  864. switch (uMsg)
  865. {
  866. case WM_INITDIALOG:
  867. OnAdvancedInit(hDlg);
  868. OnAdvancedEnable(hDlg);
  869. if( IsOS(OS_WHISTLERORGREATER))
  870. {
  871. HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
  872. if( hIcon != NULL)
  873. SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  874. // icons loaded with LoadIcon never need to be released
  875. }
  876. return TRUE;
  877. case WM_HELP: // F1
  878. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  879. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  880. break;
  881. case WM_CONTEXTMENU: // right mouse click
  882. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  883. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  884. break;
  885. case WM_COMMAND:
  886. switch(LOWORD(wParam))
  887. {
  888. case IDOK:
  889. if(FALSE == g_restrict.fPrivacySettings)
  890. {
  891. OnAdvancedOk(hDlg);
  892. }
  893. // fall through
  894. case IDCANCEL:
  895. EndDialog(hDlg, IDOK == LOWORD(wParam));
  896. return 0;
  897. case IDC_FIRST_ACCEPT:
  898. case IDC_FIRST_PROMPT:
  899. case IDC_FIRST_DENY:
  900. CheckRadioButton(hDlg, IDC_FIRST_ACCEPT, IDC_FIRST_PROMPT, LOWORD(wParam));
  901. return 0;
  902. case IDC_THIRD_ACCEPT:
  903. case IDC_THIRD_PROMPT:
  904. case IDC_THIRD_DENY:
  905. CheckRadioButton(hDlg, IDC_THIRD_ACCEPT, IDC_THIRD_PROMPT, LOWORD(wParam));
  906. return 0;
  907. case IDC_USE_ADVANCED:
  908. OnAdvancedEnable(hDlg);
  909. return 0;
  910. case IDC_PRIVACY_EDIT:
  911. DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_PERSITE),
  912. hDlg, PrivPerSiteDlgProc);
  913. return 0;
  914. }
  915. break;
  916. }
  917. return FALSE;
  918. }
  919. ///////////////////////////////////////////////////////////////////////////////////////
  920. //
  921. // Privacy pane
  922. //
  923. ///////////////////////////////////////////////////////////////////////////////////////
  924. #define PRIVACY_LEVELS 6
  925. #define SLIDER_LEVEL_CUSTOM 6
  926. TCHAR szPrivacyLevel[PRIVACY_LEVELS + 1][30];
  927. TCHAR szPrivacyDescription[PRIVACY_LEVELS + 1][400];
  928. typedef struct _privslider {
  929. DWORD_PTR dwLevel;
  930. BOOL fAdvanced;
  931. BOOL fCustom;
  932. HFONT hfontBolded;
  933. BOOL fEditDisabled;
  934. } PRIVSLIDER, *PPRIVSLIDER;
  935. void EnablePrivacyControls(HWND hDlg, BOOL fCustom)
  936. {
  937. WCHAR szBuffer[256];
  938. if( fCustom)
  939. MLLoadString( IDS_PRIVACY_SLIDERCOMMANDDEF, szBuffer, ARRAYSIZE( szBuffer));
  940. else
  941. MLLoadString( IDS_PRIVACY_SLIDERCOMMANDSLIDE, szBuffer, ARRAYSIZE( szBuffer));
  942. SendMessage(GetDlgItem(hDlg, IDC_PRIVACY_SLIDERCOMMAND), WM_SETTEXT,
  943. 0, (LPARAM)szBuffer);
  944. // slider disabled when custom
  945. EnableWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), !fCustom);
  946. ShowWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), !fCustom);
  947. // default button enabled with custom
  948. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), fCustom);
  949. // if restricted, force slider and defaults disabled
  950. if(g_restrict.fPrivacySettings)
  951. {
  952. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), FALSE);
  953. EnableWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), FALSE);
  954. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_IMPORT), FALSE);
  955. }
  956. }
  957. PPRIVSLIDER OnPrivacyInit(HWND hDlg)
  958. {
  959. DWORD i;
  960. PPRIVSLIDER pData;
  961. DWORD dwRet, dwType, dwSize, dwValue;
  962. // allocate storage for the font and current level
  963. pData = new PRIVSLIDER;
  964. if(NULL == pData)
  965. {
  966. // doh
  967. return NULL;
  968. }
  969. pData->dwLevel = -1;
  970. pData->hfontBolded = NULL;
  971. pData->fAdvanced = IsAdvancedMode();
  972. pData->fCustom = FALSE;
  973. pData->fEditDisabled = FALSE;
  974. //
  975. // Set the font of the name to the bold font
  976. //
  977. // find current font
  978. HFONT hfontOrig = (HFONT) SendDlgItemMessage(hDlg, IDC_LEVEL, WM_GETFONT, (WPARAM) 0, (LPARAM) 0);
  979. if(hfontOrig == NULL)
  980. hfontOrig = (HFONT) GetStockObject(SYSTEM_FONT);
  981. // build bold font
  982. if(hfontOrig)
  983. {
  984. LOGFONT lfData;
  985. if(GetObject(hfontOrig, SIZEOF(lfData), &lfData) != 0)
  986. {
  987. // The distance from 400 (normal) to 700 (bold)
  988. lfData.lfWeight += 300;
  989. if(lfData.lfWeight > 1000)
  990. lfData.lfWeight = 1000;
  991. pData->hfontBolded = CreateFontIndirect(&lfData);
  992. if(pData->hfontBolded)
  993. {
  994. // the zone level and zone name text boxes should have the same font, so this is okat
  995. SendDlgItemMessage(hDlg, IDC_LEVEL, WM_SETFONT, (WPARAM) pData->hfontBolded, (LPARAM) MAKELPARAM(FALSE, 0));
  996. }
  997. }
  998. }
  999. // initialize slider
  1000. SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETRANGE, (WPARAM) (BOOL) FALSE, (LPARAM) MAKELONG(0, PRIVACY_LEVELS - 1));
  1001. SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETTICFREQ, (WPARAM) 1, (LPARAM) 0);
  1002. // initialize strings for levels and descriptions
  1003. for(i=0; i<PRIVACY_LEVELS + 1; i++)
  1004. {
  1005. MLLoadString(IDS_PRIVACY_LEVEL_NO_COOKIE + i, szPrivacyLevel[i], ARRAYSIZE(szPrivacyLevel[i]));
  1006. MLLoadString(IDS_PRIVACY_DESC_NO_COOKIE + i, szPrivacyDescription[i], ARRAYSIZE(szPrivacyDescription[i]));
  1007. }
  1008. //
  1009. // Get current internet privacy level
  1010. //
  1011. DWORD dwError, dwTemplateFirst, dwTemplateThird;
  1012. // read first party setting
  1013. dwError = PrivacyGetZonePreferenceW(
  1014. URLZONE_INTERNET,
  1015. PRIVACY_TYPE_FIRST_PARTY,
  1016. &dwTemplateFirst,
  1017. NULL,
  1018. NULL);
  1019. if(dwError != ERROR_SUCCESS)
  1020. {
  1021. dwTemplateFirst = PRIVACY_TEMPLATE_CUSTOM;
  1022. }
  1023. // read third party setting
  1024. dwError = PrivacyGetZonePreferenceW(
  1025. URLZONE_INTERNET,
  1026. PRIVACY_TYPE_THIRD_PARTY,
  1027. &dwTemplateThird,
  1028. NULL,
  1029. NULL);
  1030. if(dwError != ERROR_SUCCESS)
  1031. {
  1032. dwTemplateThird = PRIVACY_TEMPLATE_CUSTOM;
  1033. }
  1034. if(dwTemplateFirst == dwTemplateThird && dwTemplateFirst != PRIVACY_TEMPLATE_CUSTOM)
  1035. {
  1036. // matched template values, set slider to template level
  1037. pData->dwLevel = dwTemplateFirst;
  1038. if(dwTemplateFirst == PRIVACY_TEMPLATE_ADVANCED)
  1039. {
  1040. pData->fAdvanced = TRUE;
  1041. pData->dwLevel = SLIDER_LEVEL_CUSTOM;
  1042. }
  1043. }
  1044. else
  1045. {
  1046. // make custom end of list
  1047. pData->dwLevel = SLIDER_LEVEL_CUSTOM;
  1048. pData->fCustom = TRUE;
  1049. }
  1050. // move slider to right spot
  1051. SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pData->dwLevel);
  1052. // Enable stuff based on mode
  1053. EnablePrivacyControls(hDlg, ((pData->fAdvanced) || (pData->fCustom)));
  1054. // save off struct
  1055. SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)pData);
  1056. dwSize = sizeof(dwValue);
  1057. dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHEDIT, REGSTR_PRIVACYPS_VALUEDIT, &dwType, &dwValue, &dwSize);
  1058. if (ERROR_SUCCESS == dwRet && 1 == dwValue && REG_DWORD == dwType)
  1059. {
  1060. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), FALSE);
  1061. pData->fEditDisabled = TRUE;
  1062. }
  1063. return pData;
  1064. }
  1065. void OnPrivacyApply(HWND hDlg, PPRIVSLIDER pData)
  1066. {
  1067. if(pData->fCustom || pData->fAdvanced)
  1068. {
  1069. // nothing else to do
  1070. return;
  1071. }
  1072. DWORD_PTR dwPos = SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_GETPOS, 0, 0);
  1073. if(pData->dwLevel != dwPos)
  1074. {
  1075. DWORD dwCookieAction = URLPOLICY_DISALLOW;
  1076. // Set privacy settings
  1077. PrivacySetZonePreferenceW(
  1078. URLZONE_INTERNET,
  1079. PRIVACY_TYPE_FIRST_PARTY,
  1080. (DWORD)dwPos,
  1081. NULL);
  1082. PrivacySetZonePreferenceW(
  1083. URLZONE_INTERNET,
  1084. PRIVACY_TYPE_THIRD_PARTY,
  1085. (DWORD)dwPos,
  1086. NULL);
  1087. // tell wininet to refresh itself
  1088. InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
  1089. // save new level as "current"
  1090. pData->dwLevel = dwPos;
  1091. }
  1092. }
  1093. void OnPrivacySlider(HWND hDlg, PPRIVSLIDER pData)
  1094. {
  1095. DWORD dwPos;
  1096. if(pData->fCustom || pData->fAdvanced)
  1097. {
  1098. dwPos = SLIDER_LEVEL_CUSTOM;
  1099. }
  1100. else
  1101. {
  1102. dwPos = (DWORD)SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_GETPOS, 0, 0);
  1103. if(dwPos != pData->dwLevel)
  1104. {
  1105. ENABLEAPPLY(hDlg);
  1106. }
  1107. // enable default button if slider moved off medium
  1108. BOOL fEnable = FALSE;
  1109. if(dwPos != PRIVACY_TEMPLATE_MEDIUM && FALSE == g_restrict.fPrivacySettings)
  1110. {
  1111. fEnable = TRUE;
  1112. }
  1113. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), fEnable);
  1114. }
  1115. if (PRIVACY_TEMPLATE_NO_COOKIES == dwPos || PRIVACY_TEMPLATE_LOW == dwPos || pData->fEditDisabled)
  1116. {
  1117. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), FALSE);
  1118. }
  1119. else
  1120. {
  1121. EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), TRUE);
  1122. }
  1123. // on Mouse Move, change the level description only
  1124. SetDlgItemText(hDlg, IDC_LEVEL_DESCRIPTION, szPrivacyDescription[dwPos]);
  1125. SetDlgItemText(hDlg, IDC_LEVEL, szPrivacyLevel[dwPos]);
  1126. }
  1127. void OnPrivacyDefault( HWND hDlg, PPRIVSLIDER pData)
  1128. {
  1129. // enable controls correctly
  1130. pData->fAdvanced = FALSE;
  1131. pData->fCustom = FALSE;
  1132. EnablePrivacyControls(hDlg, FALSE);
  1133. // set slider to medium
  1134. SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)PRIVACY_TEMPLATE_MEDIUM);
  1135. // update descriptions
  1136. pData->dwLevel = SLIDER_LEVEL_CUSTOM; // difference from medium so we get apply button
  1137. OnPrivacySlider(hDlg, pData);
  1138. // Give slider focus (if default button has focus and gets disabled,
  1139. // alt-key dialog control breaks)
  1140. SendMessage( hDlg, WM_NEXTDLGCTL,
  1141. (WPARAM)GetDlgItem( hDlg, IDC_LEVEL_SLIDER),
  1142. MAKELPARAM( TRUE, 0));
  1143. }
  1144. INT_PTR CALLBACK PrivacyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1145. {
  1146. PPRIVSLIDER pData = (PPRIVSLIDER)GetWindowLongPtr(hDlg, DWLP_USER);
  1147. switch (uMsg)
  1148. {
  1149. case WM_INITDIALOG:
  1150. // initialize slider
  1151. pData = OnPrivacyInit(hDlg);
  1152. if(pData)
  1153. {
  1154. OnPrivacySlider(hDlg, pData);
  1155. }
  1156. if( IsOS(OS_WHISTLERORGREATER))
  1157. {
  1158. HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
  1159. if( hIcon != NULL)
  1160. SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  1161. // icons loaded with LoadIcon never need to be released
  1162. }
  1163. return TRUE;
  1164. case WM_VSCROLL:
  1165. // Slider Messages
  1166. OnPrivacySlider(hDlg, pData);
  1167. return TRUE;
  1168. case WM_NOTIFY:
  1169. {
  1170. NMHDR *lpnm = (NMHDR *) lParam;
  1171. ASSERT(lpnm);
  1172. switch (lpnm->code)
  1173. {
  1174. case PSN_QUERYCANCEL:
  1175. case PSN_KILLACTIVE:
  1176. case PSN_RESET:
  1177. return TRUE;
  1178. case PSN_APPLY:
  1179. // Hitting the apply button runs this code
  1180. OnPrivacyApply(hDlg, pData);
  1181. break;
  1182. }
  1183. break;
  1184. }
  1185. case WM_DESTROY:
  1186. {
  1187. if(pData)
  1188. {
  1189. if(pData->hfontBolded)
  1190. DeleteObject(pData->hfontBolded);
  1191. delete pData;
  1192. }
  1193. break;
  1194. }
  1195. case WM_HELP: // F1
  1196. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1197. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1198. break;
  1199. case WM_CONTEXTMENU: // right mouse click
  1200. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1201. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1202. break;
  1203. case WM_COMMAND:
  1204. switch(LOWORD(wParam))
  1205. {
  1206. case IDC_PRIVACY_DEFAULT:
  1207. OnPrivacyDefault( hDlg, pData);
  1208. return 0;
  1209. case IDC_PRIVACY_ADVANCED:
  1210. {
  1211. BOOL fWasAdvanced = IsAdvancedMode();
  1212. // show advanced
  1213. if( DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_ADVANCED),
  1214. hDlg, PrivAdvancedDlgProc))
  1215. {
  1216. // refresh advanced and reset slider/controls
  1217. pData->fAdvanced = IsAdvancedMode();
  1218. if(pData->fAdvanced)
  1219. {
  1220. // no longer have a slider template
  1221. pData->fCustom = FALSE;
  1222. pData->dwLevel = SLIDER_LEVEL_CUSTOM;
  1223. EnablePrivacyControls(hDlg, (pData->fCustom || pData->fAdvanced));
  1224. OnPrivacySlider(hDlg, pData);
  1225. // Give advanced button focus (if slider has focus and gets disabled,
  1226. // alt-key dialog control breaks)
  1227. SendMessage( hDlg, WM_NEXTDLGCTL,
  1228. (WPARAM)GetDlgItem( hDlg, IDC_PRIVACY_ADVANCED),
  1229. MAKELPARAM( TRUE, 0));
  1230. }
  1231. else if (!pData->fAdvanced && fWasAdvanced)
  1232. {
  1233. OnPrivacyDefault( hDlg, pData);
  1234. }
  1235. }
  1236. return 0;
  1237. }
  1238. case IDC_PRIVACY_IMPORT:
  1239. {
  1240. WCHAR szDialogTitle[MAX_PATH_URL];
  1241. WCHAR szFileExpr[MAX_PATH_URL];
  1242. MLLoadString( IDS_PRIVACYIMPORT_TITLE, szDialogTitle, ARRAYSIZE(szDialogTitle));
  1243. int iFileExprLength = MLLoadString( IDS_PRIVACYIMPORT_FILEEXPR, szFileExpr, ARRAYSIZE(szFileExpr));
  1244. szFileExpr[ iFileExprLength + 1] = L'\0'; // the extra \0 in the resource gets clipped.. replace it.
  1245. WCHAR szFile[MAX_PATH_URL];
  1246. szFile[0] = L'\0';
  1247. OPENFILENAME ofn;
  1248. memset((void*)&ofn, 0, sizeof(ofn));
  1249. ofn.lStructSize = sizeof( ofn);
  1250. ofn.hwndOwner = hDlg;
  1251. ofn.lpstrFilter = szFileExpr;
  1252. ofn.lpstrFile = szFile;
  1253. ofn.nMaxFile = ARRAYSIZE(szFile);
  1254. ofn.lpstrTitle = szDialogTitle;
  1255. ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  1256. if( 0 != GetOpenFileName(&ofn))
  1257. {
  1258. BOOL fParsePrivacyPreferences = TRUE;
  1259. BOOL fParsePerSiteRules = TRUE;
  1260. BOOL fResults;
  1261. fResults = ImportPrivacySettings( ofn.lpstrFile,
  1262. &fParsePrivacyPreferences, &fParsePerSiteRules);
  1263. if( fResults == FALSE
  1264. || (fParsePrivacyPreferences == FALSE
  1265. && fParsePerSiteRules == FALSE))
  1266. {
  1267. MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_PRIVACYIMPORT_FAILURE),
  1268. MAKEINTRESOURCE(IDS_PRIVACYIMPORT_TITLE),
  1269. MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
  1270. }
  1271. else
  1272. {
  1273. if( fParsePrivacyPreferences)
  1274. {
  1275. pData->fCustom = TRUE;
  1276. pData->fAdvanced = FALSE;
  1277. EnablePrivacyControls( hDlg, pData->fCustom);
  1278. OnPrivacySlider(hDlg, pData);
  1279. }
  1280. MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_PRIVACYIMPORT_SUCCESS),
  1281. MAKEINTRESOURCE(IDS_PRIVACYIMPORT_TITLE),
  1282. MB_OK | MB_APPLMODAL | MB_SETFOREGROUND);
  1283. }
  1284. }
  1285. return 0;
  1286. }
  1287. case IDC_PRIVACY_EDIT:
  1288. DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_PERSITE),
  1289. hDlg, PrivPerSiteDlgProc);
  1290. return 0;
  1291. }
  1292. break;
  1293. }
  1294. return FALSE;
  1295. }