diff --git a/res/syslinux/ldlinux.bss b/res/syslinux/ldlinux.bss index 884c5a8e..62142e2f 100644 Binary files a/res/syslinux/ldlinux.bss and b/res/syslinux/ldlinux.bss differ diff --git a/res/syslinux/ldlinux.sys b/res/syslinux/ldlinux.sys index cee0f82f..e5ddced5 100644 Binary files a/res/syslinux/ldlinux.sys and b/res/syslinux/ldlinux.sys differ diff --git a/res/syslinux/readme.txt b/res/syslinux/readme.txt index 46216b8f..a8c60fd8 100644 --- a/res/syslinux/readme.txt +++ b/res/syslinux/readme.txt @@ -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: - http://www.kernel.org/pub/linux/utils/boot/syslinux/ +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/ \ No newline at end of file diff --git a/res/syslinux/syslinux.diff b/res/syslinux/syslinux.diff new file mode 100644 index 00000000..389d12eb --- /dev/null +++ b/res/syslinux/syslinux.diff @@ -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 + }; + diff --git a/src/format.c b/src/format.c index 538ca0a7..0c80f7ed 100644 --- a/src/format.c +++ b/src/format.c @@ -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 + if (!WritePBR(hLogicalVolume)) { + if (!FormatStatus) + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; 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 (!FormatStatus) - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; - 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; } } diff --git a/src/iso.c b/src/iso.c index 2ef64b68..cb1700dc 100644 --- a/src/iso.c +++ b/src/iso.c @@ -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= 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= FOUR_GIGABYTES) iso_report.has_4GB_file = TRUE; total_blocks += i_file_length/ISO_BLOCKSIZE; diff --git a/src/rufus.c b/src/rufus.c index 08348ee6..4b9cc590 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -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" diff --git a/src/rufus.h b/src/rufus.h index 13e66006..cb88fd5b 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -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 }; diff --git a/src/rufus.rc b/src/rufus.rc index 1dd4febc..004a26b6 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -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 "http://rufus.akeo.ie",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 diff --git a/src/syslinux.c b/src/syslinux.c index e46d0581..c4ff8b33 100644 --- a/src/syslinux.c +++ b/src/syslinux.c @@ -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 || diff --git a/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj b/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj index d47eabe1..4d0e1a0c 100644 --- a/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj +++ b/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj @@ -1,4 +1,4 @@ - + @@ -21,10 +21,12 @@ + + - + diff --git a/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj.filters b/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj.filters index 029884f4..5cc1daa8 100644 --- a/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj.filters +++ b/src/syslinux/libinstaller/.msvc/libinstaller.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -20,9 +20,15 @@ Header Files + + Header Files + + + Header Files + - + Source Files diff --git a/src/syslinux/libinstaller/.msvc/libinstaller_sources b/src/syslinux/libinstaller/.msvc/libinstaller_sources index 10b20516..299870cf 100644 --- a/src/syslinux/libinstaller/.msvc/libinstaller_sources +++ b/src/syslinux/libinstaller/.msvc/libinstaller_sources @@ -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 \ No newline at end of file diff --git a/src/syslinux/libinstaller/Makefile.am b/src/syslinux/libinstaller/Makefile.am index 722c167c..21249cde 100644 --- a/src/syslinux/libinstaller/Makefile.am +++ b/src/syslinux/libinstaller/Makefile.am @@ -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) \ No newline at end of file diff --git a/src/syslinux/libinstaller/Makefile.in b/src/syslinux/libinstaller/Makefile.in index 67b57790..703e4573 100644 --- a/src/syslinux/libinstaller/Makefile.in +++ b/src/syslinux/libinstaller/Makefile.in @@ -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@ diff --git a/src/syslinux/libinstaller/fat.c b/src/syslinux/libinstaller/fs.c similarity index 52% rename from src/syslinux/libinstaller/fat.c rename to src/syslinux/libinstaller/fs.c index 9cde00c2..179629e9 100644 --- a/src/syslinux/libinstaller/fat.c +++ b/src/syslinux/libinstaller/fs.c @@ -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 * * 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(§buf->bsMedia) != 0xF0 && get_8(§buf->bsMedia) < 0xF8) - return "invalid media signature (not a FAT filesystem?)"; sectorsize = get_16(§buf->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(§buf->bsSecPerClust); if (clustersize == 0 || (clustersize & (clustersize - 1))) - return "impossible cluster size"; + return "impossible cluster size on an FAT volume"; sectors = get_16(§buf->bsSectors); sectors = sectors ? sectors : get_32(§buf->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(§buf->bsFATsecs); + fatsectors = fatsectors ? fatsectors : get_32(§buf->bs32.FATSz32); + fatsectors *= get_8(§buf->bsFATs); + + if (!fatsectors) + return "zero FAT sectors"; + if (clusters < 0xFFF5) { /* FAT12 or FAT16 */ - if (!get_16(§buf->bsFATsecs)) return "zero FAT sectors (FAT12/16)"; @@ -100,10 +100,10 @@ const char *syslinux_check_bootsect(const void *bs) if (clusters < 0xFF5) return "less than 4084 clusters but claims FAT16"; } else if (!memcmp(§buf->bs16.FileSysType, "FAT32 ", 8)) { - return "less than 65525 clusters but claims FAT32"; + return "less than 65525 clusters but claims FAT32"; } else if (memcmp(§buf->bs16.FileSysType, "FAT ", 8)) { - static char fserr[] = - "filesystem type \"????????\" not supported"; + static char fserr[] = "filesystem type \"????????\" not " + "supported"; memcpy(fserr + 17, §buf->bs16.FileSysType, 8); return fserr; } @@ -119,8 +119,54 @@ const char *syslinux_check_bootsect(const void *bs) memcmp(§buf->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(§buf->bsOemName, "NTFS ", 8) && + memcmp(§buf->bsOemName, "MSWIN4.0", 8) && + memcmp(§buf->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(§buf->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(§buf->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; +} diff --git a/src/syslinux/libinstaller/setadv.c b/src/syslinux/libinstaller/setadv.c index 425fdefd..838678bd 100644 --- a/src/syslinux/libinstaller/setadv.c +++ b/src/syslinux/libinstaller/setadv.c @@ -20,6 +20,7 @@ * Return 0 on success, -1 on error, and set errno. * */ +//#define _GNU_SOURCE #include #include @@ -28,6 +29,8 @@ #include #include #include "syslxint.h" +#include "syslxcom.h" +#include "syslxfs.h" unsigned char syslinux_adv[2 * ADV_SIZE]; diff --git a/src/syslinux/libinstaller/syslinux.h b/src/syslinux/libinstaller/syslinux.h index 39564ea7..a4832b59 100644 --- a/src/syslinux/libinstaller/syslinux.h +++ b/src/syslinux/libinstaller/syslinux.h @@ -14,7 +14,6 @@ #define SYSLINUX_H #include -#include #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; diff --git a/src/syslinux/libinstaller/syslxcom.h b/src/syslinux/libinstaller/syslxcom.h new file mode 100644 index 00000000..cde8ce58 --- /dev/null +++ b/src/syslinux/libinstaller/syslxcom.h @@ -0,0 +1,6 @@ +#ifndef _H_SYSLXCOM_ +#define _H_SYSLXCOM_ + +/* Rufus placeholder */ + +#endif diff --git a/src/syslinux/libinstaller/syslxfs.h b/src/syslinux/libinstaller/syslxfs.h new file mode 100644 index 00000000..40ed56da --- /dev/null +++ b/src/syslinux/libinstaller/syslxfs.h @@ -0,0 +1,26 @@ +/* + * Copyright 2011 Paulo Alcantara + * + * 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_ */ diff --git a/src/syslinux/libinstaller/syslxint.h b/src/syslinux/libinstaller/syslxint.h index 749c74be..f6d9a4ef 100644 --- a/src/syslinux/libinstaller/syslxint.h +++ b/src/syslinux/libinstaller/syslxint.h @@ -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 * * 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) || diff --git a/src/syslinux/libinstaller/syslxmod.c b/src/syslinux/libinstaller/syslxmod.c index 035fa97c..08acb075 100644 --- a/src/syslinux/libinstaller/syslxmod.c +++ b/src/syslinux/libinstaller/syslxmod.c @@ -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)