/** * @brief Find files and subfolders from given folder. * This function saves all files and subfolders in given folder to arrays. * We use 64-bit version of stat() to get times since find doesn't return * valid times for very old files (around year 1970). Even stat() seems to * give negative time values but we can live with that. Those around 1970 * times can happen when file is created so that it doesn't get valid * creation or modificatio dates. * @param [in] sDir Base folder for files and subfolders. * @param [in, out] dirs Array where subfolders are stored. * @param [in, out] files Array where files are stored. */ static void LoadFiles(LPCTSTR sDir, DirItemArray * dirs, DirItemArray * files) { String sPattern(sDir); size_t len = sPattern.length(); if (sPattern[len - 1] != '\\') sPattern += _T("\\*.*"); else sPattern += _T("*.*"); WIN32_FIND_DATA ff; HANDLE h = FindFirstFile(sPattern.c_str(), &ff); if (h != INVALID_HANDLE_VALUE) { do { BOOL bIsDirectory = (ff.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; if (bIsDirectory && _tcsstr(_T(".."), ff.cFileName)) continue; DirItem ent; ent.bIsDir = !!bIsDirectory; // Save filetimes as seconds since January 1, 1970 // Note that times can be < 0 if they are around that 1970.. // Anyway that is not sensible case for normal files so we can // just use zero for their time. ent.ctime = FiletimeToTimeT(ff.ftCreationTime); if (ent.ctime < 0) ent.ctime = 0; ent.mtime = FiletimeToTimeT(ff.ftLastWriteTime); if (ent.mtime < 0) ent.mtime = 0; if (ff.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ent.size = -1; // No size for directories else { ent.size = ((__int64)ff.nFileSizeHigh << 32) + ff.nFileSizeLow; } ent.path = sDir; ent.filename = ff.cFileName; ent.flags.attributes = ff.dwFileAttributes; (bIsDirectory ? dirs : files)->push_back(ent); } while (FindNextFile(h, &ff)); FindClose(h); } }
static S32 buildFileList(const char* pattern, bool recurse, bool multiMatch) { static const String sSlash( "/" ); sgFindFilesResults.clear(); String sPattern(Torque::Path::CleanSeparators(pattern)); if(sPattern.isEmpty()) { Con::errorf("findFirstFile() requires a search pattern"); return -1; } if(!Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), sPattern.c_str())) { Con::errorf("findFirstFile() given initial directory cannot be expanded: '%s'", pattern); return -1; } sPattern = String::ToString(sgScriptFilenameBuffer); String::SizeType slashPos = sPattern.find('/', 0, String::Right); // if(slashPos == String::NPos) // { // Con::errorf("findFirstFile() missing search directory or expression: '%s'", sPattern.c_str()); // return -1; // } // Build the initial search path Torque::Path givenPath(Torque::Path::CompressPath(sPattern)); givenPath.setFileName("*"); givenPath.setExtension("*"); if(givenPath.getPath().length() > 0 && givenPath.getPath().find('*', 0, String::Right) == givenPath.getPath().length()-1) { // Deal with legacy searches of the form '*/*.*' String suspectPath = givenPath.getPath(); String::SizeType newLen = suspectPath.length()-1; if(newLen > 0 && suspectPath.find('/', 0, String::Right) == suspectPath.length()-2) { --newLen; } givenPath.setPath(suspectPath.substr(0, newLen)); } Torque::FS::FileSystemRef fs = Torque::FS::GetFileSystem(givenPath); //Torque::Path path = fs->mapTo(givenPath); Torque::Path path = givenPath; // Make sure that we have a root so the correct file system can be determined when using zips if(givenPath.isRelative()) path = Torque::Path::Join(Torque::FS::GetCwd(), '/', givenPath); path.setFileName(String::EmptyString); path.setExtension(String::EmptyString); if(!Torque::FS::IsDirectory(path)) { Con::errorf("findFirstFile() invalid initial search directory: '%s'", path.getFullPath().c_str()); return -1; } // Build the search expression const String expression(slashPos != String::NPos ? sPattern.substr(slashPos+1) : sPattern); if(expression.isEmpty()) { Con::errorf("findFirstFile() requires a search expression: '%s'", sPattern.c_str()); return -1; } S32 results = Torque::FS::FindByPattern(path, expression, recurse, sgFindFilesResults, multiMatch ); if(givenPath.isRelative() && results > 0) { // Strip the CWD out of the returned paths // MakeRelativePath() returns incorrect results (it adds a leading ..) so doing this the dirty way const String cwd = Torque::FS::GetCwd().getFullPath(); for(S32 i = 0;i < sgFindFilesResults.size();++i) { String str = sgFindFilesResults[i]; if(str.compare(cwd, cwd.length(), String::NoCase) == 0) str = str.substr(cwd.length()); sgFindFilesResults[i] = str; } } return results; }