diff options
-rw-r--r-- | dos/dosexe.ld | 6 | ||||
-rw-r--r-- | dos/ldlinux.S | 14 | ||||
-rw-r--r-- | dos/syslinux.c | 100 | ||||
-rw-r--r-- | extlinux/Makefile | 1 | ||||
-rw-r--r-- | extlinux/main.c | 58 | ||||
-rw-r--r-- | libinstaller/Makefile | 5 | ||||
-rw-r--r-- | libinstaller/syslinux.h | 3 | ||||
-rw-r--r-- | linux/Makefile | 1 | ||||
-rwxr-xr-x | linux/syslinux.c | 55 | ||||
-rwxr-xr-x | mtools/Makefile | 1 | ||||
-rwxr-xr-x | mtools/syslinux.c | 129 | ||||
-rw-r--r-- | win/syslinux.c | 123 | ||||
-rw-r--r-- | win32/Makefile | 1 | ||||
-rw-r--r-- | win64/Makefile | 1 |
14 files changed, 346 insertions, 152 deletions
diff --git a/dos/dosexe.ld b/dos/dosexe.ld index 76bfc758..bd6ad8ba 100644 --- a/dos/dosexe.ld +++ b/dos/dosexe.ld @@ -26,7 +26,7 @@ SECTIONS __header_size = .; __payload_lma = .; - . = 0x100000000 - syslinux_ldlinux_size; + . = 0x100000000 - syslinux_size; .payload : AT (__payload_lma) { __payload_start = .; *(.payload) @@ -35,13 +35,13 @@ SECTIONS __payload_len = ABSOLUTE(__payload_end) - ABSOLUTE(__payload_start); __payload_dwords = __payload_len >> 2; - __text_lma = __payload_lma + syslinux_ldlinux_size; + __text_lma = __payload_lma + syslinux_size; __payload_sseg = (__payload_lma - __text_lma) >> 4; _exe_text_seg = (__text_lma - __header_size) >> 4; /* * __assert1 = ASSERT((__payload_len == syslinux_ldlinux_size), - * "syslinux_ldlinux_size must equal the size of .payload"); + * "syslinux_size must equal the size of .payload"); */ . = 0; .text : AT (__text_lma) { diff --git a/dos/ldlinux.S b/dos/ldlinux.S index 17a65830..9145bd7b 100644 --- a/dos/ldlinux.S +++ b/dos/ldlinux.S @@ -1,5 +1,5 @@ /* - * Wrap ldlinux.sys; this needs special handling for DOS. + * Wrap ldlinux.sys and ldlinux.c32; this needs special handling for DOS. */ .section ".payload","aw" @@ -10,6 +10,14 @@ syslinux_ldlinux: .space ((syslinux_ldlinux - .) & 511) syslinux_ldlinux_size = . - syslinux_ldlinux .size syslinux_ldlinux, .-syslinux_ldlinux + .globl syslinux_ldlinuxc32, syslinux_ldlinuxc32_size +syslinux_ldlinuxc32: + .incbin "../com32/elflink/ldlinux/ldlinux.c32" + .space ((syslinux_ldlinuxc32 - .) & 511) +syslinux_ldlinuxc32_size = . - syslinux_ldlinuxc32 + .size syslinux_ldlinuxc32, .-syslinux_ldlinuxc32 + .globl syslinux_size +syslinux_size = . - syslinux_ldlinux .section ".rodata","a" .balign 4 @@ -17,3 +25,7 @@ syslinux_ldlinux_size = . - syslinux_ldlinux syslinux_ldlinux_len: .long syslinux_ldlinux_size .size syslinux_ldlinux_len, .-syslinux_ldlinux_len + .globl syslinux_ldlinuxc32_len +syslinux_ldlinuxc32_len: + .long syslinux_ldlinuxc32_size + .size syslinux_ldlinuxc32_len, .-syslinux_ldlinuxc32_len diff --git a/dos/syslinux.c b/dos/syslinux.c index fa4bf387..eb8bace6 100644 --- a/dos/syslinux.c +++ b/dos/syslinux.c @@ -121,15 +121,15 @@ int rename(const char *oldname, const char *newname) return 0; } -ssize_t write_ldlinux(int fd) +ssize_t write_file_seg(int fd, unsigned char *buf, const unsigned int len) { - uint16_t ldlinux_seg = ((size_t)syslinux_ldlinux >> 4) + ds(); + uint16_t seg = ((size_t)buf >> 4) + ds(); uint32_t offset = 0; uint16_t rv; uint8_t err; - while (offset < syslinux_ldlinux_len) { - uint32_t chunk = syslinux_ldlinux_len - offset; + while (offset < len) { + uint32_t chunk = len - offset; if (chunk > 32768) chunk = 32768; asm volatile ("pushw %%ds ; " @@ -137,7 +137,7 @@ ssize_t write_ldlinux(int fd) "int $0x21 ; " "popw %%ds ; " "setc %0":"=bcdm" (err), "=a"(rv) :"a"(0x4000), "b"(fd), "c"(chunk), "d" (offset & 15), - "SD" ((uint16_t)(ldlinux_seg + (offset >> 4)))); + "SD" ((uint16_t)(seg + (offset >> 4)))); if (err || rv == 0) die("file write error"); offset += rv; @@ -583,11 +583,53 @@ static void adjust_mbr(int device, int writembr, int set_active) write_mbr(device, sectbuf); } +static void move_file(int dev_fd, char *pathname, char *filename) +{ + char new_name[160]; + char *cp = new_name + 3; + const char *sd; + int slash = 1; + + new_name[0] = dev_fd | 0x40; + new_name[1] = ':'; + new_name[2] = '\\'; + + for (sd = opt.directory; *sd; sd++) { + char c = *sd; + + if (c == '/' || c == '\\') { + if (slash) + continue; + c = '\\'; + slash = 1; + } else { + slash = 0; + } + + *cp++ = c; + } + + /* Skip if subdirectory == root */ + if (cp > new_name + 3) { + if (!slash) + *cp++ = '\\'; + + memcpy(cp, filename, 12); + + set_attributes(pathname, 0); + if (rename(pathname, new_name)) + set_attributes(pathname, 0x07); + else + set_attributes(new_name, 0x07); + } +} + int main(int argc, char *argv[]) { static unsigned char sectbuf[SECTOR_SIZE]; int dev_fd, fd; static char ldlinux_name[] = "@:\\ldlinux.sys"; + static char ldlinuxc32_name[] = "@:\\ldlinux.c32"; struct libfat_filesystem *fs; libfat_sector_t s, *secp; libfat_sector_t *sectors; @@ -647,14 +689,21 @@ int main(int argc, char *argv[]) } ldlinux_name[0] = dev_fd | 0x40; + ldlinuxc32_name[0] = dev_fd | 0x40; set_attributes(ldlinux_name, 0); fd = creat(ldlinux_name, 0); /* SYSTEM HIDDEN READONLY */ - write_ldlinux(fd); + write_file_seg(fd, syslinux_ldlinux, syslinux_ldlinux_len); write_file(fd, syslinux_adv, 2 * ADV_SIZE); close(fd); set_attributes(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */ + set_attributes(ldlinuxc32_name, 0); + fd = creat(ldlinuxc32_name, 0); /* SYSTEM HIDDEN READONLY */ + write_file_seg(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len); + close(fd); + set_attributes(ldlinuxc32_name, 0x07); /* SYSTEM HIDDEN READONLY */ + /* * Now, use libfat to create a block map. This probably * should be changed to use ioctl(...,FIBMAP,...) since @@ -681,43 +730,8 @@ int main(int argc, char *argv[]) * If requested, move ldlinux.sys */ if (opt.directory) { - char new_ldlinux_name[160]; - char *cp = new_ldlinux_name + 3; - const char *sd; - int slash = 1; - - new_ldlinux_name[0] = dev_fd | 0x40; - new_ldlinux_name[1] = ':'; - new_ldlinux_name[2] = '\\'; - - for (sd = opt.directory; *sd; sd++) { - char c = *sd; - - if (c == '/' || c == '\\') { - if (slash) - continue; - c = '\\'; - slash = 1; - } else { - slash = 0; - } - - *cp++ = c; - } - - /* Skip if subdirectory == root */ - if (cp > new_ldlinux_name + 3) { - if (!slash) - *cp++ = '\\'; - - memcpy(cp, "ldlinux.sys", 12); - - set_attributes(ldlinux_name, 0); - if (rename(ldlinux_name, new_ldlinux_name)) - set_attributes(ldlinux_name, 0x07); - else - set_attributes(new_ldlinux_name, 0x07); - } + move_file(dev_fd, ldlinux_name, "ldlinux.sys"); + move_file(dev_fd, ldlinuxc32_name, "ldlinux.c32"); } /* diff --git a/extlinux/Makefile b/extlinux/Makefile index 6cde574e..f20a71db 100644 --- a/extlinux/Makefile +++ b/extlinux/Makefile @@ -32,6 +32,7 @@ SRCS = main.c \ ../libinstaller/setadv.c \ ../libinstaller/advio.c \ ../libinstaller/bootsect_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ ../libinstaller/ldlinux_bin.c OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) diff --git a/extlinux/main.c b/extlinux/main.c index d7a239e0..d1a90481 100644 --- a/extlinux/main.c +++ b/extlinux/main.c @@ -398,16 +398,18 @@ int install_bootblock(int fd, const char *device) int ext2_fat_install_file(const char *path, int devfd, struct stat *rst) { - char *file, *oldfile; + char *file, *oldfile, *c32file; int fd = -1, dirfd = -1; int modbytes; - int r1, r2; + int r1, r2, r3; r1 = asprintf(&file, "%s%sldlinux.sys", path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/"); r2 = asprintf(&oldfile, "%s%sextlinux.sys", path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/"); - if (r1 < 0 || !file || r2 < 0 || !oldfile) { + r3 = asprintf(&c32file, "%s%sldlinux.c32", + path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/"); + if (r1 < 0 || !file || r2 < 0 || !oldfile || r3 < 0 || !c32file) { perror(program); return 1; } @@ -474,8 +476,22 @@ int ext2_fat_install_file(const char *path, int devfd, struct stat *rst) unlink(oldfile); } + fd = open(c32file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC, + S_IRUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + perror(c32file); + goto bail; + } + + r3 = xpwrite(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len, 0); + if (r3 != syslinux_ldlinuxc32_len) { + fprintf(stderr, "%s: write failure on %s\n", program, c32file); + goto bail; + } + free(file); free(oldfile); + free(c32file); return 0; bail: @@ -486,6 +502,7 @@ bail: free(file); free(oldfile); + free(c32file); return 1; } @@ -494,6 +511,9 @@ bail: since the cow feature of btrfs will move the ldlinux.sys every where */ int btrfs_install_file(const char *path, int devfd, struct stat *rst) { + char *file; + int fd, rv; + patch_file_and_bootblock(-1, path, devfd); if (xpwrite(devfd, boot_image, boot_image_len, BTRFS_EXTLINUX_OFFSET) != boot_image_len) { @@ -511,7 +531,37 @@ int btrfs_install_file(const char *path, int devfd, struct stat *rst) perror(path); return 1; } - return 0; + + /* + * Note that we *can* install ldinux.c32 as a regular file because + * it doesn't need to be within the first 64K. The Syslinux core + * has enough smarts to search the btrfs dirs and find this file. + */ + rv = asprintf(&file, "%s%sldlinux.c32", + path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/"); + if (rv < 0 || !file) { + perror(program); + return 1; + } + + fd = open(file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC, + S_IRUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + perror(file); + free(file); + return 1; + } + + rv = xpwrite(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len, 0); + if (rv != (int)syslinux_ldlinuxc32_len) { + fprintf(stderr, "%s: write failure on %s\n", program, file); + rv = 1; + } else + rv = 0; + + close(fd); + free(file); + return rv; } /* diff --git a/libinstaller/Makefile b/libinstaller/Makefile index e67a4686..63446a10 100644 --- a/libinstaller/Makefile +++ b/libinstaller/Makefile @@ -1,6 +1,6 @@ # _bin.c files required by both BTARGET and ITARGET installers BINFILES = bootsect_bin.c ldlinux_bin.c \ - mbr_bin.c gptmbr_bin.c + mbr_bin.c gptmbr_bin.c ldlinuxc32_bin.c PERL = perl @@ -18,6 +18,9 @@ mbr_bin.c: ../mbr/mbr.bin bin2c.pl gptmbr_bin.c: ../mbr/gptmbr.bin bin2c.pl $(PERL) bin2c.pl syslinux_gptmbr < $< > $@ +ldlinuxc32_bin.c: ../com32/elflink/ldlinux/ldlinux.c32 bin2c.pl + $(PERL) bin2c.pl syslinux_ldlinuxc32 < $< > $@ + tidy: rm -f $(BINFILES) diff --git a/libinstaller/syslinux.h b/libinstaller/syslinux.h index 8b86f881..f60a066e 100644 --- a/libinstaller/syslinux.h +++ b/libinstaller/syslinux.h @@ -26,6 +26,9 @@ extern unsigned char syslinux_ldlinux[]; extern const unsigned int syslinux_ldlinux_len; extern const int syslinux_ldlinux_mtime; +extern unsigned char syslinux_ldlinuxc32[]; +extern const unsigned int syslinux_ldlinuxc32_len; + #define boot_sector syslinux_bootsect #define boot_sector_len syslinux_bootsect_len #define boot_image syslinux_ldlinux diff --git a/linux/Makefile b/linux/Makefile index 08a3ed49..d7facaf4 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -31,6 +31,7 @@ SRCS = syslinux.c \ ../libinstaller/fs.c \ ../libinstaller/syslxmod.c \ ../libinstaller/bootsect_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ ../libinstaller/ldlinux_bin.c OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) diff --git a/linux/syslinux.c b/linux/syslinux.c index 4b13b7fe..f4749ead 100755 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -238,6 +238,24 @@ int modify_existing_adv(const char *path) return 0; } +int do_open_file(char *name) +{ + int fd; + + if ((fd = open(name, O_RDONLY)) >= 0) { + uint32_t zero_attr = 0; + ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &zero_attr); + close(fd); + } + + unlink(name); + fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0444); + if (fd < 0) + perror(opt.device); + + return fd; +} + int main(int argc, char *argv[]) { static unsigned char sectbuf[SECTOR_SIZE]; @@ -253,7 +271,7 @@ int main(int argc, char *argv[]) const char *errmsg; int mnt_cookie; int patch_sectors; - int i; + int i, rv; mypid = getpid(); umask(077); @@ -408,16 +426,8 @@ int main(int argc, char *argv[]) if (modify_adv() < 0) exit(1); - if ((fd = open(ldlinux_name, O_RDONLY)) >= 0) { - uint32_t zero_attr = 0; - ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &zero_attr); - close(fd); - } - - unlink(ldlinux_name); - fd = open(ldlinux_name, O_WRONLY | O_CREAT | O_TRUNC, 0444); + fd = do_open_file(ldlinux_name); if (fd < 0) { - perror(opt.device); err = 1; goto umount; } @@ -451,6 +461,31 @@ int main(int argc, char *argv[]) close(fd); sync(); + sprintf(ldlinux_name, "%sldlinux.c32", ldlinux_path); + fd = do_open_file(ldlinux_name); + if (fd < 0) { + err = 1; + goto umount; + } + + rv = xpwrite(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len, 0); + if (rv != (int)syslinux_ldlinuxc32_len) { + fprintf(stderr, "%s: write failure on %s\n", program, ldlinux_name); + exit(1); + } + + fsync(fd); + /* + * Set the attributes + */ + { + uint32_t attr = 0x07; /* Hidden+System+Readonly */ + ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr); + } + + close(fd); + sync(); + umount: do_umount(mntpath, mnt_cookie); sync(); diff --git a/mtools/Makefile b/mtools/Makefile index 78cea1e2..6df18b52 100755 --- a/mtools/Makefile +++ b/mtools/Makefile @@ -14,6 +14,7 @@ SRCS = syslinux.c \ ../libinstaller/setadv.c \ ../libinstaller/bootsect_bin.c \ ../libinstaller/ldlinux_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ $(wildcard ../libfat/*.c) OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS))) diff --git a/mtools/syslinux.c b/mtools/syslinux.c index c65021bb..f43b5a5e 100755 --- a/mtools/syslinux.c +++ b/mtools/syslinux.c @@ -125,6 +125,64 @@ int libfat_xpread(intptr_t pp, void *buf, size_t secsize, return xpread(pp, buf, secsize, offset); } +static int move_file(char *filename) +{ + char target_file[4096], command[5120]; + char *cp = target_file, *ep = target_file + sizeof target_file - 16; + const char *sd; + int slash = 1; + int status; + + cp += sprintf(cp, "'s:/"); + for (sd = opt.directory; *sd; sd++) { + if (*sd == '/' || *sd == '\\') { + if (slash) + continue; /* Remove duplicated slashes */ + slash = 1; + } else if (*sd == '\'' || *sd == '!') { + slash = 0; + if (cp < ep) + *cp++ = '\''; + if (cp < ep) + *cp++ = '\\'; + if (cp < ep) + *cp++ = *sd; + if (cp < ep) + *cp++ = '\''; + continue; + } else { + slash = 0; + } + + if (cp < ep) + *cp++ = *sd; + } + if (!slash) + *cp++ = '/'; + sprintf(cp, "%s'", filename); + + /* This command may fail legitimately */ + sprintf(command, "mattrib -h -r -s %s 2>/dev/null", target_file); + status = system(command); + (void)status; /* Keep _FORTIFY_SOURCE happy */ + + sprintf(command, "mmove -D o -D O s:/%s %s", filename, target_file); + status = system(command); + + if (!WIFEXITED(status) || WEXITSTATUS(status)) { + fprintf(stderr, + "%s: warning: unable to move %s\n", program, filename); + + sprintf(command, "mattrib +r +h +s s:/%s", filename); + status = system(command); + } else { + sprintf(command, "mattrib +r +h +s %s", target_file); + status = system(command); + } + + return status; +} + int main(int argc, char *argv[]) { static unsigned char sectbuf[SECTOR_SIZE]; @@ -284,63 +342,38 @@ int main(int argc, char *argv[]) /* Move ldlinux.sys to the desired location */ if (opt.directory) { - char target_file[4096], command[5120]; - char *cp = target_file, *ep = target_file + sizeof target_file - 16; - const char *sd; - int slash = 1; - - cp += sprintf(cp, "'s:/"); - for (sd = opt.directory; *sd; sd++) { - if (*sd == '/' || *sd == '\\') { - if (slash) - continue; /* Remove duplicated slashes */ - slash = 1; - } else if (*sd == '\'' || *sd == '!') { - slash = 0; - if (cp < ep) - *cp++ = '\''; - if (cp < ep) - *cp++ = '\\'; - if (cp < ep) - *cp++ = *sd; - if (cp < ep) - *cp++ = '\''; - continue; - } else { - slash = 0; - } - - if (cp < ep) - *cp++ = *sd; - } - if (!slash) - *cp++ = '/'; - strcpy(cp, "ldlinux.sys'"); + status = move_file("ldlinux.sys"); + } else { + status = system("mattrib +r +h +s s:/ldlinux.sys"); + } - /* This command may fail legitimately */ - sprintf(command, "mattrib -h -r -s %s 2>/dev/null", target_file); - status = system(command); - (void)status; /* Keep _FORTIFY_SOURCE happy */ + if (!WIFEXITED(status) || WEXITSTATUS(status)) { + fprintf(stderr, + "%s: warning: failed to set system bit on ldlinux.sys\n", + program); + } - sprintf(command, "mmove -D o -D O s:/ldlinux.sys %s", target_file); - status = system(command); + /* This command may fail legitimately */ + status = system("mattrib -h -r -s s:/ldlinux.c32 2>/dev/null"); + (void)status; /* Keep _FORTIFY_SOURCE happy */ - if (!WIFEXITED(status) || WEXITSTATUS(status)) { - fprintf(stderr, - "%s: warning: unable to move ldlinux.sys\n", program); + mtp = popen("mcopy -D o -D O -o - s:/ldlinux.c32", "w"); + if (!mtp || fwrite(syslinux_ldlinuxc32, 1, syslinux_ldlinuxc32_len, mtp) + != syslinux_ldlinuxc32_len || + (status = pclose(mtp), !WIFEXITED(status) || WEXITSTATUS(status))) { + die("failed to create ldlinux.c32"); + } - status = system("mattrib +r +h +s s:/ldlinux.sys"); - } else { - sprintf(command, "mattrib +r +h +s %s", target_file); - status = system(command); - } + /* Move ldlinux.c32 to the desired location */ + if (opt.directory) { + status = move_file("ldlinux.c32"); } else { - status = system("mattrib +r +h +s s:/ldlinux.sys"); + status = system("mattrib +r +h +s s:/ldlinux.c32"); } if (!WIFEXITED(status) || WEXITSTATUS(status)) { fprintf(stderr, - "%s: warning: failed to set system bit on ldlinux.sys\n", + "%s: warning: failed to set system bit on ldlinux.c32\n", program); } diff --git a/win/syslinux.c b/win/syslinux.c index 669450eb..f8e27801 100644 --- a/win/syslinux.c +++ b/win/syslinux.c @@ -236,6 +236,53 @@ int libfat_readfile(intptr_t pp, void *buf, size_t secsize, return secsize; } +static void move_file(char *pathname, char *filename) +{ + char new_name[strlen(opt.directory) + 16]; + char *cp = new_name + 3; + const char *sd; + int slash = 1; + + new_name[0] = opt.device[0]; + new_name[1] = ':'; + new_name[2] = '\\'; + + for (sd = opt.directory; *sd; sd++) { + char c = *sd; + + if (c == '/' || c == '\\') { + if (slash) + continue; + c = '\\'; + slash = 1; + } else { + slash = 0; + } + + *cp++ = c; + } + + /* Skip if subdirectory == root */ + if (cp > new_name + 3) { + if (!slash) + *cp++ = '\\'; + + memcpy(cp, filename, 12); + + /* Delete any previous file */ + SetFileAttributes(pathname, FILE_ATTRIBUTE_NORMAL); + DeleteFile(pathname); + if (!MoveFile(pathname, new_name)) + SetFileAttributes(pathname, FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN); + else + SetFileAttributes(new_name, FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN); + } +} + int main(int argc, char *argv[]) { HANDLE f_handle, d_handle; @@ -249,6 +296,7 @@ int main(int argc, char *argv[]) static char drive_name[] = "\\\\.\\?:"; static char drive_root[] = "?:\\"; static char ldlinux_name[] = "?:\\ldlinux.sys"; + static char ldlinuxc32_name[] = "?:\\ldlinux.c32"; const char *errmsg; struct libfat_filesystem *fs; libfat_sector_t s, *secp; @@ -290,6 +338,7 @@ int main(int argc, char *argv[]) /* Determines the drive type */ drive_name[4] = opt.device[0]; ldlinux_name[0] = opt.device[0]; + ldlinuxc32_name[0] = opt.device[0]; drive_root[0] = opt.device[0]; drive_type = GetDriveType(drive_root); @@ -340,10 +389,12 @@ int main(int argc, char *argv[]) /* Change to normal attributes to enable deletion */ /* Just ignore error if the file do not exists */ SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_NORMAL); + SetFileAttributes(ldlinuxc32_name, FILE_ATTRIBUTE_NORMAL); /* Delete the file */ /* Just ignore error if the file do not exists */ DeleteFile(ldlinux_name); + DeleteFile(ldlinuxc32_name); /* Initialize the ADV -- this should be smarter */ syslinux_reset_adv(syslinux_adv); @@ -463,52 +514,40 @@ map_done: CloseHandle(f_handle); /* Move the file to the desired location */ - if (opt.directory) { - char new_ldlinux_name[strlen(opt.directory) + 16]; - char *cp = new_ldlinux_name + 3; - const char *sd; - int slash = 1; - - new_ldlinux_name[0] = opt.device[0]; - new_ldlinux_name[1] = ':'; - new_ldlinux_name[2] = '\\'; - - for (sd = opt.directory; *sd; sd++) { - char c = *sd; - - if (c == '/' || c == '\\') { - if (slash) - continue; - c = '\\'; - slash = 1; - } else { - slash = 0; - } + if (opt.directory) + move_file(ldlinux_name, "ldlinux.sys"); - *cp++ = c; - } + f_handle = CreateFile(ldlinuxc32_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN, NULL); - /* Skip if subdirectory == root */ - if (cp > new_ldlinux_name + 3) { - if (!slash) - *cp++ = '\\'; - - memcpy(cp, "ldlinux.sys", 12); - - /* Delete any previous file */ - SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_NORMAL); - DeleteFile(new_ldlinux_name); - if (!MoveFile(ldlinux_name, new_ldlinux_name)) - SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN); - else - SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN); - } + if (f_handle == INVALID_HANDLE_VALUE) { + error("Unable to create ldlinux.c32"); + exit(1); + } + + /* Write ldlinux.c32 file */ + if (!WriteFile(f_handle, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len, + &bytes_written, NULL) || + bytes_written != syslinux_ldlinuxc32_len) { + error("Could not write ldlinux.c32"); + exit(1); + } + + /* Now flush the media */ + if (!FlushFileBuffers(f_handle)) { + error("FlushFileBuffers failed"); + exit(1); } + CloseHandle(f_handle); + + /* Move the file to the desired location */ + if (opt.directory) + move_file(ldlinuxc32_name, "ldlinux.c32"); + /* Make the syslinux boot sector */ syslinux_make_bootsect(sectbuf, fs_type); diff --git a/win32/Makefile b/win32/Makefile index f960998a..9ff8a453 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -56,6 +56,7 @@ LIBSRC = ../libinstaller/fs.c \ ../libinstaller/getopt/getopt_long.c \ ../libinstaller/bootsect_bin.c \ ../libinstaller/ldlinux_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ ../libinstaller/mbr_bin.c \ $(wildcard ../libfat/*.c) LIBOBJS = $(patsubst %.c,%.obj,$(notdir $(LIBSRC))) diff --git a/win64/Makefile b/win64/Makefile index fe60793c..50132d48 100644 --- a/win64/Makefile +++ b/win64/Makefile @@ -46,6 +46,7 @@ LIBSRC = ../libinstaller/fs.c \ ../libinstaller/getopt/getopt_long.c \ ../libinstaller/bootsect_bin.c \ ../libinstaller/ldlinux_bin.c \ + ../libinstaller/ldlinuxc32_bin.c \ ../libinstaller/mbr_bin.c \ $(wildcard ../libfat/*.c) LIBOBJS = $(patsubst %.c,%.obj,$(notdir $(LIBSRC))) |