iPXE
Data Structures | Macros | Functions | Variables
efi_local.c File Reference

EFI local file access. More...

#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/refcnt.h>
#include <ipxe/malloc.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/uri.h>
#include <ipxe/iobuf.h>
#include <ipxe/process.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
#include <ipxe/efi/Guid/FileInfo.h>
#include <ipxe/efi/Guid/FileSystemInfo.h>

Go to the source code of this file.

Data Structures

struct  efi_local
 An EFI local file. More...
 

Macros

#define EFI_LOCAL_BLKSIZE   4096
 Download blocksize. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void efi_local_close (struct efi_local *local, int rc)
 Close local file. More...
 
static void efi_local_step (struct efi_local *local)
 Local file process. More...
 
static int efi_local_check_volume_name (struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL *root, const char *volume)
 Check for matching volume name. More...
 
static int efi_local_open_root (struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL **root)
 Open root filesystem. More...
 
static int efi_local_open_volume (struct efi_local *local, const char *volume)
 Open root filesystem of specified volume. More...
 
static int efi_local_open_resolved (struct efi_local *local, const char *resolved)
 Open fully-resolved path. More...
 
static int efi_local_open_path (struct efi_local *local, const char *filename)
 Open specified path. More...
 
static int efi_local_len (struct efi_local *local)
 Get file length. More...
 
static int efi_local_open (struct interface *xfer, struct uri *uri)
 Open local file. More...
 

Variables

static struct interface_operation efi_local_operations []
 Data transfer interface operations. More...
 
static struct interface_descriptor efi_local_xfer_desc
 Data transfer interface descriptor. More...
 
static struct process_descriptor efi_local_process_desc
 Process descriptor. More...
 
struct uri_opener efi_local_uri_opener __uri_opener
 EFI local file URI opener. More...
 

Detailed Description

EFI local file access.

Definition in file efi_local.c.

Macro Definition Documentation

◆ EFI_LOCAL_BLKSIZE

#define EFI_LOCAL_BLKSIZE   4096

Download blocksize.

Definition at line 52 of file efi_local.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ efi_local_close()

static void efi_local_close ( struct efi_local local,
int  rc 
)
static

Close local file.

Parameters
localLocal file
rcReason for close

Definition at line 77 of file efi_local.c.

77  {
78 
79  /* Stop process */
80  process_del ( &local->process );
81 
82  /* Shut down data transfer interface */
83  intf_shutdown ( &local->xfer, rc );
84 
85  /* Close EFI file */
86  if ( local->file ) {
87  local->file->Close ( local->file );
88  local->file = NULL;
89  }
90 
91  /* Close EFI root directory */
92  if ( local->root ) {
93  local->root->Close ( local->root );
94  local->root = NULL;
95  }
96 }
EFI_FILE_CLOSE Close
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
struct process process
Download process.
Definition: efi_local.c:61
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
EFI_FILE_PROTOCOL * file
EFI file.
Definition: efi_local.c:66
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:64
struct interface xfer
Data transfer interface.
Definition: efi_local.c:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References _EFI_FILE_PROTOCOL::Close, efi_local::file, intf_shutdown(), NULL, efi_local::process, process_del(), rc, efi_local::root, and efi_local::xfer.

Referenced by efi_local_open(), and efi_local_step().

◆ efi_local_step()

static void efi_local_step ( struct efi_local local)
static

Local file process.

Parameters
localLocal file

Definition at line 103 of file efi_local.c.

103  {
104  EFI_FILE_PROTOCOL *file = local->file;
105  struct io_buffer *iobuf = NULL;
106  size_t remaining;
107  size_t frag_len;
108  UINTN size;
109  EFI_STATUS efirc;
110  int rc;
111 
112  /* Wait until data transfer interface is ready */
113  if ( ! xfer_window ( &local->xfer ) )
114  return;
115 
116  /* Presize receive buffer */
117  remaining = local->len;
118  xfer_seek ( &local->xfer, remaining );
119  xfer_seek ( &local->xfer, 0 );
120 
121  /* Get file contents */
122  while ( remaining ) {
123 
124  /* Calculate length for this fragment */
125  frag_len = remaining;
126  if ( frag_len > EFI_LOCAL_BLKSIZE )
127  frag_len = EFI_LOCAL_BLKSIZE;
128 
129  /* Allocate I/O buffer */
130  iobuf = xfer_alloc_iob ( &local->xfer, frag_len );
131  if ( ! iobuf ) {
132  rc = -ENOMEM;
133  goto err;
134  }
135 
136  /* Read block */
137  size = frag_len;
138  if ( ( efirc = file->Read ( file, &size, iobuf->data ) ) != 0 ){
139  rc = -EEFI ( efirc );
140  DBGC ( local, "LOCAL %p could not read from file: %s\n",
141  local, strerror ( rc ) );
142  goto err;
143  }
144  assert ( size <= frag_len );
145  iob_put ( iobuf, size );
146 
147  /* Deliver data */
148  if ( ( rc = xfer_deliver_iob ( &local->xfer,
149  iob_disown ( iobuf ) ) ) != 0 ) {
150  DBGC ( local, "LOCAL %p could not deliver data: %s\n",
151  local, strerror ( rc ) );
152  goto err;
153  }
154 
155  /* Move to next block */
156  remaining -= frag_len;
157  }
158 
159  /* Close download */
160  efi_local_close ( local, 0 );
161 
162  return;
163 
164  err:
165  free_iob ( iobuf );
166  efi_local_close ( local, rc );
167 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:120
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
EFI_FILE_PROTOCOL * file
EFI file.
Definition: efi_local.c:66
size_t len
Length of file.
Definition: efi_local.c:68
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition: xfer.c:350
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
UINT64 UINTN
Unsigned value of native width.
static void efi_local_close(struct efi_local *local, int rc)
Close local file.
Definition: efi_local.c:77
void * data
Start of data.
Definition: iobuf.h:48
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
struct interface xfer
Data transfer interface.
Definition: efi_local.c:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define EFI_LOCAL_BLKSIZE
Download blocksize.
Definition: efi_local.c:52
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), io_buffer::data, DBGC, EEFI, EFI_LOCAL_BLKSIZE, efi_local_close(), ENOMEM, efi_local::file, free_iob(), iob_disown, iob_put, efi_local::len, NULL, rc, _EFI_FILE_PROTOCOL::Read, size, strerror(), efi_local::xfer, xfer_alloc_iob(), xfer_deliver_iob(), xfer_seek(), and xfer_window().

◆ efi_local_check_volume_name()

static int efi_local_check_volume_name ( struct efi_local local,
EFI_HANDLE  device,
EFI_FILE_PROTOCOL root,
const char *  volume 
)
static

Check for matching volume name.

Parameters
localLocal file
deviceDevice handle
rootRoot filesystem handle
volumeVolume name
Return values
rcReturn status code

Definition at line 192 of file efi_local.c.

195  {
197  UINTN size;
198  char *label;
199  EFI_STATUS efirc;
200  int rc;
201 
202  /* Get length of file system information */
203  size = 0;
204  root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
205 
206  /* Allocate file system information */
207  info = malloc ( size );
208  if ( ! info ) {
209  rc = -ENOMEM;
210  goto err_alloc_info;
211  }
212 
213  /* Get file system information */
214  if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
215  info ) ) != 0 ) {
216  rc = -EEFI ( efirc );
217  DBGC ( local, "LOCAL %p could not get file system info on %s: "
218  "%s\n", local, efi_handle_name ( device ),
219  strerror ( rc ) );
220  goto err_get_info;
221  }
222  DBGC2 ( local, "LOCAL %p found %s with label \"%ls\"\n",
223  local, efi_handle_name ( device ), info->VolumeLabel );
224 
225  /* Construct volume label for comparison */
226  if ( asprintf ( &label, "%ls", info->VolumeLabel ) < 0 ) {
227  rc = -ENOMEM;
228  goto err_alloc_label;
229  }
230 
231  /* Compare volume label */
232  if ( strcasecmp ( volume, label ) != 0 ) {
233  rc = -ENOENT;
234  goto err_compare;
235  }
236 
237  /* Success */
238  rc = 0;
239 
240  err_compare:
241  free ( label );
242  err_alloc_label:
243  err_get_info:
244  free ( info );
245  err_alloc_info:
246  return rc;
247 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
u32 info
Definition: ar9003_mac.h:67
struct stp_switch root
Root switch.
Definition: stp.h:26
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:311
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
#define ENOMEM
Not enough space.
Definition: errno.h:534
A hardware device.
Definition: device.h:73
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:724
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
UINT64 UINTN
Unsigned value of native width.
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define DBGC2(...)
Definition: compiler.h:522
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References asprintf(), DBGC, DBGC2, EEFI, efi_file_system_info_id, efi_handle_name(), ENOENT, ENOMEM, free, info, malloc(), NULL, rc, root, size, strcasecmp(), and strerror().

Referenced by efi_local_open_volume().

◆ efi_local_open_root()

static int efi_local_open_root ( struct efi_local local,
EFI_HANDLE  device,
EFI_FILE_PROTOCOL **  root 
)
static

Open root filesystem.

Parameters
localLocal file
deviceDevice handle
rootRoot filesystem handle to fill in
Return values
rcReturn status code

Definition at line 257 of file efi_local.c.

258  {
260  union {
261  void *interface;
263  } u;
264  EFI_STATUS efirc;
265  int rc;
266 
267  /* Open file system protocol */
268  if ( ( efirc = bs->OpenProtocol ( device,
270  &u.interface, efi_image_handle,
271  device,
273  rc = -EEFI ( efirc );
274  DBGC ( local, "LOCAL %p could not open filesystem on %s: %s\n",
275  local, efi_handle_name ( device ), strerror ( rc ) );
276  goto err_filesystem;
277  }
278 
279  /* Open root directory */
280  if ( ( efirc = u.fs->OpenVolume ( u.fs, root ) ) != 0 ) {
281  rc = -EEFI ( efirc );
282  DBGC ( local, "LOCAL %p could not open volume on %s: %s\n",
283  local, efi_handle_name ( device ), strerror ( rc ) );
284  goto err_volume;
285  }
286 
287  /* Success */
288  rc = 0;
289 
290  err_volume:
293  err_filesystem:
294  return rc;
295 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2030
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
struct stp_switch root
Root switch.
Definition: stp.h:26
#define DBGC(...)
Definition: compiler.h:505
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1936
A hardware device.
Definition: device.h:73
An object interface.
Definition: interface.h:124
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:237
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1299
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:724
uint32_t fs
Definition: librm.h:252
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1866
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
union @17 u
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1935

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, DBGC, EEFI, efi_handle_name(), efi_image_handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL, efi_simple_file_system_protocol_guid, efi_systab, fs, EFI_BOOT_SERVICES::OpenProtocol, rc, root, strerror(), and u.

Referenced by efi_local_open_volume().

◆ efi_local_open_volume()

static int efi_local_open_volume ( struct efi_local local,
const char *  volume 
)
static

Open root filesystem of specified volume.

Parameters
localLocal file
volumeVolume name, or NULL to use loaded image's device
Return values
rcReturn status code

Definition at line 304 of file efi_local.c.

305  {
308  int ( * check ) ( struct efi_local *local, EFI_HANDLE device,
309  EFI_FILE_PROTOCOL *root, const char *volume );
312  EFI_HANDLE *handles;
314  UINTN num_handles;
315  UINTN i;
316  EFI_STATUS efirc;
317  int rc;
318 
319  /* Identify candidate handles */
320  if ( volume ) {
321  /* Locate all filesystem handles */
322  if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
323  NULL, &num_handles,
324  &handles ) ) != 0 ) {
325  rc = -EEFI ( efirc );
326  DBGC ( local, "LOCAL %p could not enumerate handles: "
327  "%s\n", local, strerror ( rc ) );
328  return rc;
329  }
331  } else {
332  /* Locate filesystem from which we were loaded */
333  path = efi_loaded_image_path;
334  if ( ( efirc = bs->LocateDevicePath ( protocol, &path,
335  &device ) ) != 0 ) {
336  rc = -EEFI ( efirc );
337  DBGC ( local, "LOCAL %p could not locate file system "
338  "on %s: %s\n", local,
340  strerror ( rc ) );
341  return rc;
342  }
343  handles = &device;
344  num_handles = 1;
345  check = NULL;
346  }
347 
348  /* Find matching handle */
349  for ( i = 0 ; i < num_handles ; i++ ) {
350 
351  /* Get this device handle */
352  device = handles[i];
353 
354  /* Open root directory */
355  if ( ( rc = efi_local_open_root ( local, device, &root ) ) != 0)
356  continue;
357 
358  /* Check volume name, if applicable */
359  if ( ( check == NULL ) ||
360  ( ( rc = check ( local, device, root, volume ) ) == 0 ) ) {
361  DBGC ( local, "LOCAL %p using %s",
362  local, efi_handle_name ( device ) );
363  if ( volume )
364  DBGC ( local, " with label \"%s\"", volume );
365  DBGC ( local, "\n" );
366  local->root = root;
367  break;
368  }
369 
370  /* Close root directory */
371  root->Close ( root );
372  }
373 
374  /* Free handles, if applicable */
375  if ( volume )
376  bs->FreePool ( handles );
377 
378  /* Fail if we found no matching handle */
379  if ( ! local->root ) {
380  DBGC ( local, "LOCAL %p found no matching handle\n", local );
381  return -ENOENT;
382  }
383 
384  return 0;
385 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2030
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
struct stp_switch root
Root switch.
Definition: stp.h:26
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
uint16_t device
Device ID.
Definition: ena.h:24
A hardware device.
Definition: device.h:73
EFI_DEVICE_PATH_PROTOCOL * efi_loaded_image_path
Device path for the loaded image's device handle.
Definition: efi_init.c:40
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:237
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:377
static int efi_local_check_volume_name(struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL *root, const char *volume)
Check for matching volume name.
Definition: efi_local.c:192
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:724
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1866
static int efi_local_open_root(struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL **root)
Open root filesystem.
Definition: efi_local.c:257
UINT64 UINTN
Unsigned value of native width.
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1885
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:64
An EFI local file.
Definition: efi_local.c:55
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
Retrieve the set of handles from the handle database that support a specified protocol.
Definition: UefiSpec.h:1475
EFI_SYSTEM_TABLE * efi_systab
uint16_t protocol
Protocol ID.
Definition: stp.h:18
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:50
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:1943
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1907

References EFI_SYSTEM_TABLE::BootServices, ByProtocol, DBGC, device, EEFI, efi_devpath_text(), efi_handle_name(), efi_loaded_image_path, efi_local_check_volume_name(), efi_local_open_root(), efi_simple_file_system_protocol_guid, efi_systab, ENOENT, EFI_BOOT_SERVICES::FreePool, EFI_BOOT_SERVICES::LocateDevicePath, EFI_BOOT_SERVICES::LocateHandleBuffer, NULL, protocol, rc, root, efi_local::root, and strerror().

Referenced by efi_local_open().

◆ efi_local_open_resolved()

static int efi_local_open_resolved ( struct efi_local local,
const char *  resolved 
)
static

Open fully-resolved path.

Parameters
localLocal file
resolvedResolved path
Return values
rcReturn status code

Definition at line 394 of file efi_local.c.

395  {
396  size_t name_len = strlen ( resolved );
397  CHAR16 name[ name_len + 1 /* wNUL */ ];
399  EFI_STATUS efirc;
400  int rc;
401 
402  /* Construct filename */
403  efi_snprintf ( name, ( name_len + 1 /* wNUL */ ), "%s", resolved );
404 
405  /* Open file */
406  if ( ( efirc = local->root->Open ( local->root, &file, name,
407  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
408  rc = -EEFI ( efirc );
409  DBGC ( local, "LOCAL %p could not open \"%s\": %s\n",
410  local, resolved, strerror ( rc ) );
411  return rc;
412  }
413  local->file = file;
414 
415  return 0;
416 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
#define DBGC(...)
Definition: compiler.h:505
unsigned short CHAR16
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
EFI_FILE_PROTOCOL * file
EFI file.
Definition: efi_local.c:66
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:64
#define EFI_FILE_MODE_READ
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.

References DBGC, EEFI, EFI_FILE_MODE_READ, efi_snprintf(), efi_local::file, name, _EFI_FILE_PROTOCOL::Open, rc, efi_local::root, strerror(), and strlen().

Referenced by efi_local_open_path().

◆ efi_local_open_path()

static int efi_local_open_path ( struct efi_local local,
const char *  filename 
)
static

Open specified path.

Parameters
localLocal file
filenamePath to file relative to our own image
Return values
rcReturn status code

Definition at line 425 of file efi_local.c.

426  {
430  char base[ efi_path_len ( path ) / 2 /* Cannot exceed this length */ ];
431  size_t remaining = sizeof ( base );
432  size_t len;
433  char *resolved;
434  char *tmp;
435  int rc;
436 
437  /* Construct base path to our own image, if possible */
438  memset ( base, 0, sizeof ( base ) );
439  tmp = base;
440  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
441  fp = container_of ( path, FILEPATH_DEVICE_PATH, Header );
442  len = snprintf ( tmp, remaining, "%ls", fp->PathName );
443  assert ( len < remaining );
444  tmp += len;
445  remaining -= len;
446  }
447  DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
448  local, base );
449 
450  /* Convert to sane path separators */
451  for ( tmp = base ; *tmp ; tmp++ ) {
452  if ( *tmp == '\\' )
453  *tmp = '/';
454  }
455 
456  /* Resolve path */
457  resolved = resolve_path ( base, filename );
458  if ( ! resolved ) {
459  rc = -ENOMEM;
460  goto err_resolve;
461  }
462 
463  /* Convert to insane path separators */
464  for ( tmp = resolved ; *tmp ; tmp++ ) {
465  if ( *tmp == '/' )
466  *tmp = '\\';
467  }
468  DBGC ( local, "LOCAL %p using \"%s\"\n",
469  local, resolved );
470 
471  /* Open resolved path */
472  if ( ( rc = efi_local_open_resolved ( local, resolved ) ) != 0 )
473  goto err_open;
474 
475  err_open:
476  free ( resolved );
477  err_resolve:
478  return rc;
479 }
EFI_LOADED_IMAGE_PROTOCOL * efi_loaded_image
Loaded image protocol for this image.
Definition: efi_init.c:37
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
EFI_DEVICE_PATH_PROTOCOL * FilePath
A pointer to the file path portion specific to DeviceHandle that the EFI Image was loaded from.
Definition: LoadedImage.h:56
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:106
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1086
unsigned long tmp
Definition: linux_pci.h:53
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
char * resolve_path(const char *base_path, const char *relative_path)
Resolve base+relative path.
Definition: uri.c:632
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI_DEVICE_PATH_PROTOCOL * efi_path_next(EFI_DEVICE_PATH_PROTOCOL *path)
Find next element in device path.
Definition: efi_path.c:51
uint16_t base
Base address.
Definition: edd.h:14
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
static int efi_local_open_resolved(struct efi_local *local, const char *resolved)
Open fully-resolved path.
Definition: efi_local.c:394
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
void * memset(void *dest, int character, size_t len) __nonnull
PACKED union @469::@483 Header
Definition: Acpi10.h:155

References assert(), base, container_of, DBGC, DBGC2, efi_loaded_image, efi_local_open_resolved(), efi_path_len(), efi_path_next(), ENOMEM, EFI_LOADED_IMAGE_PROTOCOL::FilePath, free, Header, len, memset(), next, FILEPATH_DEVICE_PATH::PathName, rc, resolve_path(), snprintf(), and tmp.

Referenced by efi_local_open().

◆ efi_local_len()

static int efi_local_len ( struct efi_local local)
static

Get file length.

Parameters
localLocal file
Return values
rcReturn status code

Definition at line 487 of file efi_local.c.

487  {
488  EFI_FILE_PROTOCOL *file = local->file;
490  EFI_STATUS efirc;
491  UINTN size;
492  int rc;
493 
494  /* Get size of file information */
495  size = 0;
497 
498  /* Allocate file information */
499  info = malloc ( size );
500  if ( ! info ) {
501  rc = -ENOMEM;
502  goto err_alloc;
503  }
504 
505  /* Get file information */
506  if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
507  info ) ) != 0 ) {
508  rc = -EEFI ( efirc );
509  DBGC ( local, "LOCAL %p could not get file info: %s\n",
510  local, strerror ( rc ) );
511  goto err_info;
512  }
513 
514  /* Record file length */
515  local->len = info->FileSize;
516 
517  /* Success */
518  rc = 0;
519 
520  err_info:
521  free ( info );
522  err_alloc:
523  return rc;
524 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:162
u32 info
Definition: ar9003_mac.h:67
#define DBGC(...)
Definition: compiler.h:505
EFI_FILE_GET_INFO GetInfo
#define ENOMEM
Not enough space.
Definition: errno.h:534
EFI_FILE_PROTOCOL * file
EFI file.
Definition: efi_local.c:66
size_t len
Length of file.
Definition: efi_local.c:68
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
UINT64 UINTN
Unsigned value of native width.
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:308
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.

References DBGC, EEFI, efi_file_info_id, ENOMEM, efi_local::file, free, _EFI_FILE_PROTOCOL::GetInfo, info, efi_local::len, malloc(), NULL, rc, size, and strerror().

Referenced by efi_local_open().

◆ efi_local_open()

static int efi_local_open ( struct interface xfer,
struct uri uri 
)
static

Open local file.

Parameters
xferData transfer interface
uriRequest URI
Return values
rcReturn status code

Definition at line 533 of file efi_local.c.

533  {
534  struct efi_local *local;
535  const char *volume;
536  const char *path;
537  int rc;
538 
539  /* Parse URI */
540  volume = ( ( uri->host && uri->host[0] ) ? uri->host : NULL );
541  path = ( uri->opaque ? uri->opaque : uri->path );
542 
543  /* Allocate and initialise structure */
544  local = zalloc ( sizeof ( *local ) );
545  if ( ! local ) {
546  rc = -ENOMEM;
547  goto err_alloc;
548  }
549  ref_init ( &local->refcnt, NULL );
550  intf_init ( &local->xfer, &efi_local_xfer_desc, &local->refcnt );
552  &local->refcnt );
553 
554  /* Open specified volume */
555  if ( ( rc = efi_local_open_volume ( local, volume ) ) != 0 )
556  goto err_open_root;
557 
558  /* Open specified path */
559  if ( ( rc = efi_local_open_path ( local, path ) ) != 0 )
560  goto err_open_file;
561 
562  /* Get length of file */
563  if ( ( rc = efi_local_len ( local ) ) != 0 )
564  goto err_len;
565 
566  /* Start download process */
567  process_add ( &local->process );
568 
569  /* Attach to parent interface, mortalise self, and return */
570  intf_plug_plug ( &local->xfer, xfer );
571  ref_put ( &local->refcnt );
572  return 0;
573 
574  err_len:
575  err_open_file:
576  err_open_root:
577  efi_local_close ( local, 0 );
578  ref_put ( &local->refcnt );
579  err_alloc:
580  return rc;
581 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct process process
Download process.
Definition: efi_local.c:61
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
struct refcnt refcnt
Reference count.
Definition: efi_local.c:57
#define ENOMEM
Not enough space.
Definition: errno.h:534
const char * path
Path (after URI decoding)
Definition: uri.h:80
static int efi_local_len(struct efi_local *local)
Get file length.
Definition: efi_local.c:487
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static int efi_local_open_volume(struct efi_local *local, const char *volume)
Open root filesystem of specified volume.
Definition: efi_local.c:304
static struct interface_descriptor efi_local_xfer_desc
Data transfer interface descriptor.
Definition: efi_local.c:176
static struct process_descriptor efi_local_process_desc
Process descriptor.
Definition: efi_local.c:180
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
const char * host
Host name.
Definition: uri.h:76
static void efi_local_close(struct efi_local *local, int rc)
Close local file.
Definition: efi_local.c:77
const char * opaque
Opaque part.
Definition: uri.h:70
An EFI local file.
Definition: efi_local.c:55
A Uniform Resource Identifier.
Definition: uri.h:64
struct interface xfer
Data transfer interface.
Definition: efi_local.c:59
static int efi_local_open_path(struct efi_local *local, const char *filename)
Open specified path.
Definition: efi_local.c:425
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:190
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References efi_local_close(), efi_local_len(), efi_local_open_path(), efi_local_open_volume(), efi_local_process_desc, efi_local_xfer_desc, ENOMEM, uri::host, intf_init(), intf_plug_plug(), NULL, uri::opaque, uri::path, efi_local::process, process_add(), process_init_stopped(), rc, ref_init, ref_put, efi_local::refcnt, efi_local::xfer, and zalloc().

Variable Documentation

◆ efi_local_operations

struct interface_operation efi_local_operations[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void efi_local_step(struct efi_local *local)
Local file process.
Definition: efi_local.c:103
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void efi_local_close(struct efi_local *local, int rc)
Close local file.
Definition: efi_local.c:77
An EFI local file.
Definition: efi_local.c:55

Data transfer interface operations.

Definition at line 170 of file efi_local.c.

◆ efi_local_xfer_desc

struct interface_descriptor efi_local_xfer_desc
static
Initial value:
=
static struct interface_operation efi_local_operations[]
Data transfer interface operations.
Definition: efi_local.c:170
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
An EFI local file.
Definition: efi_local.c:55
struct interface xfer
Data transfer interface.
Definition: efi_local.c:59

Data transfer interface descriptor.

Definition at line 176 of file efi_local.c.

Referenced by efi_local_open().

◆ efi_local_process_desc

struct process_descriptor efi_local_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:97
static void efi_local_step(struct efi_local *local)
Local file process.
Definition: efi_local.c:103
An EFI local file.
Definition: efi_local.c:55

Process descriptor.

Definition at line 180 of file efi_local.c.

Referenced by efi_local_open().

◆ __uri_opener

struct uri_opener efi_local_uri_opener __uri_opener
Initial value:
= {
.scheme = "file",
.open = efi_local_open,
}
static int efi_local_open(struct interface *xfer, struct uri *uri)
Open local file.
Definition: efi_local.c:533

EFI local file URI opener.

Definition at line 584 of file efi_local.c.