1use std::io;
2
3use crate::efi::Variable;
4
5#[derive(Debug, thiserror::Error)]
7pub enum Error {
8 #[error("failed to parse variable name: {}", name)]
9 InvalidVarName { name: String },
10 #[error("variable not found: {}", var)]
11 VarNotFound { var: Variable },
12 #[error("permission denied for variable: {}", var)]
13 PermissionDenied { var: Variable },
14 #[error("unknown i/o error for variable: {}", var)]
15 VarUnknownError { var: Variable, error: io::Error },
16 #[error("base64 decoding error: {}", error)]
17 #[cfg(feature = "store")]
18 Base64DecodeError { error: base64::DecodeError },
19 #[error("base64 decoding error: {}", error)]
20 #[cfg(feature = "store")]
21 Base64DecodeSliceError { error: base64::DecodeSliceError },
22 #[error("unknown i/o error: {}", .0)]
23 UnknownIoError(std::io::Error),
24 #[error("unknown EFI variable flag: '{}'", flag)]
25 UnknownFlag { flag: String },
26 #[error("failed to decode name as valid UTF-8")]
27 InvalidUTF8,
28 #[error("failed to decode uuid: {}", error)]
29 UuidError { error: uuid::Error },
30 #[error("failed to parse variable content (invalid content)")]
31 VarParseError,
32 #[error("failed to parse string: {}", 0)]
33 StringParseError(crate::utils::StringParseError),
34}
35
36#[cfg(not(target_os = "windows"))]
37fn is_variable_not_found_error(err: &io::Error) -> bool {
38 err.kind() == io::ErrorKind::NotFound
39}
40
41#[cfg(target_os = "windows")]
42fn is_variable_not_found_error(err: &io::Error) -> bool {
43 err.raw_os_error() == Some(203)
44}
45
46#[cfg(not(target_os = "windows"))]
47fn is_permission_denied_error(err: &io::Error) -> bool {
48 err.kind() == io::ErrorKind::PermissionDenied
49}
50
51#[cfg(target_os = "windows")]
52fn is_permission_denied_error(err: &io::Error) -> bool {
53 err.raw_os_error() == Some(1314)
54}
55
56impl Error {
57 pub fn for_variable(error: io::Error, var: &Variable) -> Self {
58 let var = var.clone();
59
60 if is_variable_not_found_error(&error) {
61 return Error::VarNotFound { var };
62 }
63
64 if is_permission_denied_error(&error) {
65 return Error::PermissionDenied { var };
66 }
67
68 Error::VarUnknownError { var, error }
69 }
70
71 #[cfg(target_os = "windows")]
72 pub fn for_variable_os(var: &Variable) -> Self {
73 Error::for_variable(io::Error::last_os_error(), var)
74 }
75}
76
77#[cfg(feature = "store")]
78impl From<base64::DecodeError> for Error {
79 fn from(error: base64::DecodeError) -> Self {
80 Error::Base64DecodeError { error }
81 }
82}
83
84#[cfg(feature = "store")]
85impl From<base64::DecodeSliceError> for Error {
86 fn from(error: base64::DecodeSliceError) -> Self {
87 Error::Base64DecodeSliceError { error }
88 }
89}