mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[grub] add GRUB 2.0 versioning and enable external core.img download
* Closes #419 * Also updated Bled to latest
This commit is contained in:
parent
7599715ae6
commit
e90eaa4abc
11 changed files with 158 additions and 18 deletions
5
res/grub/grub_version.h
Normal file
5
res/grub/grub_version.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
* This file contains the version string of the Grub4Dos 2.x binary embedded in Rufus.
|
||||
* Should be the same as the grub4dos_version file in the source Grub4Dos was compiled from.
|
||||
*/
|
||||
#define GRUB4DOS_VERSION "0.4.5c"
|
5
res/grub2/grub2_version.h
Normal file
5
res/grub2/grub2_version.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
* This file contains the version string of the GRUB 2.x binary embedded in Rufus.
|
||||
* Should be the same as GRUB's PACKAGE_VERSION in config.h.
|
||||
*/
|
||||
#define GRUB2_PACKAGE_VERSION "2.02~beta2"
|
|
@ -305,6 +305,15 @@ t MSG_114 "This image uses Syslinux %s%s but this application only includes the
|
|||
"Note: The files will be downloaded in the current application directory and will be reused "
|
||||
"automatically if present.\n"
|
||||
t MSG_115 "Download required"
|
||||
t MSG_116 "This image uses Grub %s but the application only includes the installation files for "
|
||||
"Grub %s.\n\nAs different versions of Grub may not be compatible with one another, and it is "
|
||||
"not possible to include them all, Rufus will attempt to locate a version of the Grub "
|
||||
"installation file ('core.img') that matches the one from your image:\n"
|
||||
"- Select 'Yes' to connect to the Internet and attempt to download it\n"
|
||||
"- Select 'No' to use the embedded version regardless\n"
|
||||
"- Select 'Cancel' to abort the operation\n\n"
|
||||
"Note: The file will be downloaded in the current application directory and will be reused "
|
||||
"automatically if present. If no match can be found, then the embedded version will be used.\n"
|
||||
# Tootips
|
||||
# Partition Scheme and Target Type
|
||||
t MSG_150 "Usually the safest choice. If you have an UEFI computer and want to install "
|
||||
|
|
|
@ -23,6 +23,7 @@ uint64_t bb_total_rb;
|
|||
printf_t bled_printf = NULL;
|
||||
progress_t bled_progress = NULL;
|
||||
static bool bled_initialized = 0;
|
||||
jmp_buf bb_error_jmp;
|
||||
|
||||
static long long int unpack_none(transformer_state_t *xstate)
|
||||
{
|
||||
|
@ -72,6 +73,8 @@ int64_t bled_uncompress(const char* src, const char* dst, int type)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (setjmp(bb_error_jmp))
|
||||
goto err;
|
||||
ret = unpacker[type](&xstate);
|
||||
_close(xstate.src_fd);
|
||||
_close(xstate.dst_fd);
|
||||
|
@ -116,6 +119,8 @@ int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (setjmp(bb_error_jmp))
|
||||
return -1;
|
||||
return unpacker[type](&xstate);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ typedef unsigned int uid_t;
|
|||
|
||||
extern smallint bb_got_signal;
|
||||
extern uint32_t *global_crc32_table;
|
||||
extern jmp_buf bb_error_jmp;
|
||||
|
||||
uint32_t* crc32_filltable(uint32_t *crc_table, int endian);
|
||||
uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len, uint32_t *crc32table_le);
|
||||
|
@ -135,10 +136,11 @@ typedef struct _llist_t {
|
|||
extern void (*bled_printf) (const char* format, ...);
|
||||
extern void (*bled_progress) (const uint64_t processed_bytes);
|
||||
|
||||
#define xfunc_die() longjmp(bb_error_jmp, 1)
|
||||
#define bb_printf(...) do { if (bled_printf != NULL) bled_printf(__VA_ARGS__); \
|
||||
else { printf(__VA_ARGS__); putchar('\n'); } } while(0)
|
||||
#define bb_error_msg bb_printf
|
||||
#define bb_error_msg_and_die(...) do {bb_printf(__VA_ARGS__); return;} while(0)
|
||||
#define bb_error_msg_and_die(...) do {bb_printf(__VA_ARGS__); xfunc_die();} while(0)
|
||||
#define bb_error_msg_and_err(...) do {bb_printf(__VA_ARGS__); goto err;} while(0)
|
||||
#define bb_perror_msg bb_error_msg
|
||||
#define bb_perror_msg_and_die bb_error_msg_and_die
|
||||
|
@ -185,7 +187,6 @@ static inline ssize_t full_read(int fd, void *buf, size_t count) {
|
|||
#define xzalloc(x) calloc(x, 1)
|
||||
#define malloc_or_warn malloc
|
||||
#define xopen3 open
|
||||
#define xfunc_die() do { bb_printf("not implemented"); return -1; } while(0)
|
||||
#define mkdir(x, y) _mkdirU(x)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
|
25
src/format.c
25
src/format.c
|
@ -58,6 +58,8 @@ extern const int nb_steps[FS_MAX];
|
|||
extern uint32_t dur_mins, dur_secs;
|
||||
static int fs_index = 0;
|
||||
BOOL force_large_fat32 = FALSE, enable_ntfs_compression = FALSE;
|
||||
uint8_t *grub2_buf = NULL;
|
||||
long grub2_len;
|
||||
static BOOL WritePBR(HANDLE hLogicalDrive);
|
||||
|
||||
/*
|
||||
|
@ -952,7 +954,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
|
|||
{
|
||||
// TODO: Do we need anything special for 4K sectors?
|
||||
DWORD size, max_size, mbr_size = 0x200;
|
||||
int dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
||||
int r, dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
||||
unsigned char* buf = NULL;
|
||||
FILE fake_fd = { 0 };
|
||||
|
||||
|
@ -969,6 +971,7 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
|
|||
|
||||
switch (dt) {
|
||||
case DT_GRUB4DOS:
|
||||
uprintf("Writing Grub4Dos SBR...");
|
||||
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_GR_GRUB_GRLDR_MBR), _RT_RCDATA, "grldr.mbr", &size, FALSE);
|
||||
if ((buf == NULL) || (size <= mbr_size)) {
|
||||
uprintf("grldr.mbr is either not present or too small");
|
||||
|
@ -978,10 +981,17 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
|
|||
size -= mbr_size;
|
||||
break;
|
||||
case DT_GRUB2:
|
||||
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_GR_GRUB2_CORE_IMG), _RT_RCDATA, "core.img", &size, FALSE);
|
||||
if (buf == NULL) {
|
||||
uprintf("Could not access core.img");
|
||||
return FALSE;
|
||||
if (grub2_buf != NULL) {
|
||||
uprintf("Writing Grub 2.0 SBR (from download)...");
|
||||
buf = grub2_buf;
|
||||
size = (DWORD)grub2_len;
|
||||
} else {
|
||||
uprintf("Writing Grub 2.0 SBR (from embedded)...");
|
||||
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_GR_GRUB2_CORE_IMG), _RT_RCDATA, "core.img", &size, FALSE);
|
||||
if (buf == NULL) {
|
||||
uprintf("Could not access core.img");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -989,12 +999,13 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
uprintf("Writing SBR (Secondary Boot record)");
|
||||
if (size > max_size) {
|
||||
uprintf(" SBR size is too large - You may need to uncheck 'Add fixes for old BIOSes'.");
|
||||
return FALSE;
|
||||
}
|
||||
return (write_data(&fake_fd, mbr_size, buf, (uint64_t)size) != 0);
|
||||
r = write_data(&fake_fd, mbr_size, buf, (uint64_t)size);
|
||||
safe_free(grub2_buf);
|
||||
return (r != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
40
src/iso.c
40
src/iso.c
|
@ -552,6 +552,27 @@ out:
|
|||
return r;
|
||||
}
|
||||
|
||||
void GetGrubVersion(char* buf, size_t buf_size)
|
||||
{
|
||||
char *p, unauthorized[] = {'<', '>', ':', '|', '*', '?', '\\', '/'};
|
||||
size_t i;
|
||||
const char grub_version_str[] = "GRUB version %s";
|
||||
|
||||
for (i=0; i<buf_size; i++) {
|
||||
if (memcmp(&buf[i], grub_version_str, sizeof(grub_version_str)) == 0) {
|
||||
safe_strcpy(iso_report.grub2_version, sizeof(iso_report.grub2_version), &buf[i + sizeof(grub_version_str)]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Sanitize the string
|
||||
for (p = &iso_report.grub2_version[0]; *p; p++) {
|
||||
for (i=0; i<sizeof(unauthorized); i++) {
|
||||
if (*p == unauthorized[i])
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
|
||||
{
|
||||
size_t i, size;
|
||||
|
@ -743,6 +764,25 @@ out:
|
|||
_unlink(tmp_sif);
|
||||
safe_free(tmp);
|
||||
}
|
||||
if (iso_report.has_grub2) {
|
||||
// In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version
|
||||
strcpy(iso_report.grub2_version, "unknown");
|
||||
if ((GetTempPathU(sizeof(path), path) != 0) && (GetTempFileNameU(path, APPLICATION_NAME, 0, path) != 0)) {
|
||||
size = (size_t)ExtractISOFile(src_iso, "boot/grub/i386-pc/normal.mod", path, FILE_ATTRIBUTE_NORMAL);
|
||||
buf = (char*)calloc(size, 1);
|
||||
fd = fopen(path, "rb");
|
||||
if ((size == 0) || (buf == NULL) || (fd == NULL)) {
|
||||
uprintf("Could not read Grub version from 'boot/grub/i386-pc/normal.mod'");
|
||||
} else {
|
||||
fread(buf, 1, size, fd);
|
||||
fclose(fd);
|
||||
GetGrubVersion(buf, size);
|
||||
}
|
||||
free(buf);
|
||||
_unlink(path);
|
||||
}
|
||||
uprintf("Detected Grub version: %s", iso_report.grub2_version);
|
||||
}
|
||||
StrArrayDestroy(&config_path);
|
||||
StrArrayDestroy(&isolinux_path);
|
||||
} else if (HAS_SYSLINUX(iso_report)) {
|
||||
|
|
|
@ -427,7 +427,7 @@ static __inline DWORD GetTempFileNameU(char* lpPathName, char* lpPrefixString, U
|
|||
wconvert(lpPathName);
|
||||
wconvert(lpPrefixString);
|
||||
walloc(lpTempFileName, MAX_PATH);
|
||||
ret =GetTempFileNameW(wlpPathName, wlpPrefixString, uUnique, wlpTempFileName);
|
||||
ret = GetTempFileNameW(wlpPathName, wlpPrefixString, uUnique, wlpTempFileName);
|
||||
err = GetLastError();
|
||||
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpTempFileName, lpTempFileName, MAX_PATH)) == 0)) {
|
||||
err = GetLastError();
|
||||
|
|
63
src/rufus.c
63
src/rufus.c
|
@ -42,6 +42,8 @@
|
|||
#include "registry.h"
|
||||
#include "localization.h"
|
||||
#include "bled/bled.h"
|
||||
#include "../res/grub/grub_version.h"
|
||||
#include "../res/grub2/grub2_version.h"
|
||||
|
||||
/* Redefinitions for WDK and MinGW */
|
||||
// TODO: these would be better in a 'missing.h' file
|
||||
|
@ -99,6 +101,8 @@ static BOOL iso_provided = FALSE;
|
|||
static BOOL user_notified = FALSE;
|
||||
static BOOL relaunch = FALSE;
|
||||
extern BOOL force_large_fat32, enable_iso, enable_joliet, enable_rockridge, enable_ntfs_compression;
|
||||
extern uint8_t* grub2_buf;
|
||||
extern long grub2_len;
|
||||
extern const char* old_c32_name[NB_OLD_C32];
|
||||
static int selection_default;
|
||||
static loc_cmd* selected_locale = NULL;
|
||||
|
@ -129,6 +133,8 @@ int dialog_showing = 0;
|
|||
uint16_t rufus_version[4], embedded_sl_version[2];
|
||||
char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
|
||||
char embedded_sl_version_ext[2][32];
|
||||
char embedded_grub_version[] = GRUB4DOS_VERSION;
|
||||
char embedded_grub2_version[] = GRUB2_PACKAGE_VERSION;
|
||||
RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL};
|
||||
StrArray DriveID, DriveLabel;
|
||||
extern char szStatusMessage[256];
|
||||
|
@ -1122,12 +1128,15 @@ static BOOL BootCheck(void)
|
|||
FILE *fd;
|
||||
DWORD len;
|
||||
BOOL in_files_dir = FALSE;
|
||||
const char* grub = "grub";
|
||||
const char* core_img = "core.img";
|
||||
const char* ldlinux = "ldlinux";
|
||||
const char* syslinux = "syslinux";
|
||||
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
|
||||
char tmp[MAX_PATH], tmp2[MAX_PATH];
|
||||
|
||||
syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0;
|
||||
safe_free(grub2_buf);
|
||||
dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
|
||||
if ((dt == DT_ISO) || (dt == DT_IMG)) {
|
||||
if (image_path == NULL) {
|
||||
|
@ -1185,6 +1194,59 @@ static BOOL BootCheck(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if ((iso_report.has_grub2) && (safe_strcmp(iso_report.grub2_version, embedded_grub2_version) != 0)) {
|
||||
// We may have to download a different Grub2 version if we can find one
|
||||
IGNORE_RETVAL(_chdirU(app_dir));
|
||||
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
||||
IGNORE_RETVAL(_chdir(FILES_DIR));
|
||||
static_sprintf(tmp, "%s-%s/%s", grub, iso_report.grub2_version, core_img);
|
||||
fd = fopen(tmp, "rb");
|
||||
if (fd != NULL) {
|
||||
// If a file already exists in the current directory, use that one
|
||||
uprintf("Will reuse '%s' from './" FILES_DIR "/%s-%s/' for Grub 2.x installation\n",
|
||||
core_img, grub, iso_report.grub2_version);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
grub2_len = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
if (grub2_len > 0)
|
||||
grub2_buf = malloc(grub2_len);
|
||||
|
||||
// grub2_buf was set to NULL at the beginning of this call
|
||||
if ((grub2_buf == NULL) || (fread(grub2_buf, 1, (size_t)grub2_len, fd) != (size_t)grub2_len)) {
|
||||
uprintf("Failed to read existing '%s' data - will use embedded version", core_img);
|
||||
safe_free(grub2_buf);
|
||||
}
|
||||
fclose(fd);
|
||||
} else {
|
||||
r = MessageBoxU(hMainDialog, lmprintf(MSG_116, iso_report.grub2_version, embedded_grub2_version),
|
||||
lmprintf(MSG_115), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL);
|
||||
if (r == IDCANCEL)
|
||||
return FALSE;
|
||||
else if (r == IDYES) {
|
||||
static_sprintf(tmp, "%s-%s", grub, iso_report.grub2_version);
|
||||
IGNORE_RETVAL(_mkdir(tmp));
|
||||
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, iso_report.grub2_version, core_img);
|
||||
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, tmp));
|
||||
SetWindowTextU(hISOFileName, tmp);
|
||||
PromptOnError = FALSE;
|
||||
grub2_len = (long)DownloadFile(tmp, &tmp[sizeof(FILES_URL)], hISOProgressDlg);
|
||||
PromptOnError = TRUE;
|
||||
if (grub2_len <= 0)
|
||||
uprintf("%s was not found - will use embedded version\n", tmp);
|
||||
else {
|
||||
fd = fopen(&tmp[sizeof(FILES_URL)], "rb");
|
||||
grub2_buf = malloc(grub2_len);
|
||||
if ((fd == NULL) || (grub2_buf == NULL) || (fread(grub2_buf, 1, (size_t)grub2_len, fd) != (size_t)grub2_len)) {
|
||||
uprintf("Failed to read '%s' data - will use embedded version", core_img);
|
||||
safe_free(grub2_buf);
|
||||
}
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_SYSLINUX(iso_report)) {
|
||||
if (SL_MAJOR(iso_report.sl_version) < 5) {
|
||||
IGNORE_RETVAL(_chdirU(app_dir));
|
||||
|
@ -1434,6 +1496,7 @@ void InitDialog(HWND hDlg)
|
|||
}
|
||||
uprintf("Syslinux versions: %s%s, %s%s", embedded_sl_version_str[0], embedded_sl_version_ext[0],
|
||||
embedded_sl_version_str[1], embedded_sl_version_ext[1]);
|
||||
uprintf("Grub versions: %s, %s", embedded_grub_version, embedded_grub2_version);
|
||||
uprintf("Windows version: %s\n", WindowsVersionStr);
|
||||
uprintf("Locale ID: 0x%04X\n", GetUserDefaultUILanguage());
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ typedef struct {
|
|||
uint16_t sl_version; // Syslinux/Isolinux version
|
||||
char sl_version_str[12];
|
||||
char sl_version_ext[32];
|
||||
char grub2_version[32];
|
||||
} RUFUS_ISO_REPORT;
|
||||
|
||||
/* Isolate the Syslinux version numbers */
|
||||
|
|
16
src/rufus.rc
16
src/rufus.rc
|
@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||
|
||||
IDD_DIALOG DIALOGEX 12, 12, 242, 329
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Rufus 1.5.0.563"
|
||||
CAPTION "Rufus 1.5.0.564"
|
||||
FONT 8, "Segoe UI", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
|
||||
|
@ -164,7 +164,7 @@ END
|
|||
|
||||
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 329
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Rufus 1.5.0.563"
|
||||
CAPTION "Rufus 1.5.0.564"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
|
||||
|
@ -297,7 +297,7 @@ END
|
|||
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 329
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
|
||||
CAPTION "Rufus 1.5.0.563"
|
||||
CAPTION "Rufus 1.5.0.564"
|
||||
FONT 8, "Segoe UI", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
|
||||
|
@ -437,7 +437,7 @@ END
|
|||
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 329
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
|
||||
CAPTION "Rufus 1.5.0.563"
|
||||
CAPTION "Rufus 1.5.0.564"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Start",IDC_START,127,291,50,14
|
||||
|
@ -703,8 +703,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,0,563
|
||||
PRODUCTVERSION 1,5,0,563
|
||||
FILEVERSION 1,5,0,564
|
||||
PRODUCTVERSION 1,5,0,564
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -721,13 +721,13 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "1.5.0.563"
|
||||
VALUE "FileVersion", "1.5.0.564"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||
VALUE "OriginalFilename", "rufus.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "1.5.0.563"
|
||||
VALUE "ProductVersion", "1.5.0.564"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in a new issue