// TempActions.cpp: implementation of the CEncryptActions class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "TempActions.h" #include "resource.h" #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// bool CTempActions::DeletePrepare::Do(CActionEngine* pEngine, HWND hwndUpdates) { ASSERT(pEngine != NULL); // Need to create another array for the folders // since they need to pushed on backwards after the files // so we don't get "Folder not empty" errors action_array aFolders; Update(hwndUpdates, _T("Preparing to clear Temp Folder...")); file_iterator fileIter(m_tempFolder, file_iterator::sub_folders | file_iterator::full_paths), end; for( ; fileIter != end; fileIter++) { file_path srcFile(fileIter->cFileName); CAction* pAction; if(srcFile.attributes() & FILE_ATTRIBUTE_DIRECTORY) { pAction = new DeleteFolder(srcFile); aFolders.push_back(pAction); } else { pAction = new DeleteFile(srcFile); pEngine->Add(pAction); } } while(!aFolders.empty()) { pEngine->Add(aFolders.back()); aFolders.pop_back(); } // Error from file_iterator (listing folders) if(fileIter.state() != ERROR_SUCCESS) throw CActionError(HRESULT_FROM_WIN32(fileIter.state()), IDS_TEMP_ERR_LIST, m_tempFolder); return false; } HRESULT CTempActions::DeletePrepare::Initialize(const file_path& temp_folder) { m_tempFolder = temp_folder; return S_OK; } bool CTempActions::DeleteFile::Do(CActionEngine* pEngine, HWND hwndUpdates) { // Update any monitors Update(hwndUpdates, m_file); ::SetFileAttributes(m_file, FILE_ATTRIBUTE_NORMAL); try { if(!::DeleteFile(m_file)) throw CActionError(HRESULT_FROM_WIN32(::GetLastError()), IDS_TEMP_ERR_DELETE, m_file); } catch(CActionError& err) { // These errors are okay. The file is gone if(err.m_hRes != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && err.m_hRes != HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) throw; } return false; } bool CTempActions::DeleteFile::IsFixable(HRESULT hr) const { return (hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) || hr == HRESULT_FROM_WIN32(ERROR_LOCK_VIOLATION) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)); } void CTempActions::DeleteFile::Fix(HRESULT hr) { bool bFirst = true; start: if(IsFixable(hr)) { try { // Try again Do(NULL, NULL); return; } catch(CActionError& err) { // If it's the first around and the error is the same... if(bFirst && IsFixable(err.m_hRes)) { // ... Prompt user to close programs MessageBox(NULL, _T("Many programs keep files in the temp folder. These files cannot be deleted while the program is open. Close all other programs and then click the OK button."), _T("Empty Temp Folder"), MB_OK | MB_ICONINFORMATION); bFirst = false; } // Otherwise out with the error else throw; } } goto start; } bool CTempActions::DeleteFolder::Do(CActionEngine* pEngine, HWND hwndUpdates) { // Update any monitors Update(hwndUpdates, m_folder); if(!::RemoveDirectory(m_folder)) { DWORD dwError = ::GetLastError(); // This error will be accompanied by another file error // so we don't need to show it if(dwError != ERROR_DIR_NOT_EMPTY) throw CActionError(HRESULT_FROM_WIN32(::GetLastError()), IDS_TEMP_ERR_DELETE, m_folder); } return false; } void CTempActions::DeleteFolder::Fix(HRESULT hr) { }