win32: vacuous ADV support
authorH. Peter Anvin <hpa@linux.intel.com>
Tue, 22 Jun 2010 23:52:32 +0000 (16:52 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Tue, 22 Jun 2010 23:52:32 +0000 (16:52 -0700)
Install an empty ADV in the Windows installer to keep it from being
broken.  In order to do that, separate the Unix-specific ADV I/O
functions from the generic data structure manipulation.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
extlinux/Makefile
libinstaller/advio.c [new file with mode: 0644]
libinstaller/setadv.c
linux/Makefile
linux/syslinux.c
win32/Makefile
win32/syslinux.c

index 2501a45..83cf1a5 100644 (file)
@@ -28,6 +28,7 @@ SRCS     = main.c \
           ../libinstaller/syslxopt.c \
           ../libinstaller/syslxcom.c \
           ../libinstaller/setadv.c \
+          ../libinstaller/advio.c \
           ../libinstaller/bootsect_bin.c \
           ../libinstaller/ldlinux_bin.c
 OBJS    = $(patsubst %.c,%.o,$(notdir $(SRCS)))
diff --git a/libinstaller/advio.c b/libinstaller/advio.c
new file mode 100644 (file)
index 0000000..3112fa4
--- /dev/null
@@ -0,0 +1,159 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * advio.c
+ *
+ * Linux ADV I/O
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ */
+#define  _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "syslxint.h"
+#include "syslxcom.h"
+
+/*
+ * Read the ADV from an existing instance, or initialize if invalid.
+ * Returns -1 on fatal errors, 0 if ADV is okay, and 1 if no valid
+ * ADV was found.
+ */
+int read_adv(const char *path, const char *cfg)
+{
+    char *file;
+    int fd = -1;
+    struct stat st;
+    int err = 0;
+
+    asprintf(&file, "%s%s%s",
+            path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
+
+    if (!file) {
+       perror(program);
+       return -1;
+    }
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0) {
+       if (errno != ENOENT) {
+           err = -1;
+       } else {
+           syslinux_reset_adv(syslinux_adv);
+       }
+    } else if (fstat(fd, &st)) {
+       err = -1;
+    } else if (st.st_size < 2 * ADV_SIZE) {
+       /* Too small to be useful */
+       syslinux_reset_adv(syslinux_adv);
+       err = 0;                /* Nothing to read... */
+    } else if (xpread(fd, syslinux_adv, 2 * ADV_SIZE,
+                     st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+       err = -1;
+    } else {
+       /* We got it... maybe? */
+       err = syslinux_validate_adv(syslinux_adv) ? 1 : 0;
+    }
+
+    if (err < 0)
+       perror(file);
+
+    if (fd >= 0)
+       close(fd);
+
+    free(file);
+
+    return err;
+}
+
+/*
+ * Update the ADV in an existing installation.
+ */
+int write_adv(const char *path, const char *cfg)
+{
+    unsigned char advtmp[2 * ADV_SIZE];
+    char *file;
+    int fd = -1;
+    struct stat st, xst;
+    int err = 0;
+
+    err = asprintf(&file, "%s%s%s",
+       path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
+
+    if (!file) {
+       perror(program);
+       return -1;
+    }
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0) {
+       err = -1;
+    } else if (fstat(fd, &st)) {
+       err = -1;
+    } else if (st.st_size < 2 * ADV_SIZE) {
+       /* Too small to be useful */
+       err = -2;
+    } else if (xpread(fd, advtmp, 2 * ADV_SIZE,
+                     st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+       err = -1;
+    } else {
+       /* We got it... maybe? */
+       err = syslinux_validate_adv(advtmp) ? -2 : 0;
+       if (!err) {
+           /* Got a good one, write our own ADV here */
+           clear_attributes(fd);
+
+           /* Need to re-open read-write */
+           close(fd);
+           fd = open(file, O_RDWR | O_SYNC);
+           if (fd < 0) {
+               err = -1;
+           } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino ||
+                      xst.st_dev != st.st_dev || xst.st_size != st.st_size) {
+               fprintf(stderr, "%s: race condition on write\n", file);
+               err = -2;
+           }
+           /* Write our own version ... */
+           if (xpwrite(fd, syslinux_adv, 2 * ADV_SIZE,
+                       st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
+               err = -1;
+           }
+
+           sync();
+           set_attributes(fd);
+       }
+    }
+
+    if (err == -2)
+       fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n",
+               file);
+    else if (err == -1)
+       perror(file);
+
+    if (fd >= 0)
+       close(fd);
+    if (file)
+       free(file);
+
+    return err;
+}
index c891b87..61f1f34 100644 (file)
@@ -1,6 +1,7 @@
 /* ----------------------------------------------------------------------- *
  *
  *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
-#include <getopt.h>
-#include <unistd.h>
 #include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 #include "syslxint.h"
 #include "syslxcom.h"
@@ -170,127 +166,3 @@ int syslinux_validate_adv(unsigned char *advbuf)
        return -1;
     }
 }
-
-/*
- * Read the ADV from an existing instance, or initialize if invalid.
- * Returns -1 on fatal errors, 0 if ADV is okay, and 1 if no valid
- * ADV was found.
- */
-int read_adv(const char *path, const char *cfg)
-{
-    char *file;
-    int fd = -1;
-    struct stat st;
-    int err = 0;
-
-    asprintf(&file, "%s%s%s",
-            path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
-
-    if (!file) {
-       perror(program);
-       return -1;
-    }
-
-    fd = open(file, O_RDONLY);
-    if (fd < 0) {
-       if (errno != ENOENT) {
-           err = -1;
-       } else {
-           syslinux_reset_adv(syslinux_adv);
-       }
-    } else if (fstat(fd, &st)) {
-       err = -1;
-    } else if (st.st_size < 2 * ADV_SIZE) {
-       /* Too small to be useful */
-       syslinux_reset_adv(syslinux_adv);
-       err = 0;                /* Nothing to read... */
-    } else if (xpread(fd, syslinux_adv, 2 * ADV_SIZE,
-                     st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
-       err = -1;
-    } else {
-       /* We got it... maybe? */
-       err = syslinux_validate_adv(syslinux_adv) ? 1 : 0;
-    }
-
-    if (err < 0)
-       perror(file);
-
-    if (fd >= 0)
-       close(fd);
-
-    free(file);
-
-    return err;
-}
-
-/*
- * Update the ADV in an existing installation.
- */
-int write_adv(const char *path, const char *cfg)
-{
-    unsigned char advtmp[2 * ADV_SIZE];
-    char *file;
-    int fd = -1;
-    struct stat st, xst;
-    int err = 0;
-
-    err = asprintf(&file, "%s%s%s",
-       path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
-
-    if (!file) {
-       perror(program);
-       return -1;
-    }
-
-    fd = open(file, O_RDONLY);
-    if (fd < 0) {
-       err = -1;
-    } else if (fstat(fd, &st)) {
-       err = -1;
-    } else if (st.st_size < 2 * ADV_SIZE) {
-       /* Too small to be useful */
-       err = -2;
-    } else if (xpread(fd, advtmp, 2 * ADV_SIZE,
-                     st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
-       err = -1;
-    } else {
-       /* We got it... maybe? */
-       err = syslinux_validate_adv(advtmp) ? -2 : 0;
-       if (!err) {
-           /* Got a good one, write our own ADV here */
-           clear_attributes(fd);
-
-           /* Need to re-open read-write */
-           close(fd);
-           fd = open(file, O_RDWR | O_SYNC);
-           if (fd < 0) {
-               err = -1;
-           } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino ||
-                      xst.st_dev != st.st_dev || xst.st_size != st.st_size) {
-               fprintf(stderr, "%s: race condition on write\n", file);
-               err = -2;
-           }
-           /* Write our own version ... */
-           if (xpwrite(fd, syslinux_adv, 2 * ADV_SIZE,
-                       st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
-               err = -1;
-           }
-
-           sync();
-           set_attributes(fd);
-       }
-    }
-
-    if (err == -2)
-       fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n",
-               file);
-    else if (err == -1)
-       perror(file);
-
-    if (fd >= 0)
-       close(fd);
-    if (file)
-       free(file);
-
-    return err;
-}
index c3877f2..ffe2272 100644 (file)
@@ -26,6 +26,7 @@ SRCS     = syslinux.c \
           ../libinstaller/syslxopt.c \
           ../libinstaller/syslxcom.c \
           ../libinstaller/setadv.c \
+          ../libinstaller/advio.c \
            ../libinstaller/fat.c \
            ../libinstaller/syslxmod.c \
           ../libinstaller/bootsect_bin.c \
index fa500cf..ed65619 100644 (file)
@@ -77,12 +77,6 @@ extern const char *program;  /* Name of program */
 pid_t mypid;
 char *mntpath = NULL;          /* Path on which to mount */
 
-/*
- * Image file
- */
-#define boot_image     syslinux_ldlinux
-#define boot_image_len  syslinux_ldlinux_len
-
 #if DO_DIRECT_MOUNT
 int loop_fd = -1;              /* Loop device */
 #endif
index 9009ccd..a077b30 100644 (file)
@@ -49,6 +49,7 @@ SRCS     = syslinux.c
 OBJS     = $(patsubst %.c,%.obj,$(notdir $(SRCS)))
 LIBSRC   = ../libinstaller/fat.c \
           ../libinstaller/syslxmod.c \
+          ../libinstaller/setadv.c \
           ../libinstaller/bootsect_bin.c \
           ../libinstaller/ldlinux_bin.c \
           ../libinstaller/mbr_bin.c \
index 297b97b..ca98d78 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "syslinux.h"
 #include "libfat.h"
+#include "setadv.h"
 
 #ifdef __GNUC__
 # define noreturn void __attribute__((noreturn))
@@ -384,6 +385,9 @@ int main(int argc, char *argv[])
     /* Just ignore error if the file do not exists */
     DeleteFile(ldlinux_name);
 
+    /* Initialize the ADV -- this should be smarter */
+    syslinux_reset_adv(syslinux_adv);
+
     /* Create ldlinux.sys file */
     f_handle = CreateFile(ldlinux_name, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -397,15 +401,16 @@ int main(int argc, char *argv[])
     }
 
     /* Write ldlinux.sys file */
-    if (!WriteFile
-       (f_handle, syslinux_ldlinux, syslinux_ldlinux_len, &bytes_written,
-        NULL)) {
+    if (!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len,
+                  &bytes_written, NULL) ||
+       bytes_written != syslinux_ldlinux_len) {
        error("Could not write ldlinux.sys");
        exit(1);
     }
-
-    if (bytes_written != syslinux_ldlinux_len) {
-       fprintf(stderr, "Could not write whole ldlinux.sys\n");
+    if (!WriteFile(f_handle, syslinux_adv, 2 * ADV_SIZE,
+                  &bytes_written, NULL) ||
+       bytes_written != 2 * ADV_SIZE) {
+       error("Could not write ADV to ldlinux.sys");
        exit(1);
     }
 
@@ -416,7 +421,8 @@ int main(int argc, char *argv[])
     }
 
     /* Map the file (is there a better way to do this?) */
-    ldlinux_sectors = (syslinux_ldlinux_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
+    ldlinux_sectors = (syslinux_ldlinux_len + 2 * ADV_SIZE + SECTOR_SIZE - 1)
+       >> SECTOR_SHIFT;
     sectors = calloc(ldlinux_sectors, sizeof *sectors);
     fs = libfat_open(libfat_readfile, (intptr_t) d_handle);
     ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL);