X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ffs%2Fwindows%2Fdir.cpp;h=fde0200d029708eccd7476911e5d8dd3fa18c285;hb=HEAD;hp=6b63b471d5bc939fe11a78ccbc668cdb02573c8c;hpb=cc7c798b275b8ea9992eb82d68177ecfd50e0974;p=libs%2Fcore.git diff --git a/source/fs/windows/dir.cpp b/source/fs/windows/dir.cpp index 6b63b47..2ba2f1e 100644 --- a/source/fs/windows/dir.cpp +++ b/source/fs/windows/dir.cpp @@ -1,5 +1,7 @@ -#include +#include +#include #include +#include #include "dir.h" using namespace std; @@ -19,22 +21,75 @@ void rmdir(const Path &path) throw system_error("RemoveDirectory"); } -Path get_home_dir() +vector list_filtered(const Path &path, const string &filter) { - char home[MAX_PATH]; - if(SHGetFolderPath(0, CSIDL_PERSONAL, 0, 0, home)==S_OK) - return home; - return "."; + Regex r_filter(filter); + + vector result; + WIN32_FIND_DATA entry; + string pattern = path.str()+"\\*"; + HANDLE search_handle = FindFirstFileEx(pattern.c_str(), FindExInfoBasic, &entry, FindExSearchNameMatch, nullptr, 0); + if(search_handle==INVALID_HANDLE_VALUE) + { + DWORD err = GetLastError(); + if(err==ERROR_FILE_NOT_FOUND) + return result; + throw system_error("FindFirstFileEx"); + } + + bool more = true; + for(; more; more=FindNextFile(search_handle, &entry)) + { + const char *fn = entry.cFileName; + if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) + continue; + if(r_filter.match(fn)) + result.push_back(fn); + } + + DWORD err = GetLastError(); + FindClose(search_handle); + if(err!=ERROR_NO_MORE_FILES) + throw system_error("FindNextFile"); + + return result; +} + +/* Windows documentation says Get/SetCurrentDirectory use a global buffer and +are not thread safe. */ +static Mutex &cwd_mutex() +{ + static Mutex mutex; + return mutex; +} + +Path getcwd() +{ + MutexLock lock(cwd_mutex()); + + char buf[1024]; + Path result; + DWORD len = GetCurrentDirectory(sizeof(buf), buf); + if(len>=sizeof(buf)) + { + vector buf2(len+1); + len = GetCurrentDirectory(buf2.size(), buf2.data()); + result = buf2.data(); + } + else + result = buf; + + if(!len) + throw system_error("GetCurrentDirectory"); + + return result; } -Path get_user_data_dir(const string &appname) +void chdir(const Path &path) { - if(appname.empty()) - throw invalid_argument("get_user_data_dir"); - char datadir[MAX_PATH]; - if(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, datadir)==S_OK) - return Path(datadir)/appname; - return "."; + MutexLock lock(cwd_mutex()); + if(!SetCurrentDirectory(path.c_str())) + throw system_error("SetCurrentDirectory"); } } // namespace FS