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/errortab.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 EINFO_EEFI_OPEN   __einfo_uniqify ( EINFO_EPLATFORM, 0x01, "Could not open" )
 
#define EINFO_EEFI_OPEN_NOT_FOUND
 
#define EEFI_OPEN_NOT_FOUND   __einfo_error ( EINFO_EEFI_OPEN_NOT_FOUND )
 
#define EEFI_OPEN(efirc)
 
#define EFI_LOCAL_BLKSIZE   4096
 Download blocksize. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void efi_local_free (struct refcnt *refcnt)
 Free local file. More...
 
static void efi_local_close (struct efi_local *local, int rc)
 Close local file. 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)
 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)
 Open specified path. More...
 
static int efi_local_len (struct efi_local *local)
 Get file length. More...
 
static void efi_local_step (struct efi_local *local)
 Local file process. More...
 
static int efi_local_open (struct interface *xfer, struct uri *uri)
 Open local file. More...
 

Variables

struct errortab efi_local_errors [] __errortab
 Human-readable error messages. More...
 
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

◆ EINFO_EEFI_OPEN

#define EINFO_EEFI_OPEN   __einfo_uniqify ( EINFO_EPLATFORM, 0x01, "Could not open" )

Definition at line 53 of file efi_local.c.

◆ EINFO_EEFI_OPEN_NOT_FOUND

#define EINFO_EEFI_OPEN_NOT_FOUND
Value:
"Not found" )
#define EINFO_EEFI_OPEN
Definition: efi_local.c:53
#define __einfo_platformify(einfo_base, platform, desc)
Declare platform-generated error.
Definition: errno.h:193
#define EFI_NOT_FOUND
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:128

Definition at line 55 of file efi_local.c.

◆ EEFI_OPEN_NOT_FOUND

#define EEFI_OPEN_NOT_FOUND   __einfo_error ( EINFO_EEFI_OPEN_NOT_FOUND )

Definition at line 58 of file efi_local.c.

◆ EEFI_OPEN

#define EEFI_OPEN (   efirc)
Value:
#define EINFO_EEFI_OPEN
Definition: efi_local.c:53
#define EEFI_OPEN_NOT_FOUND
Definition: efi_local.c:58
#define EPLATFORM(einfo_base, platform,...)
Generate an error based on an external platform error code.
Definition: errno.h:248

Definition at line 60 of file efi_local.c.

◆ EFI_LOCAL_BLKSIZE

#define EFI_LOCAL_BLKSIZE   4096

Download blocksize.

Definition at line 64 of file efi_local.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ efi_local_free()

static void efi_local_free ( struct refcnt refcnt)
static

Free local file.

Parameters
refcntReference count

Definition at line 100 of file efi_local.c.

100  {
101  struct efi_local *local =
102  container_of ( refcnt, struct efi_local, refcnt );
103 
104  uri_put ( local->uri );
105  free ( local );
106 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
struct uri * uri
Download URI.
Definition: efi_local.c:76
A reference counter.
Definition: refcnt.h:26
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An EFI local file.
Definition: efi_local.c:67

References container_of, free, efi_local::uri, and uri_put().

Referenced by efi_local_open().

◆ 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 114 of file efi_local.c.

114  {
115 
116  /* Stop process */
117  process_del ( &local->process );
118 
119  /* Shut down data transfer interface */
120  intf_shutdown ( &local->xfer, rc );
121 
122  /* Close EFI file */
123  if ( local->file ) {
124  local->file->Close ( local->file );
125  local->file = NULL;
126  }
127 
128  /* Close EFI root directory */
129  if ( local->root ) {
130  local->root->Close ( local->root );
131  local->root = NULL;
132  }
133 }
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:73
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:85
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:83
struct interface xfer
Data transfer interface.
Definition: efi_local.c:71
#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_step().

◆ 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 144 of file efi_local.c.

147  {
149  UINTN size;
150  char *label;
151  EFI_STATUS efirc;
152  int rc;
153 
154  /* Get length of file system information */
155  size = 0;
156  root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
157 
158  /* Allocate file system information */
159  info = malloc ( size );
160  if ( ! info ) {
161  rc = -ENOMEM;
162  goto err_alloc_info;
163  }
164 
165  /* Get file system information */
166  if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
167  info ) ) != 0 ) {
168  rc = -EEFI ( efirc );
169  DBGC ( local, "LOCAL %p could not get file system info on %s: "
170  "%s\n", local, efi_handle_name ( device ),
171  strerror ( rc ) );
172  goto err_get_info;
173  }
174  DBGC2 ( local, "LOCAL %p found %s with label \"%ls\"\n",
175  local, efi_handle_name ( device ), info->VolumeLabel );
176 
177  /* Construct volume label for comparison */
178  if ( asprintf ( &label, "%ls", info->VolumeLabel ) < 0 ) {
179  rc = -ENOMEM;
180  goto err_alloc_label;
181  }
182 
183  /* Compare volume label */
184  if ( strcasecmp ( volume, label ) != 0 ) {
185  rc = -ENOENT;
186  goto err_compare;
187  }
188 
189  /* Success */
190  rc = 0;
191 
192  err_compare:
193  free ( label );
194  err_alloc_label:
195  err_get_info:
196  free ( info );
197  err_alloc_info:
198  return rc;
199 }
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:171
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:393
#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 * volume
Volume name, or NULL to use loaded image's device.
Definition: efi_local.c:78
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
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(), strerror(), and efi_local::volume.

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 209 of file efi_local.c.

210  {
212  union {
213  void *interface;
215  } u;
216  EFI_STATUS efirc;
217  int rc;
218 
219  /* Open file system protocol */
220  if ( ( efirc = bs->OpenProtocol ( device,
222  &u.interface, efi_image_handle,
223  device,
225  rc = -EEFI ( efirc );
226  DBGC ( local, "LOCAL %p could not open filesystem on %s: %s\n",
227  local, efi_handle_name ( device ), strerror ( rc ) );
228  goto err_filesystem;
229  }
230 
231  /* Open root directory */
232  if ( ( efirc = u.fs->OpenVolume ( u.fs, root ) ) != 0 ) {
233  rc = -EEFI ( efirc );
234  DBGC ( local, "LOCAL %p could not open volume on %s: %s\n",
235  local, efi_handle_name ( device ), strerror ( rc ) );
236  goto err_volume;
237  }
238 
239  /* Success */
240  rc = 0;
241 
242  err_volume:
245  err_filesystem:
246  return rc;
247 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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:171
struct stp_switch root
Root switch.
Definition: stp.h:26
#define DBGC(...)
Definition: compiler.h:505
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
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:303
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1344
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
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:1917
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:1986

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)
static

Open root filesystem of specified volume.

Parameters
localLocal file
Return values
rcReturn status code

Definition at line 255 of file efi_local.c.

255  {
258  int ( * check ) ( struct efi_local *local, EFI_HANDLE device,
259  EFI_FILE_PROTOCOL *root, const char *volume );
260  const char *volume = local->volume;
263  EFI_HANDLE *handles;
265  UINTN num_handles;
266  UINTN i;
267  EFI_STATUS efirc;
268  int rc;
269 
270  /* Identify candidate handles */
271  if ( volume ) {
272  /* Locate all filesystem handles */
273  if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
274  NULL, &num_handles,
275  &handles ) ) != 0 ) {
276  rc = -EEFI ( efirc );
277  DBGC ( local, "LOCAL %p could not enumerate handles: "
278  "%s\n", local, strerror ( rc ) );
279  return rc;
280  }
282  } else {
283  /* Locate filesystem from which we were loaded */
285  if ( ( efirc = bs->LocateDevicePath ( protocol, &path,
286  &device ) ) != 0 ) {
287  rc = -EEFI ( efirc );
288  DBGC ( local, "LOCAL %p could not locate file system "
289  "on %s: %s\n", local,
291  strerror ( rc ) );
292  return rc;
293  }
294  handles = &device;
295  num_handles = 1;
296  check = NULL;
297  }
298 
299  /* Find matching handle */
300  for ( i = 0 ; i < num_handles ; i++ ) {
301 
302  /* Get this device handle */
303  device = handles[i];
304 
305  /* Open root directory */
306  if ( ( rc = efi_local_open_root ( local, device, &root ) ) != 0)
307  continue;
308 
309  /* Check volume name, if applicable */
310  if ( ( check == NULL ) ||
311  ( ( rc = check ( local, device, root, volume ) ) == 0 ) ) {
312  DBGC ( local, "LOCAL %p using %s",
313  local, efi_handle_name ( device ) );
314  if ( volume )
315  DBGC ( local, " with label \"%s\"", volume );
316  DBGC ( local, "\n" );
317  local->root = root;
318  break;
319  }
320 
321  /* Close root directory */
322  root->Close ( root );
323  }
324 
325  /* Free handles, if applicable */
326  if ( volume )
327  bs->FreePool ( handles );
328 
329  /* Fail if we found no matching handle */
330  if ( ! local->root ) {
331  DBGC ( local, "LOCAL %p found no matching handle\n", local );
332  return -ENOENT;
333  }
334 
335  return 0;
336 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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:171
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:303
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:461
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:144
const char * volume
Volume name, or NULL to use loaded image's device.
Definition: efi_local.c:78
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1917
const char * path
File path.
Definition: efi_local.c:80
static int efi_local_open_root(struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL **root)
Open root filesystem.
Definition: efi_local.c:209
UINT64 UINTN
Unsigned value of native width.
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1936
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:83
An EFI local file.
Definition: efi_local.c:67
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:1520
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:59
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:1994
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1958

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, efi_local::path, protocol, rc, root, efi_local::root, strerror(), and efi_local::volume.

Referenced by efi_local_step().

◆ 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 345 of file efi_local.c.

346  {
347  size_t name_len = strlen ( resolved );
348  CHAR16 name[ name_len + 1 /* wNUL */ ];
350  EFI_STATUS efirc;
351  int rc;
352 
353  /* Construct filename */
354  efi_snprintf ( name, ( name_len + 1 /* wNUL */ ), "%s", resolved );
355 
356  /* Open file */
357  if ( ( efirc = local->root->Open ( local->root, &file, name,
358  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
359  rc = -EEFI_OPEN ( efirc );
360  DBGC ( local, "LOCAL %p could not open \"%s\": %s\n",
361  local, resolved, strerror ( rc ) );
362  return rc;
363  }
364  local->file = file;
365 
366  return 0;
367 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
#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:85
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define EEFI_OPEN(efirc)
Definition: efi_local.c:60
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:83
#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_OPEN, 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)
static

Open specified path.

Parameters
localLocal file
Return values
rcReturn status code

Definition at line 375 of file efi_local.c.

375  {
379  char base[ efi_path_len ( path ) / 2 /* Cannot exceed this length */ ];
380  size_t remaining = sizeof ( base );
381  size_t len;
382  char *resolved;
383  char *tmp;
384  int rc;
385 
386  /* Construct base path to our own image, if possible */
387  memset ( base, 0, sizeof ( base ) );
388  tmp = base;
389  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
391  len = snprintf ( tmp, remaining, "%ls", fp->PathName );
392  assert ( len < remaining );
393  tmp += len;
394  remaining -= len;
395  }
396  DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
397  local, base );
398 
399  /* Convert to sane path separators */
400  for ( tmp = base ; *tmp ; tmp++ ) {
401  if ( *tmp == '\\' )
402  *tmp = '/';
403  }
404 
405  /* Resolve path */
406  resolved = resolve_path ( base, local->path );
407  if ( ! resolved ) {
408  rc = -ENOMEM;
409  goto err_resolve;
410  }
411 
412  /* Convert to insane path separators */
413  for ( tmp = resolved ; *tmp ; tmp++ ) {
414  if ( *tmp == '/' )
415  *tmp = '\\';
416  }
417  DBGC ( local, "LOCAL %p using \"%s\"\n",
418  local, resolved );
419 
420  /* Open resolved path */
421  if ( ( rc = efi_local_open_resolved ( local, resolved ) ) != 0 )
422  goto err_open;
423 
424  err_open:
425  free ( resolved );
426  err_resolve:
427  return rc;
428 }
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:144
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
static const void * base
Base address.
Definition: crypto.h:335
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
const char * path
File path.
Definition: efi_local.c:80
EFI_DEVICE_PATH_PROTOCOL * efi_path_next(EFI_DEVICE_PATH_PROTOCOL *path)
Find next element in device path.
Definition: efi_path.c:89
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:345
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 @478::@492 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, efi_local::path, FILEPATH_DEVICE_PATH::PathName, rc, resolve_path(), snprintf(), and tmp.

Referenced by efi_local_step().

◆ 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 436 of file efi_local.c.

436  {
437  EFI_FILE_PROTOCOL *file = local->file;
439  EFI_STATUS efirc;
440  UINTN size;
441  int rc;
442 
443  /* Get size of file information */
444  size = 0;
446 
447  /* Allocate file information */
448  info = malloc ( size );
449  if ( ! info ) {
450  rc = -ENOMEM;
451  goto err_alloc;
452  }
453 
454  /* Get file information */
455  if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
456  info ) ) != 0 ) {
457  rc = -EEFI ( efirc );
458  DBGC ( local, "LOCAL %p could not get file info: %s\n",
459  local, strerror ( rc ) );
460  goto err_info;
461  }
462 
463  /* Record file length */
464  local->len = info->FileSize;
465 
466  /* Success */
467  rc = 0;
468 
469  err_info:
470  free ( info );
471  err_alloc:
472  return rc;
473 }
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:171
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:85
size_t len
Length of file.
Definition: efi_local.c:87
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:390
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_step().

◆ efi_local_step()

static void efi_local_step ( struct efi_local local)
static

Local file process.

Parameters
localLocal file

Definition at line 480 of file efi_local.c.

480  {
481  struct io_buffer *iobuf = NULL;
482  size_t remaining;
483  size_t frag_len;
484  UINTN size;
485  EFI_STATUS efirc;
486  int rc;
487 
488  /* Wait until data transfer interface is ready */
489  if ( ! xfer_window ( &local->xfer ) )
490  return;
491 
492  /* Open specified volume root directory, if not yet open */
493  if ( ( ! local->root ) &&
494  ( ( rc = efi_local_open_volume ( local ) ) != 0 ) )
495  goto err;
496 
497  /* Open specified file, if not yet open */
498  if ( ( ! local->file ) &&
499  ( ( rc = efi_local_open_path ( local ) ) != 0 ) )
500  goto err;
501 
502  /* Get file length, if not yet known */
503  if ( ( ! local->len ) &&
504  ( ( rc = efi_local_len ( local ) ) != 0 ) )
505  goto err;
506 
507  /* Presize receive buffer */
508  remaining = local->len;
509  xfer_seek ( &local->xfer, remaining );
510  xfer_seek ( &local->xfer, 0 );
511 
512  /* Get file contents */
513  while ( remaining ) {
514 
515  /* Calculate length for this fragment */
516  frag_len = remaining;
517  if ( frag_len > EFI_LOCAL_BLKSIZE )
518  frag_len = EFI_LOCAL_BLKSIZE;
519 
520  /* Allocate I/O buffer */
521  iobuf = xfer_alloc_iob ( &local->xfer, frag_len );
522  if ( ! iobuf ) {
523  rc = -ENOMEM;
524  goto err;
525  }
526 
527  /* Read block */
528  size = frag_len;
529  if ( ( efirc = local->file->Read ( local->file, &size,
530  iobuf->data ) ) != 0 ) {
531  rc = -EEFI ( efirc );
532  DBGC ( local, "LOCAL %p could not read from file: %s\n",
533  local, strerror ( rc ) );
534  goto err;
535  }
536  assert ( size <= frag_len );
537  iob_put ( iobuf, size );
538 
539  /* Deliver data */
540  if ( ( rc = xfer_deliver_iob ( &local->xfer,
541  iob_disown ( iobuf ) ) ) != 0 ) {
542  DBGC ( local, "LOCAL %p could not deliver data: %s\n",
543  local, strerror ( rc ) );
544  goto err;
545  }
546 
547  /* Move to next block */
548  remaining -= frag_len;
549  }
550 
551  /* Close download */
552  efi_local_close ( local, 0 );
553 
554  return;
555 
556  err:
557  free_iob ( iobuf );
558  efi_local_close ( local, rc );
559 }
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:171
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
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:158
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
#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:85
size_t len
Length of file.
Definition: efi_local.c:87
static int efi_local_len(struct efi_local *local)
Get file length.
Definition: efi_local.c:436
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition: xfer.c:351
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int efi_local_open_volume(struct efi_local *local)
Open root filesystem of specified volume.
Definition: efi_local.c:255
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:114
static int efi_local_open_path(struct efi_local *local)
Open specified path.
Definition: efi_local.c:375
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition: efi_local.c:83
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:71
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define EFI_LOCAL_BLKSIZE
Download blocksize.
Definition: efi_local.c:64
A persistent I/O buffer.
Definition: iobuf.h:33

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

◆ 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 582 of file efi_local.c.

582  {
583  struct efi_local *local;
584 
585  /* Allocate and initialise structure */
586  local = zalloc ( sizeof ( *local ) );
587  if ( ! local )
588  return -ENOMEM;
589  ref_init ( &local->refcnt, efi_local_free );
590  intf_init ( &local->xfer, &efi_local_xfer_desc, &local->refcnt );
592  &local->refcnt );
593  local->uri = uri_get ( uri );
594  local->volume = ( ( uri->host && uri->host[0] ) ? uri->host : NULL );
595  local->path = ( uri->opaque ? uri->opaque : uri->path );
596 
597  /* Start download process */
598  process_add ( &local->process );
599 
600  /* Attach to parent interface, mortalise self, and return */
601  intf_plug_plug ( &local->xfer, xfer );
602  ref_put ( &local->refcnt );
603  return 0;
604 }
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:194
struct process process
Download process.
Definition: efi_local.c:73
#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
static void efi_local_free(struct refcnt *refcnt)
Free local file.
Definition: efi_local.c:100
struct refcnt refcnt
Reference count.
Definition: efi_local.c:69
struct uri * uri
Download URI.
Definition: efi_local.c:76
#define ENOMEM
Not enough space.
Definition: errno.h:534
const char * path
Path (after URI decoding)
Definition: uri.h:80
const char * volume
Volume name, or NULL to use loaded image's device.
Definition: efi_local.c:78
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
const char * path
File path.
Definition: efi_local.c:80
static struct interface_descriptor efi_local_xfer_desc
Data transfer interface descriptor.
Definition: efi_local.c:568
static struct process_descriptor efi_local_process_desc
Process descriptor.
Definition: efi_local.c:572
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
const char * opaque
Opaque part.
Definition: uri.h:70
An EFI local file.
Definition: efi_local.c:67
A Uniform Resource Identifier.
Definition: uri.h:64
struct interface xfer
Data transfer interface.
Definition: efi_local.c:71
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References efi_local_free(), efi_local_process_desc, efi_local_xfer_desc, ENOMEM, uri::host, intf_init(), intf_plug_plug(), NULL, uri::opaque, efi_local::path, uri::path, efi_local::process, process_add(), process_init_stopped(), ref_init, ref_put, efi_local::refcnt, efi_local::uri, uri_get(), efi_local::volume, efi_local::xfer, and zalloc().

Variable Documentation

◆ __errortab

struct errortab efi_local_errors [] __errortab
Initial value:
= {
}
#define __einfo_errortab(einfo)
Definition: errortab.h:23
#define EINFO_EEFI_OPEN_NOT_FOUND
Definition: efi_local.c:55

Human-readable error messages.

Definition at line 91 of file efi_local.c.

◆ 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:146
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:480
#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:114
An EFI local file.
Definition: efi_local.c:67

Data transfer interface operations.

Definition at line 562 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:562
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
An EFI local file.
Definition: efi_local.c:67
struct interface xfer
Data transfer interface.
Definition: efi_local.c:71

Data transfer interface descriptor.

Definition at line 568 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:480
An EFI local file.
Definition: efi_local.c:67

Process descriptor.

Definition at line 572 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:582

EFI local file URI opener.

Definition at line 607 of file efi_local.c.