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