]> git.tdb.fi Git - libs/core.git/blob - source/fs/windows/dir.cpp
Split getcwd and chdir to platform files
[libs/core.git] / source / fs / windows / dir.cpp
1 #include <shlobj.h>
2 #include <msp/core/mutex.h>
3 #include <msp/core/systemerror.h>
4 #include "dir.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace FS {
10
11 void mkdir(const Path &path, int)
12 {
13         if(!CreateDirectory(path.str().c_str(), NULL))
14                 throw system_error("CreateDirectory");
15 }
16
17 void rmdir(const Path &path)
18 {
19         if(!RemoveDirectory(path.str().c_str()))
20                 throw system_error("RemoveDirectory");
21 }
22
23 /* Windows documentation says Get/SetCurrentDirectory use a global buffer and
24 are not thread safe. */
25 static Mutex &cwd_mutex()
26 {
27         static Mutex mutex;
28         return mutex;
29 }
30
31 Path getcwd()
32 {
33         MutexLock lock(cwd_mutex());
34
35         char buf[1024];
36         Path result;
37         DWORD len = GetCurrentDirectory(sizeof(buf), buf);
38         if(len>=sizeof(buf))
39         {
40                 vector<char> buf2(len+1);
41                 len = GetCurrentDirectory(buf2.size(), buf2.data());
42                 result = buf2.data();
43         }
44         else
45                 result = buf;
46
47         if(!len)
48                 throw system_error("GetCurrentDirectory");
49
50         return result;
51 }
52
53 void chdir(const Path &path)
54 {
55         MutexLock lock(cwd_mutex());
56         if(!SetCurrentDirectory(path.c_str()))
57                 throw system_error("SetCurrentDirectory");
58 }
59
60 Path get_home_dir()
61 {
62         char home[MAX_PATH];
63         if(SHGetFolderPath(0, CSIDL_PERSONAL, 0, 0, home)==S_OK)
64                 return home;
65         return ".";
66 }
67
68 Path get_user_data_dir(const string &appname)
69 {
70         if(appname.empty())
71                 throw invalid_argument("get_user_data_dir");
72         char datadir[MAX_PATH];
73         if(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, datadir)==S_OK)
74                 return Path(datadir)/appname;
75         return ".";
76 }
77
78 } // namespace FS
79 } // namespace Msp