// EmptyRecycleBin.cpp : Implementation of CEmptyRecycleBin #include "stdafx.h" #include "NSCmpts.h" #include "EmptyRecycleBin.h" //#include "DummyDlg.h" #include "..\common\defines.h" #include #include "PromptClose.h" ///////////////////////////////////////////////////////////////////////////// // CEmptyRecycleBin STDMETHODIMP CEmptyRecycleBin::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_ISecureShutdownWin, }; for (int i=0;i psfDesktop; CComPtr pMalloc; // Get the Malloc Interface for freeing Mem later HRESULT hr = SHGetMalloc(&pMalloc); if(FAILED(hr)) return hr; // Get Desktop Folder. Recylce is always a child of Desktop hr = ::SHGetDesktopFolder(&psfDesktop); if(FAILED(hr)) return hr; // Get ITEMID of Recycle hr = ::SHGetSpecialFolderLocation(hwndParent, CSIDL_BITBUCKET, // Recycle Bin &ppidl); if(FAILED(hr)) return hr; // Start Major Stuff CComPtr pcm; DWORD dwAttribs = 0; int idCmd = 0; HRESULT hRet = S_OK; HMENU hMenu; // Get Context Menu Interface on Recycle ITEM ID hr = psfDesktop->GetUIObjectOf (hwndParent, 1, // get attributes for only one object (const struct _ITEMIDLIST **)&ppidl, IID_IContextMenu, 0, (LPVOID *)&pcm); if (SUCCEEDED(hr)) { // Even though we won't display it we have to create it hMenu = CreatePopupMenu(); if (hMenu) { // Get the context menu items for recycle hr = pcm->QueryContextMenu (hMenu, 0, 1, 0x7fff, CMF_EXPLORE); if(FAILED(hr)) hRet = hr; else { // Did the user want to Recycle? if(m_Data.GetInt(ER_REG_RECYCLE, true)) { hr = InvokeMenuCommand(pcm, hMenu, IDS_EMPTYCOMMAND, hwndParent, true); if (FAILED(hr)) hRet = hr; } // Did the use want to clear Norton? if(m_Data.GetInt(ER_REG_NORTON, true)) { hr = InvokeMenuCommand(pcm, hMenu, IDS_NORTONCOMMAND, hwndParent, true); if (FAILED(hr)) hRet = hr; } } DestroyMenu (hMenu); } } else { hRet = E_FAIL; } // Free Recycle Bin Item ID pMalloc->Free(ppidl); if(hRet != S_OK) if (!bSilent) MessageBox(_T("Couldn't Empty Recycle Bin"), _T("Empty Recycle Bin"), MB_OK | MB_ICONEXCLAMATION); return hRet; } STDMETHODIMP CEmptyRecycleBin::get_Info(NightSecInfo nsItem, VARIANT* pvVal) { ::VariantClear(pvVal); CComBSTR bsRetVal; switch(nsItem) { case nsName: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_RECYCLENAME); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; case nsHelpText: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_RECYCLEDESC); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; case nsCmdLine: pvVal->vt = VT_BSTR; bsRetVal.LoadString(IDS_RECYCLEPARAM); pvVal->bstrVal = bsRetVal.Detach(); return S_OK; } ::VariantClear(pvVal); return S_FALSE; } STDMETHODIMP CEmptyRecycleBin::SetData(IUnknown* pUnk) { return m_Data.Initialize(pUnk); } HRESULT InvokeMenuCommand(IContextMenu* pcm, HMENU hMenu, UINT nMenuItem, HWND hWndParent, bool bClosePrompt) { HRESULT hRet = S_OK; int idCmd = 0; // Get the ID idCmd = GetMenuIdFromString(hMenu, nMenuItem); // Only Proceed if We Found it if(!idCmd) return S_FALSE; UINT nMenuState = ::GetMenuState(hMenu, idCmd, MF_BYCOMMAND); if(!(nMenuState & MF_GRAYED || nMenuState & MF_DISABLED)) { if(bClosePrompt) { CPromptClose closer; closer.CloseNext(IDYES); } // Do the Stuff hRet = InvokeMenuId(pcm, idCmd, hWndParent); return hRet; } return S_FALSE; } ////////////////////////////////////////////////////////////////// int GetMenuIdFromString(HMENU hMenu, UINT nStrID) { string sSearch; if(sSearch.load_string(nStrID)) return GetMenuIdFromString(hMenu, sSearch); else ASSERT(false); // Need a valid Resource ID return 0; } ////////////////////////////////////////////////////////////////// int GetMenuIdFromString(HMENU hMenu, string sSearch) { string sMenuItem; sSearch.make_upper(); for(int nCnt = 0; nCnt < ::GetMenuItemCount(hMenu); nCnt++) { if(::GetMenuString(hMenu, nCnt, sMenuItem.get_buffer(MAX_PATH), MAX_PATH, MF_BYPOSITION)) { sMenuItem.release_buffer(); sMenuItem.make_upper(); if(sMenuItem.find(sSearch) != string::npos) return ::GetMenuItemID(hMenu, nCnt); } } return 0; } HRESULT InvokeMenuId(IContextMenu* pcm, int nIDCmd, HWND hWndParent) { CMINVOKECOMMANDINFO cmi; // Setup for Invoking. cmi.cbSize = sizeof (CMINVOKECOMMANDINFO); cmi.fMask = CMIC_MASK_FLAG_NO_UI; cmi.hwnd = hWndParent; cmi.lpVerb = MAKEINTRESOURCEA (nIDCmd - 1); cmi.lpParameters = NULL; cmi.lpDirectory = NULL; cmi.nShow = SW_HIDE; cmi.dwHotKey = 0; cmi.hIcon = NULL; // Do the Stuff return pcm->InvokeCommand (&cmi); } ////////////////////////////////////////////////////////////////// // If the user is at the computer switching windows this won't // work, but that's okay because then the user can close the // window /* static DWORD WINAPI ClosePromptWindow( LPVOID pParam ) { HWND hwndParent = (HWND)pParam; // The Parent of the Prompt Window HWND hwndTop = ::GetTopLevel(hwndParent);// The Top Level Parent of the Prompt Window HWND hwndDlg = NULL; // Will Hold the Final Prompt Window to Close DWORD dwStartCount = ::GetTickCount(); // Find the Active Popup // Give it at least 20 seconds to come while((hwndDlg = ::GetLastActivePopup(hwndTop)) == hwndParent && ::GetTickCount() < dwStartCount + 20000) { } // Error: Window Didn't Pop up in 20 seconds if(hwndDlg == hwndParent) return 1; SetActiveWindow(hwndTop); SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); keybd_event(VK_RETURN, 0, 0, 0); return 0; } HWND GetTopLevel(HWND hwnd) { while(::GetParent(hwnd)) hwnd = ::GetParent(hwnd); return hwnd; } */