Index: src/ch/FileFilter.h =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/FileFilter.h (.../FileFilter.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/ch/FileFilter.h (.../FileFilter.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -51,7 +51,7 @@ void SetCombinedExcludeMask(const CString& pMask); void StoreInConfig(chcore::TConfig& rConfig) const; - void ReadFromConfig(const chcore::TConfig& rConfig); + void ReadFromConfig(const chcore::TConfig& rConfig); template void serialize(Archive& ar, unsigned int /*uiVersion*/) Index: src/ch/FileInfo.cpp =================================================================== diff -u -r591f291e22d2ece89acb266c8aa0b05c257a407c -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 591f291e22d2ece89acb266c8aa0b05c257a407c) +++ src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -68,57 +68,24 @@ { } -void CFileInfo::Create(const WIN32_FIND_DATA* pwfd, const chcore::TSmartPath& pathFile, size_t stSrcIndex) +void CFileInfo::Init(const chcore::TSmartPath& rpathFile, size_t stSrcIndex, const chcore::TPathContainer* pBasePaths, + DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite, + uint_t uiFlags) { - BOOST_ASSERT(stSrcIndex == std::numeric_limits::max() || m_pBasePaths); - if(stSrcIndex != std::numeric_limits::max() && !m_pBasePaths) - THROW(_t("Internal error: pointer not initialized."), 0, 0, 0); + m_pathFile = rpathFile; + m_stSrcIndex = stSrcIndex; + m_pBasePaths = pBasePaths; + m_dwAttributes = dwAttributes; + m_uhFileSize = uhFileSize; + m_ftCreation = ftCreation; + m_ftLastAccess = ftLastAccess; + m_ftLastWrite = ftLastWrite; + m_uiFlags = uiFlags; - // copy data from W32_F_D - m_pathFile = pathFile + chcore::PathFromString(pwfd->cFileName); - - // if proper index has been passed - reduce the path - if(m_pBasePaths && stSrcIndex >= 0) + if(m_pBasePaths && stSrcIndex != std::numeric_limits::max()) m_pathFile.MakeRelativePath(m_pBasePaths->GetAt(stSrcIndex)); // cut path from clipboard - - m_stSrcIndex = stSrcIndex; - m_dwAttributes = pwfd->dwFileAttributes; - m_uhFileSize = (((ULONGLONG) pwfd->nFileSizeHigh) << 32) + pwfd->nFileSizeLow; - m_ftCreation = pwfd->ftCreationTime; - m_ftLastAccess = pwfd->ftLastAccessTime; - m_ftLastWrite = pwfd->ftLastWriteTime; - m_uiFlags = 0; } -bool CFileInfo::Create(const chcore::TSmartPath& pathFile, size_t stSrcIndex) -{ - WIN32_FIND_DATA wfd; - HANDLE hFind = FindFirstFile(pathFile.ToString(), &wfd); - if (hFind != INVALID_HANDLE_VALUE) - { - FindClose(hFind); - - // add data to members - chcore::TSmartPath pathNew(pathFile); - pathNew.DeleteFileName(); - Create(&wfd, pathNew, stSrcIndex); - - return true; - } - else - { - m_pathFile.Clear(); - m_stSrcIndex = std::numeric_limits::max(); - m_dwAttributes = (DWORD)-1; - m_uhFileSize = (unsigned __int64)-1; - m_ftCreation.dwHighDateTime = m_ftCreation.dwLowDateTime = 0; - m_ftLastAccess.dwHighDateTime = m_ftCreation.dwLowDateTime = 0; - m_ftLastWrite.dwHighDateTime = m_ftCreation.dwLowDateTime = 0; - m_uiFlags = 0; - return false; - } -} - bool CFileInfo::operator==(const CFileInfo& rInfo) { return (rInfo.m_dwAttributes == m_dwAttributes && rInfo.m_ftCreation.dwHighDateTime == m_ftCreation.dwHighDateTime && rInfo.m_ftCreation.dwLowDateTime == m_ftCreation.dwLowDateTime Index: src/ch/FileInfo.h =================================================================== diff -u -r591f291e22d2ece89acb266c8aa0b05c257a407c -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/FileInfo.h (.../FileInfo.h) (revision 591f291e22d2ece89acb266c8aa0b05c257a407c) +++ src/ch/FileInfo.h (.../FileInfo.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -37,9 +37,15 @@ CFileInfo(const CFileInfo& finf); ~CFileInfo(); - void Create(const WIN32_FIND_DATA* pwfd, const chcore::TSmartPath& tFilePath, size_t stSrcIndex); - bool Create(const chcore::TSmartPath& strFilePath, size_t stSrcIndex); + // with base path + void Init(const chcore::TSmartPath& rpathFile, size_t stSrcIndex, const chcore::TPathContainer* pBasePaths, + DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, FILETIME ftLastAccess, FILETIME ftLastWrite, + uint_t uiFlags); + // without base path + void Init(const chcore::TSmartPath& rpathFile, DWORD dwAttributes, ULONGLONG uhFileSize, FILETIME ftCreation, + FILETIME ftLastAccess, FILETIME ftLastWrite, uint_t uiFlags); + ULONGLONG GetLength64() const { return m_uhFileSize; } void SetLength64(ULONGLONG uhSize) { m_uhFileSize=uhSize; } Index: src/ch/TLocalFilesystem.cpp =================================================================== diff -u -r6e8aa26e2428e3bc71099255c5911f57bc722100 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 6e8aa26e2428e3bc71099255c5911f57bc722100) +++ src/ch/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -23,6 +23,7 @@ #include "stdafx.h" #include "TLocalFilesystem.h" #include "TAutoHandles.h" +#include "FileInfo.h" void TLocalFilesystem::GetDriveData(const chcore::TSmartPath& spPath, int* piDrvNum, UINT* puiDrvType) { @@ -71,7 +72,10 @@ // search by exact name HANDLE hFind = FindFirstFile(pathToCheck.ToString(), &fd); if(hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); return true; + } // another try (add '\\' if needed and '*' for marking that we look for ie. c:\* // instead of c:\, which would never be found prev. way) @@ -100,3 +104,53 @@ return bResult != 0; } + +bool TLocalFilesystem::CreateDirectory(const chcore::TSmartPath& pathDirectory) +{ + if(pathDirectory.GetLength() > _MAX_PATH - 1) + { + std::wstring wstrPath = _T("\\\\?\\") + pathDirectory.ToWString(); + return ::CreateDirectory(wstrPath.c_str(), NULL) != FALSE; + } + else + return ::CreateDirectory(pathDirectory.ToString(), NULL) != FALSE; +} + +bool TLocalFilesystem::GetFileInfo(const chcore::TSmartPath& pathFile, CFileInfoPtr& rFileInfo, size_t stSrcIndex, const chcore::TPathContainer* pBasePaths) +{ + if(!rFileInfo) + THROW(_T("Invalid argument"), 0, 0, 0); + + WIN32_FIND_DATA wfd; + HANDLE hFind = INVALID_HANDLE_VALUE; + + if(pathFile.GetLength() > _MAX_PATH - 1) + { + std::wstring wstrPath = _T("\\\\?\\") + pathFile.ToWString(); + hFind = FindFirstFile(wstrPath.c_str(), &wfd); + } + else + hFind = FindFirstFile(pathFile.ToString(), &wfd); + + if(hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + + // add data to members + chcore::TSmartPath pathNew(pathFile); + pathNew.DeleteFileName(); + + // copy data from W32_F_D + rFileInfo->Init(pathNew + chcore::PathFromString(wfd.cFileName), stSrcIndex, pBasePaths, + wfd.dwFileAttributes, (((ULONGLONG) wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, + wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); + + return true; + } + else + { + FILETIME fi = { 0, 0 }; + rFileInfo->Init(chcore::TSmartPath(), std::numeric_limits::max(), NULL, (DWORD)-1, 0, fi, fi, fi, 0); + return false; + } +} Index: src/ch/TLocalFilesystem.h =================================================================== diff -u -r8c87d4185fbe5b952c49f72afcfd5f9fca338fb4 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 8c87d4185fbe5b952c49f72afcfd5f9fca338fb4) +++ src/ch/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -25,13 +25,18 @@ #include "../libchcore/TPath.h" +class CFileInfo; +typedef boost::shared_ptr CFileInfoPtr; + class TLocalFilesystem { public: static void GetDriveData(const chcore::TSmartPath& spPath, int *piDrvNum, UINT *puiDrvType); static bool PathExist(chcore::TSmartPath strPath); // check for file or folder existence - static bool SetFileDirectoryTime(LPCTSTR lpszName, const FILETIME& ftCreationTime, const FILETIME& ftLastAccessTime, const FILETIME& ftLastWriteTime); + static bool SetFileDirectoryTime(LPCTSTR lpszName, const FILETIME& ftCreationTime, const FILETIME& ftLastAccessTime, const FILETIME& ftLastWriteTime); + static bool CreateDirectory(const chcore::TSmartPath& pathDirectory); + static bool GetFileInfo(const chcore::TSmartPath& pathFile, CFileInfoPtr& rFileInfo, size_t stSrcIndex = std::numeric_limits::max(), const chcore::TPathContainer* pBasePaths = NULL); }; #endif Index: src/ch/TSubTaskCopyMove.cpp =================================================================== diff -u -r6e8aa26e2428e3bc71099255c5911f57bc722100 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 6e8aa26e2428e3bc71099255c5911f57bc722100) +++ src/ch/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -178,7 +178,7 @@ if(spFileInfo->IsDirectory()) { bool bRetry = true; - if(bRetry && !CreateDirectory(ccp.pathDstFile.ToString(), NULL) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) + if(bRetry && !TLocalFilesystem::CreateDirectory(ccp.pathDstFile) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) { // log fmt.SetFormat(_T("Error %errno while calling CreateDirectory %path (ProcessFiles)")); @@ -728,7 +728,8 @@ // by using spDstFileInfo->Create() (which uses FindFirstFile()) or by // reading parameters using opened handle; need to be tested in the future CFileInfoPtr spDstFileInfo(boost::make_shared()); - if(!spDstFileInfo->Create(pathDstFile, std::numeric_limits::max())) + + if(!TLocalFilesystem::GetFileInfo(pathDstFile, spDstFileInfo)) THROW(_T("Cannot get information about file which has already been opened!"), 0, GetLastError(), 0); // src and dst files are the same Index: src/ch/TSubTaskCopyMove.h =================================================================== diff -u -r6e8aa26e2428e3bc71099255c5911f57bc722100 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 6e8aa26e2428e3bc71099255c5911f57bc722100) +++ src/ch/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -36,6 +36,8 @@ ESubOperationResult Exec(); + ESubOperationResult CreateDirectoryFB(const chcore::TSmartPath& pathDirectory); + private: bool GetMove(const CFileInfoPtr& spFileInfo); int GetBufferIndex(const CFileInfoPtr& spFileInfo); Index: src/ch/TSubTaskScanDirectory.cpp =================================================================== diff -u -ra77ea347e3787d330b37917be4c72be480419c93 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/ch/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision a77ea347e3787d330b37917be4c72be480419c93) +++ src/ch/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -81,15 +81,14 @@ bSkipInputPath = false; spFileInfo.reset(new CFileInfo()); - spFileInfo->SetClipboard(&rTaskDefinition.GetSourcePaths()); // try to get some info about the input path; let user know if the path does not exist. do { bRetry = false; // read attributes of src file/folder - bool bExists = spFileInfo->Create(rTaskDefinition.GetSourcePathAt(stIndex), stIndex); + bool bExists = TLocalFilesystem::GetFileInfo(rTaskDefinition.GetSourcePathAt(stIndex), spFileInfo, stIndex, &rTaskDefinition.GetSourcePaths()); if(!bExists) { FEEDBACK_FILEERROR ferr = { rTaskDefinition.GetSourcePathAt(stIndex).ToString(), NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; @@ -233,9 +232,11 @@ if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { CFileInfoPtr spFileInfo(boost::make_shared()); - spFileInfo->SetClipboard(&rTaskDefinition.GetSourcePaths()); // this is the link table (CClipboardArray) - spFileInfo->Create(&wfd, pathDirName, stSrcIndex); + spFileInfo->Init(pathDirName + chcore::PathFromString(wfd.cFileName), stSrcIndex, &rTaskDefinition.GetSourcePaths(), + wfd.dwFileAttributes, (((ULONGLONG) wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, + wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); + if(afFilters.Match(spFileInfo)) rFilesCache.AddFileInfo(spFileInfo); } @@ -244,10 +245,12 @@ if(bIncludeDirs) { CFileInfoPtr spFileInfo(boost::make_shared()); - spFileInfo->SetClipboard(&rTaskDefinition.GetSourcePaths()); // this is the link table (CClipboardArray) // Add directory itself - spFileInfo->Create(&wfd, pathDirName, stSrcIndex); + spFileInfo->Init(pathDirName + chcore::PathFromString(wfd.cFileName), stSrcIndex, &rTaskDefinition.GetSourcePaths(), + wfd.dwFileAttributes, (((ULONGLONG) wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, + wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); + rFilesCache.AddFileInfo(spFileInfo); } if(bRecurse) Index: src/libchcore/TConfig.h =================================================================== diff -u -ra296360740c0d5a9e84f6be32e1654128d2953bc -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/libchcore/TConfig.h (.../TConfig.h) (revision a296360740c0d5a9e84f6be32e1654128d2953bc) +++ src/libchcore/TConfig.h (.../TConfig.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -108,9 +108,9 @@ // extraction of subtrees bool ExtractSubConfig(PCTSTR pszSubTreeName, TConfig& rSubConfig) const; - bool ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const; + bool ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const; void PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); - void AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); + void AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); // property change notification void ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam); Index: src/libchcore/TPath.cpp =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/libchcore/TPath.cpp (.../TPath.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/libchcore/TPath.cpp (.../TPath.cpp) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -1078,6 +1078,13 @@ return !m_pPath || m_pPath->m_strPath.empty(); } +size_t TSmartPath::GetLength() const +{ + if(!m_pPath) + return 0; + return m_pPath->m_strPath.length(); +} + void TSmartPath::StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const { rConfig.SetValue(pszPropName, m_pPath ? m_pPath->m_strPath : std::wstring()); Index: src/libchcore/TPath.h =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -re30c2b40bd1b533d8740edc88d80b2fb340f3466 --- src/libchcore/TPath.h (.../TPath.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/libchcore/TPath.h (.../TPath.h) (revision e30c2b40bd1b533d8740edc88d80b2fb340f3466) @@ -125,6 +125,7 @@ void StripSeparatorAtFront(); bool IsEmpty() const; + size_t GetLength() const; // Serialization template