On windows, to find out if I have write access to a directory, I found that it is easiest to just create a file in that directory.
In order to do so, I found GetTempFileName()
API function to get an almost(?) unique file name in the desired directory, then I was going to create a file with that name. so if everything goes well, I have the write access and everything is fine.
Then I found two behavior from the mentioned API call:
- If I have write access, it creates the temporary file and returns the path through its output parameter, named
lpTempFileName
- When I don't have write access, it just clear out the buffer, and literally returns an empty string as temp file name (
lpTempFileName
).
I can't find this bit of information in documents. Is this always valid? If so I can rely on it and just decide based on if the returned string is empty or not, instead of calling CreateFile
and Closing the Handle afterwards.
Here is what I'm doing now:
bool is_writable = true;
try
{
CString tmp_file_name;
::GetTempFileName(folder_path, "ttt", 0, tmp_file_name.GetBuffer(MAX_PATH));
HANDLE file = CreateFile(tmp_file_name, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if ( file == INVALID_HANDLE_VALUE )
{
is_writable = false;
}
else
{
CloseHandle( file );
DeleteFile( tmp_file_name );
is_writable = true;
}
}
catch (...)
{
is_writable = false;
}
But here is what I can do if the above assumption is correct:
bool is_writable = true;
try
{
CString tmp_file_name;
::GetTempFileName(folder_path, "ttt", 0, tmp_file_name.GetBuffer(MAX_PATH));
if ( tmp_file_name.IsEmpty() )
{
is_writable = false;
}
else
{
DeleteFile( tmp_file_name );
is_writable = true;
}
}
catch (...)
{
is_writable = false;
}
Certainly, two less API calls.
So is my finding always stands correct? can I rely on the second snippet?