iPXE
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.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void efi_local_free (struct refcnt *refcnt)
 Free local file.
static void efi_local_close (struct efi_local *local, int rc)
 Close local file.
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.
static int efi_local_open_root (struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL **root)
 Open root filesystem.
static int efi_local_open_volume (struct efi_local *local)
 Open root filesystem of specified volume.
static int efi_local_open_resolved (struct efi_local *local, const char *resolved)
 Open fully-resolved path.
static int efi_local_open_path (struct efi_local *local)
 Open specified path.
static int efi_local_len (struct efi_local *local)
 Get file length.
static void efi_local_step (struct efi_local *local)
 Local file process.
static int efi_local_open (struct interface *xfer, struct uri *uri)
 Open local file.

Variables

struct errortab efi_local_errors[] __errortab
 Human-readable error messages.
static struct interface_operation efi_local_operations []
 Data transfer interface operations.
static struct interface_descriptor efi_local_xfer_desc
 Data transfer interface descriptor.
static struct process_descriptor efi_local_process_desc
 Process descriptor.
struct uri_opener efi_local_uri_opener __uri_opener
 EFI local file URI opener.

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

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

◆ EINFO_EEFI_OPEN_NOT_FOUND

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

Definition at line 56 of file efi_local.c.

56#define EINFO_EEFI_OPEN_NOT_FOUND \
57 __einfo_platformify ( EINFO_EEFI_OPEN, EFI_NOT_FOUND, \
58 "Not found" )

◆ EEFI_OPEN_NOT_FOUND

#define EEFI_OPEN_NOT_FOUND    __einfo_error ( EINFO_EEFI_OPEN_NOT_FOUND )

Definition at line 59 of file efi_local.c.

59#define EEFI_OPEN_NOT_FOUND \
60 __einfo_error ( EINFO_EEFI_OPEN_NOT_FOUND )

◆ EEFI_OPEN

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

Definition at line 61 of file efi_local.c.

61#define EEFI_OPEN( efirc ) EPLATFORM ( EINFO_EEFI_OPEN, efirc, \
62 EEFI_OPEN_NOT_FOUND )

Referenced by efi_local_open_resolved().

◆ EFI_LOCAL_BLKSIZE

#define EFI_LOCAL_BLKSIZE   4096

Download blocksize.

Definition at line 65 of file efi_local.c.

Referenced by efi_local_step().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_local_free()

void efi_local_free ( struct refcnt * refcnt)
static

Free local file.

Parameters
refcntReference count

Definition at line 101 of file efi_local.c.

101 {
102 struct efi_local *local =
103 container_of ( refcnt, struct efi_local, refcnt );
104
105 uri_put ( local->uri );
106 free ( local );
107}
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An EFI local file.
Definition efi_local.c:68
struct uri * uri
Download URI.
Definition efi_local.c:77
A reference counter.
Definition refcnt.h:27
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206

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

Referenced by efi_local_open().

◆ efi_local_close()

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

Close local file.

Parameters
localLocal file
rcReason for close

Definition at line 115 of file efi_local.c.

115 {
116
117 /* Stop process */
118 process_del ( &local->process );
119
120 /* Shut down data transfer interface */
121 intf_shutdown ( &local->xfer, rc );
122
123 /* Close EFI file */
124 if ( local->file ) {
125 local->file->Close ( local->file );
126 local->file = NULL;
127 }
128
129 /* Close EFI root directory */
130 if ( local->root ) {
131 local->root->Close ( local->root );
132 local->root = NULL;
133 }
134}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
struct interface xfer
Data transfer interface.
Definition efi_local.c:72
EFI_FILE_PROTOCOL * file
EFI file.
Definition efi_local.c:86
EFI_FILE_PROTOCOL * root
EFI root directory.
Definition efi_local.c:84
struct process process
Download process.
Definition efi_local.c:74

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

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

148 {
150 UINTN size;
151 char *label;
152 EFI_STATUS efirc;
153 int rc;
154
155 /* Get length of file system information */
156 size = 0;
157 root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
158
159 /* Allocate file system information */
160 info = malloc ( size );
161 if ( ! info ) {
162 rc = -ENOMEM;
163 goto err_alloc_info;
164 }
165
166 /* Get file system information */
167 if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
168 info ) ) != 0 ) {
169 rc = -EEFI ( efirc );
170 DBGC ( local, "LOCAL %p could not get file system info on %s: "
171 "%s\n", local, efi_handle_name ( device ),
172 strerror ( rc ) );
173 goto err_get_info;
174 }
175 DBGC2 ( local, "LOCAL %p found %s with label \"%ls\"\n",
176 local, efi_handle_name ( device ), info->VolumeLabel );
177
178 /* Construct volume label for comparison */
179 if ( asprintf ( &label, "%ls", info->VolumeLabel ) < 0 ) {
180 rc = -ENOMEM;
181 goto err_alloc_label;
182 }
183
184 /* Compare volume label */
185 if ( strcasecmp ( volume, label ) != 0 ) {
186 rc = -ENOENT;
187 goto err_compare;
188 }
189
190 /* Success */
191 rc = 0;
192
193 err_compare:
194 free ( label );
195 err_alloc_label:
196 err_get_info:
197 free ( info );
198 err_alloc_info:
199 return rc;
200}
UINT64 UINTN
Unsigned value of native width.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
u32 info
Definition ar9003_mac.h:0
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition asprintf.c:42
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition efi_guid.c:466
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
uint16_t size
Buffer size.
Definition dwmac.h:3
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
struct stp_switch root
Root switch.
Definition stp.h:15
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
A hardware device.
Definition device.h:77
A text label widget.
Definition label.h:16

References asprintf(), DBGC, DBGC2, EEFI, efi_file_system_info_id, EFI_HANDLE, 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()

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

211 {
213 EFI_STATUS efirc;
214 int rc;
215
216 /* Open file system protocol */
218 &fs ) ) != 0 ) {
219 DBGC ( local, "LOCAL %p could not open filesystem on %s: %s\n",
220 local, efi_handle_name ( device ), strerror ( rc ) );
221 return rc;
222 }
223
224 /* Open root directory */
225 if ( ( efirc = fs->OpenVolume ( fs, root ) ) != 0 ) {
226 rc = -EEFI ( efirc );
227 DBGC ( local, "LOCAL %p could not open volume on %s: %s\n",
228 local, efi_handle_name ( device ), strerror ( rc ) );
229 return rc;
230 }
231
232 return 0;
233}
struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition efi_guid.c:337
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
uint32_t fs
Definition librm.h:3

References DBGC, EEFI, EFI_HANDLE, efi_handle_name(), efi_open, efi_simple_file_system_protocol_guid, fs, rc, root, and strerror().

Referenced by efi_local_open_volume().

◆ efi_local_open_volume()

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

241 {
242 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
244 int ( * check ) ( struct efi_local *local, EFI_HANDLE device,
245 EFI_FILE_PROTOCOL *root, const char *volume );
246 const char *volume = local->volume;
249 EFI_HANDLE *handles;
251 UINTN num_handles;
252 UINTN i;
253 EFI_STATUS efirc;
254 int rc;
255
256 /* Identify candidate handles */
257 if ( volume ) {
258 /* Locate all filesystem handles */
259 if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol, protocol,
260 NULL, &num_handles,
261 &handles ) ) != 0 ) {
262 rc = -EEFI ( efirc );
263 DBGC ( local, "LOCAL %p could not enumerate handles: "
264 "%s\n", local, strerror ( rc ) );
265 return rc;
266 }
268 } else {
269 /* Locate filesystem from which we were loaded */
271 if ( ( efirc = bs->LocateDevicePath ( protocol, &path,
272 &device ) ) != 0 ) {
273 rc = -EEFI ( efirc );
274 DBGC ( local, "LOCAL %p could not locate file system "
275 "on %s: %s\n", local,
277 strerror ( rc ) );
278 return rc;
279 }
280 handles = &device;
281 num_handles = 1;
282 check = NULL;
283 }
284
285 /* Find matching handle */
286 for ( i = 0 ; i < num_handles ; i++ ) {
287
288 /* Get this device handle */
289 device = handles[i];
290
291 /* Open root directory */
292 if ( ( rc = efi_local_open_root ( local, device, &root ) ) != 0)
293 continue;
294
295 /* Check volume name, if applicable */
296 if ( ( check == NULL ) ||
297 ( ( rc = check ( local, device, root, volume ) ) == 0 ) ) {
298 DBGC ( local, "LOCAL %p using %s",
299 local, efi_handle_name ( device ) );
300 if ( volume )
301 DBGC ( local, " with label \"%s\"", volume );
302 DBGC ( local, "\n" );
303 local->root = root;
304 break;
305 }
306
307 /* Close root directory */
308 root->Close ( root );
309 }
310
311 /* Free handles, if applicable */
312 if ( volume )
313 bs->FreePool ( handles );
314
315 /* Fail if we found no matching handle */
316 if ( ! local->root ) {
317 DBGC ( local, "LOCAL %p found no matching handle\n", local );
318 return -ENOENT;
319 }
320
321 return 0;
322}
struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
@ ByProtocol
Retrieve the set of handles from the handle database that support a specified protocol.
Definition UefiSpec.h:1531
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition efi_debug.c:247
EFI_DEVICE_PATH_PROTOCOL * efi_loaded_image_path
Device path for the loaded image's device handle.
Definition efi_init.c:42
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:145
static int efi_local_open_root(struct efi_local *local, EFI_HANDLE device, EFI_FILE_PROTOCOL **root)
Open root filesystem.
Definition efi_local.c:210
#define EFI_HANDLE
Definition efi.h:53
EFI_SYSTEM_TABLE * efi_systab
uint16_t protocol
Protocol ID.
Definition stp.h:7
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition UefiSpec.h:1972
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition UefiSpec.h:2008
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46
const char * path
File path.
Definition efi_local.c:81
const char * volume
Volume name, or NULL to use loaded image's device.
Definition efi_local.c:79

References ByProtocol, DBGC, EEFI, efi_devpath_text(), EFI_HANDLE, 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, efi_local::root, root, strerror(), and efi_local::volume.

Referenced by efi_local_step().

◆ efi_local_open_resolved()

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

332 {
333 size_t name_len = strlen ( resolved );
334 CHAR16 name[ name_len + 1 /* wNUL */ ];
335 EFI_FILE_PROTOCOL *file;
336 EFI_STATUS efirc;
337 int rc;
338
339 /* Construct filename */
340 efi_snprintf ( name, ( name_len + 1 /* wNUL */ ), "%s", resolved );
341
342 /* Open file */
343 if ( ( efirc = local->root->Open ( local->root, &file, name,
344 EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
345 rc = -EEFI_OPEN ( efirc );
346 DBGC ( local, "LOCAL %p could not open \"%s\": %s\n",
347 local, resolved, strerror ( rc ) );
348 return rc;
349 }
350 local->file = file;
351
352 return 0;
353}
unsigned short CHAR16
2-byte Character.
#define EFI_FILE_MODE_READ
const char * name
Definition ath9k_hw.c:1986
#define EEFI_OPEN(efirc)
Definition efi_local.c:61
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

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

int efi_local_open_path ( struct efi_local * local)
static

Open specified path.

Parameters
localLocal file
Return values
rcReturn status code

Definition at line 361 of file efi_local.c.

361 {
365 char base[ efi_path_len ( path ) / 2 /* Cannot exceed this length */ ];
366 size_t remaining = sizeof ( base );
367 size_t len;
368 char *resolved;
369 char *tmp;
370 int rc;
371
372 /* Construct base path to our own image, if possible */
373 memset ( base, 0, sizeof ( base ) );
374 tmp = base;
375 for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
377 len = snprintf ( tmp, remaining, "%ls", fp->PathName );
378 assert ( len < remaining );
379 tmp += len;
380 remaining -= len;
381 }
382 DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
383 local, base );
384
385 /* Convert to sane path separators */
386 for ( tmp = base ; *tmp ; tmp++ ) {
387 if ( *tmp == '\\' )
388 *tmp = '/';
389 }
390
391 /* Resolve path */
392 resolved = resolve_path ( base, local->path );
393 if ( ! resolved ) {
394 rc = -ENOMEM;
395 goto err_resolve;
396 }
397
398 /* Convert to insane path separators */
399 for ( tmp = resolved ; *tmp ; tmp++ ) {
400 if ( *tmp == '/' )
401 *tmp = '\\';
402 }
403 DBGC ( local, "LOCAL %p using \"%s\"\n",
404 local, resolved );
405
406 /* Open resolved path */
407 if ( ( rc = efi_local_open_resolved ( local, resolved ) ) != 0 )
408 goto err_open;
409
410 err_open:
411 free ( resolved );
412 err_resolve:
413 return rc;
414}
PACKED union @165104130223077263224044232125337106163015377141::@273126103036270271166311122320164340317073026312 Header
Definition Acpi10.h:156
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
EFI_LOADED_IMAGE_PROTOCOL * efi_loaded_image
Loaded image protocol for this image.
Definition efi_init.c:39
static int efi_local_open_resolved(struct efi_local *local, const char *resolved)
Open fully-resolved path.
Definition efi_local.c:331
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
EFI_DEVICE_PATH_PROTOCOL * efi_path_next(EFI_DEVICE_PATH_PROTOCOL *path)
Find next element in device path.
Definition efi_path.c:119
void * memset(void *dest, int character, size_t len) __nonnull
uint32_t base
Base.
Definition librm.h:3
unsigned long tmp
Definition linux_pci.h:65
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
char * resolve_path(const char *base_path, const char *relative_path)
Resolve base+relative path.
Definition uri.c:634
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References assert, base, container_of, DBGC, DBGC2, efi_loaded_image, efi_local_open_resolved(), efi_path_len(), efi_path_next(), ENOMEM, 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()

int efi_local_len ( struct efi_local * local)
static

Get file length.

Parameters
localLocal file
Return values
rcReturn status code

Definition at line 422 of file efi_local.c.

422 {
423 EFI_FILE_PROTOCOL *file = local->file;
425 EFI_STATUS efirc;
426 UINTN size;
427 int rc;
428
429 /* Get size of file information */
430 size = 0;
431 file->GetInfo ( file, &efi_file_info_id, &size, NULL );
432
433 /* Allocate file information */
434 info = malloc ( size );
435 if ( ! info ) {
436 rc = -ENOMEM;
437 goto err_alloc;
438 }
439
440 /* Get file information */
441 if ( ( efirc = file->GetInfo ( file, &efi_file_info_id, &size,
442 info ) ) != 0 ) {
443 rc = -EEFI ( efirc );
444 DBGC ( local, "LOCAL %p could not get file info: %s\n",
445 local, strerror ( rc ) );
446 goto err_info;
447 }
448
449 /* Record file length */
450 local->len = info->FileSize;
451
452 /* Success */
453 rc = 0;
454
455 err_info:
456 free ( info );
457 err_alloc:
458 return rc;
459}
EFI_GUID efi_file_info_id
File information GUID.
Definition efi_guid.c:463
EFI_FILE_GET_INFO GetInfo
size_t len
Length of file.
Definition efi_local.c:88

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

void efi_local_step ( struct efi_local * local)
static

Local file process.

Parameters
localLocal file

Definition at line 466 of file efi_local.c.

466 {
467 struct io_buffer *iobuf = NULL;
468 size_t remaining;
469 size_t frag_len;
470 UINTN size;
471 EFI_STATUS efirc;
472 int rc;
473
474 /* Wait until data transfer interface is ready */
475 if ( ! xfer_window ( &local->xfer ) )
476 return;
477
478 /* Open specified volume root directory, if not yet open */
479 if ( ( ! local->root ) &&
480 ( ( rc = efi_local_open_volume ( local ) ) != 0 ) )
481 goto err;
482
483 /* Open specified file, if not yet open */
484 if ( ( ! local->file ) &&
485 ( ( rc = efi_local_open_path ( local ) ) != 0 ) )
486 goto err;
487
488 /* Get file length, if not yet known */
489 if ( ( ! local->len ) &&
490 ( ( rc = efi_local_len ( local ) ) != 0 ) )
491 goto err;
492
493 /* Presize receive buffer */
494 remaining = local->len;
495 xfer_seek ( &local->xfer, remaining );
496 xfer_seek ( &local->xfer, 0 );
497
498 /* Get file contents */
499 while ( remaining ) {
500
501 /* Calculate length for this fragment */
502 frag_len = remaining;
503 if ( frag_len > EFI_LOCAL_BLKSIZE )
504 frag_len = EFI_LOCAL_BLKSIZE;
505
506 /* Allocate I/O buffer */
507 iobuf = xfer_alloc_iob ( &local->xfer, frag_len );
508 if ( ! iobuf ) {
509 rc = -ENOMEM;
510 goto err;
511 }
512
513 /* Read block */
514 size = frag_len;
515 if ( ( efirc = local->file->Read ( local->file, &size,
516 iobuf->data ) ) != 0 ) {
517 rc = -EEFI ( efirc );
518 DBGC ( local, "LOCAL %p could not read from file: %s\n",
519 local, strerror ( rc ) );
520 goto err;
521 }
522 assert ( size <= frag_len );
523 iob_put ( iobuf, size );
524
525 /* Deliver data */
526 if ( ( rc = xfer_deliver_iob ( &local->xfer,
527 iob_disown ( iobuf ) ) ) != 0 ) {
528 DBGC ( local, "LOCAL %p could not deliver data: %s\n",
529 local, strerror ( rc ) );
530 goto err;
531 }
532
533 /* Move to next block */
534 remaining -= frag_len;
535 }
536
537 /* Close download */
538 efi_local_close ( local, 0 );
539
540 return;
541
542 err:
543 free_iob ( iobuf );
544 efi_local_close ( local, rc );
545}
#define EFI_LOCAL_BLKSIZE
Download blocksize.
Definition efi_local.c:65
static void efi_local_close(struct efi_local *local, int rc)
Close local file.
Definition efi_local.c:115
static int efi_local_open_path(struct efi_local *local)
Open specified path.
Definition efi_local.c:361
static int efi_local_len(struct efi_local *local)
Get file length.
Definition efi_local.c:422
static int efi_local_open_volume(struct efi_local *local)
Open root filesystem of specified volume.
Definition efi_local.c:241
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition xfer.c:352
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256

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

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

568 {
569 struct efi_local *local;
570
571 /* Allocate and initialise structure */
572 local = zalloc ( sizeof ( *local ) );
573 if ( ! local )
574 return -ENOMEM;
575 ref_init ( &local->refcnt, efi_local_free );
576 intf_init ( &local->xfer, &efi_local_xfer_desc, &local->refcnt );
578 &local->refcnt );
579 local->uri = uri_get ( uri );
580 local->volume = ( ( uri->host && uri->host[0] ) ? uri->host : NULL );
581 local->path = ( uri->opaque ? uri->opaque : uri->path );
582
583 /* Start download process */
584 process_add ( &local->process );
585
586 /* Attach to parent interface, mortalise self, and return */
587 intf_plug_plug ( &local->xfer, xfer );
588 ref_put ( &local->refcnt );
589 return 0;
590}
static struct process_descriptor efi_local_process_desc
Process descriptor.
Definition efi_local.c:558
static void efi_local_free(struct refcnt *refcnt)
Free local file.
Definition efi_local.c:101
static struct interface_descriptor efi_local_xfer_desc
Data transfer interface descriptor.
Definition efi_local.c:554
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
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:146
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct refcnt refcnt
Reference count.
Definition efi_local.c:70
A Uniform Resource Identifier.
Definition uri.h:65
const char * path
Path (after URI decoding)
Definition uri.h:81
const char * host
Host name.
Definition uri.h:77
const char * opaque
Opaque part.
Definition uri.h:71
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition uri.h:195

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_EEFI_OPEN_NOT_FOUND
Definition efi_local.c:56
#define __einfo_errortab(einfo)
Definition errortab.h:24

Human-readable error messages.

Definition at line 92 of file efi_local.c.

◆ efi_local_operations

struct interface_operation efi_local_operations[]
static
Initial value:
= {
}
static void efi_local_step(struct efi_local *local)
Local file process.
Definition efi_local.c:466
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

Data transfer interface operations.

Definition at line 548 of file efi_local.c.

548 {
551};

◆ 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:548
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

Data transfer interface descriptor.

Definition at line 554 of file efi_local.c.

Referenced by efi_local_open().

◆ efi_local_process_desc

struct process_descriptor efi_local_process_desc
static
Initial value:
=
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
A process.
Definition process.h:18

Process descriptor.

Definition at line 558 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:568

EFI local file URI opener.

Definition at line 593 of file efi_local.c.

593 {
594 .scheme = "file",
595 .open = efi_local_open,
596};