firmware_uefi/service/nvram/spec_services/
nvram_services_ext.rs1use super::NvramError;
5use super::NvramResult;
6use super::NvramSpecServices;
7use guid::Guid;
8use ucs2::Ucs2LeSlice;
9use uefi_nvram_storage::InspectableNvramStorage;
10use uefi_specs::uefi::common::EfiStatus;
11
12#[async_trait::async_trait]
19pub trait NvramServicesExt {
20 #[allow(dead_code)]
23 async fn get_variable(
24 &mut self,
25 vendor: Guid,
26 name: &str,
27 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)>;
28
29 async fn get_variable_ucs2(
32 &mut self,
33 vendor: Guid,
34 name: &Ucs2LeSlice,
35 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)>;
36
37 async fn set_variable(
40 &mut self,
41 vendor: Guid,
42 name: &str,
43 attr: u32,
44 data: Vec<u8>,
45 ) -> Result<(), (EfiStatus, Option<NvramError>)>;
46
47 async fn set_variable_ucs2(
50 &mut self,
51 vendor: Guid,
52 name: &Ucs2LeSlice,
53 attr: u32,
54 data: Vec<u8>,
55 ) -> Result<(), (EfiStatus, Option<NvramError>)>;
56}
57
58#[async_trait::async_trait]
59impl<S: InspectableNvramStorage> NvramServicesExt for NvramSpecServices<S> {
60 async fn get_variable(
61 &mut self,
62 vendor: Guid,
63 name: &str,
64 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)> {
65 let name = ucs2::Ucs2LeVec::from(name);
66 self.get_variable_ucs2(vendor, &name).await
67 }
68
69 async fn get_variable_ucs2(
70 &mut self,
71 vendor: Guid,
72 name: &Ucs2LeSlice,
73 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)> {
74 let mut attr = 0;
75 let mut in_out_data_size = u32::MAX;
83 let NvramResult(data, status, err) = self
84 .uefi_get_variable(
85 Some(name.as_bytes()),
86 vendor,
87 &mut attr,
88 &mut in_out_data_size,
89 false,
90 )
91 .await;
92
93 if matches!(status, EfiStatus::SUCCESS) {
94 Ok((attr, data.expect("data will not be None on EFI_SUCCESS")))
95 } else {
96 Err((status, err))
97 }
98 }
99
100 async fn set_variable(
101 &mut self,
102 vendor: Guid,
103 name: &str,
104 attr: u32,
105 data: Vec<u8>,
106 ) -> Result<(), (EfiStatus, Option<NvramError>)> {
107 let name = ucs2::Ucs2LeVec::from(name);
108 self.set_variable_ucs2(vendor, &name, attr, data).await
109 }
110
111 async fn set_variable_ucs2(
112 &mut self,
113 vendor: Guid,
114 name: &Ucs2LeSlice,
115 attr: u32,
116 data: Vec<u8>,
117 ) -> Result<(), (EfiStatus, Option<NvramError>)> {
118 let NvramResult((), status, err) = self
119 .uefi_set_variable(
120 Some(name.as_bytes()),
121 vendor,
122 attr,
123 data.len() as u32,
124 Some(data),
125 )
126 .await;
127
128 if matches!(status, EfiStatus::SUCCESS) {
129 Ok(())
130 } else {
131 Err((status, err))
132 }
133 }
134}