mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-18 00:54:27 -04:00
[syslinux] fix Syslinux installation for some media
* Some disk devices, such as O2Micro PCI-E SD card readers, return ERROR_INVALID_PARAMETER when attempting to use ReadFile() on a volume against a non 8-byte aligned buffer. * This patch ensures that the Syslinux buffers for sector patching are 16-byte aligned. * HUGE THANKS to 424778940z, for the numerous testing that allowed to troubleshoot this issue. * Closes #767
This commit is contained in:
parent
c0393aec08
commit
3fdf622933
4 changed files with 63 additions and 23 deletions
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 2.10.956"
|
CAPTION "Rufus 2.10.957"
|
||||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||||
|
@ -320,8 +320,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,10,956,0
|
FILEVERSION 2,10,957,0
|
||||||
PRODUCTVERSION 2,10,956,0
|
PRODUCTVERSION 2,10,957,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -338,13 +338,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "2.10.956"
|
VALUE "FileVersion", "2.10.957"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "2.10.956"
|
VALUE "ProductVersion", "2.10.957"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -105,18 +105,19 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs_type)
|
||||||
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
|
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
|
||||||
const char* mboot_c32 = "mboot.c32";
|
const char* mboot_c32 = "mboot.c32";
|
||||||
char path[MAX_PATH], tmp[64];
|
char path[MAX_PATH], tmp[64];
|
||||||
|
const char *errmsg;
|
||||||
struct libfat_filesystem *fs;
|
struct libfat_filesystem *fs;
|
||||||
libfat_sector_t s, *secp;
|
libfat_sector_t s, *secp;
|
||||||
libfat_sector_t *sectors = NULL;
|
libfat_sector_t *sectors = NULL;
|
||||||
int ldlinux_sectors;
|
int ldlinux_sectors;
|
||||||
uint32_t ldlinux_cluster;
|
uint32_t ldlinux_cluster;
|
||||||
int i, nsectors;
|
int i, nsectors, sl_fs_stype;
|
||||||
int bt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
int bt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
||||||
BOOL use_v5 = (bt == BT_SYSLINUX_V6) || ((bt == BT_ISO) && (SL_MAJOR(img_report.sl_version) >= 5));
|
BOOL use_v5 = (bt == BT_SYSLINUX_V6) || ((bt == BT_ISO) && (SL_MAJOR(img_report.sl_version) >= 5));
|
||||||
|
|
||||||
PrintInfoDebug(0, MSG_234, (bt == BT_ISO)?img_report.sl_version_str:embedded_sl_version_str[use_v5?1:0]);
|
PrintInfoDebug(0, MSG_234, (bt == BT_ISO)?img_report.sl_version_str:embedded_sl_version_str[use_v5?1:0]);
|
||||||
|
|
||||||
// 4K sector size workaround
|
/* 4K sector size workaround */
|
||||||
SECTOR_SHIFT = 0;
|
SECTOR_SHIFT = 0;
|
||||||
SECTOR_SIZE = SelectedDrive.SectorSize;
|
SECTOR_SIZE = SelectedDrive.SectorSize;
|
||||||
while (SECTOR_SIZE>>=1)
|
while (SECTOR_SIZE>>=1)
|
||||||
|
@ -126,10 +127,32 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs_type)
|
||||||
LIBFAT_SECTOR_SIZE = SECTOR_SIZE;
|
LIBFAT_SECTOR_SIZE = SECTOR_SIZE;
|
||||||
LIBFAT_SECTOR_MASK = SECTOR_SIZE - 1;
|
LIBFAT_SECTOR_MASK = SECTOR_SIZE - 1;
|
||||||
|
|
||||||
sectbuf = malloc(SECTOR_SIZE);
|
/* sectbuf should be aligned to at least 8 bytes - see github #767 */
|
||||||
|
sectbuf = _aligned_malloc(SECTOR_SIZE, 16);
|
||||||
if (sectbuf == NULL)
|
if (sectbuf == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* First, reopen the volume (we already have a lock) */
|
||||||
|
d_handle = GetLogicalHandle(drive_index, TRUE, FALSE);
|
||||||
|
if ((d_handle == INVALID_HANDLE_VALUE) || (d_handle == NULL)) {
|
||||||
|
uprintf("Could open volume for Syslinux installation");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we can read the boot sector (NB: Re-open already set us to offset 0) */
|
||||||
|
if (!ReadFile(d_handle, sectbuf, SECTOR_SIZE, &bytes_read, NULL)) {
|
||||||
|
uprintf("Could not read VBR");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (bytes_read != SECTOR_SIZE) {
|
||||||
|
uprintf("Could not read the whole VBR");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if ((errmsg = syslinux_check_bootsect(sectbuf, &sl_fs_stype))) {
|
||||||
|
uprintf("Error: %s", errmsg);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the ADV -- this should be smarter */
|
/* Initialize the ADV -- this should be smarter */
|
||||||
syslinux_reset_adv(syslinux_adv);
|
syslinux_reset_adv(syslinux_adv);
|
||||||
|
|
||||||
|
@ -201,13 +224,6 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs_type)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reopen the volume (we already have a lock) */
|
|
||||||
d_handle = GetLogicalHandle(drive_index, TRUE, FALSE);
|
|
||||||
if ((d_handle == INVALID_HANDLE_VALUE) || (d_handle == NULL)) {
|
|
||||||
uprintf("Could open volume for Syslinux installation");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the file (is there a better way to do this?) */
|
/* Map the file (is there a better way to do this?) */
|
||||||
ldlinux_sectors = (syslinux_ldlinux_len[0] + 2 * ADV_SIZE + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
|
ldlinux_sectors = (syslinux_ldlinux_len[0] + 2 * ADV_SIZE + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
|
||||||
sectors = (libfat_sector_t*) calloc(ldlinux_sectors, sizeof *sectors);
|
sectors = (libfat_sector_t*) calloc(ldlinux_sectors, sizeof *sectors);
|
||||||
|
@ -366,7 +382,8 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs_type)
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
safe_free(sectbuf);
|
if (sectbuf != NULL)
|
||||||
|
_aligned_free(sectbuf);
|
||||||
safe_free(syslinux_ldlinux[0]);
|
safe_free(syslinux_ldlinux[0]);
|
||||||
safe_free(syslinux_ldlinux[1]);
|
safe_free(syslinux_ldlinux[1]);
|
||||||
safe_free(sectors);
|
safe_free(sectors);
|
||||||
|
|
|
@ -19,6 +19,20 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "libfatint.h"
|
#include "libfatint.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to align our sector buffers to at least the 8-byte mark, as some Windows
|
||||||
|
* disk devices, notably O2Micro PCI-E SD card readers, return ERROR_INVALID_PARAMETER
|
||||||
|
* when attempting to use ReadFile() against a non 8-byte aligned buffer.
|
||||||
|
* For good measure, we'll go further and align our buffers on a 16-byte boundary.
|
||||||
|
* Also, since struct libfat_sector's data[0] is our buffer, this means we must BOTH
|
||||||
|
* align that member in the struct declaration, and use aligned malloc/free.
|
||||||
|
*/
|
||||||
|
#if defined(__MINGW32__)
|
||||||
|
#define _aligned_malloc __mingw_aligned_malloc
|
||||||
|
#define _aligned_free __mingw_aligned_free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void _uprintf(const char *format, ...);
|
||||||
void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n)
|
void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n)
|
||||||
{
|
{
|
||||||
struct libfat_sector *ls;
|
struct libfat_sector *ls;
|
||||||
|
@ -29,10 +43,10 @@ void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not found in cache */
|
/* Not found in cache */
|
||||||
ls = malloc(sizeof(struct libfat_sector) + LIBFAT_SECTOR_SIZE);
|
ls = _aligned_malloc(sizeof(struct libfat_sector) + LIBFAT_SECTOR_SIZE, 16);
|
||||||
if (!ls) {
|
if (!ls) {
|
||||||
libfat_flush(fs);
|
libfat_flush(fs);
|
||||||
ls = malloc(sizeof(struct libfat_sector) + LIBFAT_SECTOR_SIZE);
|
ls = _aligned_malloc(sizeof(struct libfat_sector) + LIBFAT_SECTOR_SIZE, 16);
|
||||||
|
|
||||||
if (!ls)
|
if (!ls)
|
||||||
return NULL; /* Can't allocate memory */
|
return NULL; /* Can't allocate memory */
|
||||||
|
@ -40,7 +54,7 @@ void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n)
|
||||||
|
|
||||||
if (fs->read(fs->readptr, ls->data, LIBFAT_SECTOR_SIZE, n)
|
if (fs->read(fs->readptr, ls->data, LIBFAT_SECTOR_SIZE, n)
|
||||||
!= LIBFAT_SECTOR_SIZE) {
|
!= LIBFAT_SECTOR_SIZE) {
|
||||||
free(ls);
|
_aligned_free(ls);
|
||||||
return NULL; /* I/O error */
|
return NULL; /* I/O error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +74,6 @@ void libfat_flush(struct libfat_filesystem *fs)
|
||||||
|
|
||||||
for (ls = lsnext; ls; ls = lsnext) {
|
for (ls = lsnext; ls; ls = lsnext) {
|
||||||
lsnext = ls->next;
|
lsnext = ls->next;
|
||||||
free(ls);
|
_aligned_free(ls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,19 @@
|
||||||
#include "libfat.h"
|
#include "libfat.h"
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define ALIGN_START(m)
|
||||||
|
#define ALIGN_END(m) __attribute__ ((__aligned__(m)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define ALIGN_START(m) __declspec(align(m))
|
||||||
|
#define ALIGN_END(m)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct libfat_sector {
|
struct libfat_sector {
|
||||||
libfat_sector_t n; /* Sector number */
|
libfat_sector_t n; /* Sector number */
|
||||||
struct libfat_sector *next; /* Next in list */
|
struct libfat_sector *next; /* Next in list */
|
||||||
char data[0];
|
/* data[0] MUST be aligned to at least 8 bytes - see cache.c */
|
||||||
|
ALIGN_START(16) char data[0] ALIGN_END(16);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fat_type {
|
enum fat_type {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue