sdifs == SYSLINUX_FS_ISOLINUX;
}
-/* Search for a specific drive, based on the MBR signature; bytes 440-443 */
+/*
+ * Search for a specific drive, based on the MBR signature.
+ * Return drive and iterator at 0th position.
+ */
static int find_by_sig(uint32_t mbr_sig,
struct part_iter **_boot_part)
{
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo)))
+ if (!(boot_part = pi_begin(&diskinfo, 0)))
continue;
/* Check for a MBR disk */
if (boot_part->type != typedos) {
/*
* Search for a specific drive/partition, based on the GPT GUID.
- * We return the disk drive number if found, as well as populating the
- * boot_part pointer with the matching partition, if applicable.
- * If no matching partition is found or the GUID is a disk GUID,
- * boot_part will be populated with NULL. If not matching disk is
- * found, we return -1.
+ * Return drive and iterator at proper position.
*/
static int find_by_guid(const struct guid *gpt_guid,
struct part_iter **_boot_part)
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo)))
+ if (!(boot_part = pi_begin(&diskinfo, 0)))
continue;
/* Check for a GPT disk */
if (boot_part->type != typegpt) {
}
/*
- * Search for a specific partition, based on the GPT label.
- * We return the disk drive number if found, as well as populating the
- * boot_part pointer with the matching partition, if applicable.
- * If no matching partition is found, boot_part will be populated with
- * NULL and we return -1.
+ * Search for a specific drive/partition, based on the GPT label.
+ * Return drive and iterator at proper position.
*/
static int find_by_label(const char *label, struct part_iter **_boot_part)
{
for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
if (disk_get_params(drive, &diskinfo))
continue; /* Drive doesn't exist */
- if (!(boot_part = pi_begin(&diskinfo)))
+ if (!(boot_part = pi_begin(&diskinfo, 0)))
continue;
/* Check for a GPT disk */
- boot_part = pi_begin(&diskinfo);
if (!(boot_part->type == typegpt)) {
pi_del(&boot_part);
continue;
if (disk_get_params(drive, &diskinfo))
goto bail;
/* this will start iteration over FDD, possibly raw */
- if (!(iter = pi_begin(&diskinfo)))
+ if (!(iter = pi_begin(&diskinfo, 0)))
goto bail;
} else if (!strcmp(opt.drivename, "boot") || !strcmp(opt.drivename, "fs")) {
if (disk_get_params(drive, &diskinfo))
goto bail;
/* this will start iteration over disk emulation, possibly raw */
- if (!(iter = pi_begin(&diskinfo)))
+ if (!(iter = pi_begin(&diskinfo, 0)))
goto bail;
/* 'fs' => we should lookup the syslinux partition number and use it */
* iter_ctor() - common iterator initialization
* @iter: iterator pointer
* @args(0): disk_info structure used for disk functions
+ * @args(1): stepall modifier
*
* Second and further arguments are passed as a pointer to va_list
**/
static int iter_ctor(struct part_iter *iter, va_list *args)
{
const struct disk_info *di = va_arg(*args, const struct disk_info *);
+ int stepall = va_arg(*args, int);
#ifdef DEBUG
if (!di)
#endif
memcpy(&iter->di, di, sizeof(struct disk_info));
+ iter->stepall = stepall;
return 0;
}
/* record base EBR index */
iter->sub.dos.bebr_index0 = iter->sub.dos.index0;
}
- if (ost_is_nondata(dp->ostype))
- continue;
-
- break;
+ if (!ost_is_nondata(dp->ostype) || iter->stepall) {
+ *lba = dp->start_lba;
+ *_dp = dp;
+ break;
+ }
}
- /* safe */
- *lba = dp->start_lba;
- *_dp = dp;
-
return 0;
bail:
return -1;
if (notsane_logical(iter) || notsane_extended(iter))
goto bail;
+ iter->sub.dos.mbr_lba = abs_ebr;
dp = ((struct disk_dos_mbr *)iter->data)->table;
abs_ebr += dp[0].start_lba;
iter->sub.dos.ebr_size = 0;
}
- if (dp[0].ostype) {
+ if (dp[0].ostype || iter->stepall) {
*lba = abs_ebr;
*_dp = dp;
break;
* This way it's possible to continue, if some crazy soft left a "hole"
* - EBR with a valid extended partition without a logical one. In
* such case, linux will not reserve a number for such hole - so we
- * don't increase index0.
+ * don't increase index0. If stepall flag is set, we will never reach
+ * this place.
*/
}
return 0;
/* dos_part and start_lba are guaranteed to be valid here */
- iter->index = iter->sub.dos.index0 + 1;
+ /*
+ * note special index handling, if we have stepall set -
+ * this is made to keep index consistent with non-stepall
+ * iterators
+ */
+
+ if (iter->sub.dos.index0 >= 4 && !dos_part->ostype) {
+ iter->index = -1;
+ iter->sub.dos.index0--;
+ } else
+ iter->index = iter->sub.dos.index0 + 1;
iter->start_lba = start_lba;
iter->record = (char *)dos_part;
if (notsane_gpt(gpt_part))
goto bail;
- if (guid_is0(&gpt_part->type))
- continue;
- break;
+ if (!guid_is0(&gpt_part->type) || iter->stepall)
+ break;
}
/* no more partitions ? */
if (iter->sub.gpt.index0 == iter->sub.gpt.pe_count) {
* This function checks the disk for GPT or legacy partition table and allocates
* an appropriate iterator.
**/
-struct part_iter *pi_begin(const struct disk_info *di)
+struct part_iter *pi_begin(const struct disk_info *di, int stepall)
{
int setraw = 0;
struct part_iter *iter = NULL;
goto bail;
}
/* allocate iterator and exit */
- iter = pi_new(typegpt, di, gpth, gptl);
+ iter = pi_new(typegpt, di, stepall, gpth, gptl);
} else {
/* looks like MBR */
- iter = pi_new(typedos, di, mbr);
+ iter = pi_new(typedos, di, stepall, mbr);
}
setraw = 0;
bail:
if (setraw) {
error("WARNING: treating disk as raw.\n");
- iter = pi_new(typeraw, di);
+ iter = pi_new(typeraw, di, stepall);
}
free(mbr);
free(gpth);
struct part_iter {
const struct itertype *type;
+ char *data;
char *record;
uint64_t start_lba;
int index;
struct disk_info di;
/* internal */
- char *data;
+ int stepall;
union _sub {
struct _dos {
uint32_t disk_sig;
+ uint32_t mbr_lba;
/* internal */
uint32_t ebr_start;
uint32_t ebr_size;
extern const struct itertype * const typegpt;
extern const struct itertype * const typeraw;
-struct part_iter *pi_begin(const struct disk_info *);
+struct part_iter *pi_begin(const struct disk_info *, int stepall);
struct part_iter *pi_new(const struct itertype *, ...);
void *pi_del(struct part_iter **);
struct part_iter *pi_next(struct part_iter **);