// ClearInetCache.cpp : Implementation of CClearInetCache #include "stdafx.h" #include "NetCmpts.h" #include "ClearInetCache.h" #include "ProgressDlg.h" #include "..\common\defines.h" #include #include "parseurl.h" #include using std::find; ///////////////////////////////////////////////////////////////////////////// // CClearInetCache STDMETHODIMP CClearInetCache::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_ISecureShutdownWin, }; for (int i=0;idwStructSize = sizeof(INTERNET_CACHE_ENTRY_INFO); lpICEInfo->dwReserved = 0; // Always has to be zero // Find First hFindURL = FindFirstUrlCacheEntry (_T("*.*"), lpICEInfo, &nBufferSize); if(hFindURL != NULL) { // Create Progress dialog CProgressDlg dlgProg; dlgProg.Create(hwndParent); dlgProg.DispEventAdvise(m_spUnkSite); // Pointer from IObjectWithSite dlgProg.m_ctlProgress.SetRange(0, 2); dlgProg.m_ctlProgress.SetStep(1); bool bLoop = true; while(bLoop) { // Update Progress Dialog dlgProg.SetDlgItemText(IDC_FILENAME, lpICEInfo->lpszSourceUrlName); dlgProg.m_ctlProgress.SetPos(0); // Check if we should delete this URL if(IsDeleteableURL(lpICEInfo->lpszSourceUrlName)) { // Keep going even if error DeleteUrlCacheEntry(lpICEInfo->lpszSourceUrlName); // Update Progress Dialog dlgProg.m_ctlProgress.SetPos(2); } // nBufferSize Gets changed in FindNext... funcs // so have to reset nBufferSize = MAX_CACHE_ENTRY_INFO_SIZE; // Get Next One if(!((bLoop = FindNextUrlCacheEntry(hFindURL, lpICEInfo, &nBufferSize)) ? true : false)) { DWORD dwError = ::GetLastError(); switch(::GetLastError()) { case ERROR_NO_MORE_FILES: case ERROR_NO_MORE_ITEMS: hRet = S_OK; break; // For Debugging case ERROR_INSUFFICIENT_BUFFER: hRet = E_OUTOFMEMORY; break; default: hRet = HRESULT_FROM_WIN32(::GetLastError()); break; } } PEEK_ALL_MESSAGES(msg); // Check for Cancel if(dlgProg.IsCancelled()) { bLoop = false; hRet = E_ABORT; } } // while bLoop // Clean up time FindCloseUrlCache(hFindURL); free(lpICEInfo); if(dlgProg.IsWindow()) dlgProg.DestroyWindow(); dlgProg.DispEventUnadvise(m_spUnkSite); // Pointer from IObjectWithSite return hRet; } // if handle is null // Clean up free(lpICEInfo); switch(::GetLastError()) { case ERROR_NO_MORE_ITEMS: case ERROR_NO_MORE_FILES: return S_OK; break; default: return HRESULT_FROM_WIN32(::GetLastError()); break; } } ////////////////////////////////////////////////////////////////// // Load Server List from Registry int CClearInetCache::GetServersToDelete() { USES_CONVERSION; LoadFlags(); int nCnt = 0; // Number of URLs from Registry int nReadServers = 0; // Number of 'sane' URLs string sURL = ""; string sKeyName = ""; // Format Key Name sKeyName.format("Server%.4d", nCnt); // Used in URL Parsing DWORD dwProtocol = 0; string sServer = ""; string sObject = ""; INTERNET_PORT inetPort; // Add URLs to List Box while((sURL = m_Data.GetString(sKeyName, NO_KEY)) != NO_KEY) { // Get the Host/Server Part if(ParseURL(sURL, dwProtocol, sServer, sObject, inetPort)) { // Add to Array m_asServerURLs.push_back(sServer); nReadServers++; } nCnt++; // Format Key Name sKeyName.format("Server%.4d", nCnt); } m_bInitialized = true; return nReadServers; } ////////////////////////////////////////////////////////////////// // Checks a URL against the list bool CClearInetCache::IsDeleteableURL(const string& sURL) { // Sanity Check if(sURL.empty()) return false; // Read Servers from Registry if(!m_bInitialized) // Only continue of more than one server GetServersToDelete(); // Used in URL Parsing DWORD dwProtocol = 0; string sServer = ""; string sObject = ""; INTERNET_PORT inetPort; // Get the Host/Server Part if(ParseURL(sURL, dwProtocol, sServer, sObject, inetPort)) { if(dwProtocol == INTERNET_SCHEME_UNKNOWN) return m_bCookies; if(m_bClearAll) return true; // Check it against our array return find(m_asServerURLs.begin(), m_asServerURLs.end(), sServer) != m_asServerURLs.end(); } return false; } STDMETHODIMP CClearInetCache::get_Info(NightSecInfo nsItem, VARIANT* pvVal) { ::VariantClear(pvVal); CComBSTR bsRetVal; switch(nsItem) { case nsName: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_INETNAME); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; case nsHelpText: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_INETDESC); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; case nsCmdLine: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_INETPARAM); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; case nsHideNormal: pvVal->vt = VT_BOOL; pvVal->bVal = TRUE; return S_OK; } ::VariantClear(pvVal); return S_FALSE; } STDMETHODIMP CClearInetCache::SetData(IUnknown* pUnk) { return m_Data.Initialize(pUnk); } ///////////////////////////////////////////////////////////////////// // // Property Sheet // ///////////////////////////////////////////////////////////////////// HRESULT CClearInetCache::SaveChanges() { int nServer = 0; string sKeyName = ""; string sURL; int iItem = -1; // Setup Structures LV_ITEM lv; lv.mask = LVIF_TEXT; lv.iSubItem = 0; lv.cchTextMax = MAX_PATH * 2; HRESULT hr; HRESULT hrRet = S_OK; // Loop through selected items while((iItem = m_ctlServerList.GetNextItem(iItem, LVNI_ALL)) != -1) { lv.iItem = iItem; lv.iSubItem = 0; lv.pszText = sURL.get_buffer(MAX_PATH * 2); if(m_ctlServerList.GetItem(&lv)) { // Format Registry Key sKeyName.format("Server%.4d", nServer); sURL.release_buffer(); hr = m_Data.WriteString(sKeyName, sURL); if(FAILED(hr)) hrRet = hr; } nServer++; } for(nServer = nServer; nServer < m_nLoadedURLs; nServer++) { // Format Registry Key sKeyName.format("Server%.4d", nServer); m_Data.DeleteProperty(sKeyName); } // Save Clear All State hr = m_Data.WriteInt("Clear All", IsDlgButtonChecked(IDC_CLEARALLSERVERS)); if(FAILED(hr)) hrRet = hr; // Save Cookie State hr = m_Data.WriteInt("Clear Cookies", IsDlgButtonChecked(IDC_COOKIES)); if(FAILED(hr)) hrRet = hr; return hrRet; } LRESULT CClearInetCache::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LoadFlags(); m_ctlServerList = GetDlgItem(IDC_SERVERURLLIST); // Create the small icon image list. m_ImageListSmall.Create(16, 16, ILC_MASK, // list does not include masks 1, 0 ); // list won't grow // Set Mask color for Image Lists m_ImageListSmall.SetBkColor(::GetSysColor(COLOR_WINDOW)); // Load the icon and add to the image list. if(m_ImageListSmall.AddIcon(::LoadIcon(_Module.m_hInstResource, MAKEINTRESOURCE(IDI_INETSHORTCUT))) == -1) return false; // Associate the image lists with the list view control. m_ctlServerList.SetImageList(m_ImageListSmall, LVSIL_SMALL); // Fill List Control string sURL; string sKeyName = ""; int nCnt = 0; // Format Key Name sKeyName.format("Server%.4d", nCnt); while((sURL = m_Data.GetString(sKeyName, NO_KEY)) != NO_KEY) { m_ctlServerList.InsertItem(nCnt, sURL, 0); // Make sure each one has a unique lParam m_dwIDCounter++; nCnt++; // Format Key Name sKeyName.format("Server%.4d", nCnt); } m_nLoadedURLs = nCnt + 1; CheckDlgButton(IDC_CLEARALLSERVERS, m_bClearAll); CheckDlgButton(IDC_COOKIES, m_bCookies); UpdateClearAll(); m_hIconNew = ::LoadIcon(_Module.m_hInstResource, MAKEINTRESOURCE(IDI_NEW)); m_hIconDel = ::LoadIcon(_Module.m_hInstResource, MAKEINTRESOURCE(IDI_DEL)); CButton btn = GetDlgItem(IDC_NEWURL); btn.SetIcon(m_hIconNew); btn = GetDlgItem(IDC_DELETE); btn.SetIcon(m_hIconDel); return false; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } LRESULT CClearInetCache::OnURLListEndLabelEdit(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pnmh; // Only Change if there is Text if(pDispInfo->item.pszText != NULL) { // Used in Checking URL DWORD dwProtocol = 0; string sTemp1 = ""; string sTemp2 = ""; INTERNET_PORT inetPort; // Do a Check on URL if(ParseURL(pDispInfo->item.pszText, dwProtocol, sTemp1, sTemp2, inetPort)) { // Set Item text m_ctlServerList.SetItem(&(pDispInfo->item)); SetDirty(true); } else { // Try adding http:// string sNewURL(_T("http://")); sNewURL += pDispInfo->item.pszText; if(ParseURL(sNewURL, dwProtocol, sTemp1, sTemp2, inetPort)) { // Set Item text pDispInfo->item.pszText = sNewURL.get_buffer(); m_ctlServerList.SetItem(&(pDispInfo->item)); SetDirty(true); } else { // Give an Error Box string sMsg; sMsg.load_string(IDS_NOTVALIDURL); MessageBox(sMsg, "Night Security", MB_ICONSTOP | MB_OK); } } } return 0; } LRESULT CClearInetCache::OnURLListKeyDown(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pnmh; // if F2 then Edit if(pLVKeyDow->wVKey == VK_F2) { m_ctlServerList.SetFocus(); // Needs to have the Focus in order to edit m_ctlServerList.EditLabel(m_ctlServerList.GetNextItem(-1, LVNI_ALL | LVNI_FOCUSED)); } // If Delete then call Delete Handler if(pLVKeyDow->wVKey == VK_DELETE) OnDelete(0, 0, 0, bHandled); return 0; } LRESULT CClearInetCache::OnListSetFocus(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { // Disclaimer: This is a kludge fix // SysListView32 wouldn't redraw itself when it had focus // and app was activated m_ctlServerList.RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE); return 0; } LRESULT CClearInetCache::OnNewURL(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { int iItem = -1; string sNewURL; sNewURL.load_string(IDS_NEWURL); // Insert Item if((iItem = m_ctlServerList.InsertItem(0, sNewURL, 0)) != -1) { m_dwIDCounter++; // Open for Editing m_ctlServerList.SetFocus(); // Needs to have the Focus in order to edit m_ctlServerList.EditLabel(iItem); SetDirty(true); } return 0; } LRESULT CClearInetCache::OnDelete(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { int iItem = -1; LV_ITEM lv; lv.mask = LVIF_TEXT; lv.iSubItem = 0; // Loop through selected items while((iItem = m_ctlServerList.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED)) != -1) { // Take it out of List Box m_ctlServerList.DeleteItem(iItem); SetDirty(true); } return 0; } LRESULT CClearInetCache::OnClearAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { UpdateClearAll(); SetDirty(true); return 0; } void CClearInetCache::UpdateClearAll() { bool bEnable = !IsDlgButtonChecked(IDC_CLEARALLSERVERS); ::EnableWindow(GetDlgItem(IDC_SERVERURLLIST), bEnable); ::EnableWindow(GetDlgItem(IDC_NEWURL), bEnable); ::EnableWindow(GetDlgItem(IDC_DELETE), bEnable); SetDirty(true); } void CClearInetCache::LoadFlags() { m_bClearAll = m_Data.GetInt("Clear All", true) ? true : false; m_bCookies = m_Data.GetInt("Clear Cookies", false) ? true : false; }