Search code examples
rustffiuefi

How use UEFI locate_protocol in a rust project with r_efi crate


In a cross-compiled educative project with rust and the crate r_efi and without the rust standard library, I wanna make a small program to UEFI systems. For the moment, the goal is to be able to use the graphical output protocol.

Through the use of r_efi crate, I start by locating the GOP with the system module :

r_efi::system::BootServices::locate_protocol

The definition is :

locate_protocol: extern "win64" fn(_: *mut Guid, _: *mut c_void, _: *mut *mut c_void) -> Status

My problem is this 2 parameters :

_: *mut c_void

and

_: *mut *mut c_void

I don't know how return core::ffi::c_void parameters like in a C code :

EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) {
      EFI_BOOT_SERVICES *bs = systemTable->BootServices;
      EFI_GRAPHICS_OUTPUT_PROTOCOL *graphicsProtocol;
      EFI_STATUS status;

      status = bs->LocateProtocol(&GraphicsOutputProtocolGUID, NULL, (void**)&graphicsProtocol);

Thank in advance for your explanations.


Solution

  • Well, here a code solution ( working on virtualbox ) to locate the graphical output protocol with the r_efi crate :

    #[export_name = "efi_main"]
    pub extern fn main(_h: efi::Handle, st: *mut efi::SystemTable) -> efi::Status {
    
         let mut gop: *mut efi::protocols::graphics_output::Protocol = ptr::null_mut();
         let mut guid_gop: efi::Guid = efi::protocols::graphics_output::PROTOCOL_GUID;
    
         let stats = unsafe { ((*(*st).boot_services).locate_protocol)(
                &mut guid_gop as *mut _,
                ptr::null_mut(),
                &mut gop as *mut _ as *mut *mut core::ffi::c_void,
         )};
    
         match stats {
    
            efi::Status::SUCCESS => {...},
            efi::Status::NOT_FOUND => {...},
    
         }
    
         efi::Status::SUCCESS
    }