aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2004-12-22 17:53:54 +0000
committerhpa <hpa>2004-12-22 17:53:54 +0000
commit5aa850e10e2a8463d49b438458c78d0c8c929b36 (patch)
tree20b25c414272ff34914bdd71f4e05d6907ded85e
parent72d098b31e57e5ae81d9a4923608f12014c1d36f (diff)
downloadsyslinux-5aa850e10e2a8463d49b438458c78d0c8c929b36.tar.gz
syslinux-5aa850e10e2a8463d49b438458c78d0c8c929b36.tar.xz
syslinux-5aa850e10e2a8463d49b438458c78d0c8c929b36.zip
Add MBR-writing options to the Win32 installer. Probably should besyslinux-3.00-pre3
added to the DOS installer at some point, too.
-rw-r--r--Makefile17
-rw-r--r--NEWS4
-rw-r--r--syslinux.h5
-rw-r--r--win32/Makefile6
-rw-r--r--win32/syslinux.c161
5 files changed, 177 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index ea981b0d..f0eff92e 100644
--- a/Makefile
+++ b/Makefile
@@ -38,10 +38,6 @@ VERSION = $(shell cat version)
.c.o:
$(CC) $(INCLUDE) $(CFLAGS) -c $<
-# libsyslinux.so
-LIB_SONAME = libsyslinux.so.2.2
-LIB_SO = libsyslinux.so.$(VERSION)
-
#
# The BTARGET refers to objects that are derived from ldlinux.asm; we
# like to keep those uniform for debugging reasons; however, distributors
@@ -60,8 +56,8 @@ SOURCES = $(CSRC) *.h $(NASMSRC) *.inc
BTARGET = kwdhash.gen version.gen ldlinux.bss ldlinux.sys ldlinux.bin \
pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin \
extlinux.bin extlinux.bss extlinux.sys \
- bootsect_bin.c ldlinux_bin.c extlinux_bss_bin.c extlinux_sys_bin.c
- # libsyslinux.a $(LIB_SO)
+ bootsect_bin.c ldlinux_bin.c mbr_bin.c \
+ extlinux_bss_bin.c extlinux_sys_bin.c
BOBJECTS = $(BTARGET) dos/syslinux.com win32/syslinux.exe memdisk/memdisk
BSUBDIRS = memdisk dos win32
ITARGET = copybs.com gethostip mkdiskimage
@@ -80,9 +76,9 @@ INSTALL_AUX = pxelinux.0 isolinux.bin isolinux-debug.bin \
dos/syslinux.com win32/syslinux.exe \
copybs.com memdisk/memdisk
# Things to install in /usr/lib
-INSTALL_LIB = $(LIB_SO) libsyslinux.a
+INSTALL_LIB = # libsyslinux.a
# Things to install in /usr/include
-INSTALL_INC = syslinux.h
+INSTALL_INC = # syslinux.h
# The DATE is set on the make command line when building binaries for
# official release. Otherwise, substitute a hex string that is pretty much
@@ -162,6 +158,9 @@ extlinux.sys: extlinux.bin
mbr.bin: mbr.asm
$(NASM) -f bin -l mbr.lst -o mbr.bin mbr.asm
+mbr_bin.c: mbr.bin bin2c.pl
+ $(PERL) bin2c.pl syslinux_mbr < $< > $@
+
copybs.com: copybs.asm
$(NASM) -f bin -l copybs.lst -o copybs.com copybs.asm
@@ -177,7 +176,7 @@ extlinux_bss_bin.c: extlinux.bss bin2c.pl
extlinux_sys_bin.c: extlinux.sys bin2c.pl
$(PERL) bin2c.pl extlinux_image < $< > $@
-libsyslinux.a: bootsect_bin.o ldlinux_bin.o syslxmod.o
+libsyslinux.a: bootsect_bin.o ldlinux_bin.o mbr_bin.o syslxmod.o
rm -f $@
$(AR) cq $@ $^
$(RANLIB) $@
diff --git a/NEWS b/NEWS
index 1336ad30..defde736 100644
--- a/NEWS
+++ b/NEWS
@@ -31,7 +31,9 @@ Changes in 3.00:
from an alternate TFTP server, or just a ::
(e.g. ::filename), which suppresses the common pathname
prefix. See pxelinux.doc.
-
+ * SYSLINUX: Add an -m option to the Win32 installer (only!)
+ to write an MBR and -a to mark the partition SYSLINUX is
+ being installed on active.
Changes in 2.13:
* MEMDISK: Fix command-line parsing "brown paper bag" class
diff --git a/syslinux.h b/syslinux.h
index ccfb0f0c..6e4315b6 100644
--- a/syslinux.h
+++ b/syslinux.h
@@ -19,11 +19,16 @@
/* The standard boot sector and ldlinux image */
extern unsigned char syslinux_bootsect[];
extern unsigned int syslinux_bootsect_len;
+extern int syslinux_bootsect_mtime;
extern unsigned char syslinux_ldlinux[];
extern unsigned int syslinux_ldlinux_len;
extern int syslinux_ldlinux_mtime;
+extern unsigned char syslinux_mbr[];
+extern unsigned int syslinux_mbr_len;
+extern int syslinux_mbr_mtime;
+
/* This switches the boot sector to "stupid mode" */
void syslinux_make_stupid(void);
diff --git a/win32/Makefile b/win32/Makefile
index 3c335b79..cb9ee780 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -47,7 +47,8 @@ CC_IS_GOOD := $(shell $(CC) $(CFLAGS) $(LDFLAGS) -o hello.exe hello.c >/dev/null
.SUFFIXES: .c .o .i .s .S
-SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c $(wildcard ../libfat/*.c)
+SRCS = syslinux.c ../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c \
+ ../mbr_bin.c $(wildcard ../libfat/*.c)
OBJS = $(patsubst %.c,%.o,$(notdir $(SRCS)))
VPATH = .:..:../libfat
@@ -62,7 +63,7 @@ all:
endif
tidy:
- -rm -f *.o *.i *.s *.a .*.d
+ -rm -f *.o *.i *.s *.a .*.d *_bin.c
clean: tidy
@@ -74,6 +75,7 @@ installer:
syslinux.exe: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
+
%.o: %.c
$(CC) -Wp,-MT,$@,-MMD,.$@.d $(CFLAGS) -c -o $@ $<
%.i: %.c
diff --git a/win32/syslinux.c b/win32/syslinux.c
index 53fb3621..8cbea7c0 100644
--- a/win32/syslinux.c
+++ b/win32/syslinux.c
@@ -23,6 +23,141 @@
#include "syslinux.h"
#include "libfat.h"
+void error(char* msg);
+
+/* Begin stuff for MBR code */
+
+#include <winioctl.h>
+
+#define SECTOR_SIZE 512
+#define PART_TABLE 0x1be
+#define PART_SIZE 0x10
+#define PART_COUNT 4
+#define PART_ACTIVE 0x80
+
+// The following struct should be in the ntddstor.h file, but I didn't have it.
+// TODO: Make this a conditional compilation
+typedef struct _STORAGE_DEVICE_NUMBER {
+ DEVICE_TYPE DeviceType;
+ ULONG DeviceNumber;
+ ULONG PartitionNumber;
+} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
+
+BOOL GetStorageDeviceNumberByHandle( HANDLE handle, const STORAGE_DEVICE_NUMBER *sdn ) {
+ BOOL result = FALSE;
+ DWORD count;
+
+ if ( DeviceIoControl( handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
+ 0, (LPVOID)sdn, sizeof( *sdn ), &count, NULL ) ) {
+ result = TRUE;
+ }
+ else {
+ error("GetDriveNumber: DeviceIoControl failed.");
+ }
+
+ return( result );
+}
+
+int GetBytesPerSector( HANDLE drive ) {
+ int result = 0;
+ DISK_GEOMETRY g;
+ DWORD count;
+
+ if ( DeviceIoControl( drive, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
+ &g, sizeof( g ), &count, NULL ) ) {
+ result = g.BytesPerSector;
+ }
+
+ return( result );
+}
+
+BOOL FixMBR(int driveNum, int partitionNum, int write_mbr, int set_active) {
+ BOOL result = TRUE;
+ HANDLE drive;
+
+ char driveName[128];
+
+ sprintf( driveName, "\\\\.\\PHYSICALDRIVE%d", driveNum );
+
+ drive = CreateFile( driveName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+
+ if( drive == INVALID_HANDLE_VALUE ) {
+ error("Accessing physical drive");
+ result = FALSE;
+ }
+
+ if( result ) {
+ unsigned char sector[SECTOR_SIZE];
+ DWORD howMany;
+
+ if( GetBytesPerSector( drive ) != SECTOR_SIZE ) {
+ fprintf(stderr, "Error: Sector size of this drive is %d; must be %d\n",
+ GetBytesPerSector( drive ), SECTOR_SIZE );
+ result = FALSE;
+ }
+
+ if ( result ) {
+ if ( ReadFile( drive, sector, sizeof( sector ), &howMany, NULL ) == 0 ) {
+ error("Reading raw drive");
+ result = FALSE;
+ } else if ( howMany != sizeof( sector ) ) {
+ fprintf(stderr, "Error: ReadFile on drive only got %d of %d bytes\n",
+ (int)howMany, sizeof( sector ) );
+ result = FALSE;
+ }
+ }
+
+ // Copy over the MBR code if specified (-m)
+ if ( write_mbr ) {
+ if ( result ) {
+ if ( syslinux_mbr_len >= PART_TABLE ) {
+ fprintf(stderr, "Error: MBR will not fit; not writing\n" );
+ result = FALSE;
+ } else {
+ memcpy( sector, syslinux_mbr, syslinux_mbr_len );
+ }
+ }
+ }
+
+ // Check that our partition is active if specified (-a)
+ if ( set_active ) {
+ if ( sector[ PART_TABLE + ( PART_SIZE * ( partitionNum - 1 ) ) ] != 0x80 ) {
+ int p;
+ for ( p = 0; p < PART_COUNT; p++ )
+ sector[ PART_TABLE + ( PART_SIZE * p ) ] = ( p == partitionNum - 1 ? 0x80 : 0 );
+ }
+ }
+
+ if ( result ) {
+ SetFilePointer( drive, 0, NULL, FILE_BEGIN );
+
+ if ( WriteFile( drive, sector, sizeof( sector ), &howMany, NULL ) == 0 ) {
+ error("Writing MBR");
+ result = FALSE;
+ } else if ( howMany != sizeof( sector ) ) {
+ fprintf(stderr, "Error: WriteFile on drive only wrote %d of %d bytes\n",
+ (int)howMany, sizeof( sector ) );
+ result = FALSE;
+ }
+ }
+
+ if( !CloseHandle( drive ) ) {
+ error("CloseFile on drive");
+ result = FALSE;
+ }
+ }
+
+ return( result );
+}
+
+/* End stuff for MBR code */
+
char *program; /* Name of program */
char *drive; /* Drive to install to */
@@ -32,7 +167,7 @@ char *drive; /* Drive to install to */
* On Windows Me/98/95 you cannot open a directory, physical disk, or
* volume using CreateFile.
*/
-int checkver()
+int checkver(void)
{
OSVERSIONINFO osvi;
@@ -91,7 +226,7 @@ int libfat_readfile(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sect
void usage(void)
{
- fprintf(stderr, "Usage: syslinux.exe [-sf] <drive>:\n");
+ fprintf(stderr, "Usage: syslinux.exe [-sfma] <drive>:\n");
exit(1);
}
@@ -115,6 +250,8 @@ int main(int argc, char *argv[])
int nsectors;
int force = 0; /* -f (force) option */
+ int mbr = 0; /* -m (MBR) option */
+ int setactive = 0; /* -a (set partition active) */
(void)argc;
@@ -135,8 +272,12 @@ int main(int argc, char *argv[])
while ( *opt ) {
if ( *opt == 's' ) {
syslinux_make_stupid(); /* Use "safe, slow and stupid" code */
- } else if ( *opt == 'f' ) {
- force = 1; /* Force install */
+ } else if ( *opt == 'f' ) {
+ force = 1; /* Force install */
+ } else if ( *opt == 'm' ) {
+ mbr = 1; /* Install MBR */
+ } else if ( *opt == 'a' ) {
+ setactive = 1; /* Mark this partition active */
} else {
usage();
}
@@ -271,6 +412,18 @@ int main(int argc, char *argv[])
exit(1);
}
+ /* If desired, fix the MBR */
+ if( mbr || setactive ) {
+ STORAGE_DEVICE_NUMBER sdn;
+ if( GetStorageDeviceNumberByHandle( f_handle, &sdn ) ) {
+ if( !FixMBR(sdn.DeviceNumber, sdn.PartitionNumber, mbr, setactive) ) {
+ fprintf(stderr, "Did not successfully update the MBR; continuing...\n");
+ }
+ } else {
+ fprintf(stderr, "Could not find device number for updating MBR; continuing...\n");
+ }
+ }
+
/* Close file */
CloseHandle(f_handle);