[syslinux:elflink] com32/chain: mangle and related updates

syslinux-bot for Michal Soltys soltys at ziu.info
Sat Feb 16 01:48:11 PST 2013


Commit-ID:  ef9308f5b855b4b5c6484bd959c0334111908a44
Gitweb:     http://www.syslinux.org/commit/ef9308f5b855b4b5c6484bd959c0334111908a44
Author:     Michal Soltys <soltys at ziu.info>
AuthorDate: Thu, 14 Feb 2013 16:51:45 +0100
Committer:  Michal Soltys <soltys at ziu.info>
CommitDate: Thu, 14 Feb 2013 16:53:04 +0100

com32/chain: mangle and related updates

Comments, output and minor adjustments.

Signed-off-by: Michal Soltys <soltys at ziu.info>

---
 com32/chain/mangle.c  | 69 +++++++++++++++++++++++++++------------------------
 com32/chain/options.c | 10 ++++----
 com32/chain/options.h |  2 ++
 com32/chain/utility.c |  9 +++----
 com32/chain/utility.h |  2 +-
 5 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 0523db5..a699f3c 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 b831afa..46a26df 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 c3e1af6..ea6e470 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 18dbbc6..d0da9f8 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 769c4d1..cc2c93a 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);
 


More information about the Syslinux-commits mailing list