Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Windows equivalent of `openat`?

Tags:

winapi

The title pretty much says it, on Windows, can I somehow simulate multiple working directories in a multithreaded application by using something similar to openat?

See also this question.

like image 902
heinrich5991 Avatar asked Aug 21 '15 10:08

heinrich5991


1 Answers

Yes there is, and it's called NtCreateFile() (https://msdn.microsoft.com/en-us/library/bb432380(v=vs.85).aspx) :)

openat() takes an open fd to a base directory from which path operations start. Similarly, you can supply a HANDLE to the ObjectAttributes.RootDirectory of NtCreateFile() to have whatever that directory's path is to be used as a base for relative path operations.

If going direct to the NT kernel API is too much for you and you want to remain within Win32, you can retrieve the current path of the base directory HANDLE easily enough (see https://msdn.microsoft.com/en-us/library/windows/desktop/aa366789(v=vs.85).aspx). If you open the directory without FILE_SHARE_DELETE permissions, nobody will be able to rename it and therefore the path retrieved will never move so long as you keep the HANDLE open.

You then stitch together the retrieved path with the relative path using normal string concatenation.

The NT kernel API approach is the only solution on Windows which allows the base directory HANDLE to be arbitrarily renamed by third party processes and that not cause races in your code. i.e. it's the only equivalent to POSIX openat(). I agree it's very unfortunate that Win32 doesn't make available this facility - in fact, Win32 doesn't make available atomic renames which is a very useful POSIX facility indeed to let you avoid lock files and is something the NT kernel API provides too.

like image 161
Niall Douglas Avatar answered Nov 09 '22 17:11

Niall Douglas