[iso] add support for isolinux/syslinux ISO images

* use a modified syslinux that can use isolinux config files
* update syslinux to git version
* remove embedding of chain.c32 for the time being
This commit is contained in:
Pete Batard 2012-02-14 01:23:42 +00:00
parent 7753c017d6
commit 36be65ed23
22 changed files with 323 additions and 126 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,3 +1,5 @@
o ldlinux.bss and ldlinux.sys were extracted from syslinux-4.05/core/
and chain.c32 from syslinux-4.05/com32/modules:
o ldlinux.bss and ldlinux.sys were compiled from the syslinux git tree retreived
on 2012.02.13 from git://git.kernel.org/pub/scm/boot/syslinux/syslinux.git
with the included .diff applied to be able to use unmodified isolinux config.
o chain.c32 is from syslinux-4.05/com32/modules:
http://www.kernel.org/pub/linux/utils/boot/syslinux/

View file

@ -0,0 +1,29 @@
diff --git a/core/fs/lib/loadconfig.c b/core/fs/lib/loadconfig.c
index c9652b6..4dfe1b9 100644
--- a/core/fs/lib/loadconfig.c
+++ b/core/fs/lib/loadconfig.c
@@ -10,6 +10,8 @@
* This searches for extlinux.conf and syslinux.cfg in the install
* directory, followed by a set of fallback directories. If found,
* set the current working directory to match.
+ * isolinux configuration values are added for the case where ISO
+ * content has been duplicated to a disk (typically bootable USB).
*/
int generic_load_config(void)
{
@@ -17,12 +19,15 @@ int generic_load_config(void)
NULL, /* CurrentDirName */
"/boot/syslinux",
"/syslinux",
+ "/boot/isolinux",
+ "/isolinux",
"/",
NULL
};
static const char *filenames[] = {
"extlinux.conf",
"syslinux.cfg",
+ "isolinux.cfg",
NULL
};

View file

@ -307,7 +307,7 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive)
fake_fd._ptr = (char*)hPhysicalDrive;
fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector;
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_SYSLINUX) {
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_ISO_FAT) {
r = write_syslinux_mbr(&fake_fd);
} else {
r = write_95b_mbr(&fake_fd);
@ -321,10 +321,11 @@ out:
/*
* Process the Partition Boot Record
*/
static BOOL WritePBR(HANDLE hLogicalVolume, BOOL bFreeDOS)
static BOOL WritePBR(HANDLE hLogicalVolume)
{
int i;
FILE fake_fd = { 0 };
BOOL bFreeDOS = (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_FREEDOS);
fake_fd._ptr = (char*)hLogicalVolume;
fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector;
@ -510,10 +511,10 @@ DWORD WINAPI FormatThread(LPVOID param)
UpdateProgress(OP_FIX_MBR, -1.0f);
if (IsChecked(IDC_DOS)) {
switch (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) {
case DT_FREEDOS:
switch(ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) {
case DT_WINME:
case DT_ISO:
case DT_FREEDOS:
case DT_ISO_NTFS:
// We still have a lock, which we need to modify the volume boot record
// => no need to reacquire the lock...
hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE);
@ -527,32 +528,14 @@ DWORD WINAPI FormatThread(LPVOID param)
// after the FS is re-mounted by Windows
UnmountDrive(hLogicalVolume);
PrintStatus(0, TRUE, "Writing partition boot record...");
if (!WritePBR(hLogicalVolume, ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_FREEDOS)) {
// Errorcode has already been set
goto out;
}
// We must close and unlock the volume to write files to it
safe_unlockclose(hLogicalVolume);
UpdateProgress(OP_DOS, -1.0f);
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) != DT_ISO) {
PrintStatus(0, TRUE, "Copying DOS files...");
if (!ExtractDOS(drive_name)) {
if (!WritePBR(hLogicalVolume)) {
if (!FormatStatus)
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
goto out;
}
} else if (iso_path != NULL) {
PrintStatus(0, TRUE, "Copying ISO files...");
drive_name[2] = 0;
if ( (!ExtractISO(iso_path, drive_name, FALSE)) && (!FormatStatus)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
}
drive_name[2] = '\\';
}
break;
// Syslinux requires patching of the PBR after the files have been extracted
case DT_SYSLINUX:
case DT_ISO_FAT:
PrintStatus(0, TRUE, "Installing Syslinux...");
if (!InstallSyslinux(num, drive_name)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
}
@ -560,7 +543,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
}
// We issue a complete remount of the filesystem at the end on account of:
// We issue a complete remount of the filesystem at on account of:
// - Ensuring the file explorer properly detects that the volume was updated
// - Ensuring that an NTFS system will be reparsed so that it becomes bootable
// TODO: on cancellation, this can leave the drive unmounted!
@ -573,9 +556,39 @@ DWORD WINAPI FormatThread(LPVOID param)
uprintf("Failed to remount %s on %s\n", drive_guid, drive_name);
// This will leave the drive unaccessible and must be flagged as an error
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_REMOUNT_VOLUME);
goto out;
}
} else {
uprintf("Could not remount %s %s\n", drive_name, WindowsErrorString());
// Try to continue regardless
}
}
if (IsChecked(IDC_DOS)) {
UpdateProgress(OP_DOS, -1.0f);
switch(ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) {
case DT_WINME:
case DT_FREEDOS:
PrintStatus(0, TRUE, "Copying DOS files...");
if (!ExtractDOS(drive_name)) {
if (!FormatStatus)
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
goto out;
}
break;
case DT_ISO_NTFS:
case DT_ISO_FAT:
// TODO: ISO_FAT: ensure the ISO doesn't have ldlinux.sys as it will break the existing one
if (iso_path != NULL) {
PrintStatus(0, TRUE, "Copying ISO files...");
drive_name[2] = 0;
if ( (!ExtractISO(iso_path, drive_name, FALSE)) && (!FormatStatus)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
goto out;
}
// TODO: ISO_FAT: create menu and stuff
}
break;
}
}

View file

@ -63,7 +63,8 @@ RUFUS_ISO_REPORT iso_report;
int64_t iso_blocking_status = -1;
#define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0)
static const char *psz_extract_dir;
static const char *isolinux_name = "isolinux", *bootmgr_name = "bootmgr";
static const char *bootmgr_name = "bootmgr";
static const char *isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"};
static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE;
@ -126,13 +127,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
goto out;
}
if (udf_is_dir(p_udf_dirent)) {
if (!scan_only) {
_mkdir(psz_fullpath);
} else {
// Check for an "isolinux\" dir in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, isolinux_name) == 0))
iso_report.has_isolinux = TRUE;
}
if (!scan_only) _mkdir(psz_fullpath);
p_udf_dirent2 = udf_opendir(p_udf_dirent);
if (p_udf_dirent2 != NULL) {
if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)]))
@ -144,6 +139,11 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
// Check for a "bootmgr" file in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, bootmgr_name) == 0))
iso_report.has_bootmgr = TRUE;
// Check for a syslinux config file anywhere
for (i=0; i<ARRAYSIZE(isolinux_name); i++) {
if (safe_strcmp(psz_basename, isolinux_name[i]) == 0)
iso_report.has_isolinux = TRUE;
}
if (i_file_length >= FOUR_GIGABYTES)
iso_report.has_4GB_file = TRUE;
total_blocks += i_file_length/UDF_BLOCKSIZE;
@ -242,13 +242,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
continue;
iso9660_name_translate(p_statbuf->filename, psz_basename);
if (p_statbuf->type == _STAT_DIR) {
if (!scan_only) {
_mkdir(psz_fullpath);
} else {
// Check for an "isolinux\" dir in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, isolinux_name) == 0))
iso_report.has_isolinux = TRUE;
}
if (!scan_only) _mkdir(psz_fullpath);
if (iso_extract_files(p_iso, psz_iso_name))
goto out;
} else {
@ -257,6 +251,11 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
// Check for a "bootmgr" file in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, bootmgr_name) == 0))
iso_report.has_bootmgr = TRUE;
// Check for a syslinux config file anywhere
for (i=0; i<ARRAYSIZE(isolinux_name); i++) {
if (safe_strcmp(psz_basename, isolinux_name[i]) == 0)
iso_report.has_isolinux = TRUE;
}
if (i_file_length >= FOUR_GIGABYTES)
iso_report.has_4GB_file = TRUE;
total_blocks += i_file_length/ISO_BLOCKSIZE;

View file

@ -965,9 +965,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
}
uprintf("ISO size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c\n", iso_report.projected_size,
iso_report.has_4GB_file?'Y':'N', iso_report.has_bootmgr?'Y':'N', iso_report.has_isolinux?'Y':'N');
if (!iso_report.has_bootmgr) {
MessageBoxU(hMainDialog, "This version of Rufus supports only\n"
"ISO images that rely on 'bootmgr' - sorry.", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
if ((!iso_report.has_bootmgr) && (!iso_report.has_isolinux)) {
MessageBoxU(hMainDialog, "This version of Rufus only supports bootable ISOs\n"
"based on 'bootmgr' or 'isolinux'.\n"
"This ISO image doesn't appear to use either...", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
safe_free(iso_path);
} else {
for (i=(int)safe_strlen(iso_path); (i>0)&&(iso_path[i]!='\\'); i--);
@ -1095,7 +1096,7 @@ void InitDialog(HWND hDlg)
static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
DRAWITEMSTRUCT* pDI;
int nDeviceIndex, fs;
int nDeviceIndex, fs, dt;
DWORD DeviceNum;
char str[MAX_PATH], tmp[128];
static UINT uDOSChecked = BST_CHECKED;
@ -1218,11 +1219,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if (bWithFreeDOS)
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS));
if (bWithSyslinux)
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "Syslinux"), DT_SYSLINUX));
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO_FAT));
}
if (fs == FS_NTFS) {
// Only allow ISO with NTFS for the time being
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO));
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO_NTFS));
}
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, (bWithFreeDOS && (fs != FS_NTFS))?1:0));
if (!IsWindowEnabled(hDOS)) {
@ -1234,7 +1234,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
case IDC_DOSTYPE:
if (HIWORD(wParam) != CBN_SELCHANGE)
break;
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) != DT_ISO) {
dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType));
if ((dt != DT_ISO_NTFS) && (dt != DT_ISO_FAT)) {
ShowWindow(hSelectISO, SW_HIDE);
break;
}
@ -1272,7 +1273,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
FormatStatus = 0;
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
if (nDeviceIndex != CB_ERR) {
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_ISO) {
dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType));
if ((dt == DT_ISO_NTFS) || (dt == DT_ISO_FAT)) {
if (iso_path == NULL) {
MessageBoxA(hMainDialog, "Please click on the disc button to select a bootable ISO,\n"
"or uncheck the \"Create a bootable disk...\" checkbox.",
@ -1284,6 +1286,15 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
"for the selected target.", "ISO image too big...", MB_OK|MB_ICONERROR);
break;
}
if ((dt == DT_ISO_NTFS) && (!iso_report.has_bootmgr)) {
MessageBoxA(hMainDialog, "Only 'bootmgr' based ISO "
"images can be used with NTFS.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
break;
} else if ((dt == DT_ISO_FAT) && (!iso_report.has_isolinux)) {
MessageBoxA(hMainDialog, "Only 'isolinux' based ISO "
"images can be used with FAT.", "Unsupported ISO...", MB_OK|MB_ICONERROR);
break;
}
}
GetWindowTextA(hDeviceList, tmp, sizeof(tmp));
safe_sprintf(str, sizeof(str), "WARNING: ALL DATA ON DEVICE %s\r\nWILL BE DESTROYED.\r\n"

View file

@ -125,8 +125,8 @@ enum {
enum dos_type {
DT_WINME = 0,
DT_FREEDOS,
DT_SYSLINUX,
DT_ISO,
DT_ISO_FAT,
DT_ISO_NTFS,
DT_MAX
};

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 278
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.1.0.131"
CAPTION "Rufus v1.1.0.132"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,236,50,14
@ -71,7 +71,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9
LTEXT "Version 1.1.0 (Build 131)",IDC_STATIC,46,19,78,8
LTEXT "Version 1.1.0 (Build 132)",IDC_STATIC,46,19,78,8
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@ -171,7 +171,6 @@ BEGIN
"#if defined(WITH_SYSLINUX)\r\n"
"IDR_SL_LDLINUX_BSS RCDATA ""../res/syslinux/ldlinux.bss""\r\n"
"IDR_SL_LDLINUX_SYS RCDATA ""../res/syslinux/ldlinux.sys""\r\n"
"IDR_SL_CHAIN_C32 RCDATA ""../res/syslinux/chain.c32""\r\n"
"#endif\r\n"
"\r\n"
"// Must reference a manifest for visual styles and elevation\r\n"
@ -223,8 +222,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,0,131
PRODUCTVERSION 1,1,0,131
FILEVERSION 1,1,0,132
PRODUCTVERSION 1,1,0,132
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -241,13 +240,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.1.0.131"
VALUE "FileVersion", "1.1.0.132"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.1.0.131"
VALUE "ProductVersion", "1.1.0.132"
END
END
BLOCK "VarFileInfo"
@ -309,7 +308,6 @@ IDR_FD_EGA18_CPX RCDATA "../res/freedos/ega18.cpx"
#if defined(WITH_SYSLINUX)
IDR_SL_LDLINUX_BSS RCDATA "../res/syslinux/ldlinux.bss"
IDR_SL_LDLINUX_SYS RCDATA "../res/syslinux/ldlinux.sys"
IDR_SL_CHAIN_C32 RCDATA "../res/syslinux/chain.c32"
#endif
// Must reference a manifest for visual styles and elevation

View file

@ -29,6 +29,7 @@
#include "resource.h"
#include "syslinux.h"
#include "syslxfs.h"
#include "libfat.h"
#include "setadv.h"
@ -199,7 +200,7 @@ BOOL InstallSyslinux(DWORD num, const char* drive_name)
}
/* Make the syslinux boot sector */
syslinux_make_bootsect(sectbuf);
syslinux_make_bootsect(sectbuf, VFAT);
/* Write boot sector back */
if (SetFilePointer(d_handle, 0, NULL, FILE_BEGIN) != 0 ||

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@ -21,10 +21,12 @@
<ItemGroup>
<ClInclude Include="..\advconst.h" />
<ClInclude Include="..\syslinux.h" />
<ClInclude Include="..\syslxcom.h" />
<ClInclude Include="..\syslxfs.h" />
<ClInclude Include="..\syslxint.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\fat.c" />
<ClCompile Include="..\fs.c" />
<ClCompile Include="..\setadv.c" />
<ClCompile Include="..\syslxmod.c" />
</ItemGroup>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@ -20,9 +20,15 @@
<ClInclude Include="..\syslxint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\syslxfs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\syslxcom.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\fat.c">
<ClCompile Include="..\fs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\setadv.c">

View file

@ -12,6 +12,6 @@ USE_MSVCRT=1
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib
SOURCES=fat.c \
SOURCES=fs.c \
setadv.c \
syslxmod.c

View file

@ -1,4 +1,4 @@
noinst_LIBRARIES = libinstaller.a
libinstaller_a_SOURCES = fat.c setadv.c syslxmod.c
libinstaller_a_SOURCES = fs.c setadv.c syslxmod.c
libinstaller_a_CFLAGS = $(AM_CFLAGS)

View file

@ -52,7 +52,7 @@ am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
libinstaller_a_AR = $(AR) $(ARFLAGS)
libinstaller_a_LIBADD =
am_libinstaller_a_OBJECTS = libinstaller_a-fat.$(OBJEXT) \
am_libinstaller_a_OBJECTS = libinstaller_a-fs.$(OBJEXT) \
libinstaller_a-setadv.$(OBJEXT) \
libinstaller_a-syslxmod.$(OBJEXT)
libinstaller_a_OBJECTS = $(am_libinstaller_a_OBJECTS)
@ -167,7 +167,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LIBRARIES = libinstaller.a
libinstaller_a_SOURCES = fat.c setadv.c syslxmod.c
libinstaller_a_SOURCES = fs.c setadv.c syslxmod.c
libinstaller_a_CFLAGS = $(AM_CFLAGS)
all: all-am
@ -225,13 +225,13 @@ distclean-compile:
$(AM_V_CC) @AM_BACKSLASH@
$(COMPILE) -c `$(CYGPATH_W) '$<'`
libinstaller_a-fat.o: fat.c
libinstaller_a-fs.o: fs.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinstaller_a_CFLAGS) $(CFLAGS) -c -o libinstaller_a-fat.o `test -f 'fat.c' || echo '$(srcdir)/'`fat.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinstaller_a_CFLAGS) $(CFLAGS) -c -o libinstaller_a-fs.o `test -f 'fs.c' || echo '$(srcdir)/'`fs.c
libinstaller_a-fat.obj: fat.c
libinstaller_a-fs.obj: fs.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinstaller_a_CFLAGS) $(CFLAGS) -c -o libinstaller_a-fat.obj `if test -f 'fat.c'; then $(CYGPATH_W) 'fat.c'; else $(CYGPATH_W) '$(srcdir)/fat.c'; fi`
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinstaller_a_CFLAGS) $(CFLAGS) -c -o libinstaller_a-fs.obj `if test -f 'fs.c'; then $(CYGPATH_W) 'fs.c'; else $(CYGPATH_W) '$(srcdir)/fs.c'; fi`
libinstaller_a-setadv.o: setadv.c
$(AM_V_CC) @AM_BACKSLASH@

View file

@ -1,7 +1,8 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
* Copyright 2009-2010 Intel Corporation; author H. Peter Anvin
* Copyright 1998-2011 H. Peter Anvin - All Rights Reserved
* Copyright 2009-2011 Intel Corporation; author H. Peter Anvin
* Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
*
* 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
@ -12,7 +13,7 @@
* ----------------------------------------------------------------------- */
/*
* fat.c - Initial sanity check for FAT-based installers
* fs.c - Generic sanity check for FAT/NTFS-based installers
*/
#define _XOPEN_SOURCE 500 /* Required on glibc 2.x */
@ -25,45 +26,41 @@
#include "syslinux.h"
#include "syslxint.h"
#include "syslxcom.h"
#include "syslxfs.h"
void syslinux_make_bootsect(void *bs)
void syslinux_make_bootsect(void *bs, int fs_type)
{
struct boot_sector *bootsect = bs;
const struct boot_sector *sbs =
(const struct boot_sector *)boot_sector;
if (fs_type == VFAT) {
struct fat_boot_sector *bootsect = bs;
const struct fat_boot_sector *sbs =
(const struct fat_boot_sector *)boot_sector;
memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen);
memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen);
memcpy(&bootsect->FAT_bsHead, &sbs->FAT_bsHead, FAT_bsHeadLen);
memcpy(&bootsect->FAT_bsCode, &sbs->FAT_bsCode, FAT_bsCodeLen);
} else if (fs_type == NTFS) {
struct ntfs_boot_sector *bootsect = bs;
const struct ntfs_boot_sector *sbs =
(const struct ntfs_boot_sector *)boot_sector;
memcpy(&bootsect->NTFS_bsHead, &sbs->NTFS_bsHead, NTFS_bsHeadLen);
memcpy(&bootsect->NTFS_bsCode, &sbs->NTFS_bsCode, NTFS_bsCodeLen);
}
}
/*
* Check to see that what we got was indeed an MS-DOS boot sector/superblock;
* Return NULL if OK and otherwise an error message;
*/
const char *syslinux_check_bootsect(const void *bs)
static const char *check_fat_bootsect(const void *bs, int *fs_type)
{
int sectorsize;
const struct fat_boot_sector *sectbuf = bs;
long long sectors, fatsectors, dsectors;
long long clusters;
int rootdirents, clustersize;
const struct boot_sector *sectbuf = bs;
/* Must be 0xF0 or 0xF8..0xFF */
if (get_8(&sectbuf->bsMedia) != 0xF0 && get_8(&sectbuf->bsMedia) < 0xF8)
return "invalid media signature (not a FAT filesystem?)";
sectorsize = get_16(&sectbuf->bsBytesPerSec);
if (sectorsize == SECTOR_SIZE)
; /* ok */
else if (sectorsize >= 512 && sectorsize <= 4096 &&
(sectorsize & (sectorsize - 1)) == 0)
return "unsupported sectors size";
else
return "impossible sector size";
clustersize = get_8(&sectbuf->bsSecPerClust);
if (clustersize == 0 || (clustersize & (clustersize - 1)))
return "impossible cluster size";
return "impossible cluster size on an FAT volume";
sectors = get_16(&sectbuf->bsSectors);
sectors = sectors ? sectors : get_32(&sectbuf->bsHugeSectors);
@ -79,16 +76,19 @@ const char *syslinux_check_bootsect(const void *bs)
dsectors -= (rootdirents + sectorsize / 32 - 1) / sectorsize;
if (dsectors < 0)
return "negative number of data sectors";
if (fatsectors == 0)
return "zero FAT sectors";
return "negative number of data sectors on an FAT volume";
clusters = dsectors / clustersize;
fatsectors = get_16(&sectbuf->bsFATsecs);
fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
fatsectors *= get_8(&sectbuf->bsFATs);
if (!fatsectors)
return "zero FAT sectors";
if (clusters < 0xFFF5) {
/* FAT12 or FAT16 */
if (!get_16(&sectbuf->bsFATsecs))
return "zero FAT sectors (FAT12/16)";
@ -102,8 +102,8 @@ const char *syslinux_check_bootsect(const void *bs)
} else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT32 ", 8)) {
return "less than 65525 clusters but claims FAT32";
} else if (memcmp(&sectbuf->bs16.FileSysType, "FAT ", 8)) {
static char fserr[] =
"filesystem type \"????????\" not supported";
static char fserr[] = "filesystem type \"????????\" not "
"supported";
memcpy(fserr + 17, &sectbuf->bs16.FileSysType, 8);
return fserr;
}
@ -119,8 +119,54 @@ const char *syslinux_check_bootsect(const void *bs)
memcmp(&sectbuf->bs32.FileSysType, "FAT32 ", 8))
return "missing FAT32 signature";
} else {
return "impossibly large number of clusters";
return "impossibly large number of clusters on an FAT volume";
}
if (fs_type)
*fs_type = VFAT;
return NULL;
}
static const char *check_ntfs_bootsect(const void *bs, int *fs_type)
{
const struct ntfs_boot_sector *sectbuf = bs;
if (memcmp(&sectbuf->bsOemName, "NTFS ", 8) &&
memcmp(&sectbuf->bsOemName, "MSWIN4.0", 8) &&
memcmp(&sectbuf->bsOemName, "MSWIN4.1", 8))
return "unknown OEM name but claims NTFS";
if (fs_type)
*fs_type = NTFS;
return NULL;
}
const char *syslinux_check_bootsect(const void *bs, int *fs_type)
{
uint8_t media_sig;
int sectorsize;
const struct fat_boot_sector *sectbuf = bs;
const char *retval;
media_sig = get_8(&sectbuf->bsMedia);
/* Must be 0xF0 or 0xF8-0xFF for FAT/NTFS volumes */
if (media_sig != 0xF0 && media_sig < 0xF8)
return "invalid media signature (not an FAT/NTFS volume?)";
sectorsize = get_16(&sectbuf->bsBytesPerSec);
if (sectorsize == SECTOR_SIZE) ; /* ok */
else if (sectorsize >= 512 && sectorsize <= 4096 &&
(sectorsize & (sectorsize - 1)) == 0)
return "unsupported sectors size";
else
return "impossible sector size";
if (ntfs_check_zero_fields((struct ntfs_boot_sector *)bs))
retval = check_ntfs_bootsect(bs, fs_type);
else
retval = check_fat_bootsect(bs, fs_type);
return retval;
}

View file

@ -20,6 +20,7 @@
* Return 0 on success, -1 on error, and set errno.
*
*/
//#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
@ -28,6 +29,8 @@
#include <string.h>
#include <errno.h>
#include "syslxint.h"
#include "syslxcom.h"
#include "syslxfs.h"
unsigned char syslinux_adv[2 * ADV_SIZE];

View file

@ -14,7 +14,6 @@
#define SYSLINUX_H
#include <inttypes.h>
#include <sys/types.h>
#include "advconst.h"
#include "setadv.h"
@ -41,10 +40,10 @@ extern const int syslinux_mbr_mtime;
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
/* This takes a boot sector and merges in the syslinux fields */
void syslinux_make_bootsect(void *);
void syslinux_make_bootsect(void *bs, int fs_type);
/* Check to see that what we got was indeed an MS-DOS boot sector/superblock */
const char *syslinux_check_bootsect(const void *bs);
const char *syslinux_check_bootsect(const void *bs, int *fs_type);
/* This patches the boot sector and ldlinux.sys based on a sector map */
typedef uint64_t sector_t;

View file

@ -0,0 +1,6 @@
#ifndef _H_SYSLXCOM_
#define _H_SYSLXCOM_
/* Rufus placeholder */
#endif

View file

@ -0,0 +1,26 @@
/*
* Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
*
* 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.
*
* ----------------------------------------------------------------------- */
#ifndef _SYSLXFS_H_
#define _SYSLXFS_H_
/* Global fs_type for handling fat, ntfs, ext2/3/4 and btrfs */
enum filesystem {
NONE,
EXT2,
BTRFS,
VFAT,
NTFS,
};
//extern int fs_type;
#endif /* _SYSLXFS_H_ */

View file

@ -2,6 +2,7 @@
*
* Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
* Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
* Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
*
* 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
@ -193,7 +194,7 @@ struct syslinux_extent {
};
/* FAT bootsector format, also used by other disk-based derivatives */
struct boot_sector {
struct fat_boot_sector {
uint8_t bsJump[3];
char bsOemName[8];
uint16_t bsBytesPerSec;
@ -241,15 +242,70 @@ struct boot_sector {
uint16_t bsForwardPtr;
uint16_t bsSignature;
};
/* NTFS bootsector format */
struct ntfs_boot_sector {
uint8_t bsJump[3];
char bsOemName[8];
uint16_t bsBytesPerSec;
uint8_t bsSecPerClust;
uint16_t bsResSectors;
uint8_t bsZeroed_0[3];
uint16_t bsZeroed_1;
uint8_t bsMedia;
uint16_t bsZeroed_2;
uint16_t bsUnused_0;
uint16_t bsUnused_1;
uint32_t bsUnused_2;
uint32_t bsZeroed_3;
uint32_t bsUnused_3;
uint64_t bsTotalSectors;
uint64_t bsMFTLogicalClustNr;
uint64_t bsMFTMirrLogicalClustNr;
uint8_t bsClustPerMFTrecord;
uint8_t bsUnused_4[3];
uint8_t bsClustPerIdxBuf;
uint8_t bsUnused_5[3];
uint64_t bsVolSerialNr;
uint32_t bsUnused_6;
uint8_t Code[420];
uint32_t bsMagic;
uint16_t bsForwardPtr;
uint16_t bsSignature;
};
#pragma pack(pop)
#define bsHead bsJump
#define bsHeadLen offsetof(struct boot_sector, bsBytesPerSec)
#define bsCode bs32.Code /* The common safe choice */
#define bsCodeLen (offsetof(struct boot_sector, bsSignature) - \
offsetof(struct boot_sector, bsCode))
#define FAT_bsHead bsJump
#define FAT_bsHeadLen offsetof(struct fat_boot_sector, bsBytesPerSec)
#define FAT_bsCode bs32.Code /* The common safe choice */
#define FAT_bsCodeLen (offsetof(struct fat_boot_sector, bsSignature) - \
offsetof(struct fat_boot_sector, FAT_bsCode))
static inline int fat_check_sb_fields(const struct boot_sector *sb)
#define NTFS_bsHead bsJump
#define NTFS_bsHeadLen offsetof(struct ntfs_boot_sector, bsOemName)
#define NTFS_bsCode Code
#define NTFS_bsCodeLen (offsetof(struct ntfs_boot_sector, bsSignature) - \
offsetof(struct ntfs_boot_sector, NTFS_bsCode))
/* Check if there are specific zero fields in an NTFS boot sector */
static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb)
{
return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] &&
!sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 &&
!sb->bsZeroed_3;
}
static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb)
{
return ntfs_check_zero_fields(sb) &&
(!memcmp(sb->bsOemName, "NTFS ", 8) ||
!memcmp(sb->bsOemName, "MSWIN4.0", 8) ||
!memcmp(sb->bsOemName, "MSWIN4.1", 8));
}
static inline int fat_check_sb_fields(const struct fat_boot_sector *sb)
{
return sb->bsResSectors && sb->bsFATs &&
(!memcmp(sb->bs16.FileSysType, "FAT12 ", 8) ||

View file

@ -110,7 +110,7 @@ int syslinux_patch(const sector_t *sectp, int nsectors,
int nsect = ((boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT) + 2;
uint32_t csum;
int i, dw, nptrs;
struct boot_sector *sbs = (struct boot_sector *)boot_sector;
struct fat_boot_sector *sbs = (struct fat_boot_sector *)boot_sector;
uint64_t *advptrs;
if (nsectors < nsect)