diff options
author | Michal Soltys <soltys@ziu.info> | 2010-08-22 13:44:01 +0200 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2010-09-28 09:32:52 +0200 |
commit | b4ba30102958f77e6bef1354459a06416408c2d7 (patch) | |
tree | 44f46a9f9c3fcd504daa32f1ddc44a2dbf8c3414 /com32/chain/chain.c | |
parent | e0b353a198457ada5f2579fda0a77e1853137bd7 (diff) | |
download | syslinux-b4ba30102958f77e6bef1354459a06416408c2d7.tar.gz |
chain.c: Split chain into smaller files
new file: chain.h
new file: common.h
new file: mangle.c
new file: mangle.h
new file: options.c
new file: options.h
new file: utility.c
new file: utility.h
Signed-off-by: Michal Soltys <soltys@ziu.info>
Diffstat (limited to 'com32/chain/chain.c')
-rw-r--r-- | com32/chain/chain.c | 788 |
1 files changed, 14 insertions, 774 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c index 5af6c152..d1939ecd 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -34,83 +34,22 @@ #include <syslinux/config.h> #include <syslinux/disk.h> #include <syslinux/video.h> +#include "common.h" +#include "chain.h" +#include "utility.h" +#include "options.h" #include "partiter.h" +#include "mangle.h" -/* used in checks, whenever addresses supplied by user are sane */ +struct options opt; -#define ADDRMAX 0x9EFFFu -#define ADDRMIN 0x500u - -static const char cmldr_signature[8] = "cmdcons"; static int fixed_cnt; -static struct options { - unsigned int fseg; - unsigned int foff; - unsigned int fip; - unsigned int sseg; - unsigned int soff; - unsigned int sip; - unsigned int drvoff; - const char *drivename; - const char *partition; - const char *file; - const char *grubcfg; - bool isolinux; - bool cmldr; - bool drmk; - bool grub; - bool grldr; - bool maps; - bool hand; - bool hptr; - bool swap; - bool hide; - bool sethid; - bool setgeo; - bool setdrv; - bool sect; - bool save; - bool filebpb; - bool warn; - uint16_t keeppxe; - struct syslinux_rm_regs regs; -} opt; - -struct data_area { - void *data; - addr_t base; - addr_t size; -}; - -static void wait_key(void) -{ - int cnt; - char junk; - - /* drain */ - do { - errno = 0; - cnt = read(0, &junk, 1); - } while (cnt > 0 || (cnt < 0 && errno == EAGAIN)); - - /* wait */ - do { - errno = 0; - cnt = read(0, &junk, 1); - } while (!cnt || (cnt < 0 && errno == EAGAIN)); -} - -static void error(const char *msg) -{ - fputs(msg, stderr); -} - -static int no_ov(const struct data_area *a, const struct data_area *b) +static int overlap(const struct data_area *a, const struct data_area *b) { return - a->base + a->size <= b->base || - b->base + b->size <= a->base; + a->base + a->size > b->base && + b->base + b->size > a->base; } static int is_phys(uint8_t sdifs) @@ -400,377 +339,6 @@ out: free(mbr); } -static uint32_t get_file_lba(const char *filename) -{ - com32sys_t inregs; - uint32_t lba; - - /* Start with clean registers */ - memset(&inregs, 0, sizeof(com32sys_t)); - - /* Put the filename in the bounce buffer */ - strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size); - - /* Call comapi_open() which returns a structure pointer in SI - * to a structure whose first member happens to be the LBA. - */ - inregs.eax.w[0] = 0x0006; - inregs.esi.w[0] = OFFS(__com32.cs_bounce); - inregs.es = SEG(__com32.cs_bounce); - __com32.cs_intcall(0x22, &inregs, &inregs); - - if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) { - return 0; /* Filename not found */ - } - - /* Since the first member is the LBA, we simply cast */ - lba = *((uint32_t *) MK_PTR(inregs.ds, inregs.esi.w[0])); - - /* Clean the registers for the next call */ - memset(&inregs, 0, sizeof(com32sys_t)); - - /* Put the filename in the bounce buffer */ - strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size); - - /* Call comapi_close() to free the structure */ - inregs.eax.w[0] = 0x0008; - inregs.esi.w[0] = OFFS(__com32.cs_bounce); - inregs.es = SEG(__com32.cs_bounce); - __com32.cs_intcall(0x22, &inregs, &inregs); - - return lba; -} - -/* Convert string seg:off:ip values into numerical seg:off:ip ones */ - -static int soi_s2n(char *ptr, unsigned int *seg, - unsigned int *off, - unsigned int *ip) -{ - unsigned int segval = 0, offval = 0, ipval = 0, val; - char *p; - - segval = strtoul(ptr, &p, 0); - if (*p == ':') - offval = strtoul(p+1, &p, 0); - if (*p == ':') - ipval = strtoul(p+1, NULL, 0); - - val = (segval << 4) + offval; - - if (val < ADDRMIN || val > ADDRMAX) { - error("Invalid seg:off:* address specified..\n"); - goto bail; - } - - val = (segval << 4) + ipval; - - if (ipval > 0xFFFE || val < ADDRMIN || val > ADDRMAX) { - error("Invalid seg:*:ip address specified.\n"); - goto bail; - } - - if (seg) - *seg = segval; - if (off) - *off = offval; - if (ip) - *ip = ipval; - - return 0; - -bail: - return -1; -} - -static void usage(void) -{ - static const char *const usage[] = { "\ -Usage:\n\ - chain.c32 [options]\n\ - chain.c32 {fd|hd}<disk> [<partition>] [options]\n\ - chain.c32 mbr{:|=}<id> [<partition>] [options]\n\ - chain.c32 guid{:|=}<guid> [<partition>] [options]\n\ - chain.c32 label{:|=}<label> [<partition>] [options]\n\ - chain.c32 boot{,| }[<partition>] [options]\n\ - chain.c32 fs [options]\n\ -\nOptions ('no' prefix specify defaulti value):\n\ - file=<loader> Load and execute file\n\ - seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>\n\ - nofilebpb Treat file in memory as BPB compatible\n\ - sect[=<s[:o[:i]]>] Load sector at <s:o>, jump to <s:i>\n\ - - defaults to 0:0x7C00:0x7C00\n\ - maps Map loaded sector into real memory\n\ - nosethid[den] Set BPB's hidden sectors field\n\ - nosetgeo Set BPB's sectors per track and heads fields\n\ - nosetdrv[@<off>] Set BPB's drive unit field at <o>\n\ - - <off> defaults to autodetection\n\ - - only 0x24 and 0x40 are accepted\n\ - nosetbpb Enable set{hid,geo,drv}\n\ - nosave Write adjusted sector back to disk\n\ - hand Prepare handover area\n\ - nohptr Force ds:si and ds:bp to point to handover area\n\ - noswap Swap drive numbers, if bootdisk is not fd0/hd0\n\ - nohide Hide primary partitions, unhide selected partition\n\ - nokeeppxe Keep the PXE and UNDI stacks in memory (PXELINUX)\n\ - nowarn Wait for a keypress to continue chainloading\n\ - - useful to see emited warnings\n\ -", "\ -\nComposite options:\n\ - isolinux=<loader> Load another version of ISOLINUX\n\ - ntldr=<loader> Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n\ - cmldr=<loader> Load Recovery Console of Windows NT/2K/XP/2003\n\ - freedos=<loader> Load FreeDOS KERNEL.SYS\n\ - msdos=<loader> Load MS-DOS 2.xx - 6.xx IO.SYS\n\ - msdos7=<loader> Load MS-DOS 7+ IO.SYS\n\ - pcdos=<loader> Load PC-DOS IBMBIO.COM\n\ - drmk=<loader> Load DRMK DELLBIO.BIN\n\ - grub=<loader> Load GRUB Legacy stage2\n\ - grubcfg=<filename> Set alternative config filename for GRUB Legacy\n\ - grldr=<loader> Load GRUB4DOS grldr\n\ -\nPlease see doc/chain.txt for the detailed documentation.\n" - }; - error(usage[0]); - error("Press any key...\n"); - wait_key(); - error(usage[1]); -} - -static int parse_args(int argc, char *argv[]) -{ - int i; - unsigned int v; - char *p; - - for (i = 1; i < argc; i++) { - if (!strncmp(argv[i], "file=", 5)) { - opt.file = argv[i] + 5; - } else if (!strcmp(argv[i], "nofile")) { - opt.file = NULL; - } else if (!strncmp(argv[i], "seg=", 4)) { - if (soi_s2n(argv[i] + 4, &opt.fseg, &opt.foff, &opt.fip)) - goto bail; - } else if (!strncmp(argv[i], "isolinux=", 9)) { - opt.file = argv[i] + 9; - opt.isolinux = true; - opt.hand = false; - opt.sect = false; - } else if (!strncmp(argv[i], "ntldr=", 6)) { - opt.fseg = 0x2000; /* NTLDR wants this address */ - opt.foff = 0; - opt.fip = 0; - opt.file = argv[i] + 6; - opt.sethid = true; - opt.setgeo = true; - opt.setdrv = true; - opt.drvoff = 0x24; - /* opt.save = true; */ - opt.hand = false; - } else if (!strncmp(argv[i], "cmldr=", 6)) { - opt.fseg = 0x2000; /* CMLDR wants this address */ - opt.foff = 0; - opt.fip = 0; - opt.file = argv[i] + 6; - opt.cmldr = true; - opt.sethid = true; - opt.setgeo = true; - opt.setdrv = true; - opt.drvoff = 0x24; - /* opt.save = true; */ - opt.hand = false; - } else if (!strncmp(argv[i], "freedos=", 8)) { - opt.fseg = 0x60; /* FREEDOS wants this address */ - opt.foff = 0; - opt.fip = 0; - opt.sseg = 0x9000; - opt.soff = 0; - opt.sip = 0; - opt.file = argv[i] + 8; - opt.sethid = true; - opt.setgeo = true; - opt.setdrv = true; - opt.drvoff = ~0u; - /* opt.save = true; */ - opt.hand = false; - } else if ( (v = 6, !strncmp(argv[i], "msdos=", v) || - !strncmp(argv[i], "pcdos=", v)) || - (v = 7, !strncmp(argv[i], "msdos7=", v)) ) { - opt.fseg = 0x70; /* MS-DOS 2.00 .. 6.xx wants this address */ - opt.foff = 0; - opt.fip = v == 7 ? 0x200 : 0; /* MS-DOS 7.0+ wants this ip */ - opt.sseg = 0x9000; - opt.soff = 0; - opt.sip = 0; - opt.file = argv[i] + v; - opt.sethid = true; - opt.setgeo = true; - opt.setdrv = true; - opt.drvoff = ~0u; - /* opt.save = true; */ - opt.hand = false; - } else if (!strncmp(argv[i], "drmk=", 5)) { - opt.fseg = 0x70; /* DRMK wants this address */ - opt.foff = 0; - opt.fip = 0; - opt.sseg = 0x2000; - opt.soff = 0; - opt.sip = 0; - opt.file = argv[i] + 5; - /* opt.drmk = true; */ - opt.sethid = true; - opt.setgeo = true; - opt.setdrv = true; - opt.drvoff = ~0u; - /* opt.save = true; */ - opt.hand = false; - } else if (!strncmp(argv[i], "grub=", 5)) { - opt.fseg = 0x800; /* stage2 wants this address */ - opt.foff = 0; - opt.fip = 0x200; - opt.file = argv[i] + 5; - opt.grub = true; - opt.hand = false; - opt.sect = false; - } else if (!strncmp(argv[i], "grubcfg=", 8)) { - opt.grubcfg = argv[i] + 8; - } else if (!strncmp(argv[i], "grldr=", 6)) { - opt.file = argv[i] + 6; - opt.grldr = true; - opt.hand = false; - opt.sect = false; - } else if (!strcmp(argv[i], "keeppxe")) { - opt.keeppxe = 3; - } else if (!strcmp(argv[i], "nokeeppxe")) { - opt.keeppxe = 0; - } else if (!strcmp(argv[i], "maps")) { - opt.maps = true; - } else if (!strcmp(argv[i], "nomaps")) { - opt.maps = false; - } else if (!strcmp(argv[i], "hand")) { - opt.hand = true; - } else if (!strcmp(argv[i], "nohand")) { - opt.hand = false; - } else if (!strcmp(argv[i], "hptr")) { - opt.hptr = true; - } else if (!strcmp(argv[i], "nohptr")) { - opt.hptr = false; - } else if (!strcmp(argv[i], "swap")) { - opt.swap = true; - } else if (!strcmp(argv[i], "noswap")) { - opt.swap = false; - } else if (!strcmp(argv[i], "hide")) { - opt.hide = true; - } else if (!strcmp(argv[i], "nohide")) { - opt.hide = false; - } else if (!strcmp(argv[i], "sethid") || - !strcmp(argv[i], "sethidden")) { - opt.sethid = true; - } else if (!strcmp(argv[i], "nosethid") || - !strcmp(argv[i], "nosethidden")) { - opt.sethid = false; - } else if (!strcmp(argv[i], "setgeo")) { - opt.setgeo = true; - } else if (!strcmp(argv[i], "nosetgeo")) { - opt.setgeo = false; - } else if (!strncmp(argv[i], "setdrv",6)) { - if (!argv[i][6]) - v = ~0u; /* autodetect */ - else if (argv[i][6] == '@' || - argv[i][6] == '=' || - argv[i][6] == ':') { - v = strtoul(argv[i] + 7, NULL, 0); - if (!(v == 0x24 || v == 0x40)) { - error("Invalid 'setdrv' offset.\n"); - goto bail; - } - } else { - error("Invalid 'setdrv' specification.\n"); - goto bail; - } - opt.setdrv = true; - opt.drvoff = v; - } else if (!strcmp(argv[i], "nosetdrv")) { - opt.setdrv = false; - } else if (!strcmp(argv[i], "setbpb")) { - opt.setdrv = true; - opt.drvoff = ~0u; - opt.setgeo = true; - opt.sethid = true; - } else if (!strcmp(argv[i], "nosetbpb")) { - opt.setdrv = false; - opt.setgeo = false; - opt.sethid = false; - } else if (!strncmp(argv[i], "sect=", 5) || - !strcmp(argv[i], "sect")) { - if (argv[i][4]) { - if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip)) - goto bail; - if ((opt.sseg << 4) + opt.soff + SECTOR - 1 > ADDRMAX) { - error("Arguments of 'sect=' are invalid - resulting address too big.\n"); - goto bail; - } - } - opt.sect = true; - } else if (!strcmp(argv[i], "nosect")) { - opt.sect = false; - } else if (!strcmp(argv[i], "save")) { - opt.save = true; - } else if (!strcmp(argv[i], "nosave")) { - opt.save = false; - } else if (!strcmp(argv[i], "filebpb")) { - opt.filebpb = true; - } else if (!strcmp(argv[i], "nofilebpb")) { - opt.filebpb = false; - } else if (!strcmp(argv[i], "warn")) { - opt.warn = true; - } else if (!strcmp(argv[i], "nowarn")) { - opt.warn = false; - } else if (((argv[i][0] == 'h' || argv[i][0] == 'f') - && argv[i][1] == 'd') - || !strncmp(argv[i], "mbr:", 4) - || !strncmp(argv[i], "mbr=", 4) - || !strncmp(argv[i], "guid:", 5) - || !strncmp(argv[i], "guid=", 5) - || !strncmp(argv[i], "label:", 6) - || !strncmp(argv[i], "label=", 6) - || !strcmp(argv[i], "boot") - || !strncmp(argv[i], "boot,", 5) - || !strcmp(argv[i], "fs")) { - opt.drivename = argv[i]; - p = strchr(opt.drivename, ','); - if (p) { - *p = '\0'; - opt.partition = p + 1; - } else if (argv[i + 1] && argv[i + 1][0] >= '0' - && argv[i + 1][0] <= '9') { - opt.partition = argv[++i]; - } - } else { - usage(); - goto bail; - } - } - - if (opt.grubcfg && !opt.grub) { - error("grubcfg=<filename> must be used together with grub=<loader>.\n"); - goto bail; - } - - if ((!opt.maps || !opt.sect) && !opt.file) { - error("You have to load something.\n"); - goto bail; - } - - if (opt.filebpb && !opt.file) { - error("Option 'filebpb' requires file.\n"); - goto bail; - } - - return 0; -bail: - return -1; -} - int find_dp(struct part_iter **_iter) { struct part_iter *iter; @@ -888,256 +456,6 @@ bail: return -1; } -/* Create boot info table: needed when you want to chainload - * another version of ISOLINUX (or another bootlaoder that needs - * the -boot-info-table switch of mkisofs) - * (will only work when run from ISOLINUX) - */ -static int manglef_isolinux(struct data_area *data) -{ - const union syslinux_derivative_info *sdi; - unsigned char *isolinux_bin; - uint32_t *checksum, *chkhead, *chktail; - uint32_t file_lba = 0; - - sdi = syslinux_derivative_info(); - - if (sdi->c.filesystem != SYSLINUX_FS_ISOLINUX) { - error ("The isolinux= option is only valid when run from ISOLINUX.\n"); - goto bail; - } - - /* Boot info table info (integers in little endian format) - - Offset Name Size Meaning - 8 bi_pvd 4 bytes LBA of primary volume descriptor - 12 bi_file 4 bytes LBA of boot file - 16 bi_length 4 bytes Boot file length in bytes - 20 bi_csum 4 bytes 32-bit checksum - 24 bi_reserved 40 bytes Reserved - - The 32-bit checksum is the sum of all the 32-bit words in the - boot file starting at byte offset 64. All linear block - addresses (LBAs) are given in CD sectors (normally 2048 bytes). - - LBA of primary volume descriptor should already be set to 16. - */ - - isolinux_bin = (unsigned char *)data->data; - - /* Get LBA address of bootfile */ - file_lba = get_file_lba(opt.file); - - if (file_lba == 0) { - error("Failed to find LBA offset of the boot file\n"); - goto bail; - } - /* Set it */ - *((uint32_t *) & isolinux_bin[12]) = file_lba; - - /* Set boot file length */ - *((uint32_t *) & isolinux_bin[16]) = data->size; - - /* Calculate checksum */ - checksum = (uint32_t *) & isolinux_bin[20]; - chkhead = (uint32_t *) & isolinux_bin[64]; - chktail = (uint32_t *) & isolinux_bin[data->size & ~3u]; - *checksum = 0; - while (chkhead < chktail) - *checksum += *chkhead++; - - /* - * Deal with possible fractional dword at the end; - * this *should* never happen... - */ - if (data->size & 3) { - uint32_t xword = 0; - memcpy(&xword, chkhead, data->size & 3); - *checksum += xword; - } - return 0; -bail: - return -1; -} - -/* - * GRLDR of GRUB4DOS wants the partition number in DH: - * -1: whole drive (default) - * 0-3: primary partitions - * 4-*: logical partitions - */ -static int manglef_grldr(const struct part_iter *iter) -{ - opt.regs.edx.b[1] = (uint8_t)(iter->index - 1); - return 0; -} - -/* - * Legacy grub's stage2 chainloading - */ -static int manglef_grub(const struct part_iter *iter, struct data_area *data) -{ - /* Layout of stage2 file (from byte 0x0 to 0x270) */ - struct grub_stage2_patch_area { - /* 0x0 to 0x205 */ - char unknown[0x206]; - /* 0x206: compatibility version number major */ - uint8_t compat_version_major; - /* 0x207: compatibility version number minor */ - uint8_t compat_version_minor; - - /* 0x208: install_partition variable */ - struct { - /* 0x208: sub-partition in sub-partition part2 */ - uint8_t part3; - /* 0x209: sub-partition in top-level partition */ - uint8_t part2; - /* 0x20a: top-level partiton number */ - uint8_t part1; - /* 0x20b: BIOS drive number (must be 0) */ - uint8_t drive; - } __attribute__ ((packed)) install_partition; - - /* 0x20c: deprecated (historical reason only) */ - uint32_t saved_entryno; - /* 0x210: stage2_ID: will always be STAGE2_ID_STAGE2 = 0 in stage2 */ - uint8_t stage2_id; - /* 0x211: force LBA */ - uint8_t force_lba; - /* 0x212: version string (will probably be 0.97) */ - char version_string[5]; - /* 0x217: config filename */ - char config_file[89]; - /* 0x270: start of code (after jump from 0x200) */ - char codestart[1]; - } __attribute__ ((packed)) *stage2; - - if (data->size < sizeof(struct grub_stage2_patch_area)) { - error("The file specified by grub=<loader> is too small to be stage2 of GRUB Legacy.\n"); - goto bail; - } - stage2 = data->data; - - /* - * Check the compatibility version number to see if we loaded a real - * stage2 file or a stage2 file that we support. - */ - if (stage2->compat_version_major != 3 - || stage2->compat_version_minor != 2) { - error("The file specified by grub=<loader> is not a supported stage2 GRUB Legacy binary.\n"); - goto bail; - } - - /* - * GRUB Legacy wants the partition number in the install_partition - * variable, located at offset 0x208 of stage2. - * When GRUB Legacy is loaded, it is located at memory address 0x8208. - * - * It looks very similar to the "boot information format" of the - * Multiboot specification: - * http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format - * - * 0x208 = part3: sub-partition in sub-partition part2 - * 0x209 = part2: sub-partition in top-level partition - * 0x20a = part1: top-level partition number - * 0x20b = drive: BIOS drive number (must be 0) - * - * GRUB Legacy doesn't store the BIOS drive number at 0x20b, but at - * another location. - * - * Partition numbers always start from zero. - * Unused partition bytes must be set to 0xFF. - * - * We only care about top-level partition, so we only need to change - * "part1" to the appropriate value: - * -1: whole drive (default) (-1 = 0xFF) - * 0-3: primary partitions - * 4-*: logical partitions - */ - stage2->install_partition.part1 = (uint8_t)(iter->index - 1); - - /* - * Grub Legacy reserves 89 bytes (from 0x8217 to 0x826f) for the - * config filename. The filename passed via grubcfg= will overwrite - * the default config filename "/boot/grub/menu.lst". - */ - if (opt.grubcfg) { - if (strlen(opt.grubcfg) > sizeof(stage2->config_file) - 1) { - error ("The config filename length can't exceed 88 characters.\n"); - goto bail; - } - - strcpy((char *)stage2->config_file, opt.grubcfg); - } - - return 0; -bail: - return -1; -} - -/* - * Dell's DRMK chainloading. - */ -static int manglef_drmk(struct data_area *data) -{ - /* - * DRMK entry is different than MS-DOS/PC-DOS - * A new size, aligned to 16 bytes to ease use of ds:[bp+28]. - * We only really need 4 new, usable bytes at the end. - */ - - uint32_t tsize = (data->size + 19) & 0xfffffff0; - opt.regs.ss = opt.regs.fs = opt.regs.gs = 0; /* Used before initialized */ - if (!realloc(data->data, tsize)) { - error("Failed to realloc for DRMK.\n"); - goto bail; - } - data->size = tsize; - /* ds:[bp+28] must be 0x0000003f */ - opt.regs.ds = (uint16_t)((tsize >> 4) + (opt.fseg - 2)); - /* "Patch" into tail of the new space */ - *(uint32_t *)((char*)data->data + tsize - 4) = 0x0000003f; - - return 0; -bail: - return -1; -} - -static uint32_t lba2chs(const struct disk_info *di, uint64_t lba) -{ - uint32_t c, h, s, t; - - if (di->cbios) { - if (lba >= di->cyl * di->head * di->sect) { - s = di->sect; - h = di->head - 1; - c = di->cyl - 1; - goto out; - } - s = ((uint32_t)lba % di->sect) + 1; - t = (uint32_t)lba / di->sect; - h = t % di->head; - c = t / di->head; - } else - goto fallback; - -out: - return h | (s << 8) | ((c & 0x300) << 6) | ((c & 0xFF) << 16); - -fallback: - if (di->disk & 0x80) - return 0x00FFFFFE; /* 1023/63/254 */ - else - /* FIXME ? - * this is mostly "useful" with partitioned floppy, - * maybe stick to 2.88mb ? - */ - return 0x004F1201; /* 79/18/1 */ -#if 0 - return 0x004F2401; /* 79/36/1 */ -#endif -} - static int setup_handover(const struct part_iter *iter, struct data_area *data) { @@ -1218,86 +536,6 @@ bail: return -1; } -static int manglef_bpb(const struct part_iter *iter, struct data_area *data) -{ - /* BPB: hidden sectors */ - if (opt.sethid) { - if (iter->start_lba < ~0u) - *(uint32_t *) ((char *)data->data + 0x1c) = (uint32_t)iter->start_lba; - else - /* won't really help much, but ... */ - *(uint32_t *) ((char *)data->data + 0x1c) = ~0u; - } - /* BPB: legacy geometry */ - if (opt.setgeo) { - if (iter->di.cbios) - *(uint32_t *)((char *)data->data + 0x18) = (uint32_t)((iter->di.head << 16) | iter->di.sect); - else { - if (iter->di.disk & 0x80) - *(uint32_t *)((char *)data->data + 0x18) = 0x00FF003F; - else - *(uint32_t *)((char *)data->data + 0x18) = 0x00020012; - } - } - - /* BPB: drive */ - if (opt.setdrv) - *(uint8_t *)((char *)data->data + opt.drvoff) = (uint8_t) - (opt.swap ? iter->di.disk & 0x80 : iter->di.disk); - - return 0; -} - -static int try_mangles_bpb(const struct part_iter *iter, struct data_area *data) -{ - void *cmp_buf = NULL; - - if (!(opt.setdrv || opt.setgeo || opt.sethid)) - return 0; - -#if 0 - /* Turn this off for now. It's hard to find a reason to - * BPB-mangle sector 0 of whatever there is, but it's - * "potentially" useful (fixing fdd's sector ?). - */ - if (!iter->index) - return 0; -#endif - - if (!(cmp_buf = malloc(data->size))) { - error("Could not allocate sector-compare buffer.\n"); - goto bail; - } - - memcpy(cmp_buf, data->data, data->size); - - manglef_bpb(iter, data); - - if (opt.save && memcmp(cmp_buf, data->data, data->size)) { - if (disk_write_verify_sector(&iter->di, iter->start_lba, data->data)) { - error("Cannot write updated boot sector.\n"); - goto bail; - } - } - - free(cmp_buf); - return 0; - -bail: - return -1; -} - -/* - * To boot the Recovery Console of Windows NT/2K/XP we need to write - * the string "cmdcons\0" to memory location 0000:7C03. - * Memory location 0000:7C00 contains the bootsector of the partition. - */ -static int mangles_cmldr(struct data_area *data) -{ - memcpy((char *)data->data + 3, cmldr_signature, sizeof(cmldr_signature)); - return 0; -} - int setdrv_auto(const struct part_iter *iter) { int a, b; @@ -1408,7 +646,7 @@ int main(int argc, char *argv[]) data[ndata].size = SECTOR; data[ndata].base = (opt.sseg << 4) + opt.soff; - if (opt.file && opt.maps && !no_ov(data + fidx, data + ndata)) { + if (opt.file && opt.maps && overlap(data + fidx, data + ndata)) { error("WARNING: The sector won't be loaded, as it would conflict with the boot file.\n"); } else { if (!(data[ndata].data = disk_read_sectors(&iter->di, iter->start_lba, 1))) { @@ -1429,8 +667,8 @@ int main(int argc, char *argv[]) hand_area = (void *)data[ndata].data; /* Verify possible conflicts */ - if ( ( fidx >= 0 && !no_ov(data + fidx, data + ndata)) || - ( sidx >= 0 && opt.maps && !no_ov(data + sidx, data + ndata)) ) { + if ( ( fidx >= 0 && overlap(data + fidx, data + ndata)) || + ( sidx >= 0 && opt.maps && overlap(data + sidx, data + ndata)) ) { error("WARNING: Handover area won't be prepared,\n" "as it would conflict with the boot file and/or the sector.\n"); } else { @@ -1470,8 +708,10 @@ int main(int argc, char *argv[]) if (opt.grub && manglef_grub(iter, data + fidx)) goto bail; +#if 0 if (opt.drmk && manglef_drmk(data + fidx)) goto bail; +#endif if (opt.filebpb && manglef_bpb(iter, data + fidx)) goto bail; |