/* Return the device path node right before the end node. */ static grub_efi_device_path_t * find_last_device_path (const grub_efi_device_path_t *dp) { grub_efi_device_path_t *next, *p; if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) return 0; for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p); ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) ; return p; }
char * grub_efi_get_filename (grub_efi_device_path_t *dp) { char *name = 0; while (1) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) break; else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) { grub_efi_file_path_device_path_t *fp; grub_efi_uint16_t len; char *p; grub_size_t size; if (name) { size = grub_strlen (name); name[size] = '/'; size++; } else size = 0; len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) / sizeof (grub_efi_char16_t)); p = grub_realloc (name, size + len * 4 + 1); if (! p) { grub_free (name); return 0; } name = p; fp = (grub_efi_file_path_device_path_t *) dp; *grub_utf16_to_utf8 ((grub_uint8_t *) name + size, fp->path_name, len) = '\0'; } dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); } if (name) { /* EFI breaks paths with backslashes. */ char *p; for (p = name; *p; p++) if (*p == '\\') *p = '/'; } return name; }
/* Duplicate a device path. */ static grub_efi_device_path_t * duplicate_device_path (const grub_efi_device_path_t *dp) { grub_efi_device_path_t *p; grub_size_t total_size = 0; for (p = (grub_efi_device_path_t *) dp; ; p = GRUB_EFI_NEXT_DEVICE_PATH (p)) { total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) break; } p = grub_malloc (total_size); if (! p) return 0; grub_memcpy (p, dp, total_size); return p; }
char * grub_efi_get_filename (grub_efi_device_path_t *dp0) { char *name = 0, *p, *pi; grub_size_t filesize = 0; grub_efi_device_path_t *dp; dp = dp0; while (1) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) break; if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) { grub_efi_uint16_t len; len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) / sizeof (grub_efi_char16_t)); filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2; } dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); } if (!filesize) return NULL; dp = dp0; p = name = grub_malloc (filesize); if (!name) return NULL; while (1) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) break; else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) { grub_efi_file_path_device_path_t *fp; grub_efi_uint16_t len; *p++ = '/'; len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) / sizeof (grub_efi_char16_t)); fp = (grub_efi_file_path_device_path_t *) dp; p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len); } dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); } *p = '\0'; for (pi = name, p = name; *pi;) { /* EFI breaks paths with backslashes. */ if (*pi == '\\' || *pi == '/') { *p++ = '/'; while (*pi == '\\' || *pi == '/') pi++; continue; } *p++ = *pi++; } *p = '\0'; return name; }