aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-09-14 15:22:29 +0100
committerMatt Fleming <matt.fleming@intel.com>2012-09-19 10:46:41 +0100
commitbda54cb680676bffa731394096956f5d10fbcfaf (patch)
treeeccf1b93b239c19ace4ed72a0ec79c382c4cf8ba
parent040f273035ca84fc963d0d0c0b39794f7a5fc7d4 (diff)
downloadsyslinux-bda54cb680676bffa731394096956f5d10fbcfaf.tar.gz
syslinux-bda54cb680676bffa731394096956f5d10fbcfaf.tar.xz
syslinux-bda54cb680676bffa731394096956f5d10fbcfaf.zip
installers: Install ldlinux.c32 automaticallysyslinux-5.00-pre8
Because ldlinux.c32 is required for Syslinux to function correctly, we should be installing it automatically much like ldlinux.sys. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--dos/dosexe.ld6
-rw-r--r--dos/ldlinux.S14
-rw-r--r--dos/syslinux.c100
-rw-r--r--extlinux/Makefile1
-rw-r--r--extlinux/main.c58
-rw-r--r--libinstaller/Makefile5
-rw-r--r--libinstaller/syslinux.h3
-rw-r--r--linux/Makefile1
-rwxr-xr-xlinux/syslinux.c55
-rwxr-xr-xmtools/Makefile1
-rwxr-xr-xmtools/syslinux.c129
-rw-r--r--win/syslinux.c123
-rw-r--r--win32/Makefile1
-rw-r--r--win64/Makefile1
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)))