/** Processes the core image file to produce a directory tree. @return KErrNone for successful read or error number if failed */ TInt CCoreImage::ProcessImage() { iRomFileName = iReader->Filename(); int result = CreateRootDir(); if (result == KErrNone) { if (iReader->Open()) { RCoreImageReader::TImageType imageType = iReader->ReadImageType(); if (imageType == RCoreImageReader::E_ROFS) { TRofsHeader header; result = iReader->ReadCoreHeader(header); if (result == KErrNone) { SaveDirInfo(header); result = ProcessDirectory(0); } } else result = KErrNotSupported; } else result = KErrGeneral; } return result; }
void ProcessDirectory(char *szPath) { char szCurPath[MAX_PATH]; intptr_t hFind; __finddata64_t fd; strcpy(szCurPath, szPath); strcat(szCurPath, "\\*.*"); hFind = _findfirst64(szCurPath, &fd); if (hFind == -1) return; do { if (fd.attrib & _A_SUBDIR) { if (strcmp(fd.name, ".") && strcmp(fd.name, "..")) { sprintf(szCurPath, "%s\\%s", szPath, fd.name); ProcessDirectory(szCurPath); } } else { sprintf(szCurPath, "%s\\%s", szPath, fd.name); ProcessFile(szCurPath); } } while (_findnext64(hFind, &fd) != -1); _findclose(hFind); }
void InventoryEngine::ProcessDirectory(const char* name, int level) { DIR* dir = opendir(name); if (dir == NULL) return; struct dirent* entry = readdir(dir); do { char cwpath[PATH_MAX]; int len = snprintf(cwpath, sizeof(cwpath) - 1, "%s/%s", name, entry->d_name); cwpath[len] = 0; if (entry->d_type == DT_DIR) { if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) continue; ProcessDirectory(cwpath, level + 1); } else { char hash[SHA_LENGTH_MAX]; if (!GenerateSHA(cwpath, hash)) { continue; } else { fBaselineStore->Add(cwpath, hash); } } } while (entry = readdir(dir)); }
DWORD CDirWatcher::Run() { int delay = 0; ReadIgnoreList(); for(;;) { if(CNewzflow::Instance()->IsShuttingDown() || WaitForSingleObject(shutDown, 0) == WAIT_OBJECT_0) break; if(delay > 0) { WaitForSingleObject(shutDown, delay * 1000); // either waits until the delay ran out, or we need to shut down delay = 0; continue; } ProcessDirectory(CNewzflow::Instance()->settings->GetWatchDir()); delay = 5; } WriteIgnoreList(); return 0; }
void DeleteRecursive(LPCTSTR target, wregex* ignorePattern) { if (!Utilities::DirectoryExists(target)) { CString message; message.Format(TEXT("Cannot delete directory %s because it does not exist. Proceeding anyway."), target); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); return; } CDeleteAction deleteAction(target); ProcessDirectory(target, deleteAction, TEXT(""), true, ignorePattern); }
/** * Recursively processes directory structure, storing the relative path to each file found. */ void CDiskResource::ProcessDirectory(std::wstring path) { // Determine the package-relative resource path. std::wstring findPath(m_path); if (path.length() > 0) findPath.append(std::wstring(_T("\\"))).append(path); std::wstring search(findPath); search.append(_T("\\*")); WIN32_FIND_DATA fd; HANDLE ff = FindFirstFile(search.c_str(),&fd); if (ff != INVALID_HANDLE_VALUE) { do { if (_tcscmp(fd.cFileName,_T(".")) != 0 && _tcscmp(fd.cFileName,_T("..")) != 0 && _tcscmp(fd.cFileName,_T(".svn")) != 0) { std::wstring foundPath(path); if (foundPath.length() > 0) foundPath.append(_T("\\")).append(fd.cFileName); else foundPath = fd.cFileName; if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { // Recurse into this sub-directory. ProcessDirectory(foundPath); } else { m_files.push_back(foundPath); } } } while (FindNextFile(ff,&fd) != 0); FindClose(ff); } }
INT CommandDelete (LPTSTR param) { /*cmd is the command that was given, in this case it will always be "del" or "delete" param is whatever is given after the command*/ LPTSTR *arg = NULL; INT args; INT i; INT nEvalArgs = 0; /* nunber of evaluated arguments */ DWORD dwFlags = 0; DWORD dwAttrFlags = 0; DWORD dwFiles = 0; LONG ch; TCHAR szOrginalArg[MAX_PATH]; /*checks the first two chars of param to see if it is /? this however allows the following command to not show help "del frog.txt /?" */ if (!StringsLoaded) { LoadStrings(); } if (!_tcsncmp (param, _T("/?"), 2)) { ConOutResPaging(TRUE,STRING_DEL_HELP1); return 0; } nErrorLevel = 0; arg = split (param, &args, FALSE); if (args == 0) { /* only command given */ error_req_param_missing (); freep (arg); return 1; } /* check for options anywhere in command line */ for (i = 0; i < args; i++) { if (*arg[i] == _T('/')) { /*found a command, but check to make sure it has something after it*/ if (_tcslen (arg[i]) >= 2) { ch = _totupper (arg[i][1]); if (ch == _T('N')) { dwFlags |= DEL_NOTHING; } else if (ch == _T('P')) { dwFlags |= DEL_PROMPT; } else if (ch == _T('Q')) { dwFlags |= DEL_QUIET; } else if (ch == _T('F')) { dwFlags |= DEL_FORCE; } else if (ch == _T('S')) { dwFlags |= DEL_SUBDIR; } else if (ch == _T('T')) { dwFlags |= DEL_TOTAL; } else if (ch == _T('W')) { dwFlags |= DEL_WIPE; } else if (ch == _T('Y')) { dwFlags |= DEL_YES; } else if (ch == _T('A')) { dwFlags |= DEL_ATTRIBUTES; /*the proper syntax for /A has a min of 4 chars i.e. /A:R or /A:-H */ if (_tcslen (arg[i]) < 4) { error_invalid_parameter_format(arg[i]); return 0; } ch = _totupper (arg[i][3]); if (_tcslen (arg[i]) == 4) { if(ch == _T('A')) { dwAttrFlags |= ATTR_ARCHIVE; } if(ch == _T('H')) { dwAttrFlags |= ATTR_HIDDEN; } if(ch == _T('S')) { dwAttrFlags |= ATTR_SYSTEM; } if(ch == _T('R')) { dwAttrFlags |= ATTR_READ_ONLY; } } if (_tcslen (arg[i]) == 5) { if(ch == _T('-')) { ch = _totupper (arg[i][4]); if(ch == _T('A')) { dwAttrFlags |= ATTR_N_ARCHIVE; } if(ch == _T('H')) { dwAttrFlags |= ATTR_N_HIDDEN; } if(ch == _T('S')) { dwAttrFlags |= ATTR_N_SYSTEM; } if(ch == _T('R')) { dwAttrFlags |= ATTR_N_READ_ONLY; } } } } } nEvalArgs++; } } /* there are only options on the command line --> error!!! there is the same number of args as there is flags, so none of the args were filenames*/ if (args == nEvalArgs) { error_req_param_missing (); freep (arg); return 1; } /* keep quiet within batch files */ if (bc != NULL) dwFlags |= DEL_QUIET; /* check for filenames anywhere in command line */ for (i = 0; i < args && !(dwFiles & 0x80000000); i++) { /*this checks to see if it isnt a flag, if it isnt, we assume it is a file name*/ if((*arg[i] == _T('/')) || (*arg[i] == _T('-'))) continue; /* We want to make a copies of the argument */ if(_tcslen(arg[i]) == 2 && arg[i][1] == _T(':')) { /* Check for C: D: ... */ GetRootPath(arg[i],szOrginalArg,MAX_PATH); } else { _tcscpy(szOrginalArg,arg[i]); } dwFiles += ProcessDirectory(szOrginalArg, &dwFlags, dwAttrFlags); } freep (arg); /*Based on MS cmd, we only tell what files are being deleted when /S is used */ if (dwFlags & DEL_TOTAL) { dwFiles &= 0x7fffffff; if (dwFiles < 2) { ConOutResPrintf(STRING_DEL_HELP3, dwFiles); } else { ConOutResPrintf(STRING_DEL_HELP4, dwFiles); } } return 0; }
static DWORD ProcessDirectory(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags) { TCHAR szFullPath[MAX_PATH]; LPTSTR pFilePart; LPTSTR pSearchPart; HANDLE hFile; WIN32_FIND_DATA f; DWORD dwFiles = 0; GetFullPathName (FileName, MAX_PATH, szFullPath, &pFilePart); dwFiles = DeleteFiles(szFullPath, dwFlags, dwAttrFlags); if (dwFiles & 0x80000000) return dwFiles; if (*dwFlags & DEL_SUBDIR) { /* Get just the file name */ pSearchPart = _tcsrchr(FileName,_T('\\')); if(pSearchPart != NULL) pSearchPart++; else pSearchPart = FileName; /* Get the full path to the file */ GetFullPathName (FileName,MAX_PATH,szFullPath,NULL); /* strip the filename off of it */ pFilePart = _tcsrchr(szFullPath, _T('\\')); if (pFilePart == NULL) { pFilePart = szFullPath; } else { pFilePart++; } _tcscpy(pFilePart, _T("*")); hFile = FindFirstFile(szFullPath, &f); if (hFile != INVALID_HANDLE_VALUE) { do { if (!(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !_tcscmp(f.cFileName, _T(".")) || !_tcscmp(f.cFileName, _T(".."))) continue; _tcscpy(pFilePart, f.cFileName); _tcscat(pFilePart, _T("\\")); _tcscat(pFilePart, pSearchPart); dwFiles +=ProcessDirectory(szFullPath, dwFlags, dwAttrFlags); if (dwFiles & 0x80000000) { break; } } while (FindNextFile (hFile, &f)); FindClose (hFile); } } return dwFiles; }
//-------------------------------------------------------------------- // // ProcessDirectory // // Recursive routine that passes files to the delete function. // //-------------------------------------------------------------------- void ProcessDirectory( TCHAR *PathName, TCHAR *SearchPattern ) { TCHAR subName[MAX_PATH], fileSearchName[MAX_PATH], searchName[MAX_PATH]; HANDLE dirHandle, patternHandle; static BOOLEAN firstCall = TRUE; static BOOLEAN deleteDirectories = FALSE; WIN32_FIND_DATA foundFile; // // Scan the files and/or directories if this is a directory // if( firstCall ) { if( _tcsrchr( PathName, '*' ) ) { if( _tcsrchr( PathName, '\\' ) ) { _stprintf( SearchPattern, _tcsrchr( PathName, '\\' )+1 ); _tcscpy( searchName, PathName ); _tcscpy( _tcsrchr( searchName, '\\')+1, _T("*.*") ); if( !_tcscmp( SearchPattern, _T("*.*")) || !_tcscmp( SearchPattern, _T("*"))) { deleteDirectories = TRUE; } } else { _stprintf( SearchPattern, PathName ); _tcscpy( searchName, PathName ); } _stprintf( fileSearchName, _T("%s"), PathName ); } else { _stprintf( SearchPattern, _T("*.*") ); _stprintf( searchName, _T("%s"), PathName ); _stprintf( fileSearchName, _T("%s"), PathName ); deleteDirectories = TRUE; } } else { _stprintf( searchName, _T("%s\\*.*"), PathName ); _stprintf( fileSearchName, _T("%s\\%s"), PathName, SearchPattern ); } // // Process all the files, according to the search pattern // if( (patternHandle = FindFirstFile( fileSearchName, &foundFile )) != INVALID_HANDLE_VALUE ) { do { if( _tcscmp( foundFile.cFileName, _T(".") ) && _tcscmp( foundFile.cFileName, _T("..") )) { _tcscpy( subName, searchName ); if( _tcsrchr( subName, '\\' ) ) _tcscpy( _tcsrchr( subName, '\\')+1, foundFile.cFileName ); else _tcscpy( subName, foundFile.cFileName ); // // Do this file/directory // ProcessFile( &foundFile, subName ); } } while( FindNextFile( patternHandle, &foundFile )); FindClose( patternHandle ); } // // Now recurse if we're supposed to // if( Recurse ) { if( firstCall && !_tcsrchr( searchName, L'\\') ) { if( _tcsrchr( searchName, L'*' )) { if( (dirHandle = FindFirstFile( _T("*.*"), &foundFile )) == INVALID_HANDLE_VALUE ) { // // Nothing to process // return; } } else { if( (dirHandle = FindFirstFile( searchName, &foundFile )) == INVALID_HANDLE_VALUE ) { // // Nothing to process // return; } } } else { if( (dirHandle = FindFirstFile( searchName, &foundFile )) == INVALID_HANDLE_VALUE ) { // // Nothing to process // return; } } firstCall = FALSE; do { if( (foundFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && _tcscmp( foundFile.cFileName, _T(".") ) && _tcscmp( foundFile.cFileName, _T("..") )) { _tcscpy( subName, searchName ); if( _tcsrchr( subName, '\\' ) ) _tcscpy( _tcsrchr( subName, '\\')+1, foundFile.cFileName ); else _tcscpy( subName, foundFile.cFileName ); // // Go into this directory // ProcessDirectory( subName, SearchPattern ); // // Delete the directory if we're supposed to // if( deleteDirectories ) { if( !RemoveDirectory( subName )) { _tprintf( _T("\nError deleting %s: "), subName ); PrintWin32Error( GetLastError() ); } } } } while( FindNextFile( dirHandle, &foundFile )); FindClose( dirHandle ); } }
//-------------------------------------------------------------------- // // Main // // Runs the show. // //-------------------------------------------------------------------- int _tmain( int argc, TCHAR *argv[] ) { TCHAR searchPattern[MAX_PATH]; TCHAR searchPath[MAX_PATH]; PTCHAR filePart; BOOL foundFileArg = FALSE; int i; // // Print banner and perform parameter check // _tprintf(_T("\nSDelete - Secure Delete v1.51\n") ); _tprintf(_T("Copyright (C) 1999-2005 Mark Russinovich\n")); _tprintf(_T("Sysinternals - www.sysinternals.com\n\n")); if( argc < 2 ) { return Usage( argv[0] ); } for( i = 1; i < argc; i++ ) { if( !_tcsicmp( argv[i], _T("/s") ) || !_tcsicmp( argv[i], _T("-s") )) { Recurse = TRUE; } else if( !_tcsicmp( argv[i], _T("/q") ) || !_tcsicmp( argv[i], _T("-q") )) { Silent = TRUE; } else if( !_tcsicmp( argv[i], _T("/z") ) || !_tcsicmp( argv[i], _T("-z") )) { ZapFreeSpace = TRUE; } else if( !_tcsicmp( argv[i], _T("/c") ) || !_tcsicmp( argv[i], _T("-c") )) { ZapFreeSpace = TRUE; ZeroFreeSpace = TRUE; } else if( !_tcsicmp( argv[i], _T("/p") ) || !_tcsicmp( argv[i], _T("-p") )) { NumPasses = argc > i ? atoi( argv[i+1] ) : 1; if( !NumPasses ) return Usage( argv[0] ); i++; } else if( !_tcsicmp( argv[i], _T("/?") ) || !_tcsicmp( argv[i], _T("-?") )) { return Usage( argv[0] ); } else { if( foundFileArg ) return Usage( argv[0] ); foundFileArg = TRUE; } } // // Have to have file if not zapping free space // if( !ZapFreeSpace && !foundFileArg ) { return Usage( argv[0] ); } // // Locate Native entry points we need // LocateNativeEntryPoints(); if( foundFileArg ) { // // Get canonical path name // GetFullPathName( argv[argc-1], MAX_PATH, searchPath, &filePart ); } printf("SDelete is set for %d pass%s.\n", NumPasses, NumPasses > 1 ? "es" : ""); // // Do the deleting // if( !ZapFreeSpace ) { // // Now go and process directories // ProcessDirectory( searchPath, searchPattern ); if( !FilesFound ) _tprintf(_T("No files found that match %s.\n"), argv[argc-1] ); } else if( !foundFileArg ) { GetCurrentDirectory( MAX_PATH, searchPath ); } // // If we encountered a compressed file along the way, and we couldn't directly // zap its on-disk clusters then we have to clean all the free space. // if( CleanCompressedFiles || ZapFreeSpace ) { CleanFreeSpace( searchPath ); } _tprintf(_T("\n")); return 0; }
ForceInline void main2(int argc, char **argv) { if (argc < 2) return; char *path; intptr_t hFind; __finddata64_t fd; iBufferSize = 0x3000; gpbBuffer = (uchar *)malloc(iBufferSize); for (int i = 1; i != argc; ++i) { hFind = _findfirst64(argv[i], &fd); if (hFind == -1) continue; do { path = findpath(argv[i]); if (path) *path = 0; if (fd.attrib & _A_SUBDIR) { if (strcmp(fd.name, ".") && strcmp(fd.name, "..")) { int j; if (path) { j = strlen(argv[i]); strcpy(&fd.name[j + 1], fd.name); strcpy(fd.name, argv[i]); fd.name[j] = '\\'; } ProcessDirectory(fd.name); if (path) *path = '\\'; } } else { int j; if (path) { j = strlen(argv[i]); strcpy(&fd.name[j + 1], fd.name); strcpy(fd.name, argv[i]); fd.name[j] = '\\'; } ProcessFile(fd.name); } if (path) *path = '\\'; } while (_findnext64(hFind, &fd) != -1); } _findclose(hFind); free(gpbBuffer); }
void InventoryEngine::Baseline() { ProcessDirectory("/etc", 0); }
CDiskResource::CDiskResource(std::wstring path) : CPackageResource(path) { ProcessDirectory(_T("")); }
////////////////////////////////////////////////////////////////////// // feature_Factory::Create() // \author Logan Jones ////////////////////////////// \date 2/12/2002 // //==================================================================== // Parameters: // BYTE* pTntFileBuffer - // LPTSTR strWorld - // game_Main::LoadGameStruct Load - // // Return: BOOL - // BOOL feature_Factory::Create( BYTE* pTntFileBuffer, LPTSTR strWorld, game_LoadFacilitator Load ) { app_FileTree::HFIND hList; app_FileTree::FindData_t ListInfo; app_FileTree::HFIND hFind; app_FileTree::FindData_t FindInfo; BOOL bWorkingFeatureFolders; BOOL bWorkingFeatureFiles; char SubDirectoryToSearch[128]; LPTA_TNT_HEADER pHeader; LPTA_TNT_EXT_HEADER pMapHeader; DWORD count; TA_TNT_FEATURE_ENTRY* pFeatureToLoad; int CurrentProgress; if( bFAILED( AddHardcodedFeatureTypes() ) ) { return FALSE; } // Initialize some loading members m_LoadPass = -1; m_CurrentAnimFile = NULL; m_CurrentAnimFileName[0] = '\0'; // TODO: Add unit feature stuff (corpses, etc...) to the list pHeader = (LPTA_TNT_HEADER)pTntFileBuffer; pMapHeader = (LPTA_TNT_EXT_HEADER)(pTntFileBuffer + sizeof(TA_TNT_HEADER)); // Add the features from the map to the list pFeatureToLoad = (TA_TNT_FEATURE_ENTRY*)(pTntFileBuffer + pMapHeader->OffsetToFeatureEntryArray); for( count=pMapHeader->NumberOfFeatures; count>0; --count, ++pFeatureToLoad) AddToLoadList( pFeatureToLoad->Name, 0 ); // Precheck features in the all worlds folder to speed loading theApp.Console.Comment( CT_LOAD, "Processing features/all worlds" ); for( m_NewFeatureAdded=TRUE; m_NewFeatureAdded; ) { m_NewFeatureAdded = FALSE; ProcessDirectory( "all worlds", Load ); } Load.Progress( 10 ); // Precheck features in the specific world folder to speed loading if( strWorld[0]!='\0' ) { theApp.Console.Comment( CT_LOAD, "Processing features/%s", strWorld ); for( m_NewFeatureAdded=TRUE; m_NewFeatureAdded; ) { m_NewFeatureAdded = FALSE; ProcessDirectory( strWorld, Load ); } } Load.Progress( 20 ); // If there are any features left to load, look through all the other subdirectories for( m_LoadPass=0,CurrentProgress=20; !m_FeaturesToLoad.empty(); ++m_LoadPass ) { // Check if we need to check for unfound features if( m_LoadPass>0 ) { FeatureToLoadList_t::iterator e,it = m_FeaturesToLoad.begin(); FeatureToLoadList_t::const_iterator end= m_FeaturesToLoad.end(); for( ; it!=end; ) { if( (*it).second.SearchAdded<m_LoadPass ) { theApp.Console.Comment( CT_LOAD, "Could not find feature \"%s\"", (*it).second.Name ); m_FeaturesToLoad.erase( e=it++ ); } else ++it; } if( m_FeaturesToLoad.empty() ) break; } // end if( m_LoadPass > 0 ) // Search all subdirectories ind 'features' hList = theFileTree.Find( app_FileTree::DIRECTORIES, NULL, "features", &ListInfo ); bWorkingFeatureFolders = hList!=NULL; while( bWorkingFeatureFolders ) { // Make sure this is a directory if( ListInfo.bIsFile==FALSE ) { theApp.Console.Comment( CT_LOAD, "Processing features/%s", ListInfo.Name ); // Search all tdf files in this subdirectory sprintf( SubDirectoryToSearch, "features/%s", ListInfo.Name ); hFind = theFileTree.Find( app_FileTree::FILES_WITH_EXTENSIONS, "tdf", SubDirectoryToSearch, &FindInfo ); bWorkingFeatureFiles = hFind!=NULL; while( bWorkingFeatureFiles ) { //theApp.Console.Comment( CT_LOAD, "Processing features/%s/%s", ListInfo.ItemName, FindInfo.Name ); ProcessTDF( FindInfo.hFile, ListInfo.Name, FindInfo.Name, Load ); // Check if there is anything else to load if( m_FeaturesToLoad.empty() ) break; // Find next file bWorkingFeatureFiles = theFileTree.ContinueFind( hFind, &FindInfo ); } // end while( tdf files ) theFileTree.CloseFind( hFind ); } // end if( IsDirectory ) // Check if there is anything else to load if( m_FeaturesToLoad.empty() ) break; // Find next subdirectory bWorkingFeatureFolders = theFileTree.ContinueFind( hList, &ListInfo ); } // end while( subdirectories ) theFileTree.CloseFind( hList ); } // end while( there are still features to load ) // Clean up some loading members SAFE_DELETE_ARRAY( m_CurrentAnimFile ); theApp.Console.Comment( CT_LOAD, "Placing features on the terrain..." ); Load.Progress( 90 ); // Spawn all the features on the map pFeatureToLoad = (TA_TNT_FEATURE_ENTRY*)(pTntFileBuffer + pMapHeader->OffsetToFeatureEntryArray); LPTA_TNT_MAP_ENTRY pMapStuff = (LPTA_TNT_MAP_ENTRY)(pTntFileBuffer + pMapHeader->OffsetToMapInfoArray); for( DWORD y=0; y<pHeader->Height-1; ++y,pMapStuff+=pHeader->Width) for( DWORD x=0; x<pHeader->Width-1; ++x) if( pMapStuff[x].Special>=0 ) SpawnFeature( pFeatureToLoad[pMapStuff[x].Special].Name, x * 16, y * 16, pMapStuff[x].Elevation ); Load.Progress( 100 ); return TRUE; }
void ProcessDirectory(LPCTSTR srcbase, CDirectoryAction& action, LPCTSTR directory, bool recursive, wregex* ignorePattern) { WIN32_FIND_DATA findData; HANDLE hFindHandle; CString srcdir; Utilities::CombinePath(srcbase, directory, srcdir); if (!ShouldProcess(ignorePattern, srcdir)) { return; } action.VisitDirectoryInitial(directory); CString pattern; Utilities::CombinePath(srcdir, TEXT("*"), pattern); Utilities::FixLongFilenames(pattern); hFindHandle = ::FindFirstFile(pattern, &findData); if (hFindHandle != INVALID_HANDLE_VALUE) { BOOL done = false; while (!done) { if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { if (recursive) { if (Utilities::AreEqual(findData.cFileName, L".") || Utilities::AreEqual(findData.cFileName, L"..")) { // Do nothing } else { CString subdirectory; Utilities::CombinePath(directory, findData.cFileName, subdirectory); if (!ShouldProcess(ignorePattern, srcbase, subdirectory)) { continue; } ProcessDirectory(srcbase, action, subdirectory, recursive, ignorePattern); } } } else { CString file; Utilities::CombinePath(directory, findData.cFileName, file); if (!ShouldProcess(ignorePattern, srcbase, file)) continue; action.VisitFile(file); } BOOL worked = ::FindNextFile(hFindHandle, &findData); if (!worked) { int error = GetLastError(); if (error == ERROR_NO_MORE_FILES) { done = true; } else { CString errorMessage; Utilities::FormatErrorMessage(error, errorMessage); CString message; message.AppendFormat(TEXT("There was an error calling FindNextFile. Path: %s Error: %s"), pattern, errorMessage); throw new CVSSCopyException(message.GetString()); } } } } else { int error = GetLastError(); if (error != ERROR_FILE_NOT_FOUND) { CString errorMessage; Utilities::FormatErrorMessage(error, errorMessage); CString message; message.AppendFormat(TEXT("There was an error calling FindFirstFile. Path: %s Error: %s"), pattern, errorMessage); throw new CVSSCopyException(message.GetString()); } } ::FindClose(hFindHandle); // Important to put this after FindClose, since otherwise there's still an // open handle to the directory, and that can interfere with (e.g.) directory // deletion action.VisitDirectoryFinal(directory); }
void startBackup(COptions options) { GUID snapshotSetId = GUID_NULL; bool bSnapshotCreated = false; bool bAbnormalAbort = true; CComPtr<IVssBackupComponents> pBackupComponents; int fileCount = 0; LONGLONG byteCount = 0; int directoryCount = 0; int skipCount = 0; SYSTEMTIME startTime; try { OutputWriter::SetVerbosityLevel((VERBOSITY_LEVEL)options.get_VerbosityLevel()); //for (int i = 0; i < argc; ++i) //{ // CString message; // message.AppendFormat(TEXT("Argument %d: %s"), i, argv[i]); // OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_IF_VERBOSE); //} OutputWriter::WriteLine(TEXT("Calling CoInitialize")); CHECK_HRESULT(::CoInitialize(NULL)); CHECK_HRESULT( ::CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL)); ::GetSystemTime(&startTime); CString startTimeString; Utilities::FormatDateTime(&startTime, TEXT(" "), false, startTimeString); CString message; message.AppendFormat(TEXT("Starting a %s copy from %s to %s"), options.get_BackupType() == VSS_BT_FULL ? TEXT("full") : TEXT("incremental"), options.get_Source(), options.get_Destination()); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); if (options.get_ClearDestination()) { if (!Utilities::DirectoryExists(options.get_Destination())) { CString message; message.AppendFormat(TEXT("Skipping recursive delete of destination directory %s because it appears not to exist."), options.get_Destination()); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); } else { CString message; message.AppendFormat(TEXT("Recursively deleting destination directory %s."), options.get_Destination()); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); bool doDelete = options.get_AcceptAll(); if (!doDelete) { if (Confirm(message)) { doDelete = true; } else { OutputWriter::WriteLine(TEXT("Aborting backup."), VERBOSITY_THRESHOLD_NORMAL); return; } } if (doDelete) { DeleteRecursive(options.get_Destination(), options.get_IgnorePattern()); } } } CBackupState backupState; LPSYSTEMTIME lastBackupTime; if (options.get_BackupType() == VSS_BT_INCREMENTAL) { backupState.Load(options.get_StateFile()); LPSYSTEMTIME lastFullBackupTime = backupState.get_LastFullBackupTime(); LPSYSTEMTIME lastIncrementalBackupTime = backupState.get_LastIncrementalBackupTime(); if (lastIncrementalBackupTime != NULL) { lastBackupTime = lastIncrementalBackupTime; } else { lastBackupTime = lastFullBackupTime; } } OutputWriter::WriteLine(TEXT("Calling CreateVssBackupComponents")); CHECK_HRESULT(::CreateVssBackupComponents(&pBackupComponents)); OutputWriter::WriteLine(TEXT("Calling InitializeForBackup")); CHECK_HRESULT(pBackupComponents->InitializeForBackup()); CComPtr<IVssAsync> pWriterMetadataStatus; OutputWriter::WriteLine(TEXT("Calling GatherWriterMetadata")); CHECK_HRESULT(pBackupComponents->GatherWriterMetadata(&pWriterMetadataStatus)); OutputWriter::WriteLine(TEXT("Waiting for call to GatherWriterMetadata to finish...")); CHECK_HRESULT(pWriterMetadataStatus->Wait()); HRESULT hrGatherStatus; OutputWriter::WriteLine(TEXT("Calling QueryStatus for GatherWriterMetadata")); CHECK_HRESULT(pWriterMetadataStatus->QueryStatus(&hrGatherStatus, NULL)); if (hrGatherStatus == VSS_S_ASYNC_CANCELLED) { throw new CVSSCopyException(L"GatherWriterMetadata was cancelled."); } OutputWriter::WriteLine(TEXT("Call to GatherWriterMetadata finished.")); OutputWriter::WriteLine(TEXT("Calling GetWriterMetadataCount")); vector<CWriter> writers; UINT cWriters; CHECK_HRESULT(pBackupComponents->GetWriterMetadataCount(&cWriters)); for (UINT iWriter = 0; iWriter < cWriters; ++iWriter) { CWriter writer; CComPtr<IVssExamineWriterMetadata> pExamineWriterMetadata; GUID id; OutputWriter::WriteLine(TEXT("Calling GetWriterMetadata")); CHECK_HRESULT(pBackupComponents->GetWriterMetadata(iWriter, &id, &pExamineWriterMetadata)); GUID idInstance; GUID idWriter; BSTR bstrWriterName; VSS_USAGE_TYPE usage; VSS_SOURCE_TYPE source; CHECK_HRESULT(pExamineWriterMetadata->GetIdentity(&idInstance, &idWriter, &bstrWriterName, &usage, &source)); writer.set_InstanceId(idInstance); writer.set_Name(bstrWriterName); writer.set_WriterId(idWriter); CComBSTR writerName(bstrWriterName); CString message; message.AppendFormat(TEXT("Writer %d named %s"), iWriter, (LPCTSTR)writerName); OutputWriter::WriteLine(message); UINT cIncludeFiles; UINT cExcludeFiles; UINT cComponents; CHECK_HRESULT(pExamineWriterMetadata->GetFileCounts(&cIncludeFiles, &cExcludeFiles, &cComponents)); message.Empty(); message.AppendFormat(TEXT("Writer has %d components"), cComponents); OutputWriter::WriteLine(message); for (UINT iComponent = 0; iComponent < cComponents; ++iComponent) { CWriterComponent component; CComPtr<IVssWMComponent> pComponent; CHECK_HRESULT(pExamineWriterMetadata->GetComponent(iComponent, &pComponent)); PVSSCOMPONENTINFO pComponentInfo; CHECK_HRESULT(pComponent->GetComponentInfo(&pComponentInfo)); CString message; message.AppendFormat(TEXT("Component %d is named %s, has a path of %s, and is %sselectable for backup. %d files, %d databases, %d log files."), iComponent, pComponentInfo->bstrComponentName, pComponentInfo->bstrLogicalPath, pComponentInfo->bSelectable ? TEXT("") : TEXT("not "), pComponentInfo->cFileCount, pComponentInfo->cDatabases, pComponentInfo->cLogFiles); OutputWriter::WriteLine(message); component.set_LogicalPath(pComponentInfo->bstrLogicalPath); component.set_SelectableForBackup(pComponentInfo->bSelectable); component.set_Writer(iWriter); component.set_Name(pComponentInfo->bstrComponentName); component.set_Type(pComponentInfo->type); for (UINT iFile = 0; iFile < pComponentInfo->cFileCount; ++iFile) { CComPtr<IVssWMFiledesc> pFileDesc; CHECK_HRESULT(pComponent->GetFile(iFile, &pFileDesc)); CComBSTR bstrPath; CHECK_HRESULT(pFileDesc->GetPath(&bstrPath)); CComBSTR bstrFileSpec; CHECK_HRESULT(pFileDesc->GetFilespec(&bstrFileSpec)); CString message; message.AppendFormat(TEXT("File %d has path %s\\%s"), iFile, bstrPath, bstrFileSpec); OutputWriter::WriteLine(message); } for (UINT iDatabase = 0; iDatabase < pComponentInfo->cDatabases; ++iDatabase) { CComPtr<IVssWMFiledesc> pFileDesc; CHECK_HRESULT(pComponent->GetDatabaseFile(iDatabase, &pFileDesc)); CComBSTR bstrPath; CHECK_HRESULT(pFileDesc->GetPath(&bstrPath)); CComBSTR bstrFileSpec; CHECK_HRESULT(pFileDesc->GetFilespec(&bstrFileSpec)); CString message; message.AppendFormat(TEXT("Database file %d has path %s\\%s"), iDatabase, bstrPath, bstrFileSpec); OutputWriter::WriteLine(message); } for (UINT iDatabaseLogFile = 0; iDatabaseLogFile < pComponentInfo->cLogFiles; ++iDatabaseLogFile) { CComPtr<IVssWMFiledesc> pFileDesc; CHECK_HRESULT(pComponent->GetDatabaseLogFile(iDatabaseLogFile, &pFileDesc)); CComBSTR bstrPath; CHECK_HRESULT(pFileDesc->GetPath(&bstrPath)); CComBSTR bstrFileSpec; CHECK_HRESULT(pFileDesc->GetFilespec(&bstrFileSpec)); CString message; message.AppendFormat(TEXT("Database log file %d has path %s\\%s"), iDatabaseLogFile, bstrPath, bstrFileSpec); OutputWriter::WriteLine(message); } CHECK_HRESULT(pComponent->FreeComponentInfo(pComponentInfo)); writer.get_Components().push_back(component); } writer.ComputeComponentTree(); for (unsigned int iComponent = 0; iComponent < writer.get_Components().size(); ++iComponent) { CWriterComponent& component = writer.get_Components()[iComponent]; CString message; message.AppendFormat(TEXT("Component %d has name %s, path %s, is %sselectable for backup, and has parent %s"), iComponent, component.get_Name(), component.get_LogicalPath(), component.get_SelectableForBackup() ? TEXT("") : TEXT("not "), component.get_Parent() == NULL ? TEXT("(no parent)") : component.get_Parent()->get_Name()); OutputWriter::WriteLine(message); } writers.push_back(writer); } OutputWriter::WriteLine(TEXT("Calling StartSnapshotSet")); CHECK_HRESULT(pBackupComponents->StartSnapshotSet(&snapshotSetId)); OutputWriter::WriteLine(TEXT("Calling GetVolumePathName")); WCHAR wszVolumePathName[MAX_PATH]; BOOL bWorked = ::GetVolumePathName(options.get_Source(), wszVolumePathName, MAX_PATH); if (!bWorked) { DWORD error = ::GetLastError(); CString errorMessage; Utilities::FormatErrorMessage(error, errorMessage); CString message; message.AppendFormat(TEXT("There was an error retrieving the volume name from the path. Path: %s Error: %s"), options.get_Source(), errorMessage); throw new CVSSCopyException(message.GetString()); } OutputWriter::WriteLine(TEXT("Calling AddToSnapshotSet")); GUID snapshotId; CHECK_HRESULT(pBackupComponents->AddToSnapshotSet(wszVolumePathName, GUID_NULL, &snapshotId)); for (unsigned int iWriter = 0; iWriter < writers.size(); ++iWriter) { CWriter writer = writers[iWriter]; CString message; message.AppendFormat(TEXT("Adding components to snapshot set for writer %s"), writer.get_Name()); OutputWriter::WriteLine(message); for (unsigned int iComponent = 0; iComponent < writer.get_Components().size(); ++iComponent) { CWriterComponent component = writer.get_Components()[iComponent]; if (ShouldAddComponent(component)) { CString message; message.AppendFormat(TEXT("Adding component %s (%s) from writer %s"), component.get_Name(), component.get_LogicalPath(), writer.get_Name()); OutputWriter::WriteLine(message); CHECK_HRESULT(pBackupComponents->AddComponent( writer.get_InstanceId(), writer.get_WriterId(), component.get_Type(), component.get_LogicalPath(), component.get_Name() )); } else { CString message; message.AppendFormat(TEXT("Not adding component %s from writer %s."), component.get_Name(), writer.get_Name()); OutputWriter::WriteLine(message); } } } OutputWriter::WriteLine(TEXT("Calling SetBackupState")); // Issue #29: trying to figure out if using VSS_BT_INCREMENTAL causes a problem CHECK_HRESULT(pBackupComponents->SetBackupState(TRUE, FALSE, VSS_BT_FULL, FALSE)); OutputWriter::WriteLine(TEXT("Calling PrepareForBackup")); CComPtr<IVssAsync> pPrepareForBackupResults; CHECK_HRESULT(pBackupComponents->PrepareForBackup(&pPrepareForBackupResults)); OutputWriter::WriteLine(TEXT("Waiting for call to PrepareForBackup to finish...")); CHECK_HRESULT(pPrepareForBackupResults->Wait()); HRESULT hrPrepareForBackupResults; CHECK_HRESULT(pPrepareForBackupResults->QueryStatus(&hrPrepareForBackupResults, NULL)); if (hrPrepareForBackupResults != VSS_S_ASYNC_FINISHED) { throw new CVSSCopyException(TEXT("Prepare for backup failed.")); } OutputWriter::WriteLine(TEXT("Call to PrepareForBackup finished.")); SYSTEMTIME snapshotTime; ::GetSystemTime(&snapshotTime); bWorked = ::SetConsoleCtrlHandler(CtrlHandler, TRUE); if (!bWorked) { OutputWriter::WriteLine(TEXT("Unable to set control handler. Ctrl-C and Ctrl-Break may have undesirable results."), VERBOSITY_THRESHOLD_NORMAL); } if (!options.get_Simulate()) { OutputWriter::WriteLine(TEXT("Calling DoSnapshotSet")); CComPtr<IVssAsync> pDoSnapshotSetResults; CHECK_HRESULT(pBackupComponents->DoSnapshotSet(&pDoSnapshotSetResults)); OutputWriter::WriteLine(TEXT("Waiting for call to DoSnapshotSet to finish...")); CHECK_HRESULT(pDoSnapshotSetResults->Wait()); bSnapshotCreated = true; if (s_cancel) { throw new CVSSCopyException(TEXT("Processing was cancelled by control-c, control-break, or a shutdown event. Terminating.")); } bWorked = ::SetConsoleCtrlHandler(CtrlHandler, FALSE); if (!bWorked) { OutputWriter::WriteLine(TEXT("Unable to reset control handler. Ctrl-C and Ctrl-Break may have undesirable results."), VERBOSITY_THRESHOLD_NORMAL); } HRESULT hrDoSnapshotSetResults; CHECK_HRESULT(pDoSnapshotSetResults->QueryStatus(&hrDoSnapshotSetResults, NULL)); if (hrDoSnapshotSetResults != VSS_S_ASYNC_FINISHED) { throw new CVSSCopyException(L"DoSnapshotSet failed."); } OutputWriter::WriteLine(TEXT("Call to DoSnapshotSet finished.")); OutputWriter::WriteLine(TEXT("Calling GetSnapshotProperties")); VSS_SNAPSHOT_PROP snapshotProperties; CHECK_HRESULT(pBackupComponents->GetSnapshotProperties(snapshotId, &snapshotProperties)); OutputWriter::WriteLine(TEXT("Calling CalculateSourcePath")); // TODO: We'll eventually have to deal with mount points CString wszSource; CalculateSourcePath( snapshotProperties.m_pwszSnapshotDeviceObject, options.get_Source(), wszVolumePathName, wszSource ); message.Empty(); message.AppendFormat(TEXT("Recursively creating destination directory %s."), options.get_Destination()); OutputWriter::WriteLine(message); Utilities::CreateDirectory(options.get_Destination()); OutputWriter::WriteLine(TEXT("Calling CopyRecursive")); vector<CCopyFilter*> filters; if (options.get_BackupType() == VSS_BT_FULL) { filters.push_back(new CIncludeAllCopyFilter()); } else if (options.get_BackupType() == VSS_BT_INCREMENTAL) { filters.push_back(new CModifiedSinceCopyFilter(lastBackupTime, options.get_SkipDenied())); } filters.push_back(new CFilespecCopyFilter(options.get_Filespecs())); CCopyAction copyAction(wszSource, options.get_Destination(), options.get_SkipDenied(), filters); ProcessDirectory(wszSource, copyAction, TEXT(""), options.get_Recursive(), options.get_IgnorePattern()); for (unsigned int iFilter = 0; iFilter < filters.size(); ++iFilter) { delete filters[iFilter]; } fileCount = copyAction.get_FileCount(); directoryCount = copyAction.get_DirectoryCount(); skipCount = copyAction.get_SkipCount(); byteCount = copyAction.get_ByteCount(); OutputWriter::WriteLine(TEXT("Calling BackupComplete")); CComPtr<IVssAsync> pBackupCompleteResults; CHECK_HRESULT(pBackupComponents->BackupComplete(&pBackupCompleteResults)); OutputWriter::WriteLine(TEXT("Waiting for call to BackupComplete to finish...")); CHECK_HRESULT(pBackupCompleteResults->Wait()); HRESULT hrBackupCompleteResults; CHECK_HRESULT(pBackupCompleteResults->QueryStatus(&hrBackupCompleteResults, NULL)); if (hrBackupCompleteResults != VSS_S_ASYNC_FINISHED) { throw new CVSSCopyException(TEXT("Completion of backup failed.")); } OutputWriter::WriteLine(TEXT("Call to BackupComplete finished.")); bAbnormalAbort = false; if (options.get_StateFile() != NULL) { OutputWriter::WriteLine(TEXT("Calling SaveAsXML")); CComBSTR bstrBackupDocument; CHECK_HRESULT(pBackupComponents->SaveAsXML(&bstrBackupDocument)); if (options.get_BackupType() == VSS_BT_FULL) { backupState.set_LastFullBackupTime(&snapshotTime); } else if (options.get_BackupType() == VSS_BT_INCREMENTAL) { backupState.set_LastIncrementalBackupTime(&snapshotTime); } else { throw new CVSSCopyException(TEXT("Unsupported backup type.")); } backupState.Save(options.get_StateFile(), bstrBackupDocument); } } } catch (CComException* e) { Cleanup(bAbnormalAbort, bSnapshotCreated, pBackupComponents, snapshotSetId); CString message; CString file; e->get_File(file); message.Format(TEXT("There was a COM failure 0x%x - %s (%d)"), e->get_Hresult(), file, e->get_Line()); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_UNLESS_SILENT); return; } catch (CVSSCopyException* e) { Cleanup(bAbnormalAbort, bSnapshotCreated, pBackupComponents, snapshotSetId); OutputWriter::WriteLine(e->get_Message(), VERBOSITY_THRESHOLD_UNLESS_SILENT); return; } catch (CParseOptionsException* e) { Cleanup(bAbnormalAbort, bSnapshotCreated, pBackupComponents, snapshotSetId); CString message; message.AppendFormat(TEXT("Error: %s\n"), e->get_Message()); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_UNLESS_SILENT); OutputWriter::WriteLine(COptions::get_Usage(), VERBOSITY_THRESHOLD_UNLESS_SILENT); return; } Cleanup(false, bSnapshotCreated, pBackupComponents, snapshotSetId); OutputWriter::WriteLine(TEXT("Backup successfully completed."), VERBOSITY_THRESHOLD_UNLESS_SILENT); CString message; CString startTimeStringLocal; Utilities::FormatDateTime(&startTime, TEXT(" "), true, startTimeStringLocal); CString finishTimeString; SYSTEMTIME finishTime; ::GetSystemTime(&finishTime); Utilities::FormatDateTime(&finishTime, TEXT(" "), true, finishTimeString); message.AppendFormat(TEXT("Backup started at %s, completed at %s."), startTimeStringLocal, finishTimeString); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); message.Empty(); float unitCount = (float)byteCount; LPCTSTR units = TEXT("bytes"); if (unitCount > 1024) { unitCount = unitCount / 1024.0F; units = TEXT("KB"); } if (unitCount > 1024) { unitCount = unitCount / 1024.0F; units = TEXT("MB"); } if (unitCount > 1024) { unitCount = unitCount / 1024.0F; units = TEXT("GB"); } message.AppendFormat(TEXT("%d files (%.2f %s, %d directories) copied, %d files skipped"), fileCount, unitCount, units, directoryCount, skipCount); OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_NORMAL); OutputWriter::SetVerbosityLevel((VERBOSITY_LEVEL)options.get_VerbosityLevel()); //for (int i = 0; i < argc; ++i) //{ // CString message; // message.AppendFormat(TEXT("Argument %d: %s"), i, argv[i]); // OutputWriter::WriteLine(message, VERBOSITY_THRESHOLD_IF_VERBOSE); //} }