iPXE
efi_file.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * EFI file protocols
30  *
31  */
32 
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <errno.h>
39 #include <wchar.h>
40 #include <ipxe/image.h>
41 #include <ipxe/efi/efi.h>
45 #include <ipxe/efi/Guid/FileInfo.h>
47 #include <ipxe/efi/efi_strings.h>
48 #include <ipxe/efi/efi_file.h>
49 
50 /** EFI media ID */
51 #define EFI_MEDIA_ID_MAGIC 0x69505845
52 
53 /** An image exposed as an EFI file */
54 struct efi_file {
55  /** EFI file protocol */
57  /** Image */
58  struct image *image;
59  /** Current file position */
60  size_t pos;
61 };
62 
63 static struct efi_file efi_file_root;
64 
65 /**
66  * Get EFI file name (for debugging)
67  *
68  * @v file EFI file
69  * @ret name Name
70  */
71 static const char * efi_file_name ( struct efi_file *file ) {
72 
73  return ( file->image ? file->image->name : "<root>" );
74 }
75 
76 /**
77  * Find EFI file image
78  *
79  * @v wname Filename
80  * @ret image Image, or NULL
81  */
82 static struct image * efi_file_find ( const CHAR16 *wname ) {
83  char name[ wcslen ( wname ) + 1 /* NUL */ ];
84  struct image *image;
85 
86  /* Find image */
87  snprintf ( name, sizeof ( name ), "%ls", wname );
89  if ( strcasecmp ( image->name, name ) == 0 )
90  return image;
91  }
92 
93  return NULL;
94 
95 }
96 
97 /**
98  * Open file
99  *
100  * @v this EFI file
101  * @ret new New EFI file
102  * @v wname Filename
103  * @v mode File mode
104  * @v attributes File attributes (for newly-created files)
105  * @ret efirc EFI status code
106  */
107 static EFI_STATUS EFIAPI
109  CHAR16 *wname, UINT64 mode __unused,
110  UINT64 attributes __unused ) {
111  struct efi_file *file = container_of ( this, struct efi_file, file );
112  struct efi_file *new_file;
113  struct image *image;
114 
115  /* Initial '\' indicates opening from the root directory */
116  while ( *wname == L'\\' ) {
117  file = &efi_file_root;
118  wname++;
119  }
120 
121  /* Allow root directory itself to be opened */
122  if ( ( wname[0] == L'\0' ) || ( wname[0] == L'.' ) ) {
123  *new = &efi_file_root.file;
124  return 0;
125  }
126 
127  /* Fail unless opening from the root */
128  if ( file->image ) {
129  DBGC ( file, "EFIFILE %s is not a directory\n",
130  efi_file_name ( file ) );
131  return EFI_NOT_FOUND;
132  }
133 
134  /* Identify image */
135  image = efi_file_find ( wname );
136  if ( ! image ) {
137  DBGC ( file, "EFIFILE \"%ls\" does not exist\n", wname );
138  return EFI_NOT_FOUND;
139  }
140 
141  /* Fail unless opening read-only */
142  if ( mode != EFI_FILE_MODE_READ ) {
143  DBGC ( file, "EFIFILE %s cannot be opened in mode %#08llx\n",
144  image->name, mode );
145  return EFI_WRITE_PROTECTED;
146  }
147 
148  /* Allocate and initialise file */
149  new_file = zalloc ( sizeof ( *new_file ) );
150  memcpy ( &new_file->file, &efi_file_root.file,
151  sizeof ( new_file->file ) );
152  new_file->image = image_get ( image );
153  *new = &new_file->file;
154  DBGC ( new_file, "EFIFILE %s opened\n", efi_file_name ( new_file ) );
155 
156  return 0;
157 }
158 
159 /**
160  * Close file
161  *
162  * @v this EFI file
163  * @ret efirc EFI status code
164  */
166  struct efi_file *file = container_of ( this, struct efi_file, file );
167 
168  /* Do nothing if this is the root */
169  if ( ! file->image )
170  return 0;
171 
172  /* Close file */
173  DBGC ( file, "EFIFILE %s closed\n", efi_file_name ( file ) );
174  image_put ( file->image );
175  free ( file );
176 
177  return 0;
178 }
179 
180 /**
181  * Close and delete file
182  *
183  * @v this EFI file
184  * @ret efirc EFI status code
185  */
187  struct efi_file *file = container_of ( this, struct efi_file, file );
188 
189  DBGC ( file, "EFIFILE %s cannot be deleted\n", efi_file_name ( file ) );
190 
191  /* Close file */
192  efi_file_close ( this );
193 
194  /* Warn of failure to delete */
196 }
197 
198 /**
199  * Return variable-length data structure
200  *
201  * @v base Base data structure (starting with UINT64)
202  * @v base_len Length of base data structure
203  * @v name Name to append to base data structure
204  * @v len Length of data buffer
205  * @v data Data buffer
206  * @ret efirc EFI status code
207  */
208 static EFI_STATUS efi_file_varlen ( UINT64 *base, size_t base_len,
209  const char *name, UINTN *len, VOID *data ) {
210  size_t name_len;
211 
212  /* Calculate structure length */
213  name_len = strlen ( name );
214  *base = ( base_len + ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
215  if ( *len < *base ) {
216  *len = *base;
217  return EFI_BUFFER_TOO_SMALL;
218  }
219 
220  /* Copy data to buffer */
221  *len = *base;
222  memcpy ( data, base, base_len );
223  efi_snprintf ( ( data + base_len ), ( name_len + 1 /* NUL */ ),
224  "%s", name );
225 
226  return 0;
227 }
228 
229 /**
230  * Return file information structure
231  *
232  * @v image Image, or NULL for the root directory
233  * @v len Length of data buffer
234  * @v data Data buffer
235  * @ret efirc EFI status code
236  */
238  VOID *data ) {
240  const char *name;
241 
242  /* Populate file information */
243  memset ( &info, 0, sizeof ( info ) );
244  if ( image ) {
245  info.FileSize = image->len;
246  info.PhysicalSize = image->len;
247  info.Attribute = EFI_FILE_READ_ONLY;
248  name = image->name;
249  } else {
250  info.Attribute = ( EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY );
251  name = "";
252  }
253 
255  len, data );
256 }
257 
258 /**
259  * Read directory entry
260  *
261  * @v file EFI file
262  * @v len Length to read
263  * @v data Data buffer
264  * @ret efirc EFI status code
265  */
267  VOID *data ) {
268  EFI_STATUS efirc;
269  struct image *image;
270  unsigned int index;
271 
272  /* Construct directory entry at current position */
273  index = file->pos;
274  for_each_image ( image ) {
275  if ( index-- == 0 ) {
276  efirc = efi_file_info ( image, len, data );
277  if ( efirc == 0 )
278  file->pos++;
279  return efirc;
280  }
281  }
282 
283  /* No more entries */
284  *len = 0;
285  return 0;
286 }
287 
288 /**
289  * Read from file
290  *
291  * @v this EFI file
292  * @v len Length to read
293  * @v data Data buffer
294  * @ret efirc EFI status code
295  */
297  UINTN *len, VOID *data ) {
298  struct efi_file *file = container_of ( this, struct efi_file, file );
299  size_t remaining;
300 
301  /* If this is the root directory, then construct a directory entry */
302  if ( ! file->image )
303  return efi_file_read_dir ( file, len, data );
304 
305  /* Read from the file */
306  remaining = ( file->image->len - file->pos );
307  if ( *len > remaining )
308  *len = remaining;
309  DBGC ( file, "EFIFILE %s read [%#08zx,%#08zx)\n",
310  efi_file_name ( file ), file->pos,
311  ( ( size_t ) ( file->pos + *len ) ) );
312  copy_from_user ( data, file->image->data, file->pos, *len );
313  file->pos += *len;
314  return 0;
315 }
316 
317 /**
318  * Write to file
319  *
320  * @v this EFI file
321  * @v len Length to write
322  * @v data Data buffer
323  * @ret efirc EFI status code
324  */
326  UINTN *len, VOID *data __unused ) {
327  struct efi_file *file = container_of ( this, struct efi_file, file );
328 
329  DBGC ( file, "EFIFILE %s cannot write [%#08zx, %#08zx)\n",
330  efi_file_name ( file ), file->pos,
331  ( ( size_t ) ( file->pos + *len ) ) );
332  return EFI_WRITE_PROTECTED;
333 }
334 
335 /**
336  * Set file position
337  *
338  * @v this EFI file
339  * @v position New file position
340  * @ret efirc EFI status code
341  */
343  UINT64 position ) {
344  struct efi_file *file = container_of ( this, struct efi_file, file );
345 
346  /* If this is the root directory, reset to the start */
347  if ( ! file->image ) {
348  DBGC ( file, "EFIFILE root directory rewound\n" );
349  file->pos = 0;
350  return 0;
351  }
352 
353  /* Check for the magic end-of-file value */
354  if ( position == 0xffffffffffffffffULL )
355  position = file->image->len;
356 
357  /* Fail if we attempt to seek past the end of the file (since
358  * we do not support writes).
359  */
360  if ( position > file->image->len ) {
361  DBGC ( file, "EFIFILE %s cannot seek to %#08llx of %#08zx\n",
362  efi_file_name ( file ), position, file->image->len );
363  return EFI_UNSUPPORTED;
364  }
365 
366  /* Set position */
367  file->pos = position;
368  DBGC ( file, "EFIFILE %s position set to %#08zx\n",
369  efi_file_name ( file ), file->pos );
370 
371  return 0;
372 }
373 
374 /**
375  * Get file position
376  *
377  * @v this EFI file
378  * @ret position New file position
379  * @ret efirc EFI status code
380  */
382  UINT64 *position ) {
383  struct efi_file *file = container_of ( this, struct efi_file, file );
384 
385  *position = file->pos;
386  return 0;
387 }
388 
389 /**
390  * Get file information
391  *
392  * @v this EFI file
393  * @v type Type of information
394  * @v len Buffer size
395  * @v data Buffer
396  * @ret efirc EFI status code
397  */
399  EFI_GUID *type,
400  UINTN *len, VOID *data ) {
401  struct efi_file *file = container_of ( this, struct efi_file, file );
402  EFI_FILE_SYSTEM_INFO fsinfo;
403  struct image *image;
404 
405  /* Determine information to return */
406  if ( memcmp ( type, &efi_file_info_id, sizeof ( *type ) ) == 0 ) {
407 
408  /* Get file information */
409  DBGC ( file, "EFIFILE %s get file information\n",
410  efi_file_name ( file ) );
411  return efi_file_info ( file->image, len, data );
412 
413  } else if ( memcmp ( type, &efi_file_system_info_id,
414  sizeof ( *type ) ) == 0 ) {
415 
416  /* Get file system information */
417  DBGC ( file, "EFIFILE %s get file system information\n",
418  efi_file_name ( file ) );
419  memset ( &fsinfo, 0, sizeof ( fsinfo ) );
420  fsinfo.ReadOnly = 1;
422  fsinfo.VolumeSize += image->len;
423  return efi_file_varlen ( &fsinfo.Size,
425  len, data );
426  } else {
427 
428  DBGC ( file, "EFIFILE %s cannot get information of type %s\n",
429  efi_file_name ( file ), efi_guid_ntoa ( type ) );
430  return EFI_UNSUPPORTED;
431  }
432 }
433 
434 /**
435  * Set file information
436  *
437  * @v this EFI file
438  * @v type Type of information
439  * @v len Buffer size
440  * @v data Buffer
441  * @ret efirc EFI status code
442  */
443 static EFI_STATUS EFIAPI
446  struct efi_file *file = container_of ( this, struct efi_file, file );
447 
448  DBGC ( file, "EFIFILE %s cannot set information of type %s\n",
450  return EFI_WRITE_PROTECTED;
451 }
452 
453 /**
454  * Flush file modified data
455  *
456  * @v this EFI file
457  * @v type Type of information
458  * @v len Buffer size
459  * @v data Buffer
460  * @ret efirc EFI status code
461  */
463  struct efi_file *file = container_of ( this, struct efi_file, file );
464 
465  DBGC ( file, "EFIFILE %s flushed\n", efi_file_name ( file ) );
466  return 0;
467 }
468 
469 /** Root directory */
470 static struct efi_file efi_file_root = {
471  .file = {
473  .Open = efi_file_open,
474  .Close = efi_file_close,
475  .Delete = efi_file_delete,
476  .Read = efi_file_read,
477  .Write = efi_file_write,
478  .GetPosition = efi_file_get_position,
479  .SetPosition = efi_file_set_position,
480  .GetInfo = efi_file_get_info,
481  .SetInfo = efi_file_set_info,
482  .Flush = efi_file_flush,
483  },
484  .image = NULL,
485 };
486 
487 /**
488  * Open root directory
489  *
490  * @v filesystem EFI simple file system
491  * @ret file EFI file handle
492  * @ret efirc EFI status code
493  */
494 static EFI_STATUS EFIAPI
496  EFI_FILE_PROTOCOL **file ) {
497 
498  DBGC ( &efi_file_root, "EFIFILE open volume\n" );
499  *file = &efi_file_root.file;
500  return 0;
501 }
502 
503 /** EFI simple file system protocol */
506  .OpenVolume = efi_file_open_volume,
507 };
508 
509 /** Dummy block I/O reset */
510 static EFI_STATUS EFIAPI
512 
513  DBGC ( &efi_file_root, "EFIFILE block %sreset\n",
514  ( extended ? "extended " : "" ) );
515  return 0;
516 }
517 
518 /** Dummy block I/O read */
519 static EFI_STATUS EFIAPI
521  EFI_LBA lba, UINTN len, VOID *data ) {
522 
523  DBGC ( &efi_file_root, "EFIFILE block read ID %#08x LBA %#08llx -> "
524  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
525  data, ( ( size_t ) len ) );
526  return EFI_NO_MEDIA;
527 }
528 
529 /** Dummy block I/O write */
530 static EFI_STATUS EFIAPI
532  UINT32 MediaId, EFI_LBA lba, UINTN len,
533  VOID *data ) {
534 
535  DBGC ( &efi_file_root, "EFIFILE block write ID %#08x LBA %#08llx <- "
536  "%p+%zx\n", MediaId, ( ( unsigned long long ) lba ),
537  data, ( ( size_t ) len ) );
538  return EFI_NO_MEDIA;
539 }
540 
541 /** Dummy block I/O flush */
542 static EFI_STATUS EFIAPI
544 
545  DBGC ( &efi_file_root, "EFIFILE block flush\n" );
546  return 0;
547 }
548 
549 /** Dummy block I/O media */
552  .MediaPresent = TRUE,
553  .ReadOnly = TRUE,
554  .BlockSize = 1,
555 };
556 
557 /** Dummy EFI block I/O protocol */
560  .Media = &efi_block_io_media,
561  .Reset = efi_block_io_reset,
562  .ReadBlocks = efi_block_io_read_blocks,
563  .WriteBlocks = efi_block_io_write_blocks,
564  .FlushBlocks = efi_block_io_flush_blocks,
565 };
566 
567 /** Dummy disk I/O read */
568 static EFI_STATUS EFIAPI
570  UINT64 offset, UINTN len, VOID *data ) {
571 
572  DBGC ( &efi_file_root, "EFIFILE disk read ID %#08x offset %#08llx -> "
573  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
574  data, ( ( size_t ) len ) );
575  return EFI_NO_MEDIA;
576 }
577 
578 /** Dummy disk I/O write */
579 static EFI_STATUS EFIAPI
581  UINT64 offset, UINTN len, VOID *data ) {
582 
583  DBGC ( &efi_file_root, "EFIFILE disk write ID %#08x offset %#08llx <- "
584  "%p+%zx\n", MediaId, ( ( unsigned long long ) offset ),
585  data, ( ( size_t ) len ) );
586  return EFI_NO_MEDIA;
587 }
588 
589 /** Dummy EFI disk I/O protocol */
592  .ReadDisk = efi_disk_io_read_disk,
593  .WriteDisk = efi_disk_io_write_disk,
594 };
595 
596 /**
597  * Install EFI simple file system protocol
598  *
599  * @v handle EFI handle
600  * @ret rc Return status code
601  */
604  union {
605  EFI_DISK_IO_PROTOCOL *diskio;
606  void *interface;
607  } diskio;
608  EFI_STATUS efirc;
609  int rc;
610 
611  /* Reset root directory state */
612  efi_file_root.pos = 0;
613 
614  /* Install the simple file system protocol, block I/O
615  * protocol, and disk I/O protocol. We don't have a block
616  * device, but large parts of the EDK2 codebase make the
617  * assumption that file systems are normally attached to block
618  * devices, and so we create a dummy block device on the same
619  * handle just to keep things looking normal.
620  */
621  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
622  &handle,
629  rc = -EEFI ( efirc );
630  DBGC ( handle, "Could not install simple file system "
631  "protocols: %s\n", strerror ( rc ) );
632  goto err_install;
633  }
634 
635  /* The FAT filesystem driver has a bug: if a block device
636  * contains no FAT filesystem but does have an
637  * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instance, the FAT driver
638  * will assume that it must have previously installed the
639  * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This causes the FAT
640  * driver to claim control of our device, and to refuse to
641  * stop driving it, which prevents us from later uninstalling
642  * correctly.
643  *
644  * Work around this bug by opening the disk I/O protocol
645  * ourselves, thereby preventing the FAT driver from opening
646  * it.
647  *
648  * Note that the alternative approach of opening the block I/O
649  * protocol (and thereby in theory preventing DiskIo from
650  * attaching to the block I/O protocol) causes an endless loop
651  * of calls to our DRIVER_STOP method when starting the EFI
652  * shell. I have no idea why this is.
653  */
654  if ( ( efirc = bs->OpenProtocol ( handle, &efi_disk_io_protocol_guid,
655  &diskio.interface, efi_image_handle,
656  handle,
657  EFI_OPEN_PROTOCOL_BY_DRIVER ) ) != 0){
658  rc = -EEFI ( efirc );
659  DBGC ( handle, "Could not open disk I/O protocol: %s\n",
660  strerror ( rc ) );
662  goto err_open;
663  }
664  assert ( diskio.diskio == &efi_disk_io_protocol );
665 
666  return 0;
667 
670  err_open:
672  handle,
679  err_install:
680  return rc;
681 }
682 
683 /**
684  * Uninstall EFI simple file system protocol
685  *
686  * @v handle EFI handle
687  */
690  EFI_STATUS efirc;
691  int rc;
692 
693  /* Close our own disk I/O protocol */
696 
697  /* We must install the file system protocol first, since
698  * otherwise the EDK2 code will attempt to helpfully uninstall
699  * it when the block I/O protocol is uninstalled, leading to a
700  * system lock-up.
701  */
702  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
703  handle,
709  &efi_block_io_protocol, NULL ) ) != 0 ) {
710  rc = -EEFI ( efirc );
711  DBGC ( handle, "Could not uninstall simple file system "
712  "protocols: %s\n", strerror ( rc ) );
713  /* Oh dear */
714  }
715 }
UINT64 Revision
The version of the EFI_FILE_PROTOCOL interface.
static EFI_STATUS EFIAPI efi_file_set_info(EFI_FILE_PROTOCOL *this, EFI_GUID *type, UINTN len __unused, VOID *data __unused)
Set file information.
Definition: efi_file.c:444
static EFI_STATUS EFIAPI efi_disk_io_read_disk(EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId, UINT64 offset, UINTN len, VOID *data)
Dummy disk I/O read.
Definition: efi_file.c:569
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
BOOLEAN ReadOnly
TRUE if the volume only supports read access.
static EFI_STATUS EFIAPI efi_file_get_info(EFI_FILE_PROTOCOL *this, EFI_GUID *type, UINTN *len, VOID *data)
Get file information.
Definition: efi_file.c:398
EFI file protocols.
UINT64 Revision
The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:157
u32 info
Definition: ar9003_mac.h:67
static EFI_STATUS EFIAPI efi_file_get_position(EFI_FILE_PROTOCOL *this, UINT64 *position)
Get file position.
Definition: efi_file.c:381
uint32_t lba
Start address.
Definition: scsi.h:23
static EFI_STATUS EFIAPI efi_file_open(EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new, CHAR16 *wname, UINT64 mode __unused, UINT64 attributes __unused)
Open file.
Definition: efi_file.c:108
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:306
128 bit buffer containing a unique identifier value.
Definition: Base.h:263
Error codes.
EFI strings.
unsigned char BOOLEAN
Definition: ProcessorBind.h:61
Disk IO protocol as defined in the UEFI 2.0 specification.
uint8_t type
Type.
Definition: ena.h:16
static EFI_BLOCK_IO_PROTOCOL efi_block_io_protocol
Dummy EFI block I/O protocol.
Definition: efi_file.c:558
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
static EFI_STATUS efi_file_info(struct image *image, UINTN *len, VOID *data)
Return file information structure.
Definition: efi_file.c:237
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition: image.h:196
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:222
unsigned int UINT32
Definition: ProcessorBind.h:56
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1274
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
static struct image * efi_file_find(const CHAR16 *wname)
Find EFI file image.
Definition: efi_file.c:82
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:192
unsigned short CHAR16
Definition: ProcessorBind.h:59
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition: efi_file.c:688
static EFI_STATUS EFIAPI efi_file_read(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data)
Read from file.
Definition: efi_file.c:296
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:260
An executable image.
Definition: image.h:24
#define EFI_FILE_READ_ONLY
static EFI_STATUS EFIAPI efi_block_io_read_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId, EFI_LBA lba, UINTN len, VOID *data)
Dummy block I/O read.
Definition: efi_file.c:520
#define EFI_BUFFER_TOO_SMALL
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:125
EFI_FILE_PROTOCOL file
EFI file protocol.
Definition: efi_file.c:56
#define EFI_FILE_DIRECTORY
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1906
#define SIZE_OF_EFI_FILE_INFO
The FileName field of the EFI_FILE_INFO data structure is variable length.
Definition: FileInfo.h:69
static EFI_DISK_IO_PROTOCOL efi_disk_io_protocol
Dummy EFI disk I/O protocol.
Definition: efi_file.c:590
#define EFI_NO_MEDIA
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:132
size_t wcslen(const wchar_t *string)
Calculate length of wide-character string.
Definition: wchar.c:41
EFI_GUID efi_disk_io_protocol_guid
Disk I/O protocol GUID.
Definition: efi_guid.c:144
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:602
static EFI_STATUS EFIAPI efi_disk_io_write_disk(EFI_DISK_IO_PROTOCOL *this __unused, UINT32 MediaId, UINT64 offset, UINTN len, VOID *data)
Dummy disk I/O write.
Definition: efi_file.c:580
size_t pos
Current file position.
Definition: efi_file.c:60
static EFI_STATUS EFIAPI efi_file_open_volume(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *filesystem __unused, EFI_FILE_PROTOCOL **file)
Open root directory.
Definition: efi_file.c:495
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:109
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
Executable images.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:232
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:51
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct efi_file efi_file_root
Root directory.
Definition: efi_file.c:63
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:104
#define EFI_DISK_IO_PROTOCOL_REVISION
Definition: DiskIo.h:96
uint8_t filesystem
System type.
Definition: eltorito.h:24
This protocol is used to abstract Block I/O interfaces.
Definition: DiskIo.h:106
static EFI_STATUS EFIAPI efi_file_set_position(EFI_FILE_PROTOCOL *this, UINT64 position)
Set file position.
Definition: efi_file.c:342
#define EFI_WRITE_PROTECTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:128
#define for_each_image(image)
Iterate over all registered images.
Definition: image.h:149
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static EFI_STATUS efi_file_varlen(UINT64 *base, size_t base_len, const char *name, UINTN *len, VOID *data)
Return variable-length data structure.
Definition: efi_file.c:208
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EFIAPI
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:30
size_t len
Length of raw file image.
Definition: image.h:43
struct list_head images
List of registered images.
Definition: image.c:56
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
static EFI_STATUS EFIAPI efi_file_close(EFI_FILE_PROTOCOL *this)
Close file.
Definition: efi_file.c:165
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:206
static EFI_STATUS EFIAPI efi_file_flush(EFI_FILE_PROTOCOL *this)
Flush file modified data.
Definition: efi_file.c:462
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
UINT64 VolumeSize
The number of bytes managed by the file system.
static EFI_STATUS EFIAPI efi_block_io_write_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused, UINT32 MediaId, EFI_LBA lba, UINTN len, VOID *data)
Dummy block I/O write.
Definition: efi_file.c:531
static EFI_STATUS EFIAPI efi_file_write(EFI_FILE_PROTOCOL *this, UINTN *len, VOID *data __unused)
Write to file.
Definition: efi_file.c:325
#define VOID
Undeclared type.
Definition: Base.h:319
unsigned long long UINT64
Definition: ProcessorBind.h:54
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.SetInfo() and EFI_FILE_P...
#define TRUE
Definition: tlan.h:46
#define EFI_FILE_PROTOCOL_REVISION
uint16_t base
Base address.
Definition: edd.h:14
#define EFI_WARN_DELETE_FAILURE
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:155
EFI API.
#define EFI_MEDIA_ID_MAGIC
EFI media ID.
Definition: efi_file.c:51
static EFI_STATUS efi_file_read_dir(struct efi_file *file, UINTN *len, VOID *data)
Read directory entry.
Definition: efi_file.c:266
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:136
const char * efi_guid_ntoa(EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:192
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static EFI_STATUS EFIAPI efi_file_delete(EFI_FILE_PROTOCOL *this)
Close and delete file.
Definition: efi_file.c:186
#define EFI_NOT_FOUND
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:134
uint32_t len
Length.
Definition: ena.h:14
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:108
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
EFI_GUID efi_file_info_id
File information GUID.
Definition: efi_guid.c:303
#define EFI_FILE_MODE_READ
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Block IO protocol as defined in the UEFI 2.0 specification.
struct image * image
Image.
Definition: efi_file.c:58
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *this __unused, BOOLEAN extended)
Dummy block I/O reset.
Definition: efi_file.c:511
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
UINT32 MediaId
The curent media Id.
Definition: BlockIo.h:140
static EFI_STATUS EFIAPI efi_block_io_flush_blocks(EFI_BLOCK_IO_PROTOCOL *this __unused)
Dummy block I/O flush.
Definition: efi_file.c:543
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
UINT64 Revision
The revision to which the block IO interface adheres.
Definition: BlockIo.h:228
static EFI_SIMPLE_FILE_SYSTEM_PROTOCOL efi_simple_file_system_protocol
EFI simple file system protocol.
Definition: efi_file.c:504
struct list_head list
List of registered images.
Definition: image.h:29
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
uint16_t handle
Handle.
Definition: smbios.h:16
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
char * name
Name.
Definition: image.h:34
#define EFI_BLOCK_IO_PROTOCOL_REVISION
Definition: BlockIo.h:210
UINT64 Revision
The revision to which the disk I/O interface adheres.
Definition: DiskIo.h:112
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
UINT64 Size
The size of the EFI_FILE_SYSTEM_INFO structure, including the Null-terminated VolumeLabel string.
String functions.
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
static EFI_BLOCK_IO_MEDIA efi_block_io_media
Dummy block I/O media.
Definition: efi_file.c:550
An image exposed as an EFI file.
Definition: efi_file.c:54
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
Definition: efi.h:55
#define SIZE_OF_EFI_FILE_SYSTEM_INFO
The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.
String functions.
static const char * efi_file_name(struct efi_file *file)
Get EFI file name (for debugging)
Definition: efi_file.c:71
void * memset(void *dest, int character, size_t len) __nonnull