mirror of https://github.com/ipxe/ipxe.git
[efi] Expose efi_path_next() utility function
Provide a single central implementation of the logic for stepping through elements of an EFI device path. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/844/head
parent
0f3ace92c6
commit
099e4d39b3
|
@ -21,6 +21,8 @@ struct fcp_description;
|
|||
struct ib_srp_device;
|
||||
struct usb_function;
|
||||
|
||||
extern EFI_DEVICE_PATH_PROTOCOL *
|
||||
efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path );
|
||||
extern EFI_DEVICE_PATH_PROTOCOL *
|
||||
efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
|
||||
extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
|
||||
|
|
|
@ -419,14 +419,15 @@ static int efi_local_open_resolved ( struct efi_local *local,
|
|||
* Open specified path
|
||||
*
|
||||
* @v local Local file
|
||||
* @v path Path to file
|
||||
* @v filename Path to file relative to our own image
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efi_local_open_path ( struct efi_local *local, const char *path ) {
|
||||
FILEPATH_DEVICE_PATH *fp = container_of ( efi_loaded_image->FilePath,
|
||||
FILEPATH_DEVICE_PATH, Header);
|
||||
size_t fp_len = efi_path_len ( &fp->Header );
|
||||
char base[ fp_len / 2 /* Cannot exceed this length */ ];
|
||||
static int efi_local_open_path ( struct efi_local *local,
|
||||
const char *filename ) {
|
||||
EFI_DEVICE_PATH_PROTOCOL *path = efi_loaded_image->FilePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *next;
|
||||
FILEPATH_DEVICE_PATH *fp;
|
||||
char base[ efi_path_len ( path ) / 2 /* Cannot exceed this length */ ];
|
||||
size_t remaining = sizeof ( base );
|
||||
size_t len;
|
||||
char *resolved;
|
||||
|
@ -436,13 +437,12 @@ static int efi_local_open_path ( struct efi_local *local, const char *path ) {
|
|||
/* Construct base path to our own image, if possible */
|
||||
memset ( base, 0, sizeof ( base ) );
|
||||
tmp = base;
|
||||
while ( fp && ( fp->Header.Type != END_DEVICE_PATH_TYPE ) ) {
|
||||
for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
|
||||
fp = container_of ( path, FILEPATH_DEVICE_PATH, Header );
|
||||
len = snprintf ( tmp, remaining, "%ls", fp->PathName );
|
||||
assert ( len < remaining );
|
||||
tmp += len;
|
||||
remaining -= len;
|
||||
fp = ( ( ( void * ) fp ) + ( ( fp->Header.Length[1] << 8 ) |
|
||||
fp->Header.Length[0] ) );
|
||||
}
|
||||
DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
|
||||
local, base );
|
||||
|
@ -454,7 +454,7 @@ static int efi_local_open_path ( struct efi_local *local, const char *path ) {
|
|||
}
|
||||
|
||||
/* Resolve path */
|
||||
resolved = resolve_path ( base, path );
|
||||
resolved = resolve_path ( base, filename );
|
||||
if ( ! resolved ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_resolve;
|
||||
|
|
|
@ -40,6 +40,31 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find next element in device path
|
||||
*
|
||||
* @v path Device path, or NULL
|
||||
* @v next Next element in device path, or NULL if at end
|
||||
*/
|
||||
EFI_DEVICE_PATH_PROTOCOL * efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path ) {
|
||||
|
||||
/* Check for non-existent device path */
|
||||
if ( ! path )
|
||||
return NULL;
|
||||
|
||||
/* Check for end of device path */
|
||||
if ( path->Type == END_DEVICE_PATH_TYPE )
|
||||
return NULL;
|
||||
|
||||
/* Move to next component of the device path */
|
||||
path = ( ( ( void * ) path ) +
|
||||
/* There's this amazing new-fangled thing known as
|
||||
* a UINT16, but who wants to use one of those? */
|
||||
( ( path->Length[1] << 8 ) | path->Length[0] ) );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find end of device path
|
||||
*
|
||||
|
@ -47,12 +72,11 @@
|
|||
* @ret path_end End of device path, or NULL
|
||||
*/
|
||||
EFI_DEVICE_PATH_PROTOCOL * efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
|
||||
EFI_DEVICE_PATH_PROTOCOL *next;
|
||||
|
||||
while ( path && ( path->Type != END_DEVICE_PATH_TYPE ) ) {
|
||||
path = ( ( ( void * ) path ) +
|
||||
/* There's this amazing new-fangled thing known as
|
||||
* a UINT16, but who wants to use one of those? */
|
||||
( ( path->Length[1] << 8 ) | path->Length[0] ) );
|
||||
/* Find end of device path */
|
||||
while ( ( next = efi_path_next ( path ) ) != NULL ) {
|
||||
path = next;
|
||||
}
|
||||
|
||||
return path;
|
||||
|
|
Loading…
Reference in New Issue