I have an application which needs to create its settings directory inside the user's %APPDATA% directory. To do this it uses code similar to the following:
std::string appDataBase = getenv("APPDATA");
std::string appDir = appDataBase + "\\MyDir";
std::cerr << "About to invoke _mkdir(" << appDir << ")" << std::endl;
int rv = _mkdir(appDir.c_str());
std::cerr << "_mkdir returned " << rv << ", errno = " << errno << std::endl;
However, when this code runs, the _mkdir
call fails and errno
is set to EACCES
:
About to invoke _mkdir(C:\Users\mdm\AppData\Roaming\MyDir)
_mkdir returned -1, errno = 13
I would have assumed this is a simple permissions issue, except for the fact that (1) I can create the directory manually in Explorer without any permission problems, and (2) the exact same code works fine if I copy it into a project by itself.
I have done extensive searching for information about this issue but can only find discussions of general permissions problems such as the user not being able to access/write into this folder using Explorer. The code in my application works if I run it as Administrator, so clearly there is something odd going on with its permissions, but I don't know what else to check. I have inspected with Process Explorer and confirmed that the application is running with my user account, which has full write permissions into the %APPDATA% directory, and I have ensured that the %APPDATA% tree is not set to Hidden or Read-Only.
Is there some kind of "effective user ID" or "effective permissions" that can be set on a Windows application, which might depend on something in the build configuration or process initialisation? Are there any other factors that would prevent one specific application from writing into %APPDATA% while other user processes can?
Update
Further investigation reveals that the difference in behaviour is not related to the content of the code, but the location of the executable in the filesystem. My application is being built from a source tree inside a Development
folder in my user directory, and the _mkdir
call fails for executables within this directory; however, copying the .exe file into a new directory C:\Development
allows it to work fine (although moving the existing Development
directory does not). The simple test program was inside Documents\Visual Studio\Projects
, which also seems to be a satisfactory location.