diff options
author | Michal Soltys <soltys@ziu.info> | 2010-08-22 15:36:23 +0200 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2010-09-28 09:32:52 +0200 |
commit | bd488610577a8cafb4f226f8ec3d093c51b67121 (patch) | |
tree | 7b56cbd4c77aad3729350f9b33dc1d9082430295 | |
parent | b4ba30102958f77e6bef1354459a06416408c2d7 (diff) | |
download | syslinux-bd488610577a8cafb4f226f8ec3d093c51b67121.tar.gz syslinux-bd488610577a8cafb4f226f8ec3d093c51b67121.tar.xz syslinux-bd488610577a8cafb4f226f8ec3d093c51b67121.zip |
partiter.c: add stepall modifier; bugfixes + comment changes
In certain situations (new features to be added later), it's useful
to be able to step through all partitions in a partition list. This
patch adds necessary functionality.
Adjust chain.c to use new version of partiter.
Also small bugfixes and comment changes.
Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r-- | com32/chain/chain.c | 29 | ||||
-rw-r--r-- | com32/chain/partiter.c | 47 | ||||
-rw-r--r-- | com32/chain/partiter.h | 6 |
3 files changed, 45 insertions, 37 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c index d1939ecd..88424dbd 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -60,7 +60,10 @@ static int is_phys(uint8_t sdifs) 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) { @@ -71,7 +74,7 @@ static int find_by_sig(uint32_t mbr_sig, 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) { @@ -90,11 +93,7 @@ ok: /* * 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) @@ -106,7 +105,7 @@ static int find_by_guid(const struct guid *gpt_guid, 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) { @@ -130,11 +129,8 @@ ok: } /* - * 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) { @@ -145,10 +141,9 @@ 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; @@ -383,7 +378,7 @@ int find_dp(struct part_iter **_iter) 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")) { @@ -408,7 +403,7 @@ int find_dp(struct part_iter **_iter) 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 */ diff --git a/com32/chain/partiter.c b/com32/chain/partiter.c index 2859694a..0d1ea5e7 100644 --- a/com32/chain/partiter.c +++ b/com32/chain/partiter.c @@ -95,12 +95,14 @@ static int inv_type(const void *type) * 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) @@ -108,6 +110,7 @@ static int iter_ctor(struct part_iter *iter, va_list *args) #endif memcpy(&iter->di, di, sizeof(struct disk_info)); + iter->stepall = stepall; return 0; } @@ -340,16 +343,13 @@ static int pi_dos_next_mbr(struct part_iter *iter, uint32_t *lba, /* 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; @@ -402,6 +402,7 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba, 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; @@ -413,7 +414,7 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba, iter->sub.dos.ebr_size = 0; } - if (dp[0].ostype) { + if (dp[0].ostype || iter->stepall) { *lba = abs_ebr; *_dp = dp; break; @@ -422,7 +423,8 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba, * 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; @@ -447,7 +449,17 @@ static struct part_iter *pi_dos_next(struct part_iter *iter) /* 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; @@ -487,9 +499,8 @@ static struct part_iter *pi_gpt_next(struct part_iter *iter) 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) { @@ -658,7 +669,7 @@ void *pi_del(struct part_iter **_iter) * 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; @@ -723,17 +734,17 @@ struct part_iter *pi_begin(const struct disk_info *di) 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); diff --git a/com32/chain/partiter.h b/com32/chain/partiter.h index d00d6099..718f6033 100644 --- a/com32/chain/partiter.h +++ b/com32/chain/partiter.h @@ -52,15 +52,17 @@ struct itertype { 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; @@ -85,7 +87,7 @@ extern const struct itertype * const typedos; 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 **); |