std\sys\io\error/
windows.rs1use crate::sys::pal::{api, c};
2use crate::{io, ptr};
3
4#[cfg(test)]
5mod tests;
6
7pub fn errno() -> i32 {
8 api::get_last_error().code as i32
9}
10
11#[inline]
12pub fn is_interrupted(_errno: i32) -> bool {
13 false
14}
15
16pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
17 use io::ErrorKind::*;
18
19 match errno as u32 {
20 c::ERROR_ACCESS_DENIED => return PermissionDenied,
21 c::ERROR_ALREADY_EXISTS => return AlreadyExists,
22 c::ERROR_FILE_EXISTS => return AlreadyExists,
23 c::ERROR_BROKEN_PIPE => return BrokenPipe,
24 c::ERROR_FILE_NOT_FOUND
25 | c::ERROR_PATH_NOT_FOUND
26 | c::ERROR_INVALID_DRIVE
27 | c::ERROR_BAD_NETPATH
28 | c::ERROR_BAD_NET_NAME => return NotFound,
29 c::ERROR_NO_DATA => return BrokenPipe,
30 c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
31 c::ERROR_INVALID_PARAMETER => return InvalidInput,
32 c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
33 c::ERROR_SEM_TIMEOUT
34 | c::WAIT_TIMEOUT
35 | c::ERROR_DRIVER_CANCEL_TIMEOUT
36 | c::ERROR_OPERATION_ABORTED
37 | c::ERROR_SERVICE_REQUEST_TIMEOUT
38 | c::ERROR_COUNTER_TIMEOUT
39 | c::ERROR_TIMEOUT
40 | c::ERROR_RESOURCE_CALL_TIMED_OUT
41 | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
42 | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
43 | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
44 | c::ERROR_DS_TIMELIMIT_EXCEEDED
45 | c::DNS_ERROR_RECORD_TIMED_OUT
46 | c::ERROR_IPSEC_IKE_TIMED_OUT
47 | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
48 | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
49 c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
50 c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
51 c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
52 c::ERROR_DIRECTORY => return NotADirectory,
53 c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
54 c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
55 c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
56 c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
57 c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
58 c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded,
59 c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
60 c::ERROR_BUSY => return ResourceBusy,
61 c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
62 c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
63 c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
64 c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
65 c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
66 _ => {}
67 }
68
69 match errno {
70 c::WSAEACCES => PermissionDenied,
71 c::WSAEADDRINUSE => AddrInUse,
72 c::WSAEADDRNOTAVAIL => AddrNotAvailable,
73 c::WSAECONNABORTED => ConnectionAborted,
74 c::WSAECONNREFUSED => ConnectionRefused,
75 c::WSAECONNRESET => ConnectionReset,
76 c::WSAEINVAL => InvalidInput,
77 c::WSAENOTCONN => NotConnected,
78 c::WSAEWOULDBLOCK => WouldBlock,
79 c::WSAETIMEDOUT => TimedOut,
80 c::WSAEHOSTUNREACH => HostUnreachable,
81 c::WSAENETDOWN => NetworkDown,
82 c::WSAENETUNREACH => NetworkUnreachable,
83 c::WSAEDQUOT => QuotaExceeded,
84 c::WSAESHUTDOWN => BrokenPipe,
88
89 _ => Uncategorized,
90 }
91}
92
93pub fn error_string(mut errnum: i32) -> String {
95 let mut buf = [0 as c::WCHAR; 2048];
96
97 unsafe {
98 let mut module = ptr::null_mut();
99 let mut flags = 0;
100
101 if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
105 const NTDLL_DLL: &[u16] = &[
107 'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
108 'L' as _, 0,
109 ];
110 module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
111
112 if !module.is_null() {
113 errnum ^= c::FACILITY_NT_BIT as i32;
114 flags = c::FORMAT_MESSAGE_FROM_HMODULE;
115 }
116 }
117
118 let res = c::FormatMessageW(
119 flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
120 module,
121 errnum as u32,
122 0,
123 buf.as_mut_ptr(),
124 buf.len() as u32,
125 ptr::null(),
126 ) as usize;
127 if res == 0 {
128 let fm_err = errno();
130 return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
131 }
132
133 match String::from_utf16(&buf[..res]) {
134 Ok(mut msg) => {
135 let len = msg.trim_ascii_end().len();
137 msg.truncate(len);
138 msg
139 }
140 Err(..) => format!(
141 "OS Error {} (FormatMessageW() returned \
142 invalid UTF-16)",
143 errnum
144 ),
145 }
146 }
147}