aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2013-02-14 16:51:45 +0100
committerMichal Soltys <soltys@ziu.info>2013-02-14 16:53:04 +0100
commitef9308f5b855b4b5c6484bd959c0334111908a44 (patch)
treed1aaa5f7158bb12b04067baf845caac0e24943a3
parentefcb57e2bec24c3a88bafe599f33e47f5f11069b (diff)
downloadsyslinux-ef9308f5b855b4b5c6484bd959c0334111908a44.tar.gz
syslinux-ef9308f5b855b4b5c6484bd959c0334111908a44.tar.xz
syslinux-ef9308f5b855b4b5c6484bd959c0334111908a44.zip
com32/chain: mangle and related updates
Comments, output and minor adjustments. Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r--com32/chain/mangle.c69
-rw-r--r--com32/chain/options.c10
-rw-r--r--com32/chain/options.h2
-rw-r--r--com32/chain/utility.c9
-rw-r--r--com32/chain/utility.h2
5 files changed, 49 insertions, 43 deletions
diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 0523db54..a699f3ca 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) = (opt.swap ? iter->di.disk & 0x80 : iter->di.disk);
}
@@ -343,7 +343,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;
@@ -479,7 +479,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) {
@@ -487,7 +487,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 =
@@ -500,7 +500,7 @@ static int mpe_sethide(struct part_iter *iter, struct part_iter *miter)
if ((t <= 0x1f) && ((mask >> (t & ~0x10u)) & 1)) {
/* It's a hideable partition type */
- if (miter->index == iter->index || opt.hide & 4)
+ if (miter->index == iter->index || opt.hide & HIDE_REV)
t &= ~0x10u; /* unhide */
else
t |= 0x10u; /* hide */
@@ -526,34 +526,35 @@ int manglepe_hide(struct part_iter *miter)
struct disk_dos_part_entry *dp;
int ridx;
- if (!opt.hide)
+ if (!(opt.hide & HIDE_ON))
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");
+ if (miter->index > 4 && !(opt.hide & HIDE_EXT))
+ 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 & HIDE_EXT) && 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;
}
@@ -562,20 +563,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)
{
@@ -606,7 +607,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;
}
@@ -614,15 +615,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, iter->start_lba);
- if (ridx > 4)
- wb |= mpe_setchs(&iter->di, dp + 1, iter->dos.nebr_lba);
+ wb |= updchs(&iter->di, dp, 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;
}
@@ -631,9 +636,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 b831afaa..46a26df2 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 = HIDE_OFF;
} else if (!strcmp(argv[i], "hide")) {
- opt.hide = 1; /* 001b */
+ opt.hide = HIDE_ON;
} else if (!strcmp(argv[i], "hideall")) {
- opt.hide = 2; /* 010b */
+ opt.hide = HIDE_ON | HIDE_EXT;
} else if (!strcmp(argv[i], "unhide")) {
- opt.hide = 5; /* 101b */
+ opt.hide = HIDE_ON | HIDE_REV;
} else if (!strcmp(argv[i], "unhideall")) {
- opt.hide = 6; /* 110b */
+ opt.hide = HIDE_ON | HIDE_EXT | HIDE_REV;
} else if (!strcmp(argv[i], "setbpb")) {
opt.setbpb = true;
} else if (!strcmp(argv[i], "nosetbpb")) {
diff --git a/com32/chain/options.h b/com32/chain/options.h
index c3e1af64..ea6e4700 100644
--- a/com32/chain/options.h
+++ b/com32/chain/options.h
@@ -34,6 +34,8 @@
#include <stdint.h>
#include <syslinux/bootrm.h>
+enum {HIDE_OFF = 0, HIDE_ON = 1, HIDE_EXT = 2, HIDE_REV = 4};
+
struct options {
unsigned int fseg;
unsigned int foff;
diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index 18dbbc6d..d0da9f8f 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -166,14 +166,13 @@ fail:
}
/* 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 769c4d10..cc2c93aa 100644
--- a/com32/chain/utility.h
+++ b/com32/chain/utility.h
@@ -50,7 +50,7 @@ enum {L2C_CNUL, L2C_CADD, L2C_CMAX};
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);
int guid_is0(const struct guid *guid);