uefi: Add process · model-checking/verify-rust-std@e6eeb4e (original) (raw)

`@@ -12,7 +12,7 @@

`

12

12

`use r_efi::efi::{self, Guid};

`

13

13

`use r_efi::protocols::{device_path, device_path_to_text};

`

14

14

``

15

``

`-

use crate::ffi::OsString;

`

``

15

`+

use crate::ffi::{OsString, OsStr};

`

16

16

`use crate::io::{self, const_io_error};

`

17

17

`use crate::mem::{size_of, MaybeUninit};

`

18

18

`use crate::os::uefi::{self, env::boot_services, ffi::OsStringExt};

`

`@@ -221,3 +221,73 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>>

`

221

221

`let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services };

`

222

222

`NonNull::new(runtime_services)

`

223

223

`}

`

``

224

+

``

225

`+

pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>);

`

``

226

+

``

227

`+

impl DevicePath {

`

``

228

`+

pub(crate) fn from_text(p: &OsStr) -> io::Result {

`

``

229

`+

fn inner(

`

``

230

`+

p: &OsStr,

`

``

231

`+

protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,

`

``

232

`+

) -> io::Result {

`

``

233

`+

let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec>();

`

``

234

`+

let path =

`

``

235

`+

unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };

`

``

236

+

``

237

`+

NonNull::new(path).map(DevicePath).ok_or_else(|| {

`

``

238

`+

const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")

`

``

239

`+

})

`

``

240

`+

}

`

``

241

+

``

242

`+

static LAST_VALID_HANDLE: AtomicPtrcrate::ffi::c_void =

`

``

243

`+

AtomicPtr::new(crate::ptr::null_mut());

`

``

244

+

``

245

`+

if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {

`

``

246

`+

if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(

`

``

247

`+

handle,

`

``

248

`+

r_efi::protocols::device_path_from_text::PROTOCOL_GUID,

`

``

249

`+

) {

`

``

250

`+

return inner(p, protocol);

`

``

251

`+

}

`

``

252

`+

}

`

``

253

+

``

254

`+

let handles = locate_handles(r_efi::protocols::device_path_from_text::PROTOCOL_GUID)?;

`

``

255

`+

for handle in handles {

`

``

256

`+

if let Ok(protocol) = open_protocol::<r_efi::protocols::device_path_from_text::Protocol>(

`

``

257

`+

handle,

`

``

258

`+

r_efi::protocols::device_path_from_text::PROTOCOL_GUID,

`

``

259

`+

) {

`

``

260

`+

LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);

`

``

261

`+

return inner(p, protocol);

`

``

262

`+

}

`

``

263

`+

}

`

``

264

+

``

265

`+

io::Result::Err(const_io_error!(

`

``

266

`+

io::ErrorKind::NotFound,

`

``

267

`+

"DevicePathFromText Protocol not found"

`

``

268

`+

))

`

``

269

`+

}

`

``

270

`+

}

`

``

271

+

``

272

`+

impl AsRef<r_efi::protocols::device_path::Protocol> for DevicePath {

`

``

273

`+

fn as_ref(&self) -> &r_efi::protocols::device_path::Protocol {

`

``

274

`+

unsafe { self.0.as_ref() }

`

``

275

`+

}

`

``

276

`+

}

`

``

277

+

``

278

`+

impl AsMut<r_efi::protocols::device_path::Protocol> for DevicePath {

`

``

279

`+

fn as_mut(&mut self) -> &mut r_efi::protocols::device_path::Protocol {

`

``

280

`+

unsafe { self.0.as_mut() }

`

``

281

`+

}

`

``

282

`+

}

`

``

283

+

``

284

`+

impl Drop for DevicePath {

`

``

285

`+

fn drop(&mut self) {

`

``

286

`+

if let Some(bt) = boot_services() {

`

``

287

`+

let bt: NonNull<r_efi::efi::BootServices> = bt.cast();

`

``

288

`+

unsafe {

`

``

289

`+

((*bt.as_ptr()).free_pool)(self.0.as_ptr() as *mut crate::ffi::c_void);

`

``

290

`+

}

`

``

291

`+

}

`

``

292

`+

}

`

``

293

`+

}

`