//********************************************************************* //* Microsoft Windows ** //* Copyright(c) Microsoft Corp., 1995 ** //********************************************************************* // // PRIVACY.cpp - "Privacy" Property Sheet and support dialogs // // HISTORY: // // 2/26/2001 darrenmi new code // 4/05/2001 jeffdav did per-site cookie dialog ui stuff #include "inetcplp.h" #include #include #include BOOL DeleteCacheCookies(); INT_PTR CALLBACK EmptyCacheCookiesDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam); #define REGSTR_PATH_SETTINGS TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings") #define REGSTR_VAL_PRIVADV TEXT("PrivacyAdvanced") #define REGSTR_PRIVACYPS_PATHEDIT TEXT("Software\\Policies\\Microsoft\\Internet Explorer") #define REGSTR_PRIVACYPS_VALUEDIT TEXT("PrivacyAddRemoveSites") // this key is duplicated in shdocvw\privacyui.cpp #define REGSTR_PRIVACYPS_PATHPANE TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel") #define REGSTR_PRIVACYPS_VALUPANE TEXT("Privacy Settings") // this key is duplicated in shdocvw\privacyui.cpp /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list dialog // /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list utility function to minimize the domain name // WCHAR *GetMinCookieDomainFromUrl(WCHAR *bstrFullUrl) { WCHAR *pMinimizedDomain = NULL; if(bstrFullUrl == NULL) goto doneGetMinimizedCookieDomain; if(bstrFullUrl[0] == '\0') goto doneGetMinimizedCookieDomain; WCHAR *pBeginUrl = bstrFullUrl; WCHAR *pEndUrl = pBeginUrl; // pEndUrl will find the '/path/path..' and clip it from pBeginUrl while(*pEndUrl != L'\0' && *pEndUrl != L'/') pEndUrl++; *pEndUrl = L'\0'; pMinimizedDomain = pEndUrl; do { pMinimizedDomain--; while(pBeginUrl < pMinimizedDomain && *(pMinimizedDomain-1) != L'.') { pMinimizedDomain--; } } while(!IsDomainLegalCookieDomain( pMinimizedDomain, pBeginUrl) && pBeginUrl < pMinimizedDomain); doneGetMinimizedCookieDomain: return pMinimizedDomain; } /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list sorting function and data structure // struct LVCOMPAREINFO { HWND hwndLV; //hwnd for listview int iCol; //column (0 based) BOOL fAscending; //true if ascending, false if descending }; int CALLBACK CompareByAlpha(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { struct LVCOMPAREINFO *plvci = (struct LVCOMPAREINFO *)lParamSort; WCHAR wz1[INTERNET_MAX_URL_LENGTH]; WCHAR wz2[INTERNET_MAX_URL_LENGTH]; ListView_GetItemText(plvci->hwndLV, lParam1, plvci->iCol, wz1, ARRAYSIZE(wz1)); ListView_GetItemText(plvci->hwndLV, lParam2, plvci->iCol, wz2, ARRAYSIZE(wz2)); int iVal = _wcsicmp(wz1, wz2); if (iVal < 0) return (plvci->fAscending ? -1 : 1); if (iVal == 0) return (0); // only thing left is if (iVal > 0)... return (plvci->fAscending ? 1 : -1); } /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list defines and prototypes // #define PRIVACYPS_ACTION_ACCEPT 0 #define PRIVACYPS_ACTION_REJECT 1 #define PRIVACYPS_ACTION_NOACTION 2 void OnContextMenu(HWND hDlg, LPARAM lParam); void OnInvalidDomain(HWND hDlg); void OnSiteSet(HWND hDlg); void OnSiteDelete(HWND hDlg); void OnSiteClear(HWND hDlg); void PerSiteInit(HWND hDlg); LRESULT CALLBACK PrivPerSiteEBProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam); /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list functions // void OnContextMenu(HWND hWnd, int iIndex, POINT pointClick) { HMENU hMenu0 = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(IDR_PERSITE_CONTEXT_MENU)); HMENU hMenu1 = GetSubMenu(hMenu0, 0); DWORD dwAction = PRIVACYPS_ACTION_NOACTION; WCHAR wzUrl[INTERNET_MAX_URL_LENGTH]; WCHAR wzAction[32]; LVITEM lvi; if(!hMenu1) return; if(pointClick.x == -1 && pointClick.y == -1) { RECT rectListRect; RECT rectSelectionRect; if( 0 != GetWindowRect(hWnd, &rectListRect) && TRUE == ListView_GetItemRect(hWnd, iIndex, &rectSelectionRect, LVIR_LABEL)) { pointClick.x = rectListRect.left + (rectSelectionRect.left + rectSelectionRect.right) / 2; pointClick.y = rectListRect.top + (rectSelectionRect.top + rectSelectionRect.bottom) / 2; } else return; } // display it, get choice (if any) int iPick = TrackPopupMenu(hMenu1, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pointClick.x, pointClick.y, 0, hWnd, (RECT *)NULL); DestroyMenu(hMenu0); DestroyMenu(hMenu1); if (iPick) { switch(iPick) { case IDM_PRIVACYPS_CTXM_ACCEPT: // set the action... dwAction = PRIVACYPS_ACTION_ACCEPT; MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAction, ARRAYSIZE(wzAction)); // then fall-through... case IDM_PRIVACYPS_CTXM_REJECT: // set the action IFF its reject if (PRIVACYPS_ACTION_NOACTION == dwAction) { dwAction = PRIVACYPS_ACTION_REJECT; MLLoadString(IDS_PRIVACYPS_REJECT, wzAction, ARRAYSIZE(wzAction)); } // update the ui... lvi.iItem = iIndex; lvi.iSubItem = 1; lvi.mask = LVIF_TEXT; lvi.pszText = wzAction; ListView_SetItem(hWnd, &lvi); // get the text... ListView_GetItemText(hWnd, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl)); // update the internal list... InternetSetPerSiteCookieDecisionW( wzUrl, ((PRIVACYPS_ACTION_ACCEPT == dwAction) ? COOKIE_STATE_ACCEPT : COOKIE_STATE_REJECT) ); break; case IDM_PRIVACYPS_CTXM_DELETE: OnSiteDelete(GetParent(hWnd)); break; default: break; } } } void OnInvalidDomain(HWND hDlg) { WCHAR szError[256]; WCHAR szTitle[64]; // error message here MLLoadString(IDS_PRIVACYPS_ERRORTTL, szTitle, ARRAYSIZE(szTitle)); MLLoadString(IDS_PRIVACYPS_ERRORTXT, szError, ARRAYSIZE(szError)); MessageBox(hDlg, szError, szTitle, MB_ICONEXCLAMATION | MB_OK); // select the editbox text so the user can try again... SendMessage(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), EM_SETSEL, (WPARAM)0, (LPARAM)-1); } void AutosizeStatusColumnWidth(HWND hwndList) { int iColWidth = 0; RECT rc; if (0 == ListView_GetItemCount(hwndList)) { // auto size it based on header text... ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER); } else { // auto size it based on content... ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); } // see how big that was... iColWidth = ListView_GetColumnWidth(hwndList, 1); // size the 1st col... GetClientRect(hwndList, &rc); ListView_SetColumnWidth(hwndList, 0, rc.right-rc.left-iColWidth-GetSystemMetrics(SM_CXVSCROLL)); } void OnSiteSet(HWND hDlg, UINT uiChoice) { WCHAR wzUrl[INTERNET_MAX_URL_LENGTH]; WCHAR wzUrlDomain[INTERNET_MAX_URL_LENGTH]; WCHAR wzUrlMinimized[INTERNET_MAX_URL_LENGTH]; WCHAR wzSchema[INTERNET_MAX_URL_LENGTH]; WCHAR wzAction[32]; LVFINDINFO lvfi; LVITEM lvi; DWORD dwAction = 0; DWORD dwCount = 0; int iIndex; HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX); // the enter key and dbl click should do the same thing, so if the listbox has focus // and we got called, then they hit enter in the listbox, so let the listbox process // a WM_KEYDOWN/VK_RETURN message. if (GetFocus() == hwndList) { INT_PTR iIndx = ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX)); if (-1 != iIndx) { SendMessage(hwndList, WM_KEYDOWN, VK_RETURN, NULL); return; } } // read url and setting from ui GetWindowText(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), wzUrl, INTERNET_MAX_URL_LENGTH); // if it came from AutoComplete it'll have an http:// or https:// in it... if(wcsstr(_wcslwr(wzUrl), TEXT("http://")) || wcsstr(_wcslwr(wzUrl), TEXT("https://"))) { // ...and we found it, so get just the domain name... if(S_OK != CoInternetParseUrl(wzUrl, PARSE_DOMAIN, NULL, wzUrlDomain, ARRAYSIZE(wzUrlDomain), &dwCount, 0)) { OnInvalidDomain(hDlg); return; } else if(wcslen(wzUrlDomain) < 2) { OnInvalidDomain(hDlg); return; } } else if (wcslen(wzUrl) < 2) { // we don't want null strings. in fact, the smallest a domain could theoretically be would be something like "f." // so, to avoid null strings and stuff we check... OnInvalidDomain(hDlg); return; } else { // ...otherwise just use it wcsncpy(wzUrlDomain, wzUrl, wcslen(wzUrl)+1); } // only http:// or https:// domains in the internet zone are valid, so if we still have a schema after asking for just // the domain (see above) then we must have something like file:/// or some junk like that. CoInternetParseUrl(wzUrlDomain, PARSE_SCHEMA, NULL, wzSchema, ARRAYSIZE(wzSchema), &dwCount, 0); if (wcslen(wzSchema) != 0) { OnInvalidDomain(hDlg); return; } // minimize the domain wcsncpy(wzUrlMinimized, GetMinCookieDomainFromUrl(wzUrlDomain), wcslen(wzUrlDomain)+1); for (unsigned int i=0;i= 1) if (L'.' == wzUrlMinimized[i-1]) //prevent duplicate periods like "www..net" break; // (fallthrough) case L'-': if (i == 0) // first character cannot be a dash break; // (fallthrough) case L'/': continue; default: break; } OnInvalidDomain(hDlg); return; } } if (!wcschr(_wcslwr(wzUrlMinimized), L'.')) { OnInvalidDomain(hDlg); return; } // valid domain? if(FALSE == IsDomainLegalCookieDomainW(wzUrlMinimized, wzUrlMinimized)) { OnInvalidDomain(hDlg); return; } // are we accepting or rejecting this site? if (IDC_PRIVACYPS_ACCEPTBTN == uiChoice) { dwAction = PRIVACYPS_ACTION_ACCEPT; MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAction, ARRAYSIZE(wzAction)); } else if (IDC_PRIVACYPS_REJECTBTN == uiChoice) { dwAction = PRIVACYPS_ACTION_REJECT; MLLoadString(IDS_PRIVACYPS_REJECT, wzAction, ARRAYSIZE(wzAction)); } else { return; } // update UI... lvfi.flags = LVFI_STRING; lvfi.psz = wzUrlMinimized; iIndex = ListView_FindItem(hwndList, -1, &lvfi); if(iIndex != -1) { // found it, ensure correct subitem... lvi.iItem = iIndex; lvi.iSubItem = 1; lvi.pszText = wzAction; lvi.mask = LVIF_TEXT; ListView_SetItem(hwndList, &lvi); AutosizeStatusColumnWidth(hwndList); } else { // add a new item... lvi.iItem = 0; lvi.iSubItem = 0; lvi.mask = LVIF_TEXT; lvi.pszText = wzUrlMinimized; iIndex = ListView_InsertItem(hwndList, &lvi); lvi.iItem = iIndex; lvi.iSubItem = 1; lvi.mask = LVIF_TEXT; lvi.pszText = wzAction; ListView_SetItem(hwndList, &lvi); AutosizeStatusColumnWidth(hwndList); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), TRUE); } // update internal list... InternetSetPerSiteCookieDecisionW( wzUrlMinimized, ((PRIVACYPS_ACTION_ACCEPT == dwAction) ? COOKIE_STATE_ACCEPT : COOKIE_STATE_REJECT) ); // clear the edit box... SetWindowText(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), TEXT("")); SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET)); } void OnSiteDelete(HWND hDlg) { WCHAR wzUrl[INTERNET_MAX_URL_LENGTH]; HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX); INT_PTR iIndex; // get the current selection in the list view... iIndex = ListView_GetSelectionMark(hwndList); // if we got something get the URL and delete it... if(iIndex != -1) { // remove from listview... ListView_GetItemText(hwndList, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl)); ListView_DeleteItem(hwndList, iIndex); // disable buttons if the listbox is now empty... if(0 == ListView_GetItemCount(hwndList)) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE); } InternetSetPerSiteCookieDecisionW(wzUrl, COOKIE_STATE_UNKNOWN); // clear selection SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX)); iIndex = ListView_GetSelectionMark(hwndList); ListView_SetItemState(hwndList, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); } } void OnSiteClear(HWND hDlg) { // empty the list... ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX)); InternetClearAllPerSiteCookieDecisions(); // disable the remove buttons... EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE); // set focus back to the edit box so they can add more if they feel like it... SetFocus(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET)); } void PerSiteInit(HWND hDlg) { HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX); LVITEM lviEntry; DWORD dwSizeOfBuffer = 0; // in bytes DWORD dwDecision = 0; DWORD dwIndex = 0; WCHAR wzSiteNameBuffer[INTERNET_MAX_URL_LENGTH]; LONG_PTR wndprocOld = NULL; WCHAR wzTitle[64]; WCHAR wzAccept[32]; WCHAR wzReject[32]; int iItem; DWORD dwRet, dwType, dwValue, dwSize; // subclass the editbox wndprocOld = SetWindowLongPtr(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), GWLP_WNDPROC, (LONG_PTR)PrivPerSiteEBProc); // put a pointer to the old proc in GWLP_USERDATA so we can call it... SetWindowLongPtr(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), GWLP_USERDATA, wndprocOld); if (!hwndList) return; // empty the listview... ListView_DeleteAllItems(hwndList); // initialize domain column in the listview... LV_COLUMN lvColumn; RECT rc; // load the accept and reject strings... MLLoadString(IDS_PRIVACYPS_ACCEPT, wzAccept, ARRAYSIZE(wzAccept)); MLLoadString(IDS_PRIVACYPS_REJECT, wzReject, ARRAYSIZE(wzReject)); lvColumn.mask = LVCF_FMT | LVCF_TEXT; lvColumn.fmt = LVCFMT_LEFT; if( 0 != GetClientRect( hwndList, &rc)) { lvColumn.cx = rc.right - rc.left - GetSystemMetrics(SM_CXVSCROLL) - 75; lvColumn.mask |= LVCF_WIDTH; } MLLoadString(IDS_PRIVACYPS_COLSITE, wzTitle, ARRAYSIZE(wzTitle)); lvColumn.pszText = wzTitle; ListView_InsertColumn(hwndList, 0, &lvColumn); // initialize setting column lvColumn.mask = LVCF_FMT | LVCF_TEXT; lvColumn.fmt = LVCFMT_LEFT; if( 0 != GetClientRect( hwndList, &rc)) { lvColumn.cx = 75; lvColumn.mask |= LVCF_WIDTH; } MLLoadString(IDS_PRIVACYPS_COLSET, wzTitle, ARRAYSIZE(wzTitle)); lvColumn.pszText = wzTitle; ListView_InsertColumn(hwndList, 1, &lvColumn); // enumerate elements... while((dwSizeOfBuffer = ARRAYSIZE(wzSiteNameBuffer)) && InternetEnumPerSiteCookieDecision(wzSiteNameBuffer,&dwSizeOfBuffer,&dwDecision,dwIndex)) { lviEntry.iItem = dwIndex; lviEntry.iSubItem = 0; lviEntry.mask = LVIF_TEXT /*| LVIF_IMAGE*/; lviEntry.pszText = wzSiteNameBuffer; // don't display crap users may hack into the registry themselves, or hosed entries we may write :) if(FALSE == IsDomainLegalCookieDomainW(wzSiteNameBuffer, wzSiteNameBuffer)) { dwIndex++; continue; } iItem = ListView_InsertItem(hwndList, &lviEntry); lviEntry.iItem = iItem; lviEntry.iSubItem = 1; lviEntry.mask = LVIF_TEXT; if (dwDecision == COOKIE_STATE_ACCEPT) lviEntry.pszText = wzAccept; else if (dwDecision == COOKIE_STATE_REJECT) lviEntry.pszText = wzReject; else { dwIndex++; continue; } ListView_SetItem(hwndList, &lviEntry); dwIndex++; } AutosizeStatusColumnWidth(hwndList); // enable the remove all button if we enumerated anything... if (dwIndex > 0) { ListView_SetItemState(hwndList, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), TRUE); } // enable autocomplete for the editbox... SHAutoComplete(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), SHACF_DEFAULT); // check for policy to make this dialog read-only... dwSize = sizeof(dwValue); dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHPANE, REGSTR_PRIVACYPS_VALUPANE, &dwType, &dwValue, &dwSize); if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType) { SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)TRUE); // disable all buttons and stuff... EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_SITETOSET), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REJECTBTN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_ACCEPTBTN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEALLBTN), FALSE); } } void OnDoubleClick(HWND hWnd) { int iIndex = ListView_GetSelectionMark(hWnd); WCHAR wzUrl[INTERNET_MAX_URL_LENGTH]; // on dbl clicks we want to enter the item in the edit box so the user can edit it, or cut & paste, or whatever // but only if we actually have a selected item... if (-1 == iIndex) return; // get the current selection... ListView_GetItemText(hWnd, iIndex, 0, wzUrl, ARRAYSIZE(wzUrl)); // enter the text into the edit box... SetDlgItemText(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET, wzUrl); // select it for the user... SendMessage(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET), EM_SETSEL, (WPARAM)0, (LPARAM)-1); // set focus to the edit box... SetFocus(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_SITETOSET)); // unselect the listview item... ListView_SetItemState(hWnd, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED); } /////////////////////////////////////////////////////////////////////////////////////// // // Per-site list window proc's // LRESULT CALLBACK PrivPerSiteEBProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam) { HWND hDlg = GetParent(hWnd); HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX); int iIndex = ListView_GetSelectionMark(hwndList); switch (uMsg) { case WM_SETFOCUS: // disable the remove button and unselect whatever in the listview... EnableWindow(GetDlgItem(GetParent(hWnd), IDC_PRIVACYPS_REMOVEBTN), FALSE); ListView_SetItemState(hwndList, iIndex, NULL, LVIS_FOCUSED | LVIS_SELECTED); break; default: break; } return (CallWindowProc((WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA), hWnd, uMsg, wParam, lParam)); } INT_PTR CALLBACK PrivPerSiteDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) { HWND hwndList = GetDlgItem(hDlg, IDC_PRIVACYPS_LISTBOX); switch (uMsg) { case WM_INITDIALOG: PerSiteInit(hDlg); if( IsOS(OS_WHISTLERORGREATER)) { HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP)); if( hIcon != NULL) SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0); // icons loaded with LoadIcon never need to be released } return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: case IDOK: return EndDialog(hDlg, 0); case IDC_PRIVACYPS_REMOVEALLBTN: OnSiteClear(hDlg); return TRUE; case IDC_PRIVACYPS_REMOVEBTN: OnSiteDelete(hDlg); return TRUE; case IDC_PRIVACYPS_ACCEPTBTN: OnSiteSet(hDlg, IDC_PRIVACYPS_ACCEPTBTN); return TRUE; case IDC_PRIVACYPS_REJECTBTN: OnSiteSet(hDlg, IDC_PRIVACYPS_REJECTBTN); return TRUE; } break; case WM_NOTIFY: if (IDC_PRIVACYPS_LISTBOX == ((LPNMHDR)lParam)->idFrom) { switch (((LPNMHDR)lParam)->code) { case NM_KILLFOCUS: // lost focus, turn off remove button if ((GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN) != GetFocus()) || (-1 == ListView_GetSelectionMark(hwndList))) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); } return TRUE; case NM_SETFOCUS: { // if there is nothing in the list we have nothing to do if (0 == ListView_GetItemCount(hwndList)) break; // if this is true a policy has been set making per-site list read-only, so do nothing... if ((BOOL)GetWindowLongPtr(hDlg, DWLP_USER)) break; int iIndex = ListView_GetSelectionMark(hwndList); if (-1 == iIndex) { iIndex = 0; } // select|focus the correct item... ListView_SetItemState(hwndList, iIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), TRUE); } return TRUE; case NM_CLICK: if (-1 != ListView_GetSelectionMark(hwndList) && !((BOOL)GetWindowLongPtr(hDlg, DWLP_USER))) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), TRUE); } else { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACYPS_REMOVEBTN), FALSE); } return TRUE; case NM_DBLCLK: OnDoubleClick(hwndList); return TRUE; case NM_RCLICK: { // if this is true a policy has been set making per-site list read-only, so don't show the context menu, // since all it does is allow you to change or remove things... if ((BOOL)GetWindowLongPtr(hDlg, DWLP_USER)) break; int iItem = ((LPNMITEMACTIVATE)lParam)->iItem; if (-1 != iItem) { POINT pointClick = ((LPNMITEMACTIVATE)lParam)->ptAction; RECT rc; if(0 != GetWindowRect(hwndList, &rc)) { pointClick.x += rc.left; pointClick.y += rc.top; } else { pointClick.x = -1; pointClick.y = -1; } OnContextMenu(hwndList, iItem, pointClick); } return TRUE; } case LVN_KEYDOWN: switch (((LPNMLVKEYDOWN)lParam)->wVKey) { case VK_DELETE: OnSiteDelete(hDlg); return TRUE; case VK_RETURN: OnDoubleClick(hwndList); return TRUE; default: break; } break; case LVN_COLUMNCLICK: { struct LVCOMPAREINFO lvci; static BOOL fAscending = TRUE; fAscending = !fAscending; lvci.fAscending = fAscending; lvci.hwndLV = hwndList; lvci.iCol = ((LPNMLISTVIEW)lParam)->iSubItem; return ListView_SortItemsEx(hwndList, CompareByAlpha, &lvci); } default: break; } } break; case WM_HELP: // F1 ResWinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE, HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break; case WM_CONTEXTMENU: // right mouse click if ((HWND)wParam != hwndList) { ResWinHelp((HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); } else if (-1 == GET_X_LPARAM(lParam) && -1 == GET_Y_LPARAM(lParam)) { POINT pointClick; pointClick.x = -1; pointClick.y = -1; OnContextMenu(hwndList, ListView_GetSelectionMark(hwndList), pointClick); } break; } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////// // // Advanced privacy settings dialog // /////////////////////////////////////////////////////////////////////////////////////// BOOL IsAdvancedMode(void) { DWORD dwTemplate, dwError; BOOL fAdvanced = FALSE; dwError = PrivacyGetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_FIRST_PARTY, &dwTemplate, NULL, NULL); if(ERROR_SUCCESS == dwError && PRIVACY_TEMPLATE_ADVANCED == dwTemplate) { fAdvanced = TRUE; } return fAdvanced; } DWORD MapPrefToIndex(WCHAR wcPref) { switch(wcPref) { case 'r': return 1; // reject case 'p': return 2; // prompt default: return 0; // default is accept } } WCHAR MapRadioToPref(HWND hDlg, DWORD dwResource) { if(IsDlgButtonChecked(hDlg, dwResource + 1)) // deny { return 'r'; } if(IsDlgButtonChecked(hDlg, dwResource + 2)) // prompt { return 'p'; } // deafult is accept return 'a'; } void OnAdvancedInit(HWND hDlg) { BOOL fSession = FALSE; DWORD dwFirst = IDC_FIRST_ACCEPT; DWORD dwThird = IDC_THIRD_ACCEPT; if(IsAdvancedMode()) { WCHAR szBuffer[MAX_PATH]; // MAX_PATH is sufficent for advanced mode setting strings, MaxPrivacySettings is overkill. WCHAR *pszAlways; DWORD dwBufferSize, dwTemplate; DWORD dwError; // // turn on advanced check box // CheckDlgButton(hDlg, IDC_USE_ADVANCED, TRUE); // // Figure out first party setting and session // dwBufferSize = ARRAYSIZE( szBuffer); dwError = PrivacyGetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_FIRST_PARTY, &dwTemplate, szBuffer, &dwBufferSize); if(ERROR_SUCCESS == dwError) { pszAlways = StrStrW(szBuffer, L"always="); if(pszAlways) { dwFirst = IDC_FIRST_ACCEPT + MapPrefToIndex(*(pszAlways + 7)); } if(StrStrW(szBuffer, L"session")) { fSession = TRUE; } } // // Figure out third party setting // dwBufferSize = ARRAYSIZE( szBuffer); dwError = PrivacyGetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_THIRD_PARTY, &dwTemplate, szBuffer, &dwBufferSize); if(ERROR_SUCCESS == dwError) { WCHAR *pszAlways; pszAlways = StrStrW(szBuffer, L"always="); if(pszAlways) { dwThird = IDC_THIRD_ACCEPT + MapPrefToIndex(*(pszAlways + 7)); } } } CheckRadioButton(hDlg, IDC_FIRST_ACCEPT, IDC_FIRST_PROMPT, dwFirst); CheckRadioButton(hDlg, IDC_THIRD_ACCEPT, IDC_THIRD_PROMPT, dwThird); CheckDlgButton( hDlg, IDC_SESSION_OVERRIDE, fSession); } void OnAdvancedOk(HWND hDlg) { BOOL fWasAdvanced = IsAdvancedMode(); BOOL fAdvanced = IsDlgButtonChecked(hDlg, IDC_USE_ADVANCED); // if advanced, build first and third party strings if(fAdvanced) { WCHAR szBuffer[MAX_PATH]; wnsprintf(szBuffer, ARRAYSIZE( szBuffer), L"IE6-P3PV1/settings: always=%c%s", MapRadioToPref(hDlg, IDC_FIRST_ACCEPT), IsDlgButtonChecked(hDlg, IDC_SESSION_OVERRIDE) ? L" session=a" : L"" ); PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_FIRST_PARTY, PRIVACY_TEMPLATE_ADVANCED, szBuffer); wnsprintf(szBuffer, ARRAYSIZE( szBuffer), L"IE6-P3PV1/settings: always=%c%s", MapRadioToPref(hDlg, IDC_THIRD_ACCEPT), IsDlgButtonChecked(hDlg, IDC_SESSION_OVERRIDE) ? L" session=a" : L"" ); PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_THIRD_PARTY, PRIVACY_TEMPLATE_ADVANCED, szBuffer); // tell wininet to refresh itself InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0); } else if ( fWasAdvanced && !fAdvanced) { PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_FIRST_PARTY, PRIVACY_TEMPLATE_MEDIUM, NULL); PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_THIRD_PARTY, PRIVACY_TEMPLATE_MEDIUM, NULL); // tell wininet to refresh itself InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0); } } void OnAdvancedEnable(HWND hDlg) { BOOL fEnabled = IsDlgButtonChecked(hDlg, IDC_USE_ADVANCED); // if restricted, disable checkbox and force all others disabled if(g_restrict.fPrivacySettings) { EnableWindow(GetDlgItem(hDlg, IDC_USE_ADVANCED), FALSE); fEnabled = FALSE; } EnableWindow(GetDlgItem(hDlg, IDC_FIRST_ACCEPT), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_FIRST_DENY), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_FIRST_PROMPT), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_THIRD_ACCEPT), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_THIRD_DENY), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_THIRD_PROMPT), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_SESSION_OVERRIDE), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_TX_FIRST), fEnabled); EnableWindow(GetDlgItem(hDlg, IDC_TX_THIRD), fEnabled); } INT_PTR CALLBACK PrivAdvancedDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: OnAdvancedInit(hDlg); OnAdvancedEnable(hDlg); if( IsOS(OS_WHISTLERORGREATER)) { HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP)); if( hIcon != NULL) SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0); // icons loaded with LoadIcon never need to be released } return TRUE; case WM_HELP: // F1 ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE, HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break; case WM_CONTEXTMENU: // right mouse click ResWinHelp( (HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: if(FALSE == g_restrict.fPrivacySettings) { OnAdvancedOk(hDlg); } // fall through case IDCANCEL: EndDialog(hDlg, IDOK == LOWORD(wParam)); return 0; case IDC_FIRST_ACCEPT: case IDC_FIRST_PROMPT: case IDC_FIRST_DENY: CheckRadioButton(hDlg, IDC_FIRST_ACCEPT, IDC_FIRST_PROMPT, LOWORD(wParam)); return 0; case IDC_THIRD_ACCEPT: case IDC_THIRD_PROMPT: case IDC_THIRD_DENY: CheckRadioButton(hDlg, IDC_THIRD_ACCEPT, IDC_THIRD_PROMPT, LOWORD(wParam)); return 0; case IDC_USE_ADVANCED: OnAdvancedEnable(hDlg); return 0; case IDC_PRIVACY_EDIT: DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_PERSITE), hDlg, PrivPerSiteDlgProc); return 0; } break; } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////// // // Privacy pane // /////////////////////////////////////////////////////////////////////////////////////// #define PRIVACY_LEVELS 6 #define SLIDER_LEVEL_CUSTOM 6 TCHAR szPrivacyLevel[PRIVACY_LEVELS + 1][30]; TCHAR szPrivacyDescription[PRIVACY_LEVELS + 1][400]; typedef struct _privslider { DWORD_PTR dwLevel; BOOL fAdvanced; BOOL fCustom; HFONT hfontBolded; BOOL fEditDisabled; } PRIVSLIDER, *PPRIVSLIDER; void EnablePrivacyControls(HWND hDlg, BOOL fCustom) { WCHAR szBuffer[256]; if( fCustom) MLLoadString( IDS_PRIVACY_SLIDERCOMMANDDEF, szBuffer, ARRAYSIZE( szBuffer)); else MLLoadString( IDS_PRIVACY_SLIDERCOMMANDSLIDE, szBuffer, ARRAYSIZE( szBuffer)); SendMessage(GetDlgItem(hDlg, IDC_PRIVACY_SLIDERCOMMAND), WM_SETTEXT, 0, (LPARAM)szBuffer); // slider disabled when custom EnableWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), !fCustom); ShowWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), !fCustom); // default button enabled with custom EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), fCustom); // if restricted, force slider and defaults disabled if(g_restrict.fPrivacySettings) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_LEVEL_SLIDER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_IMPORT), FALSE); } } PPRIVSLIDER OnPrivacyInit(HWND hDlg) { DWORD i; PPRIVSLIDER pData; DWORD dwRet, dwType, dwSize, dwValue; // allocate storage for the font and current level pData = new PRIVSLIDER; if(NULL == pData) { // doh return NULL; } pData->dwLevel = -1; pData->hfontBolded = NULL; pData->fAdvanced = IsAdvancedMode(); pData->fCustom = FALSE; pData->fEditDisabled = FALSE; // // Set the font of the name to the bold font // // find current font HFONT hfontOrig = (HFONT) SendDlgItemMessage(hDlg, IDC_LEVEL, WM_GETFONT, (WPARAM) 0, (LPARAM) 0); if(hfontOrig == NULL) hfontOrig = (HFONT) GetStockObject(SYSTEM_FONT); // build bold font if(hfontOrig) { LOGFONT lfData; if(GetObject(hfontOrig, SIZEOF(lfData), &lfData) != 0) { // The distance from 400 (normal) to 700 (bold) lfData.lfWeight += 300; if(lfData.lfWeight > 1000) lfData.lfWeight = 1000; pData->hfontBolded = CreateFontIndirect(&lfData); if(pData->hfontBolded) { // the zone level and zone name text boxes should have the same font, so this is okat SendDlgItemMessage(hDlg, IDC_LEVEL, WM_SETFONT, (WPARAM) pData->hfontBolded, (LPARAM) MAKELPARAM(FALSE, 0)); } } } // initialize slider SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETRANGE, (WPARAM) (BOOL) FALSE, (LPARAM) MAKELONG(0, PRIVACY_LEVELS - 1)); SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETTICFREQ, (WPARAM) 1, (LPARAM) 0); // initialize strings for levels and descriptions for(i=0; idwLevel = dwTemplateFirst; if(dwTemplateFirst == PRIVACY_TEMPLATE_ADVANCED) { pData->fAdvanced = TRUE; pData->dwLevel = SLIDER_LEVEL_CUSTOM; } } else { // make custom end of list pData->dwLevel = SLIDER_LEVEL_CUSTOM; pData->fCustom = TRUE; } // move slider to right spot SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pData->dwLevel); // Enable stuff based on mode EnablePrivacyControls(hDlg, ((pData->fAdvanced) || (pData->fCustom))); // save off struct SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)pData); dwSize = sizeof(dwValue); dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHEDIT, REGSTR_PRIVACYPS_VALUEDIT, &dwType, &dwValue, &dwSize); if (ERROR_SUCCESS == dwRet && 1 == dwValue && REG_DWORD == dwType) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), FALSE); pData->fEditDisabled = TRUE; } return pData; } void OnPrivacyApply(HWND hDlg, PPRIVSLIDER pData) { if(pData->fCustom || pData->fAdvanced) { // nothing else to do return; } DWORD_PTR dwPos = SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_GETPOS, 0, 0); if(pData->dwLevel != dwPos) { DWORD dwCookieAction = URLPOLICY_DISALLOW; // Set privacy settings PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_FIRST_PARTY, (DWORD)dwPos, NULL); PrivacySetZonePreferenceW( URLZONE_INTERNET, PRIVACY_TYPE_THIRD_PARTY, (DWORD)dwPos, NULL); // tell wininet to refresh itself InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0); // save new level as "current" pData->dwLevel = dwPos; } } void OnPrivacySlider(HWND hDlg, PPRIVSLIDER pData) { DWORD dwPos; if(pData->fCustom || pData->fAdvanced) { dwPos = SLIDER_LEVEL_CUSTOM; } else { dwPos = (DWORD)SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_GETPOS, 0, 0); if(dwPos != pData->dwLevel) { ENABLEAPPLY(hDlg); } // enable default button if slider moved off medium BOOL fEnable = FALSE; if(dwPos != PRIVACY_TEMPLATE_MEDIUM && FALSE == g_restrict.fPrivacySettings) { fEnable = TRUE; } EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_DEFAULT), fEnable); } if (PRIVACY_TEMPLATE_NO_COOKIES == dwPos || PRIVACY_TEMPLATE_LOW == dwPos || pData->fEditDisabled) { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), FALSE); } else { EnableWindow(GetDlgItem(hDlg, IDC_PRIVACY_EDIT), TRUE); } // on Mouse Move, change the level description only SetDlgItemText(hDlg, IDC_LEVEL_DESCRIPTION, szPrivacyDescription[dwPos]); SetDlgItemText(hDlg, IDC_LEVEL, szPrivacyLevel[dwPos]); } void OnPrivacyDefault( HWND hDlg, PPRIVSLIDER pData) { // enable controls correctly pData->fAdvanced = FALSE; pData->fCustom = FALSE; EnablePrivacyControls(hDlg, FALSE); // set slider to medium SendDlgItemMessage(hDlg, IDC_LEVEL_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)PRIVACY_TEMPLATE_MEDIUM); // update descriptions pData->dwLevel = SLIDER_LEVEL_CUSTOM; // difference from medium so we get apply button OnPrivacySlider(hDlg, pData); // Give slider focus (if default button has focus and gets disabled, // alt-key dialog control breaks) SendMessage( hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem( hDlg, IDC_LEVEL_SLIDER), MAKELPARAM( TRUE, 0)); } INT_PTR CALLBACK PrivacyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { PPRIVSLIDER pData = (PPRIVSLIDER)GetWindowLongPtr(hDlg, DWLP_USER); switch (uMsg) { case WM_INITDIALOG: // initialize slider pData = OnPrivacyInit(hDlg); if(pData) { OnPrivacySlider(hDlg, pData); } if( IsOS(OS_WHISTLERORGREATER)) { HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP)); if( hIcon != NULL) SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0); // icons loaded with LoadIcon never need to be released } return TRUE; case WM_VSCROLL: // Slider Messages OnPrivacySlider(hDlg, pData); return TRUE; case WM_NOTIFY: { NMHDR *lpnm = (NMHDR *) lParam; ASSERT(lpnm); switch (lpnm->code) { case PSN_QUERYCANCEL: case PSN_KILLACTIVE: case PSN_RESET: return TRUE; case PSN_APPLY: // Hitting the apply button runs this code OnPrivacyApply(hDlg, pData); break; } break; } case WM_DESTROY: { if(pData) { if(pData->hfontBolded) DeleteObject(pData->hfontBolded); delete pData; } break; } case WM_HELP: // F1 ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE, HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break; case WM_CONTEXTMENU: // right mouse click ResWinHelp( (HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_PRIVACY_DEFAULT: OnPrivacyDefault( hDlg, pData); return 0; case IDC_PRIVACY_ADVANCED: { BOOL fWasAdvanced = IsAdvancedMode(); // show advanced if( DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_ADVANCED), hDlg, PrivAdvancedDlgProc)) { // refresh advanced and reset slider/controls pData->fAdvanced = IsAdvancedMode(); if(pData->fAdvanced) { // no longer have a slider template pData->fCustom = FALSE; pData->dwLevel = SLIDER_LEVEL_CUSTOM; EnablePrivacyControls(hDlg, (pData->fCustom || pData->fAdvanced)); OnPrivacySlider(hDlg, pData); // Give advanced button focus (if slider has focus and gets disabled, // alt-key dialog control breaks) SendMessage( hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem( hDlg, IDC_PRIVACY_ADVANCED), MAKELPARAM( TRUE, 0)); } else if (!pData->fAdvanced && fWasAdvanced) { OnPrivacyDefault( hDlg, pData); } } return 0; } case IDC_PRIVACY_IMPORT: { WCHAR szDialogTitle[MAX_PATH_URL]; WCHAR szFileExpr[MAX_PATH_URL]; MLLoadString( IDS_PRIVACYIMPORT_TITLE, szDialogTitle, ARRAYSIZE(szDialogTitle)); int iFileExprLength = MLLoadString( IDS_PRIVACYIMPORT_FILEEXPR, szFileExpr, ARRAYSIZE(szFileExpr)); szFileExpr[ iFileExprLength + 1] = L'\0'; // the extra \0 in the resource gets clipped.. replace it. WCHAR szFile[MAX_PATH_URL]; szFile[0] = L'\0'; OPENFILENAME ofn; memset((void*)&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof( ofn); ofn.hwndOwner = hDlg; ofn.lpstrFilter = szFileExpr; ofn.lpstrFile = szFile; ofn.nMaxFile = ARRAYSIZE(szFile); ofn.lpstrTitle = szDialogTitle; ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; if( 0 != GetOpenFileName(&ofn)) { BOOL fParsePrivacyPreferences = TRUE; BOOL fParsePerSiteRules = TRUE; BOOL fResults; fResults = ImportPrivacySettings( ofn.lpstrFile, &fParsePrivacyPreferences, &fParsePerSiteRules); if( fResults == FALSE || (fParsePrivacyPreferences == FALSE && fParsePerSiteRules == FALSE)) { MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_PRIVACYIMPORT_FAILURE), MAKEINTRESOURCE(IDS_PRIVACYIMPORT_TITLE), MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION | MB_SETFOREGROUND); } else { if( fParsePrivacyPreferences) { pData->fCustom = TRUE; pData->fAdvanced = FALSE; EnablePrivacyControls( hDlg, pData->fCustom); OnPrivacySlider(hDlg, pData); } MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_PRIVACYIMPORT_SUCCESS), MAKEINTRESOURCE(IDS_PRIVACYIMPORT_TITLE), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND); } } return 0; } case IDC_PRIVACY_EDIT: DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_PERSITE), hDlg, PrivPerSiteDlgProc); return 0; } break; } return FALSE; }