@@ -5,120 +5,154 @@ use super::Result;
5
5
use core:: ops;
6
6
use ucs2;
7
7
8
- const HIGHEST_BIT_SET : usize = !( ( !0_usize ) >> 1 ) ;
9
-
10
- /// Status codes are returned by UEFI interfaces
11
- /// to indicate whether an operation completed successfully.
8
+ /// UEFI uses status codes in order to report successes, errors, and warnings.
9
+ ///
10
+ /// Unfortunately, the spec allows and encourages implementation-specific
11
+ /// non-portable status codes. Therefore, these cannot be modeled as a Rust
12
+ /// enum, as injecting an unknown value in a Rust enum is undefined behaviour.
13
+ ///
14
+ /// For lack of a better option, we therefore model them as a newtype of usize.
12
15
#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
13
- #[ repr( usize ) ]
16
+ #[ repr( transparent ) ]
14
17
#[ must_use]
15
- pub enum Status {
18
+ pub struct Status ( usize ) ;
19
+
20
+ /// Macro to make implementation of status codes easier
21
+ macro_rules! status_codes {
22
+ ( $( $( #[ $attr: meta] ) *
23
+ $status: ident = $code: expr, ) *
24
+ ) => {
25
+ #[ allow( unused) ]
26
+ impl Status {
27
+ $( $( #[ $attr] ) *
28
+ pub const $status: Status = Status ( $code) ; ) *
29
+ }
30
+ }
31
+ }
32
+ //
33
+ status_codes ! {
16
34
/// The operation completed successfully.
17
- Success ,
18
- /// The string contained characters that the device could not render and were skipped.
19
- WarnUnknownGlyph ,
35
+ SUCCESS = 0 ,
36
+ /// The string contained characters that could not be rendered and were skipped.
37
+ WARN_UNKNOWN_GLYPH = 1 ,
20
38
/// The handle was closed, but the file was not deleted.
21
- WarnDeleteFailure ,
39
+ WARN_DELETE_FAILURE = 2 ,
22
40
/// The handle was closed, but the data to the file was not flushed properly.
23
- WarnWriteFailure ,
24
- /// The resulting buffer was too small,
25
- /// and the data was truncated to the buffer size.
26
- WarnBufferTooSmall ,
27
- /// The data has not been updated within the timeframe
28
- /// set by local policy for this type of data.
29
- WarnStaleData ,
41
+ WARN_WRITE_FAILURE = 3 ,
42
+ /// The resulting buffer was too small, and the data was truncated.
43
+ WARN_BUFFER_TOO_SMALL = 4 ,
44
+ /// The data has not been updated within the timeframe set by local policy.
45
+ WARN_STALE_DATA = 5 ,
30
46
/// The resulting buffer contains UEFI-compliant file system.
31
- WarnFileSystem ,
47
+ WARN_FILE_SYSTEM = 6 ,
32
48
/// The operation will be processed across a system reset.
33
- WarnResetRequired ,
49
+ WARN_RESET_REQUIRED = 7 ,
50
+ }
51
+
52
+ /// Bit indicating that a status code is an error
53
+ const ERROR_BIT : usize = 1 << ( core:: mem:: size_of :: < usize > ( ) * 8 - 1 ) ;
54
+
55
+ /// Macro to make implementation of error codes easier
56
+ macro_rules! error_codes {
57
+ ( $( $( #[ $attr: meta] ) *
58
+ $status: ident = $error_code: expr, ) *
59
+ ) => {
60
+ status_codes! { $(
61
+ $( #[ $attr] ) *
62
+ $status = $error_code | ERROR_BIT ,
63
+ ) * }
64
+ }
65
+ }
66
+ //
67
+ error_codes ! {
34
68
/// The image failed to load.
35
- LoadError = 1 | HIGHEST_BIT_SET ,
69
+ LOAD_ERROR = 1 ,
36
70
/// A parameter was incorrect.
37
- InvalidParameter ,
71
+ INVALID_PARAMETER = 2 ,
38
72
/// The operation is not supported.
39
- Unsupported ,
73
+ UNSUPPORTED = 3 ,
40
74
/// The buffer was not the proper size for the request.
41
- BadBufferSize ,
75
+ BAD_BUFFER_SIZE = 4 ,
42
76
/// The buffer is not large enough to hold the requested data.
43
77
/// The required buffer size is returned in the appropriate parameter.
44
- BufferTooSmall ,
78
+ BUFFER_TOO_SMALL = 5 ,
45
79
/// There is no data pending upon return.
46
- NotReady ,
80
+ NOT_READY = 6 ,
47
81
/// The physical device reported an error while attempting the operation.
48
- DeviceError ,
82
+ DEVICE_ERROR = 7 ,
49
83
/// The device cannot be written to.
50
- WriteProtected ,
84
+ WRITE_PROTECTED = 8 ,
51
85
/// A resource has run out.
52
- OutOfResources ,
53
- /// An inconstancy was detected on the file system causing the operating to fail .
54
- VolumeCorrupted ,
86
+ OUT_OF_RESOURCES = 9 ,
87
+ /// An inconstency was detected on the file system.
88
+ VOLUME_CORRUPTED = 10 ,
55
89
/// There is no more space on the file system.
56
- VolumeFull ,
90
+ VOLUME_FULL = 11 ,
57
91
/// The device does not contain any medium to perform the operation.
58
- NoMedia ,
92
+ NO_MEDIA = 12 ,
59
93
/// The medium in the device has changed since the last access.
60
- MediaChanged ,
94
+ MEDIA_CHANGED = 13 ,
61
95
/// The item was not found.
62
- NotFound ,
96
+ NOT_FOUND = 14 ,
63
97
/// Access was denied.
64
- AccessDenied ,
98
+ ACCESS_DENIED = 15 ,
65
99
/// The server was not found or did not respond to the request.
66
- NoResponse ,
100
+ NO_RESPONSE = 16 ,
67
101
/// A mapping to a device does not exist.
68
- NoMapping ,
102
+ NO_MAPPING = 17 ,
69
103
/// The timeout time expired.
70
- Timeout ,
104
+ TIMEOUT = 18 ,
71
105
/// The protocol has not been started.
72
- NotStarted ,
106
+ NOT_STARTED = 19 ,
73
107
/// The protocol has already been started.
74
- AlreadyStarted ,
108
+ ALREADY_STARTED = 20 ,
75
109
/// The operation was aborted.
76
- Aborted ,
110
+ ABORTED = 21 ,
77
111
/// An ICMP error occurred during the network operation.
78
- IcmpError ,
112
+ ICMP_ERROR = 22 ,
79
113
/// A TFTP error occurred during the network operation.
80
- TftpError ,
114
+ TFTP_ERROR = 23 ,
81
115
/// A protocol error occurred during the network operation.
82
- ProtocolError ,
116
+ PROTOCOL_ERROR = 24 ,
83
117
/// The function encountered an internal version that was
84
118
/// incompatible with a version requested by the caller.
85
- IncompatibleVersion ,
119
+ INCOMPATIBLE_VERSION = 25 ,
86
120
/// The function was not performed due to a security violation.
87
- SecurityViolation ,
121
+ SECURITY_VIOLATION = 26 ,
88
122
/// A CRC error was detected.
89
- CrcError ,
123
+ CRC_ERROR = 27 ,
90
124
/// Beginning or end of media was reached
91
- EndOfMedia ,
125
+ END_OF_MEDIA = 28 ,
92
126
/// The end of the file was reached.
93
- EndOfFile = 31 | HIGHEST_BIT_SET ,
127
+ END_OF_FILE = 31 ,
94
128
/// The language specified was invalid.
95
- InvalidLanguage ,
129
+ INVALID_LANGUAGE = 32 ,
96
130
/// The security status of the data is unknown or compromised and
97
131
/// the data must be updated or replaced to restore a valid security status.
98
- CompromisedData ,
132
+ COMPROMISED_DATA = 33 ,
99
133
/// There is an address conflict address allocation
100
- IpAddressConflict ,
134
+ IP_ADDRESS_CONFLICT = 34 ,
101
135
/// A HTTP error occurred during the network operation.
102
- HttpError ,
136
+ HTTP_ERROR = 35 ,
103
137
}
104
138
105
139
impl Status {
106
140
/// Returns true if status code indicates success.
107
141
#[ inline]
108
142
pub fn is_success ( self ) -> bool {
109
- self == Status :: Success
143
+ self == Status :: SUCCESS
110
144
}
111
145
112
146
/// Returns true if status code indicates a warning.
113
147
#[ inline]
114
148
pub fn is_warning ( self ) -> bool {
115
- ( self as usize ) & HIGHEST_BIT_SET == 0
149
+ ( self != Status :: SUCCESS ) && ( self . 0 & ERROR_BIT == 0 )
116
150
}
117
151
118
152
/// Returns true if the status code indicates an error.
119
153
#[ inline]
120
154
pub fn is_error ( self ) -> bool {
121
- ( self as usize ) & HIGHEST_BIT_SET != 0
155
+ self . 0 & ERROR_BIT != 0
122
156
}
123
157
124
158
/// Converts this status code into a result with a given value.
@@ -127,6 +161,7 @@ impl Status {
127
161
where
128
162
F : FnOnce ( ) -> T ,
129
163
{
164
+ // FIXME: Is that the best way to handle warnings?
130
165
if self . is_success ( ) {
131
166
Ok ( f ( ) )
132
167
} else {
@@ -155,18 +190,18 @@ impl ops::Try for Status {
155
190
}
156
191
157
192
fn from_ok ( _: Self :: Ok ) -> Self {
158
- Status :: Success
193
+ Status :: SUCCESS
159
194
}
160
195
}
161
196
162
197
impl From < ucs2:: Error > for Status {
163
198
fn from ( other : ucs2:: Error ) -> Self {
164
199
use ucs2:: Error ;
165
200
match other {
166
- Error :: InvalidData => Status :: CompromisedData ,
167
- Error :: BufferUnderflow => Status :: BadBufferSize ,
168
- Error :: BufferOverflow => Status :: BufferTooSmall ,
169
- Error :: MultiByte => Status :: Unsupported ,
201
+ Error :: InvalidData => Status :: INVALID_PARAMETER ,
202
+ Error :: BufferUnderflow => Status :: BAD_BUFFER_SIZE ,
203
+ Error :: BufferOverflow => Status :: BUFFER_TOO_SMALL ,
204
+ Error :: MultiByte => Status :: UNSUPPORTED ,
170
205
}
171
206
}
172
207
}
0 commit comments