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::VmmNvramStorage;
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 #[allow(dead_code)]
32 async fn get_variable_ucs2(
33 &mut self,
34 vendor: Guid,
35 name: &Ucs2LeSlice,
36 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)>;
37
38 async fn set_variable(
41 &mut self,
42 vendor: Guid,
43 name: &str,
44 attr: u32,
45 data: Vec<u8>,
46 ) -> Result<(), (EfiStatus, Option<NvramError>)>;
47
48 async fn set_variable_ucs2(
51 &mut self,
52 vendor: Guid,
53 name: &Ucs2LeSlice,
54 attr: u32,
55 data: Vec<u8>,
56 ) -> Result<(), (EfiStatus, Option<NvramError>)>;
57}
58
59#[async_trait::async_trait]
60impl<S: VmmNvramStorage> NvramServicesExt for NvramSpecServices<S> {
61 async fn get_variable(
62 &mut self,
63 vendor: Guid,
64 name: &str,
65 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)> {
66 let name = ucs2::Ucs2LeVec::from(name);
67 self.get_variable_ucs2(vendor, &name).await
68 }
69
70 async fn get_variable_ucs2(
71 &mut self,
72 vendor: Guid,
73 name: &Ucs2LeSlice,
74 ) -> Result<(u32, Vec<u8>), (EfiStatus, Option<NvramError>)> {
75 let mut attr = 0;
76 let mut in_out_data_size = u32::MAX;
84 let NvramResult(data, status, err) = self
85 .uefi_get_variable(
86 Some(name.as_bytes()),
87 vendor,
88 &mut attr,
89 &mut in_out_data_size,
90 false,
91 )
92 .await;
93
94 if matches!(status, EfiStatus::SUCCESS) {
95 Ok((attr, data.expect("data will not be None on EFI_SUCCESS")))
96 } else {
97 Err((status, err))
98 }
99 }
100
101 async fn set_variable(
102 &mut self,
103 vendor: Guid,
104 name: &str,
105 attr: u32,
106 data: Vec<u8>,
107 ) -> Result<(), (EfiStatus, Option<NvramError>)> {
108 let name = ucs2::Ucs2LeVec::from(name);
109 self.set_variable_ucs2(vendor, &name, attr, data).await
110 }
111
112 async fn set_variable_ucs2(
113 &mut self,
114 vendor: Guid,
115 name: &Ucs2LeSlice,
116 attr: u32,
117 data: Vec<u8>,
118 ) -> Result<(), (EfiStatus, Option<NvramError>)> {
119 let NvramResult((), status, err) = self
120 .uefi_set_variable(
121 Some(name.as_bytes()),
122 vendor,
123 attr,
124 data.len() as u32,
125 Some(data),
126 )
127 .await;
128
129 if matches!(status, EfiStatus::SUCCESS) {
130 Ok(())
131 } else {
132 Err((status, err))
133 }
134 }
135}