/// <summary> /// Find Files and Directories in the immediate folder - handles long path names, expects local or UNC path /// </summary> /// <param name="dirName">Directory to search in UNC path or local path format</param> /// <param name="dtFilters">Data table with "Enabled" and "FileFilter" columns required</param> /// <param name="checkSubFolders">Recursively check all sub folders</param> /// <returns></returns> public static List <ContentDetectorLib.FileResult> FindImmediateFilesAndDirs(string dirName, DataTable dtFilters, bool checkSubFolders) { string strDirConverted = LongPathPrepend(dirName); List <ContentDetectorLib.FileResult> results = new List <ContentDetectorLib.FileResult>(); IntPtr findHandle = INVALID_HANDLE_VALUE; bool blIgnoreFile = false; WIN32_FIND_DATA findData; if (dtFilters != null) { //For Each File filter find them in the current folder foreach (DataRow row in dtFilters.Rows) { try { FindFileFilter filter = new FindFileFilter(row); if (filter.Enabled && filter.FileFilter != "") { //Valid File Filter? if (VerifyPattern(filter.FileFilter) && Delimon.Win32.IO.Directory.Exists(dirName)) { try { //Search for the file filter in the current directory if (filter.ObjectType == ContentDetectorLib.Common.FileFilterObjectType.Folder) { findHandle = FindFirstFileEx(strDirConverted + @"\" + filter.FileFilter, FINDEX_INFO_LEVELS.FindExInfoBasic, out findData, FINDEX_SEARCH_OPS.FindExSearchLimitToDirectories, IntPtr.Zero, FIND_FIRST_EX_LARGE_FETCH); } else { findHandle = FindFirstFileEx(strDirConverted + @"\" + filter.FileFilter, FINDEX_INFO_LEVELS.FindExInfoBasic, out findData, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, FIND_FIRST_EX_LARGE_FETCH); } if (findHandle != INVALID_HANDLE_VALUE) { bool found; do { string currentFileName = findData.cFileName; blIgnoreFile = false; char[] delimiters = new char[] { ';' }; if (filter.ExcludeFiles != "") { string[] strArr_excludedfiles = filter.ExcludeFiles.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); if (!(strArr_excludedfiles == null || strArr_excludedfiles.Length == 0)) { //loop through excluded folders foreach (string strExclude in strArr_excludedfiles) { if (currentFileName.ToLower() == strExclude.ToLower()) { blIgnoreFile = true; } } } } if (!blIgnoreFile) { // if this is a directory, add directory found to the results. if (((int)findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { if (filter.ObjectType == ContentDetectorLib.Common.FileFilterObjectType.Folder || filter.ObjectType == ContentDetectorLib.Common.FileFilterObjectType.Both) { if (currentFileName != "." && currentFileName != "..") { string strFilePath = RemovePrependGetPath(Path.Combine(dirName, currentFileName)); try { Delimon.Win32.IO.DirectoryInfo ddir = new Delimon.Win32.IO.DirectoryInfo(strFilePath); ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(ddir); fr1.FileFilterSearched = filter.FileFilter; results.Add(fr1); //results.Add("\"" + strFilePath + "\"" + ",FolderCreated: " + ddir.CreationTime.ToString("G") + ",Owner: " + strOwner); } catch (Exception) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.FileFilterSearched = filter.FileFilter; fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.Folder; fr1.FullPath = strFilePath; results.Add(fr1); } } } } // it’s a file; add it to the results else { if (filter.ObjectType == ContentDetectorLib.Common.FileFilterObjectType.File || filter.ObjectType == ContentDetectorLib.Common.FileFilterObjectType.Both) { string strFilePath = RemovePrependGetPath(Path.Combine(dirName, currentFileName)); Delimon.Win32.IO.FileInfo dfile; try { dfile = new Delimon.Win32.IO.FileInfo(strFilePath); if (filter.DeleteFilesFound) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(dfile); fr1.FileFilterSearched = filter.FileFilter; fr1.Deleted = true; results.Add(fr1); //Delete the ransomware related file //results.Add("File Deleted: " + "\"" + strFilePath + "\"" + ",FileCreated: " + dfile.CreationTime.ToString("G") + ",Owner: " + strOwner); dfile.Delete(); } else { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(dfile); fr1.FileFilterSearched = filter.FileFilter; results.Add(fr1); //Document the file found //results.Add("\"" + strFilePath + "\"" + ",FileCreated: " + dfile.CreationTime.ToString("G") + ",Owner: " + strOwner); } } catch (Exception) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.FileFilterSearched = filter.FileFilter; fr1.FullPath = strFilePath; fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.None; fr1.Comment = "\"" + strFilePath + "\""; results.Add(fr1); //results.Add("\"" + strFilePath + "\""); } } } } // find next if any found = FindNextFile(findHandle, out findData); }while (found); } } finally { // close the find handle FindClose(findHandle); } } else { //invalid search filter if (results.Count == 0) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.FileFilterSearched = filter.FileFilter; fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.None; fr1.Comment = "Invalid Search Filter or Directory Problem: " + filter.FileFilter + " " + dirName; results.Add(fr1); //results.Add("Invalid Search Filter or Directory Problem: " + filter.FileFilter + " " + dirName); } } } } catch { } } } return(results); }
/// <summary> /// Recursively Searches for all files and folders specified by the filter; Optimized for best performance by only going through folder structure once and searching the all of the file filters in each folder /// </summary> /// <param name="dirName"></param> /// <param name="filter"></param> /// <param name="checkSubFolders"></param> /// <param name="excludeFolders">Separate folders with semicolon no back slashes or forward slashes</param> /// <returns></returns> public static List <ContentDetectorLib.FileResult> FindAllfiles(string dirName, DataTable dtFilters, bool checkSubFolders, string excludeFolders, ref bool blShuttingDown) { List <ContentDetectorLib.FileResult> results = new List <ContentDetectorLib.FileResult>(); string strDirConverted = LongPathPrepend(dirName); WIN32_FIND_DATA findData; IntPtr findHandle = INVALID_HANDLE_VALUE; if (!checkSubFolders) { //Get find results for the current directory being searched and no recursion results = FindImmediateFilesAndDirs(dirName, dtFilters, checkSubFolders); } else { try { //Search through each folder findHandle = FindFirstFileEx(strDirConverted + @"\*", FINDEX_INFO_LEVELS.FindExInfoBasic, out findData, FINDEX_SEARCH_OPS.FindExSearchLimitToDirectories, IntPtr.Zero, FIND_FIRST_EX_LARGE_FETCH); if (findHandle != INVALID_HANDLE_VALUE) { bool found; //Get find results for the current directory being searched List <ContentDetectorLib.FileResult> mainResults = FindImmediateFilesAndDirs(dirName, dtFilters, checkSubFolders); results.AddRange(mainResults); mainResults.Clear(); do { if (blShuttingDown) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.None; fr1.FullPath = dirName; fr1.Comment = "Ransomware Detection Service Search Shutting Down at:" + dirName; results.Add(fr1); break; } string currentFileName = findData.cFileName; // if this is a directory, find its contents if (((int)findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { bool blIgnoreDirectory = false; char[] delimiters = new char[] { ';' }; string[] strArr_excludedfolders = excludeFolders.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); if (!(strArr_excludedfolders == null || strArr_excludedfolders.Length == 0)) { //loop through excluded folders foreach (string strExclude in strArr_excludedfolders) { if (currentFileName.ToLower() == strExclude.ToLower()) { blIgnoreDirectory = true; } } } if (!blIgnoreDirectory && !(currentFileName == "." || currentFileName == "..")) { if (checkSubFolders) { //Recursively go through all folders and sub folders List <ContentDetectorLib.FileResult> childResults2 = FindAllfiles(Path.Combine(dirName, currentFileName), dtFilters, checkSubFolders, excludeFolders, ref blShuttingDown); results.AddRange(childResults2); childResults2.Clear(); } //string strFilePath = ConvertURIToUNCPath(Path.Combine(strDirConverted, currentFileName)); //results.Add(strFilePath); } } found = FindNextFile(findHandle, out findData); }while (found); } else { if (results.Count == 0) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.None; fr1.FullPath = dirName; fr1.Comment = "File Path Not Found:" + dirName; results.Add(fr1); } } } catch { if (results.Count == 0) { ContentDetectorLib.FileResult fr1 = new ContentDetectorLib.FileResult(); fr1.ObjectType = ContentDetectorLib.Common.FileFilterObjectType.None; fr1.FullPath = dirName; fr1.Comment = "Error occurred while in Path:" + dirName; results.Add(fr1); } } finally { // close the find handle FindClose(findHandle); } } return(results); }