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_TOO_MANY_OPEN_FILES => return TooManyOpenFiles,
65 c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
66 c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
67 c::ERROR_IO_DEVICE => return InputOutputError,
68 _ => {}
69 }
70
71 match errno {
72 c::WSAEACCES => PermissionDenied,
73 c::WSAEADDRINUSE => AddrInUse,
74 c::WSAEADDRNOTAVAIL => AddrNotAvailable,
75 c::WSAECONNABORTED => ConnectionAborted,
76 c::WSAECONNREFUSED => ConnectionRefused,
77 c::WSAECONNRESET => ConnectionReset,
78 c::WSAEINVAL => InvalidInput,
79 c::WSAENOTCONN => NotConnected,
80 c::WSAEWOULDBLOCK => WouldBlock,
81 c::WSAETIMEDOUT => TimedOut,
82 c::WSAEHOSTUNREACH => HostUnreachable,
83 c::WSAENETDOWN => NetworkDown,
84 c::WSAENETUNREACH => NetworkUnreachable,
85 c::WSAEDQUOT => QuotaExceeded,
86 c::WSAEMFILE => TooManyOpenFiles,
87 c::WSAESHUTDOWN => BrokenPipe,
91
92 _ => Uncategorized,
93 }
94}
95
96pub fn error_string(mut errnum: i32) -> String {
98 let mut buf = [0 as c::WCHAR; 2048];
99
100 unsafe {
101 let mut module = ptr::null_mut();
102 let mut flags = 0;
103
104 if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
108 const NTDLL_DLL: &[u16] = &[
110 'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
111 'L' as _, 0,
112 ];
113 module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
114
115 if !module.is_null() {
116 errnum ^= c::FACILITY_NT_BIT as i32;
117 flags = c::FORMAT_MESSAGE_FROM_HMODULE;
118 }
119 }
120
121 let res = c::FormatMessageW(
122 flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
123 module,
124 errnum as u32,
125 0,
126 buf.as_mut_ptr(),
127 buf.len() as u32,
128 ptr::null(),
129 ) as usize;
130 if res == 0 {
131 let fm_err = errno();
133 return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
134 }
135
136 match String::from_utf16(&buf[..res]) {
137 Ok(mut msg) => {
138 let len = msg.trim_ascii_end().len();
140 msg.truncate(len);
141 msg
142 }
143 Err(..) => format!(
144 "OS Error {} (FormatMessageW() returned \
145 invalid UTF-16)",
146 errnum
147 ),
148 }
149 }
150}