diff options
author | Stef Walter <stef@thewalter.net> | 2003-09-17 19:07:23 +0000 |
---|---|---|
committer | Stef Walter <stef@thewalter.net> | 2003-09-17 19:07:23 +0000 |
commit | 3f95d417d9e623ac0c74df8ef11d7a01846392dd (patch) | |
tree | 45ec73f2dc07eafd7f41a6f62a8cdfbaa279469f /NSCmpts/EncryptActions.cpp |
Diffstat (limited to 'NSCmpts/EncryptActions.cpp')
-rw-r--r-- | NSCmpts/EncryptActions.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/NSCmpts/EncryptActions.cpp b/NSCmpts/EncryptActions.cpp new file mode 100644 index 0000000..aac7fb5 --- /dev/null +++ b/NSCmpts/EncryptActions.cpp @@ -0,0 +1,235 @@ +// EncryptActions.cpp: implementation of the CEncryptActions class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "EncryptActions.h" + +#include "resource.h" +#include <appmisc.h> + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +bool CEncryptActions::EncryptPrepare::Do(CActionEngine* pEngine, + HWND hwndUpdates) +{ + ASSERT(pEngine != NULL); + + Update(hwndUpdates, _T("Listing files to encrypt..."), NULL); + + // Iterate through source folders + string_array::const_iterator iterSrc; + for(iterSrc = m_aFiles.begin(); iterSrc != m_aFiles.end(); iterSrc++) + { + Update(hwndUpdates, NULL, (LPCTSTR)*iterSrc); + + file_iterator fileIter((file_path)*iterSrc, file_iterator::sub_folders | file_iterator::full_paths), end; + for( ; fileIter != end; fileIter++) + { + file_path srcFile(fileIter->cFileName); + if(!(srcFile.attributes() & FILE_ATTRIBUTE_DIRECTORY)) + { + if(m_asIgnore.find(srcFile.ext().make_lower()) == m_asIgnore.end()) + { + // Construct File + Encrypt* pEncrypt = new Encrypt(srcFile); + pEngine->Add(pEncrypt); + } + } + } + + // Error from file_iterator (listing folders) + if(fileIter.state() != ERROR_SUCCESS) + throw CActionError(HRESULT_FROM_WIN32(fileIter.state()), IDS_ENCRYPT_ERR_LIST, (file_path)*iterSrc); + } + + return false; +} + +HRESULT CEncryptActions::EncryptPrepare::Initialize(const CPropertyBag& data) +{ + if(!data.GetStringSet(NS_ENCRYPT_REG_FILES, m_aFiles)) + return S_FALSE; + + CEncryptActions::Encrypt::m_bEncryptReadOnly = data.GetInt(NS_ENCRYPT_REG_READONLY, false) ? true : false; + + string_array asTemp; + data.GetStringSet(NS_IGNORE_REG_EXT, asTemp); + + // Make them all lower + for_each(asTemp.begin(), asTemp.end(), Lower); + + // And copy them to the set (removes doubles) + copy(asTemp.begin(), asTemp.end(), inserter(m_asIgnore, m_asIgnore.begin())); + + // Remove any blanks from ignore + m_asIgnore.erase(_T("")); + + return S_OK; +} + + +IXpyExPtr CEncryptActions::Encrypt::m_pXpy; +bool CEncryptActions::Encrypt::m_bEncryptReadOnly = false; +UINT CEncryptActions::Encrypt::m_nXpyRefs = 0; + +bool CEncryptActions::Encrypt::Do(CActionEngine* pEngine, + HWND hwndUpdates) +{ + // Update any monitors + Update(hwndUpdates, _T("Encrypting..."), m_file); + + // Initialize XPY + HRESULT hr; + if(FAILED(hr = InitXpy())) + { + // If it doesn't work then trash all the encryption actions + // in the engine + if(pEngine) + pEngine->RemoveAll(this); + + // And spit out an error + throw CActionError(hr, IDS_ENCRYPT_ERR_XPYINIT); + } + + + // Use this in case we need to reset the attributes + // in order to encrypt the file. XPY won't encrypt + // read-only files. There's an option here + // to let you. So basically what we have to do is + // reset the file to normal attributes and then set + // it back + + // If it's 0 that means we haven't messed with the + // attributes yet. If it has a value that means we + // need to set the value back before returning + DWORD dwAttributes = 0; + +encrypt: + + try + { + // Here's the actual close code + // rest is basically error checking + m_pXpy->Close((LPCTSTR)m_file); + + } + catch(_com_error& e) + { + // Here we check for the read-only error that Xpy + // will spit up. If the flag is set then go ahead + // and reset the attributes + + if(e.Error() == XPY_E_FILE_ATTRIBUTES && // Read Only Error + m_bEncryptReadOnly) // flag to encrypt read-only + { + + // If we haven't messed with the attributes + // yet then go ahead and reset them + if(!dwAttributes) + { + // Get Attributes + dwAttributes = GetFileAttributes(m_file); + + // Let System files blow! (with an error) + if(!(dwAttributes & FILE_ATTRIBUTE_SYSTEM)) + { + SetFileAttributes(m_file, FILE_ATTRIBUTE_NORMAL); + + // Reencrypt + goto encrypt; + } + + } + + // Otherwise we won't try again + } + + // Set the Attributes back + if(dwAttributes) + SetFileAttributes(m_file, dwAttributes); + + // Get the proper error message + _bstr_t bsError = e.Description(); + + if(bsError.length()) + throw CActionError((LPCTSTR)bsError, e.Error(), IDS_ENCRYPT_ERR, m_file); + else + throw CActionError(e.Error(), IDS_ENCRYPT_ERR, m_file); + } + + // Set the Attributes back + if(dwAttributes) + SetFileAttributes(m_file, dwAttributes); + + return false; +} + +bool CEncryptActions::Encrypt::IsFixable(HRESULT hr) const +{ + switch(hr) + { + case XPY_E_FILE_ATTRIBUTES: + case HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION): + case HRESULT_FROM_WIN32(ERROR_LOCK_VIOLATION): + return true; + default: + return false; + } +} + +void CEncryptActions::Encrypt::Fix(HRESULT hr) +{ + if(hr == XPY_E_FILE_ATTRIBUTES) + { + if(SetFileAttributes(m_file, FILE_ATTRIBUTE_NORMAL)) + Do(NULL, NULL); + else + throw CActionError(HRESULT_FROM_WIN32(::GetLastError()), IDS_ENCRYPT_ERR, m_file); + } + else if(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) || + hr == HRESULT_FROM_WIN32(ERROR_LOCK_VIOLATION)) + { + bool bFirst = true; +start: + 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)) + { + HCURSOR hCurs = ::GetCursor(); + + // ... Prompt user to close programs + MessageBox(NULL, _T("Files cannot be encrypted while they are opened in a program. Close all other programs and then click the OK button."), _T("Encrypt Files"), MB_OK | MB_ICONINFORMATION); + + if(hCurs) + ::SetCursor(hCurs); + + bFirst = false; + } + // Otherwise out with the error + else + throw; + } + + goto start; + } +} + +HRESULT CEncryptActions::Encrypt::InitXpy() +{ + if(m_pXpy) + return S_OK; + else + return m_pXpy.CreateInstance(__uuidof(XpyEx)); +} + |