[syslinux] [PATCH 11/23] com32/chain: mangle and related updates
Michal Soltys
soltys at ziu.info
Mon Nov 5 16:32:45 PST 2012
Comments, output and minor adjustments.
Signed-off-by: Michal Soltys <soltys at ziu.info>
---
com32/chain/mangle.c | 65 ++++++++++++++++++++++++++-----------------------
com32/chain/options.c | 6 ++---
com32/chain/utility.c | 9 +++----
com32/chain/utility.h | 2 +-
4 files changed, 43 insertions(+), 39 deletions(-)
diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 60cee13..0eb35b3 100644
--- a/com32/chain/mangle.c
+++ b/com32/chain/mangle.c
@@ -276,8 +276,8 @@ bail:
/* Adjust BPB common function */
static int mangle_bpb(const struct part_iter *iter, struct data_area *data, const char *tag)
{
- unsigned int off;
int type = bpb_detect(data->data, tag);
+ int off = drvoff_detect(type);
/* BPB: hidden sectors 32bit*/
if (type >= bpbV34) {
@@ -307,7 +307,7 @@ static int mangle_bpb(const struct part_iter *iter, struct data_area *data, cons
}
}
/* BPB: drive */
- if (drvoff_detect(type, &off)) {
+ if (off >= 0) {
*(uint8_t *)((char *)data->data + off) = (uint8_t)
(opt.swap ? iter->di.disk & 0x80 : iter->di.disk);
}
@@ -344,7 +344,7 @@ int mangles_bpb(const struct part_iter *iter, struct data_area *data)
int manglesf_bss(struct data_area *sec, struct data_area *fil)
{
int type1, type2;
- unsigned int cnt = 0;
+ size_t cnt = 0;
if (!(opt.sect && opt.file && opt.bss))
return 0;
@@ -480,7 +480,7 @@ int mangler_grldr(const struct part_iter *iter)
/*
* try to copy values from temporary iterator, if positions match
*/
-static void push_embr(struct part_iter *diter, struct part_iter *siter)
+static void mbrcpy(struct part_iter *diter, struct part_iter *siter)
{
if (diter->dos.cebr_lba == siter->dos.cebr_lba &&
diter->di.disk == siter->di.disk) {
@@ -488,7 +488,7 @@ static void push_embr(struct part_iter *diter, struct part_iter *siter)
}
}
-static int mpe_sethide(struct part_iter *iter, struct part_iter *miter)
+static int fliphide(struct part_iter *iter, struct part_iter *miter)
{
struct disk_dos_part_entry *dp;
static const uint16_t mask =
@@ -527,34 +527,35 @@ int manglepe_hide(struct part_iter *miter)
struct disk_dos_part_entry *dp;
int ridx;
- if (!opt.hide)
+ if (!(opt.hide & 1))
return 0;
if (miter->type != typedos) {
- error("Options '*hide*' is meaningful only for legacy partition scheme.\n");
+ error("Option '[un]hide[all]' is meaningful only for legacy (DOS) partition scheme.\n");
return -1;
}
- if (miter->index < 1)
- error("WARNING: It's impossible to unhide a disk.\n");
-
if (miter->index > 4 && !(opt.hide & 2))
- error("WARNING: your partition is beyond mbr, so it can't be unhidden without '*hideall'.\n");
+ error("WARNING: your partition is logical, so it can't be unhidden without 'unhideall'.\n");
if (!(iter = pi_begin(&miter->di, PIF_STEPALL)))
return -1;
while (!pi_next(iter) && !werr) {
- ridx = iter->index0 + 1;
- if (!(opt.hide & 2) && ridx > 4)
+ ridx = iter->index0;
+ if (!(opt.hide & 2) && ridx > 3)
break; /* skip when we're constrained to pri only */
dp = (struct disk_dos_part_entry *)iter->record;
if (dp->ostype)
- wb |= mpe_sethide(iter, miter);
-
- if (ridx >= 4 && wb && !werr) {
- push_embr(miter, iter);
+ wb |= fliphide(iter, miter);
+
+ /*
+ * we have to update mbr and each extended partition, but only if
+ * changes (wb) were detected and there was no prior write error (werr)
+ */
+ if (ridx >= 3 && wb && !werr) {
+ mbrcpy(miter, iter);
werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
wb = 0;
}
@@ -563,20 +564,20 @@ int manglepe_hide(struct part_iter *miter)
if (pi_errored(iter))
goto bail;
- /* last write */
+ /* last update */
if (wb && !werr) {
- push_embr(miter, iter);
+ mbrcpy(miter, iter);
werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
}
if (werr)
- error("WARNING: failed to write E/MBR during '*hide*'\n");
+ error("WARNING: failed to write E/MBR during '[un]hide[all]'\n");
bail:
pi_del(&iter);
return 0;
}
-static int mpe_setchs(const struct disk_info *di,
+static int updchs(const struct disk_info *di,
struct disk_dos_part_entry *dp,
uint32_t lba1)
{
@@ -607,7 +608,7 @@ int manglepe_fixchs(struct part_iter *miter)
return 0;
if (miter->type != typedos) {
- error("Options 'fixchs' is meaningful only for legacy partition scheme.\n");
+ error("Option 'fixchs' is meaningful only for legacy (DOS) partition scheme.\n");
return -1;
}
@@ -615,15 +616,19 @@ int manglepe_fixchs(struct part_iter *miter)
return -1;
while (!pi_next(iter) && !werr) {
- ridx = iter->index0 + 1;
+ ridx = iter->index0;
dp = (struct disk_dos_part_entry *)iter->record;
- wb |= mpe_setchs(&iter->di, dp, (uint32_t)iter->start_lba);
- if (ridx > 4)
- wb |= mpe_setchs(&iter->di, dp + 1, iter->dos.nebr_lba);
+ wb |= updchs(&iter->di, dp, (uint32_t)iter->start_lba);
+ if (ridx > 3)
+ wb |= updchs(&iter->di, dp + 1, iter->dos.nebr_lba);
- if (ridx >= 4 && wb && !werr) {
- push_embr(miter, iter);
+ /*
+ * we have to update mbr and each extended partition, but only if
+ * changes (wb) were detected and there was no prior write error (werr)
+ */
+ if (ridx >= 3 && wb && !werr) {
+ mbrcpy(miter, iter);
werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
wb = 0;
}
@@ -632,9 +637,9 @@ int manglepe_fixchs(struct part_iter *miter)
if (pi_errored(iter))
goto bail;
- /* last write */
+ /* last update */
if (wb && !werr) {
- push_embr(miter, iter);
+ mbrcpy(miter, iter);
werr |= disk_write_sectors(&iter->di, iter->dos.cebr_lba, iter->data, 1);
}
if (werr)
diff --git a/com32/chain/options.c b/com32/chain/options.c
index b831afa..d8c601c 100644
--- a/com32/chain/options.c
+++ b/com32/chain/options.c
@@ -284,15 +284,15 @@ int opt_parse_args(int argc, char *argv[])
} else if (!strcmp(argv[i], "noswap")) {
opt.swap = false;
} else if (!strcmp(argv[i], "nohide")) {
- opt.hide = 0;
+ opt.hide = 0; /* bit 0 means disabled */
} else if (!strcmp(argv[i], "hide")) {
opt.hide = 1; /* 001b */
} else if (!strcmp(argv[i], "hideall")) {
- opt.hide = 2; /* 010b */
+ opt.hide = 3; /* 011b */
} else if (!strcmp(argv[i], "unhide")) {
opt.hide = 5; /* 101b */
} else if (!strcmp(argv[i], "unhideall")) {
- opt.hide = 6; /* 110b */
+ opt.hide = 7; /* 111b */
} else if (!strcmp(argv[i], "setbpb")) {
opt.setbpb = true;
} else if (!strcmp(argv[i], "nosetbpb")) {
diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index d40c0dd..9ec829a 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -166,14 +166,13 @@ uint32_t get_file_lba(const char *filename)
}
/* drive offset detection */
-int drvoff_detect(int type, unsigned int *off)
+int drvoff_detect(int type)
{
if (bpbV40 <= type && type <= bpbVNT) {
- *off = 0x24;
+ return 0x24;
} else if (type == bpbV70) {
- *off = 0x40;
- } else
- return 0;
+ return 0x40;
+ }
return -1;
}
diff --git a/com32/chain/utility.h b/com32/chain/utility.h
index a0519b7..4cca1c9 100644
--- a/com32/chain/utility.h
+++ b/com32/chain/utility.h
@@ -52,7 +52,7 @@
void wait_key(void);
void lba2chs(disk_chs *dst, const struct disk_info *di, uint64_t lba, int mode);
uint32_t get_file_lba(const char *filename);
-int drvoff_detect(int type, unsigned int *off);
+int drvoff_detect(int type);
int bpb_detect(const uint8_t *bpb, const char *tag);
static inline
--
1.7.10.4
More information about the Syslinux
mailing list