vector<FoundFile> GetFilesInDirectory(const char *path) { vector<FoundFile> ret; DIR *d = opendir(path); if(d == NULL) { uint32_t flags = eFileProp_ErrorUnknown; if(errno == ENOENT) flags = eFileProp_ErrorInvalidPath; else if(errno == EACCES) flags = eFileProp_ErrorAccessDenied; ret.push_back(FoundFile(path, flags)); return ret; } dirent *ent = NULL; for(;;) { ent = readdir(d); if(!ent) break; // skip "." and ".." if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; string fullpath = path; fullpath += '/'; fullpath += ent->d_name; struct ::stat st; int res = stat(fullpath.c_str(), &st); // invalid/bad file - skip it if(res != 0) continue; uint32_t flags = 0; // make directory/executable mutually exclusive for clarity's sake if(S_ISDIR(st.st_mode)) flags |= eFileProp_Directory; else if(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) flags |= eFileProp_Executable; if(ent->d_name[0] == '.') flags |= eFileProp_Hidden; ret.push_back(FoundFile(ent->d_name, flags)); } // don't care if we hit an error or enumerated all files, just finish closedir(d); return ret; }
vector<FoundFile> GetFilesInDirectory(const char *path) { vector<FoundFile> ret; if(path[0] == '/' && path[1] == 0) { DWORD driveMask = GetLogicalDrives(); for(int i = 0; i < 26; i++) { DWORD mask = (1 << i); if(driveMask & mask) { string fn = "A:/"; fn[0] = char('A' + i); ret.push_back(FoundFile(fn, eFileProp_Directory)); } } return ret; } string pathstr = path; // normalise path to windows style for(size_t i = 0; i < pathstr.size(); i++) if(pathstr[i] == '/') pathstr[i] = '\\'; // remove any trailing slash if(pathstr[pathstr.size() - 1] == '\\') pathstr.resize(pathstr.size() - 1); // append '\*' to do the search we want pathstr += "\\*"; wstring wpath = StringFormat::UTF82Wide(pathstr); WIN32_FIND_DATAW findData = {}; HANDLE find = FindFirstFileW(wpath.c_str(), &findData); if(find == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); uint32_t flags = eFileProp_ErrorUnknown; if(err == ERROR_FILE_NOT_FOUND) flags = eFileProp_ErrorInvalidPath; else if(err == ERROR_ACCESS_DENIED) flags = eFileProp_ErrorAccessDenied; ret.push_back(FoundFile(path, flags)); return ret; } do { if(findData.cFileName[0] == L'.' && findData.cFileName[1] == 0) { // skip "." } else if(findData.cFileName[0] == L'.' && findData.cFileName[1] == L'.' && findData.cFileName[2] == 0) { // skip ".." } else { uint32_t flags = 0; if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) flags |= eFileProp_Directory; if(findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) flags |= eFileProp_Hidden; if(wcsstr(findData.cFileName, L".EXE") || wcsstr(findData.cFileName, L".exe") || wcsstr(findData.cFileName, L".Exe")) { flags |= eFileProp_Executable; } ret.push_back(FoundFile(StringFormat::Wide2UTF8(findData.cFileName), flags)); } } while(FindNextFile(find, &findData) != FALSE); // don't care if we hit an error or enumerated all files, just finish FindClose(find); return ret; }