From a4c27d72bbd9286666eb8610ce47cbd7c142b46f Mon Sep 17 00:00:00 2001 From: hpa Date: Fri, 11 Jul 2003 01:13:27 +0000 Subject: [PATCH] Win32 installer --- win32/Makefile | 81 ++++++++++++++++ win32/syslinux-mingw.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 325 insertions(+) create mode 100644 win32/Makefile create mode 100644 win32/syslinux-mingw.c diff --git a/win32/Makefile b/win32/Makefile new file mode 100644 index 0000000..c295c4f --- /dev/null +++ b/win32/Makefile @@ -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 index 0000000..6ec5e96 --- /dev/null +++ b/win32/syslinux-mingw.c @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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] :\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; +} -- 2.7.4