-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Use NtCreateFile on Win32 #27195
Use NtCreateFile on Win32 #27195
Conversation
NtCreateFile allows passing in a base handle which makes opening child directories much faster. This cuts anywhere from 3-10% of the time off of a GetFiles() call. It is significantly faster as it avoids normalization and path parsing overhead.
|
This is a fully supported stable API right? It's hard to imagine it changing but the doc links to https://msdn.microsoft.com/en-us/library/bb432200(v=vs.85).aspx |
| [Flags] | ||
| public enum ObjectAttributes : uint | ||
| { | ||
| // https://msdn.microsoft.com/en-us/library/windows/hardware/ff564586.aspx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bad link?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It worked for me.
| // https://msdn.microsoft.com/en-us/library/bb432380.aspx | ||
| // https://msdn.microsoft.com/en-us/library/windows/hardware/ff566424.aspx | ||
| [DllImport(Libraries.NtDll, CharSet = CharSet.Unicode, ExactSpelling = true)] | ||
| private unsafe static extern int NtCreateFile( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not define it to return Interop.StatusOptions (NTSTATUS)
BTW are we consistent when we use "original" name (seems structs and constants) vs "C# style" name (seems enum here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it isn't an enum. I'd prefer it to be. I can follow up with another change that does this- I'd have to change some other projects.
| { | ||
| return IntPtr.Zero; | ||
| } | ||
| throw Win32Marshal.GetExceptionForWin32Error(error, fullPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is worth the trouble in this case but worth mentioning that we probably could get better error messages by calling FormatMessage passing the handle to ntdll instead of converting the NTSTATUS to Win32 error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would get more discrete errors, but it wouldn't match the Win32 behavior. Want to be consistent historically, but more importantly, with our UAP builds.
Yes. The API is fully documented. Fyi, the signature hasn't changed since at least NT3.5, probably hasn't changed since the start (NT3.1). Changing it would break every kernel-mode driver/service that creates a file handle. |
NtCreateFile allows passing in a base handle which makes opening child directories much faster. This cuts anywhere from 3-10% of the time off of a GetFiles() call. It is significantly faster as it avoids normalization and path parsing overhead.
NtCreateFile allows passing in a base handle which makes opening child directories much faster. This cuts anywhere from 3-10% of the time off of a GetFiles() call. It is significantly faster as it avoids normalization and path parsing overhead. Commit migrated from dotnet/corefx@a28a2cd
NtCreateFile allows passing in a base handle which makes opening child directories much faster. This cuts anywhere from 3-10% of the time off of a GetFiles() call.
It is significantly faster as it avoids normalization and path parsing overhead.
cc: @terrajobst, @danmosemsft