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