From 001b16e7a29269e28c0cdbeee6bd483cdd75d3b4 Mon Sep 17 00:00:00 2001 From: Ryan Cohen Date: Wed, 21 Dec 2022 11:01:46 -0500 Subject: [PATCH 1/2] Add some documentation for media protocols Also revised some existing documentation to match the current style of how most errors are documented. --- uefi/src/proto/media/file/dir.rs | 12 ++-- uefi/src/proto/media/file/mod.rs | 82 ++++++++++++++++++---------- uefi/src/proto/media/file/regular.rs | 38 ++++++++----- uefi/src/proto/media/fs.rs | 22 +++++--- uefi/src/table/boot.rs | 10 ++++ 5 files changed, 108 insertions(+), 56 deletions(-) diff --git a/uefi/src/proto/media/file/dir.rs b/uefi/src/proto/media/file/dir.rs index 9fd517e7d..03358346c 100644 --- a/uefi/src/proto/media/file/dir.rs +++ b/uefi/src/proto/media/file/dir.rs @@ -38,12 +38,8 @@ impl Directory { /// * `buffer` The target buffer of the read operation /// /// # Errors - /// * `uefi::Status::NO_MEDIA` The device has no media - /// * `uefi::Status::DEVICE_ERROR` The device reported an error, the file was deleted, - /// or the end of the file was reached before the `read()`. - /// * `uefi::Status::VOLUME_CORRUPTED` The filesystem structures are corrupted - /// * `uefi::Status::BUFFER_TOO_SMALL` The buffer is too small to hold a directory entry, - /// the required buffer size is provided into the error. + /// + /// All errors come from calls to [`RegularFile::read`]. pub fn read_entry<'buf>( &mut self, buffer: &'buf mut [u8], @@ -120,6 +116,10 @@ impl Directory { } /// Start over the process of enumerating directory entries + /// + /// # Errors + /// + /// All errors come from calls to [`RegularFile::set_position`]. pub fn reset_entry_readout(&mut self) -> Result { self.0.set_position(0) } diff --git a/uefi/src/proto/media/file/mod.rs b/uefi/src/proto/media/file/mod.rs index f29331eef..ef9191209 100644 --- a/uefi/src/proto/media/file/mod.rs +++ b/uefi/src/proto/media/file/mod.rs @@ -41,16 +41,27 @@ pub trait File: Sized { /// * `attributes` Only valid when `FILE_MODE_CREATE` is used as a mode /// /// # Errors - /// * `uefi::Status::INVALID_PARAMETER` The filename exceeds the maximum length of 255 chars - /// * `uefi::Status::NOT_FOUND` Could not find file - /// * `uefi::Status::NO_MEDIA` The device has no media - /// * `uefi::Status::MEDIA_CHANGED` The device has a different medium in it - /// * `uefi::Status::DEVICE_ERROR` The device reported an error - /// * `uefi::Status::VOLUME_CORRUPTED` The filesystem structures are corrupted - /// * `uefi::Status::WRITE_PROTECTED` Write/Create attempted on readonly file - /// * `uefi::Status::ACCESS_DENIED` The service denied access to the file - /// * `uefi::Status::OUT_OF_RESOURCES` Not enough resources to open file - /// * `uefi::Status::VOLUME_FULL` The volume is full + /// + /// See section `EFI_FILE_PROTOCOL.Open()` in the UEFI Specification for more details. + /// + /// ## Note + /// + /// Although [`INVALID_PARAMETER`] is not defined as an error in the UEFI Specification, + /// it can be returned if the opened filename exceeds the maximum length of 255 UCS-2 + /// characters (not including the null terminator). + /// + /// [`INVALID_PARAMETER`]: uefi::Status::INVALID_PARAMETER + /// + /// * [`uefi::Status::INVALID_PARAMETER`] + /// * [`uefi::Status::NOT_FOUND`] + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::MEDIA_CHANGED`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::WRITE_PROTECTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::OUT_OF_RESOURCES`] + /// * [`uefi::Status::VOLUME_FULL`] fn open( &mut self, filename: &CStr16, @@ -77,7 +88,10 @@ pub trait File: Sized { /// Closes and deletes this file /// /// # Warnings - /// * `uefi::Status::WARN_DELETE_FAILURE` The file was closed, but deletion failed + /// + /// See section `EFI_FILE_PROTOCOL.Delete()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::WARN_DELETE_FAILURE`] fn delete(mut self) -> Result { let result = (self.imp().delete)(self.imp()).into(); mem::forget(self); @@ -95,11 +109,14 @@ pub trait File: Sized { /// * `buffer` Buffer that the information should be written into /// /// # Errors - /// * `uefi::Status::UNSUPPORTED` The file does not possess this information type - /// * `uefi::Status::NO_MEDIA` The device has no medium - /// * `uefi::Status::DEVICE_ERROR` The device reported an error - /// * `uefi::Status::VOLUME_CORRUPTED` The file system structures are corrupted - /// * `uefi::Status::BUFFER_TOO_SMALL` The buffer is too small for the requested + /// + /// See section `EFI_FILE_PROTOCOL.GetInfo()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::UNSUPPORTED`] + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::BUFFER_TOO_SMALL`] fn get_info<'buf, Info: FileProtocolInfo + ?Sized>( &mut self, buffer: &'buf mut [u8], @@ -137,13 +154,17 @@ pub trait File: Sized { /// * `info` Info that should be set for the file /// /// # Errors - /// * `uefi::Status::UNSUPPORTED` The file does not possess this information type - /// * `uefi::Status::NO_MEDIA` The device has no medium - /// * `uefi::Status::DEVICE_ERROR` The device reported an error - /// * `uefi::Status::VOLUME_CORRUPTED` The file system structures are corrupted - /// * `uefi::Status::WRITE_PROTECTED` Attempted to set information on a read-only media - /// * `uefi::Status::ACCESS_DENIED` Requested change is invalid for this information type - /// * `uefi::Status::VOLUME_FULL` Not enough space left on the volume to change the info + /// + /// See section `EFI_FILE_PROTOCOL.SetInfo()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::UNSUPPORTED`] + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::WRITE_PROTECTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::VOLUME_FULL`] + /// * [`uefi::Status::BAD_BUFFER_SIZE`] fn set_info(&mut self, info: &Info) -> Result { let info_ptr = (info as *const Info).cast::(); let info_size = mem::size_of_val(&info); @@ -153,12 +174,15 @@ pub trait File: Sized { /// Flushes all modified data associated with the file handle to the device /// /// # Errors - /// * `uefi::Status::NO_MEDIA` The device has no media - /// * `uefi::Status::DEVICE_ERROR` The device reported an error - /// * `uefi::Status::VOLUME_CORRUPTED` The filesystem structures are corrupted - /// * `uefi::Status::WRITE_PROTECTED` The file or medium is write protected - /// * `uefi::Status::ACCESS_DENIED` The file was opened read only - /// * `uefi::Status::VOLUME_FULL` The volume is full + /// + /// See section `EFI_FILE_PROTOCOL.Flush()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::WRITE_PROTECTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::VOLUME_FULL`] fn flush(&mut self) -> Result { (self.imp().flush)(self.imp()).into() } diff --git a/uefi/src/proto/media/file/regular.rs b/uefi/src/proto/media/file/regular.rs index d1e143bfe..b4fd1af73 100644 --- a/uefi/src/proto/media/file/regular.rs +++ b/uefi/src/proto/media/file/regular.rs @@ -31,12 +31,13 @@ impl RegularFile { /// * `buffer` The target buffer of the read operation /// /// # Errors - /// * `uefi::Status::NO_MEDIA` The device has no media - /// * `uefi::Status::DEVICE_ERROR` The device reported an error, the file was deleted, - /// or the end of the file was reached before the `read()`. - /// * `uefi::Status::VOLUME_CORRUPTED` The filesystem structures are corrupted - /// * `uefi::Status::BUFFER_TOO_SMALL` The buffer is too small to hold a directory entry, - /// and the required buffer size is provided as output. + /// + /// See section `EFI_FILE_PROTOCOL.Read()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::BUFFER_TOO_SMALL`] pub fn read(&mut self, buffer: &mut [u8]) -> Result> { let mut buffer_size = buffer.len(); let status = @@ -67,12 +68,15 @@ impl RegularFile { /// * `buffer` Buffer to write to file /// /// # Errors - /// * `uefi::Status::NO_MEDIA` The device has no media - /// * `uefi::Status::DEVICE_ERROR` The device reported an error or the file was deleted. - /// * `uefi::Status::VOLUME_CORRUPTED` The filesystem structures are corrupted - /// * `uefi::Status::WRITE_PROTECTED` Attempt to write to readonly file - /// * `uefi::Status::ACCESS_DENIED` The file was opened read only. - /// * `uefi::Status::VOLUME_FULL` The volume is full + /// + /// See section `EFI_FILE_PROTOCOL.Write()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::WRITE_PROTECTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::VOLUME_FULL`] pub fn write(&mut self, buffer: &[u8]) -> Result<(), usize> { let mut buffer_size = buffer.len(); unsafe { (self.imp().write)(self.imp(), &mut buffer_size, buffer.as_ptr()) } @@ -82,7 +86,10 @@ impl RegularFile { /// Get the file's current position /// /// # Errors - /// * `uefi::Status::DEVICE_ERROR` An attempt was made to get the position of a deleted file + /// + /// See section `EFI_FILE_PROTOCOL.GetPosition()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::DEVICE_ERROR`] pub fn get_position(&mut self) -> Result { let mut pos = 0u64; (self.imp().get_position)(self.imp(), &mut pos).into_with_val(|| pos) @@ -99,7 +106,10 @@ impl RegularFile { /// * `position` The new absolution position of the file handle /// /// # Errors - /// * `uefi::Status::DEVICE_ERROR` An attempt was made to set the position of a deleted file + /// + /// See section `EFI_FILE_PROTOCOL.SetPosition()` in the UEFI Specification for more details. + /// + /// * [`uefi::Status::DEVICE_ERROR`] pub fn set_position(&mut self, position: u64) -> Result { (self.imp().set_position)(self.imp(), position).into() } diff --git a/uefi/src/proto/media/fs.rs b/uefi/src/proto/media/fs.rs index c016388c7..9c9112e77 100644 --- a/uefi/src/proto/media/fs.rs +++ b/uefi/src/proto/media/fs.rs @@ -31,13 +31,21 @@ impl SimpleFileSystem { /// Open the root directory on a volume. /// /// # Errors - /// * `uefi::Status::UNSUPPORTED` - The volume does not support the requested filesystem type - /// * `uefi::Status::NO_MEDIA` - The device has no media - /// * `uefi::Status::DEVICE_ERROR` - The device reported an error - /// * `uefi::Status::VOLUME_CORRUPTED` - The file system structures are corrupted - /// * `uefi::Status::ACCESS_DENIED` - The service denied access to the file - /// * `uefi::Status::OUT_OF_RESOURCES` - The volume was not opened - /// * `uefi::Status::MEDIA_CHANGED` - The device has a different medium in it + /// + /// See section `EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()` in the UEFI Specification + /// for more details. + /// + /// If you can't find the function definition, try searching for + /// `EFI_SIMPLE_FILE SYSTEM_PROTOCOL.OpenVolume()` (this has a space in between FILE and + /// SYSTEM; it could be a typo in the UEFI spec). + /// + /// * [`uefi::Status::UNSUPPORTED`] + /// * [`uefi::Status::NO_MEDIA`] + /// * [`uefi::Status::DEVICE_ERROR`] + /// * [`uefi::Status::VOLUME_CORRUPTED`] + /// * [`uefi::Status::ACCESS_DENIED`] + /// * [`uefi::Status::OUT_OF_RESOURCES`] + /// * [`uefi::Status::MEDIA_CHANGED`] pub fn open_volume(&mut self) -> Result { let mut ptr = ptr::null_mut(); (self.open_volume)(self, &mut ptr) diff --git a/uefi/src/table/boot.rs b/uefi/src/table/boot.rs index 2f5d6b638..26ca387af 100644 --- a/uefi/src/table/boot.rs +++ b/uefi/src/table/boot.rs @@ -996,6 +996,10 @@ impl BootServices { /// # Ok(()) /// # } /// ``` + /// + /// # Errors + /// + /// Returns [`NOT_FOUND`] if no handles support the requested protocol. pub fn get_handle_for_protocol(&self) -> Result { // Delegate to a non-generic function to potentially reduce code size. self.get_handle_for_protocol_impl(&P::GUID) @@ -1523,6 +1527,12 @@ impl BootServices { #[cfg(feature = "alloc")] impl BootServices { /// Returns all the handles implementing a certain protocol. + /// + /// # Errors + /// + /// All errors come from calls to [`locate_handle`]. + /// + /// [`locate_handle`]: Self::locate_handle pub fn find_handles(&self) -> Result> { // Search by protocol. let search_type = SearchType::from_proto::

(); From 21c2a424edd6acb43924db71481e8fb12b0075b7 Mon Sep 17 00:00:00 2001 From: Ryan Cohen Date: Tue, 27 Dec 2022 11:06:48 -0500 Subject: [PATCH 2/2] Fix error documentation for `File::open` --- uefi/src/proto/media/file/mod.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/uefi/src/proto/media/file/mod.rs b/uefi/src/proto/media/file/mod.rs index ef9191209..61cd8568c 100644 --- a/uefi/src/proto/media/file/mod.rs +++ b/uefi/src/proto/media/file/mod.rs @@ -43,12 +43,9 @@ pub trait File: Sized { /// # Errors /// /// See section `EFI_FILE_PROTOCOL.Open()` in the UEFI Specification for more details. - /// - /// ## Note - /// - /// Although [`INVALID_PARAMETER`] is not defined as an error in the UEFI Specification, - /// it can be returned if the opened filename exceeds the maximum length of 255 UCS-2 - /// characters (not including the null terminator). + /// Note that [`INVALID_PARAMETER`] is not listed in the specification as one of the + /// errors returned by this function, but some implementations (such as EDK2) perform + /// additional validation and may return that status for invalid inputs. /// /// [`INVALID_PARAMETER`]: uefi::Status::INVALID_PARAMETER ///