-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows io::Error: also format NTSTATUS error codes #41684
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
d4b03e5
to
1438068
Compare
src/libstd/sys/windows/os.rs
Outdated
// format according to https://support.microsoft.com/en-us/help/259693 | ||
const NTDLL_DLL: &'static [u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, | ||
'.' as _, 'D' as _, 'L' as _, 'L' as _, 0]; | ||
let module = c::LoadLibraryW(NTDLL_DLL.as_ptr()); |
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.
Since on Windows, the ntdll.dll
is always loaded, we could use GetModuleHandle()
to get a handle of ntdll.dll
. And since the ntdll.dll
is not loaded by our code (it's loaded by Windows itself), we could just drop the handle after using it.
src/libstd/sys/windows/os.rs
Outdated
errnum, error_string(errno())); | ||
} | ||
|
||
errnum ^= NTSTATUS_BIT; |
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 unset the NTSTATUS_BIT
? Does this bit stop FormatMessage()
to work?
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.
Right
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.
Oh, OK then.
Build failure looks spurious |
Restarted Travis job, and logged. |
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.
Neat! Would it be possible to add a test for this as well? Can you also expand on the contexts in which this would want to be called? I'm not personally 100% familiar with the exhausive set of error codes in Windows, but should we be using this in libstd somehow?
What kinds of functions return NTSTATUS?
src/libstd/sys/windows/os.rs
Outdated
|
||
if module == ptr::null_mut() { | ||
// Ok to call recursively, GetModuleHandleW doesn't return NTSTATUS | ||
return format!("OS Error {} (GetModuleHandleW() returned 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.
This seems like it'd be a confusing error message perhaps? The os error errnum
has nothing to do with GetModuleHandleW
returning an 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.
I copied this from the way FormatMessage errors below are handled. I could rewrite both these messages to include that this is why there is no text?
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.
Sure yeah, but that's an error about how it can't be formatted. This is an error about how an intermediate step failed, so this message could be confusing. I think if the ptr coming out here is null we should just fall through to the same code path as below
As mentioned in the PR, I'm not sure what would be appropriate here. What did you have in mind?
Functions that return
I linked to the error reference in the PR. Since these errors can be returned from I'm not 100% when such codes might be returned from Windows APIs that are called from with std, but since you're dealing with file handles, which can map to various device drivers, there's a real possibility you'll encounter these. |
Since when does libstd even work with |
As far as I can tell, these are practically equivalent. A Win32 error is only 16 bits, according to MS-ERREF. Here's an example of Compile this program: fn main() {
std::collections::HashMap::<(),()>::new();
} Now backup, and then delete the registry key
-2146893799 is 0x80090019 ( Remember to restore the registry from your backup. |
Just something that executes this code path, I don't particularly mind how it's executed. I suppose I'm still confused a bit about how this is used. We don't even define |
Yes, this, exactly. |
Could you add some more comments in the source about these relationships? Right now there's no mention of how the DWORD from GetLastError relates to an HRESULT or an NTSTATUS |
4286ba4
to
404ece5
Compare
@alexcrichton looks like your concerns were addressed? |
📌 Commit 404ece5 has been approved by |
⌛ Testing commit 404ece5 with merge 0b1c374... |
💔 Test failed - status-appveyor |
|
404ece5
to
b0aab8f
Compare
Whoops, fixed. Does this work? |
Oh @bors only accepts commands from reviewers, but it looks like there's a tidy problem? (feel free to just ping me when this is ready to go and I'll r+) |
b0aab8f
to
3305e74
Compare
@alexcrichton updated |
@bors: r+ |
📌 Commit 3305e74 has been approved by |
…ichton Windows io::Error: also format NTSTATUS error codes `NTSTATUS` errors may be encoded as `HRESULT`, see [[MS-ERREF]](https://msdn.microsoft.com/en-us/library/cc231198.aspx). These error codes can still be formatted using `FormatMessageW` but require some different parameters to be passed in. I wasn't sure if this needed a test and if so, how to test it. Presumably we wouldn't want to make our tests dependent on localization-dependent strings returned from `FormatMessageW`. Users that get an `err: NTSTATUS` will need to do `io::Error::from_raw_os_error(err|0x1000_0000)` (the equivalent of [`HRESULT_FROM_NT`](https://msdn.microsoft.com/en-us/library/ms693780(VS.85).aspx))
⌛ Testing commit 3305e74 with merge 4ab969c... |
💔 Test failed - status-appveyor |
Legitimate failure:
|
3305e74
to
71de9db
Compare
Third time's the charm, right? |
@bors: r+ |
📌 Commit 71de9db has been approved by |
Windows io::Error: also format NTSTATUS error codes `NTSTATUS` errors may be encoded as `HRESULT`, see [[MS-ERREF]](https://msdn.microsoft.com/en-us/library/cc231198.aspx). These error codes can still be formatted using `FormatMessageW` but require some different parameters to be passed in. I wasn't sure if this needed a test and if so, how to test it. Presumably we wouldn't want to make our tests dependent on localization-dependent strings returned from `FormatMessageW`. Users that get an `err: NTSTATUS` will need to do `io::Error::from_raw_os_error(err|0x1000_0000)` (the equivalent of [`HRESULT_FROM_NT`](https://msdn.microsoft.com/en-us/library/ms693780(VS.85).aspx))
…ichton Windows io::Error: also format NTSTATUS error codes `NTSTATUS` errors may be encoded as `HRESULT`, see [[MS-ERREF]](https://msdn.microsoft.com/en-us/library/cc231198.aspx). These error codes can still be formatted using `FormatMessageW` but require some different parameters to be passed in. I wasn't sure if this needed a test and if so, how to test it. Presumably we wouldn't want to make our tests dependent on localization-dependent strings returned from `FormatMessageW`. Users that get an `err: NTSTATUS` will need to do `io::Error::from_raw_os_error(err|0x1000_0000)` (the equivalent of [`HRESULT_FROM_NT`](https://msdn.microsoft.com/en-us/library/ms693780(VS.85).aspx))
☀️ Test successful - status-appveyor, status-travis |
NTSTATUS
errors may be encoded asHRESULT
, see [MS-ERREF]. These error codes can still be formatted usingFormatMessageW
but require some different parameters to be passed in.I wasn't sure if this needed a test and if so, how to test it. Presumably we wouldn't want to make our tests dependent on localization-dependent strings returned from
FormatMessageW
.Users that get an
err: NTSTATUS
will need to doio::Error::from_raw_os_error(err|0x1000_0000)
(the equivalent ofHRESULT_FROM_NT
)