win-error-codes 0.0.2

The numbers Windows reports failure in, as types: Win32 error codes, the signed LSTATUS, HRESULT and NTSTATUS, with an exact io::Error round trip for every Win32 code, including those above 2^31. No unsafe code and no native API surface.
Documentation
  • Coverage
  • 100%
    10 out of 10 items documented4 out of 4 items with examples
  • Size
  • Source code size: 113.3 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 769.6 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • MikeGrier/windows-threadpool-sys
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • MikeGrier

win-error-codes

The numbers Windows reports failure in, as types.

Windows reports a failure as a number, and which number space it is in is not in the number. A DWORD from GetLastError is one; a HRESULT is another. Crates here each kept a bare u32 or wrote a Win32Error of their own, and the two that did disagreed about a code of 2^31 or more, which exist: the virtdisk errors, such as ERROR_VIRTDISK_NOT_VIRTUAL_DISK, are WIN32_ERRORs of 3225026581. This crate gives each number space its own type, and the conversion to and from std::io::Error is written once and is exact for every code.

What it gives

  • Win32Error, a u32: the code unaltered, is_success and into_result (zero is ERROR_SUCCESS), and on Windows to_io_error, from_io and last.
  • LStatus, an i32: the same number space in the signed LONG that registry calls return, converting to and from Win32Error by a bit cast that loses nothing, a code above 2^31 being a negative value.
  • HResult, an i32: the signed HRESULT, with is_failure and is_success, code, facility, from_win32 (HRESULT_FROM_WIN32's rule, which keeps only the low 16 bits of a positive code) and win32 (the inverse for the codes from 1 to 65535).
  • NtStatus, an i32: the signed NTSTATUS, with its NtSeverity, NT_SUCCESS and the other three predicates, code, facility, and HResult::from_ntstatus (HRESULT_FROM_NT). There is no conversion to a Win32 code: that is an Rtl* call.
use win_error_codes::{HResult, LStatus, NtStatus, Win32Error};

// A call that returns its code directly: zero is success.
assert_eq!(Win32Error::from_code(0).into_result(), Ok(()));

// A registry call returns the same thing as a signed LONG.
assert_eq!(LStatus::from_raw(2).into_result(), Err(Win32Error::from_code(2)));

// ERROR_IO_DEVICE, wrapped as an HRESULT.
let hresult = HResult::from_win32(Win32Error::from_code(1117));
assert_eq!(hresult.to_string(), "0x8007045D");
assert_eq!(hresult.win32(), Some(Win32Error::from_code(1117)));

// STATUS_ACCESS_VIOLATION: an error, and not a success. HRESULT_FROM_NT sets one bit.
let status = NtStatus::from_raw(0xC000_0005_u32.cast_signed());
assert!(!status.is_success());
assert_eq!(HResult::from_ntstatus(status).raw().cast_unsigned(), 0xD000_0005);

// ERROR_VIRTDISK_NOT_VIRTUAL_DISK, a code above 2^31, keeps its value through io::Error.
# #[cfg(windows)] {
let error = Win32Error::from_code(0xC03A_0015);
assert_eq!(Win32Error::from_io(&error.to_io_error()), Some(error));
# }

What it does not do

  • No named constants. windows-sys has them.
  • No mapping onto a friendlier taxonomy. A type carries what Windows said.
  • No unsafe and no native API surface. The numbers and their conversions build on every target. The bridge to io::Error is Windows-only, because off Windows a raw OS error is an errno, and reading one as a Win32 code would be a wrong answer.

The decisions are in DESIGN-NOTES.md and the plan is in CHECKLIST.md.