// Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu // // Source Code Originally from: // http://support.microsoft.com/kb/814463 // #include "stdafx.h" #include "dirops.h" ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION: RemoveReadOnly // DESCRIPTION: Removes the write protection of a specific file (including full path), // if case the file exists. // // RETURN: TRUE for success, FALSE for failure // ///////////////////////////////////////////////////////////////////////////////////// BOOL RemoveReadOnly(tstring& csFileName) { DWORD dwFileAttributes = GetFileAttributes(csFileName.c_str()); // In case the file does not exist if (dwFileAttributes == -1) return FALSE; dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY; if (SetFileAttributes(csFileName.c_str(), dwFileAttributes) != 0) return TRUE; return FALSE; } ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION: CopyFolder // DESCRIPTION: Copies a directory to a new location // // RETURN: TRUE for success, FALSE for failure // ///////////////////////////////////////////////////////////////////////////////////// BOOL RecursiveCopyFolder(tstring& csPath, tstring& csNewPath) { BOOL bRet = TRUE; if( !CreateDirectory(csNewPath.c_str(), NULL)) bRet = FALSE; tstring csPathMask; tstring csFullPath; tstring csNewFullPath; csPath += _T("\\"); csNewPath += _T("\\"); csPathMask = csPath + _T("*.*"); WIN32_FIND_DATA ffData; HANDLE hFind; hFind = FindFirstFile(csPathMask.c_str(), &ffData); if (hFind == INVALID_HANDLE_VALUE){ return FALSE; } // Copying all the files while (hFind && FindNextFile(hFind, &ffData)) { csFullPath = csPath + ffData.cFileName; csNewFullPath = csNewPath + ffData.cFileName; RemoveReadOnly(csNewFullPath); if( !(ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { if( !CopyFile(csFullPath.c_str(), csNewFullPath.c_str(), FALSE) ) { // Not stopping here, trying to copy the rest of the files bRet = FALSE; } } else // it is a directory -> Copying recursively { if( (_tcscmp(ffData.cFileName, _T(".")) != 0) && (_tcscmp(ffData.cFileName, _T("..")) != 0) ) { if( !RecursiveCopyFolder(csFullPath, csNewFullPath) ) { // Not stopping here, trying to copy the rest of the files bRet = FALSE; } } } } FindClose(hFind); return bRet; } ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION: RecursiveDeleteFolder // DESCRIPTION: Deletes a directory, even if not empty // // RETURN: TRUE for success, FALSE for failure // ///////////////////////////////////////////////////////////////////////////////////// BOOL RecursiveDeleteFolder(tstring& csPath) { BOOL bRet = TRUE; tstring csPathMask; tstring csFullPath; csPath += _T("\\"); csPathMask = csPath + _T("*.*"); WIN32_FIND_DATA ffData; HANDLE hFind; hFind = FindFirstFile(csPathMask.c_str(), &ffData); if (hFind == INVALID_HANDLE_VALUE){ return FALSE; } // Delete all the files while (hFind && FindNextFile(hFind, &ffData)) { csFullPath = csPath + ffData.cFileName; RemoveReadOnly(csFullPath); if( !(ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { if( !DeleteFile(csFullPath.c_str()) ) { // Not stopping here, trying to copy the rest of the files bRet = FALSE; } } else // it is a directory -> Copying recursively { if( (_tcscmp(ffData.cFileName, _T(".")) != 0) && (_tcscmp(ffData.cFileName, _T("..")) != 0) ) { if( !RecursiveDeleteFolder(csFullPath) ) { // Not stopping here, trying to copy the rest of the files bRet = FALSE; } } } } FindClose(hFind); RemoveReadOnly(csPath); if( !RemoveDirectory(csPath.c_str())) bRet = FALSE; return bRet; } ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION: MoveFolder // DESCRIPTION: Moves a directory to a new location // // RETURN: TRUE for success, FALSE for failure // ///////////////////////////////////////////////////////////////////////////////////// BOOL MoveFolder(tstring& csPath, tstring& csNewPath) { BOOL bRet = TRUE; if(!RecursiveCopyFolder(csPath, csNewPath)) bRet = FALSE; if(!RecursiveDeleteFolder(csPath)) bRet = FALSE; return bRet; } ///////////////////////////////////////////////////////////////////////////////////// // FUNCTION: RecursiveSetPermissions // DESCRIPTION: Copies a directory to a new location // // RETURN: TRUE for success, FALSE for failure // ///////////////////////////////////////////////////////////////////////////////////// BOOL RecursiveSetPermissions(tstring& csPath, PACL pACL) { BOOL bRet = TRUE; tstring csPathMask; tstring csFullPath; csPath += _T("\\"); csPathMask = csPath + _T("*.*"); WIN32_FIND_DATA ffData; HANDLE hFind; hFind = FindFirstFile(csPathMask.c_str(), &ffData); if (hFind == INVALID_HANDLE_VALUE){ return FALSE; } // Copying all the files while (hFind && FindNextFile(hFind, &ffData)) { if( (_tcscmp(ffData.cFileName, _T(".")) != 0) && (_tcscmp(ffData.cFileName, _T("..")) != 0) ) { csFullPath = csPath + ffData.cFileName; // Set the ACL on the file. SetNamedSecurityInfo( #ifdef _UNICODE (LPWSTR)csFullPath.c_str(), #else (LPSTR)csFullPath.c_str(), #endif SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pACL, NULL ); if( ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { RecursiveSetPermissions(csFullPath, pACL); } } } FindClose(hFind); return bRet; }