Win32 installer
authorhpa <hpa>
Fri, 11 Jul 2003 01:13:27 +0000 (01:13 +0000)
committerhpa <hpa>
Fri, 11 Jul 2003 01:13:27 +0000 (01:13 +0000)
win32/Makefile [new file with mode: 0644]
win32/syslinux-mingw.c [new file with mode: 0644]

diff --git a/win32/Makefile b/win32/Makefile
new file mode 100644 (file)
index 0000000..c295c4f
--- /dev/null
@@ -0,0 +1,81 @@
+## -----------------------------------------------------------------------
+##  $Id$
+##
+##   Copyright 1998-2003 H. Peter Anvin - All Rights Reserved
+##
+##   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., 675 Mass Ave, Cambridge MA 02139,
+##   USA; either version 2 of the License, or (at your option) any later
+##   version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+#
+# Makefile for SYSLINUX Win32
+#
+# This is separated out mostly so we can have a different set of Makefile
+# variables.
+#
+
+OSTYPE   = $(shell uname -msr)
+ifeq ($(findstring CYGWIN,$(OSTYPE)),CYGWIN)
+CC       = gcc
+AR      = ar
+RANLIB   = ranlib
+CFLAGS   = -mno-cygwin -Wall -O2 -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
+PIC     =
+LDFLAGS  = -mno-cygwin -O2 -s
+else
+ifeq ($(findstring MINGW32,$(OSTYPE)),MINGW32)
+CC       = gcc
+AR      = ar
+RANLIB   = ranlib
+else
+CC       = mingw-gcc
+AR      = mingw-ar
+RANLIB   = mingw-ranlib
+endif
+CFLAGS   = -Wall -O2 -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
+PIC      =
+LDFLAGS  = -O2 -s
+endif
+INCLUDE += -I..
+
+PERL     = perl
+
+VERSION  = $(shell cat ../version)
+
+.c.o:
+       $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $<
+
+.c.i:
+       $(CC) $(INCLUDE) $(CFLAGS) -E -o $@ $<
+
+all: ../syslinux.exe
+
+libsyslinux.a: bootsect_bin.o ldlinux_bin.o syslxmod.o
+       rm -f $@
+       $(AR) cq $@ $^
+       $(RANLIB) $@
+
+../syslinux.exe: syslinux-mingw.o libsyslinux.a
+       $(CC) $(LDFLAGS) -o $@ $^
+
+syslxmod.o: ../syslxmod.c ../patch.offset
+       $(CC) $(INCLUDE) $(CFLAGS) $(PIC) -DPATCH_OFFSET=`cat ../patch.offset` \
+               -c -o $@ $<
+
+bootsect_bin.o: ../bootsect_bin.c
+       $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $<
+
+ldlinux_bin.o: ../ldlinux_bin.c
+       $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $<
+
+tidy:
+       rm -f *.o *.a
+
+clean: tidy
+
+spotless:
+       rm -f ../syslinux.exe
diff --git a/win32/syslinux-mingw.c b/win32/syslinux-mingw.c
new file mode 100644 (file)
index 0000000..6ec5e96
--- /dev/null
@@ -0,0 +1,244 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2003 Lars Munch Christensen - All Rights Reserved
+ *     
+ *   Based on the Linux installer program for SYSLINUX by 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., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux.c - Win2k/WinXP installer program for SYSLINUX
+ *
+ * To compile this install Cygwin with gcc, gcc-mingw, w32api,
+ * nasm, make and perl. Then build with: 'make syslinux.exe'
+ */
+
+#include <varargs.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winnt.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include <winioctl.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "syslinux.h"
+
+char *program;                 /* Name of program */
+char *drive;                   /* Drive to install to */
+
+/*
+ * Check Windows version.
+ *
+ * On Windows Me/98/95 you cannot open a directory, physical disk, or
+ * volume using CreateFile.
+ */
+int checkver()
+{
+  OSVERSIONINFO osvi;
+
+  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  GetVersionEx(&osvi);
+
+  return  (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+          ((osvi.dwMajorVersion > 4) ||
+          ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0)));
+}
+
+/*
+ * Windows error function
+ */
+void error(char* msg)
+{
+  LPVOID lpMsgBuf;
+
+  /* Format the Windows error message */
+  FormatMessage( 
+               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+               FORMAT_MESSAGE_FROM_SYSTEM | 
+               FORMAT_MESSAGE_IGNORE_INSERTS,
+               NULL, GetLastError(),
+               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+               (LPTSTR) &lpMsgBuf, 0, NULL );
+  
+  /* Print it */
+  fprintf(stderr, "%s: %s", msg, (char*) lpMsgBuf);
+
+  /* Free the buffer */
+  LocalFree(lpMsgBuf);
+}
+
+void usage(void)
+{
+  fprintf(stderr, "Usage: syslinux.exe [-sf] <drive>:\n");
+  exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+  HANDLE f_handle;
+  DISK_GEOMETRY dg;
+  DWORD bytes_read;
+  DWORD bytes_written;
+  DWORD junk;
+
+  static unsigned char sectbuf[512];
+  char **argp, *opt;
+  char drive_name[128];
+  char ldlinux_name[128];
+
+  int force = 0;               /* -f (force) option */
+
+  if (!checkver()) {
+    fprintf(stderr, "You need to be running at least Windows NT\n");
+    exit(1);       
+  }
+
+  program = argv[0];
+  drive = NULL;
+
+  for ( argp = argv+1 ; *argp ; argp++ ) {
+    if ( **argp == '-' ) {
+      opt = *argp + 1;
+      if ( !*opt )
+       usage();
+
+      while ( *opt ) {
+       if ( *opt == 's' ) {
+         syslinux_make_stupid();       /* Use "safe, slow and stupid" code */
+        } else if ( *opt == 'f' ) {
+          force = 1;                    /* Force install */
+       } else {
+         usage();
+       }
+       opt++;
+      }
+    } else {
+      if ( drive )
+       usage();
+      drive = *argp;
+    }
+  }
+
+  if ( !drive )
+    usage();
+
+  /*
+   * First open the drive
+   */
+  sprintf(drive_name, "\\\\.\\%c:", drive[0]);
+  f_handle = CreateFile(drive_name, GENERIC_READ | GENERIC_WRITE,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL, OPEN_EXISTING, 0, NULL );
+
+  if(f_handle == INVALID_HANDLE_VALUE) {
+    error("Could not open drive");
+    exit(1);
+  }
+
+  /* Get drive geometry */
+  if(!DeviceIoControl(f_handle, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+                     NULL, 0, &dg, sizeof(dg),
+                     &junk, (LPOVERLAPPED) NULL)) {
+
+    error("GetDriveGeometry failed");
+    exit(1);
+  }
+    
+  /* Test for removeable media */
+  if ((dg.MediaType == FixedMedia) && (force == 0)) {
+    fprintf(stderr, "Not a removable drive (use -f to override) \n");
+    exit(1);
+  }
+
+  /* Test for unknown media */
+  if ((dg.MediaType == Unknown) && (force == 0)) {
+    fprintf(stderr, "Drive media unknown (use -f to override) \n");
+    exit(1);
+  }
+    
+  /*
+   * Read the boot sector
+   */  
+  ReadFile(f_handle, sectbuf, 512, &bytes_read, NULL);
+  if(bytes_read != 512) {
+    fprintf(stderr, "Could not read the whole boot sector\n");
+    exit(1);
+  }
+  
+  /* Check to see that what we got was indeed an MS-DOS boot sector/superblock */
+  if(!syslinux_check_bootsect(sectbuf,drive)) {
+    exit(1);
+  }
+
+  /* Make the syslinux boot sector */
+  syslinux_make_bootsect(sectbuf);
+
+  /* Write the syslinux boot sector into the boot sector */
+  SetFilePointer(f_handle, 0, NULL, FILE_BEGIN);
+  WriteFile( (HANDLE) f_handle, sectbuf, 512, &bytes_written, NULL ) ;
+
+  if(bytes_written != 512) {
+    fprintf(stderr, "Could not write the whole boot sector\n");
+    exit(1);
+  }
+
+  /* Close file */ 
+  CloseHandle(f_handle);
+
+  /* Create the filename */
+  sprintf(ldlinux_name, "%s%s", drive_name, "\\ldlinux.sys"); 
+
+  /* Change to normal attributes to enable deletion */
+  /* Just ignore error if the file do not exists */
+  SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_NORMAL);
+
+  /* Delete the file */
+  /* Just ignore error if the file do not exists */
+  DeleteFile(ldlinux_name);
+
+  /* Create ldlinux.sys file */
+  f_handle = CreateFile(ldlinux_name, GENERIC_READ | GENERIC_WRITE,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                       NULL, CREATE_ALWAYS, 
+                       FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY,
+                       NULL );
+  
+  if(f_handle == INVALID_HANDLE_VALUE) {
+    error("Unable to create ldlinux.sys");
+    exit(1);
+  }
+
+  /* Write ldlinux.sys file */
+  if (!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len, &bytes_written, NULL)) {
+    error("Could not write ldlinux.sys");
+    exit(1);
+  }
+
+  if (bytes_written != syslinux_ldlinux_len) {
+    fprintf(stderr, "Could not write whole ldlinux.sys\n");
+    exit(1);
+  }
+
+  /* Close file */ 
+  CloseHandle(f_handle);
+
+  /* TODO: flush device. Not really sure how */
+
+  /* Done! */
+  return 0;
+}