[misc] pocketful of enhancement and fixes - part 5

* Check compressed DD images for boot capability
* Add DisableLGP setting
* Silence libcdio errors when scanning non ISO images
* Ensure UI displays "No image selected" when relevant
* Also update Bled to latest
This commit is contained in:
Pete Batard 2015-02-11 23:22:18 +00:00
parent 63bb91493a
commit 818fa4da88
18 changed files with 156 additions and 70 deletions

View File

@ -5,6 +5,8 @@ Features:
- Creates DOS bootable USB drives, using FreeDOS or MS-DOS with no external files required
- Creates MBR or GPT/UEFI bootable drives
- Creates bootable drives from bootable ISOs (Windows, Linux, etc.)
- Creates bootbale drives from disk images, including compressed ones
- Creates Windows To Go drives
- Twice as fast as Microsoft's USB/DVD tool or UNetbootin, on ISO->USB (1)
- Can perform bad blocks check, with fake drive detection
- Modern and familiar UI, with more than 30 languages natively supported (2)

View File

@ -15,3 +15,7 @@ LastUpdateCheck = 13068056756
UpdateCheckInterval = 86400
; Use this to increases the log verbosity, for the update checks
VerboseUpdateCheck = 0
; If you are paranoid about apps writing to the registry, you can uncomment the
; following. It will disable the Local Group Policy calls that Rufus issues, to
; temporarily prevent the *annoying* notices Windows issues about new drives.
; DisableLGP = 1

View File

@ -225,7 +225,6 @@ typedef struct transformer_state_t {
void init_transformer_state(transformer_state_t *xstate) FAST_FUNC;
ssize_t transformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) FAST_FUNC;
ssize_t xtransformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) FAST_FUNC;
int check_signature16(transformer_state_t *xstate, unsigned magic16) FAST_FUNC;
IF_DESKTOP(long long) int inflate_unzip(transformer_state_t *xstate) FAST_FUNC;

View File

@ -28,18 +28,19 @@ jmp_buf bb_error_jmp;
static long long int unpack_none(transformer_state_t *xstate)
{
bb_printf("BLED_COMPRESSION_NONE is not supported");
bb_printf("This compression type is not supported");
return -1;
}
unpacker_t unpacker[BLED_COMPRESSION_MAX] = {
unpack_none,
inflate_unzip,
unpack_none,
unpack_Z_stream,
unpack_gz_stream,
unpack_lzma_stream,
unpack_bz2_stream,
unpack_xz_stream
unpack_xz_stream,
unpack_none
};
/* Uncompress file 'src', compressed using 'type', to file 'dst' */
@ -125,6 +126,48 @@ int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type)
return unpacker[type](&xstate);
}
/* Uncompress file 'src', compressed using 'type', to buffer 'buf' of size 'size' */
int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int type)
{
transformer_state_t xstate;
int64_t ret;
if (!bled_initialized)
return -1;
bb_total_rb = 0;
init_transformer_state(&xstate);
xstate.src_fd = -1;
xstate.dst_fd = -1;
xstate.check_signature = 1;
xstate.src_fd = _openU(src, _O_RDONLY | _O_BINARY, 0);
if (xstate.src_fd < 0) {
bb_printf("Could not open '%s' (errno: %d)", src, errno);
goto err;
}
xstate.mem_output_buf = buf;
xstate.mem_output_size = 0;
xstate.mem_output_size_max = size;
if ((type < 0) || (type >= BLED_COMPRESSION_MAX)) {
bb_printf("unsupported compression format");
goto err;
}
if (setjmp(bb_error_jmp))
goto err;
ret = unpacker[type](&xstate);
_close(xstate.src_fd);
return ret;
err:
if (xstate.src_fd > 0)
_close(xstate.src_fd);
return -1;
}
/* Initialize the library.
* When the parameters are not NULL you can:
* - specify the printf-like function you want to use to output message
@ -150,7 +193,9 @@ void bled_exit(void)
bled_printf = NULL;
bled_progress = NULL;
bled_cancel_request = NULL;
if (global_crc32_table)
if (global_crc32_table) {
free(global_crc32_table);
global_crc32_table = NULL;
}
bled_initialized = false;
}

View File

@ -26,7 +26,7 @@ typedef enum {
BLED_COMPRESSION_LZMA, // .lzma
BLED_COMPRESSION_BZIP2, // .bz2
BLED_COMPRESSION_XZ, // .xz
// BLED_COMPRESSION_7ZIP // .7z
BLED_COMPRESSION_7ZIP, // .7z
BLED_COMPRESSION_MAX
} bled_compression_type;
@ -36,6 +36,9 @@ int64_t bled_uncompress(const char* src, const char* dst, int type);
/* Uncompress using Windows handles */
int64_t bled_uncompress_with_handles(HANDLE hSrc, HANDLE hDst, int type);
/* Uncompress file 'src', compressed using 'type', to buffer 'buf' of size 'size' */
int64_t bled_uncompress_to_buffer(const char* src, char* buf, size_t size, int type);
/* Initialize the library.
* When the parameters are not NULL you can:
* - specify the printf-like function you want to use to output message

View File

@ -736,7 +736,7 @@ unpack_bz2_stream(transformer_state_t *xstate)
IF_DESKTOP(long long total_written = 0;)
bunzip_data *bd;
char *outbuf;
int i;
int i, nwrote;
unsigned len;
if (check_signature16(xstate, BZIP2_MAGIC))
@ -756,8 +756,9 @@ unpack_bz2_stream(transformer_state_t *xstate)
i = IOBUF_SIZE - i; /* number of bytes produced */
if (i == 0) /* EOF? */
break;
if (i != transformer_write(xstate, outbuf, i)) {
i = RETVAL_SHORT_WRITE;
nwrote = (int)transformer_write(xstate, outbuf, i);
if (nwrote != i) {
i = (nwrote == -ENOSPC)?(int)xstate->mem_output_size_max:RETVAL_SHORT_WRITE;
goto release_mem;
}
IF_DESKTOP(total_written += i;)

View File

@ -1003,8 +1003,9 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
while (1) {
int r = inflate_get_next_window(PASS_STATE_ONLY);
nwrote = transformer_write(xstate, gunzip_window, gunzip_outbuf_count);
if (nwrote == (ssize_t)-1) {
n = -1;
if (nwrote != (ssize_t)gunzip_outbuf_count) {
huft_free_all(PASS_STATE_ONLY);
n = (nwrote <0)?nwrote:-1;
goto ret;
}
IF_DESKTOP(n += nwrote;)
@ -1226,7 +1227,7 @@ unpack_gz_stream(transformer_state_t *xstate)
n = inflate_unzip_internal(PASS_STATE xstate);
if (n < 0) {
total = -1;
total = (n == -ENOSPC)?xstate->mem_output_size_max:n;
goto ret;
}
total += n;

View File

@ -274,7 +274,11 @@ unpack_Z_stream(transformer_state_t *xstate)
}
if (outpos >= OBUFSIZ) {
xtransformer_write(xstate, outbuf, outpos);
retval = transformer_write(xstate, outbuf, outpos);
if (retval != (ssize_t)outpos) {
retval = (retval == -ENOSPC)?xstate->mem_output_size_max:-1;
goto err;
}
IF_DESKTOP(total_written += outpos;)
outpos = 0;
}
@ -301,7 +305,9 @@ unpack_Z_stream(transformer_state_t *xstate)
} while (rsize > 0);
if (outpos > 0) {
xtransformer_write(xstate, outbuf, outpos);
retval = transformer_write(xstate, outbuf, outpos);
if (retval != (ssize_t)outpos)
retval = (retval == -ENOSPC)?xstate->mem_output_size_max:-1;
IF_DESKTOP(total_written += outpos;)
}

View File

@ -220,6 +220,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
uint8_t *buffer;
uint8_t previous_byte = 0;
size_t buffer_pos = 0, global_pos = 0;
ssize_t nwrote;
int len = 0;
int state = 0;
uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
@ -307,7 +308,8 @@ unpack_lzma_stream(transformer_state_t *xstate)
if (buffer_pos == header.dict_size) {
buffer_pos = 0;
global_pos += header.dict_size;
if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size)
nwrote = transformer_write(xstate, buffer, header.dict_size);
if (nwrote != (ssize_t)header.dict_size)
goto bad;
IF_DESKTOP(total_written += header.dict_size;)
}
@ -441,7 +443,8 @@ unpack_lzma_stream(transformer_state_t *xstate)
if (buffer_pos == header.dict_size) {
buffer_pos = 0;
global_pos += header.dict_size;
if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size)
nwrote = transformer_write(xstate, buffer, header.dict_size);
if (nwrote != (ssize_t)header.dict_size)
goto bad;
IF_DESKTOP(total_written += header.dict_size;)
}
@ -456,9 +459,10 @@ unpack_lzma_stream(transformer_state_t *xstate)
{
IF_NOT_DESKTOP(int total_written = 0; /* success */)
IF_DESKTOP(total_written += buffer_pos;)
if (transformer_write(xstate, buffer, buffer_pos) != (ssize_t)buffer_pos) {
nwrote = transformer_write(xstate, buffer, buffer_pos);
if (nwrote != (ssize_t)buffer_pos) {
bad:
total_written = -1; /* failure */
total_written = (nwrote == -ENOSPC)?xstate->mem_output_size_max:-1;
}
rc_free(rc);
free(p);

View File

@ -70,7 +70,11 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_xz_stream(transformer_state_t *xstate
if (b.out_pos == BUFSIZ) {
nwrote = transformer_write(xstate, b.out, b.out_pos);
if (nwrote == (ssize_t)-1) {
if (nwrote == -ENOSPC) {
ret = XZ_BUF_FULL;
goto out;
}
if (nwrote < 0) {
ret = XZ_DATA_ERROR;
bb_error_msg_and_err("write error (errno: %d)", errno);
}
@ -89,7 +93,11 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_xz_stream(transformer_state_t *xstate
#endif
nwrote = transformer_write(xstate, b.out, b.out_pos);
if (nwrote == (ssize_t)-1) {
if (nwrote == -ENOSPC) {
ret = XZ_BUF_FULL;
goto out;
}
if (nwrote < 0) {
ret = XZ_DATA_ERROR;
bb_error_msg_and_err("write error (errno: %d)", errno);
}
@ -99,24 +107,20 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_xz_stream(transformer_state_t *xstate
case XZ_STREAM_END:
ret = XZ_OK;
goto out;
case XZ_MEM_ERROR:
bb_error_msg_and_err("memory allocation error");
case XZ_MEMLIMIT_ERROR:
bb_error_msg_and_err("memory usage limit error");
case XZ_FORMAT_ERROR:
bb_error_msg_and_err("not a .xz file");
case XZ_OPTIONS_ERROR:
bb_error_msg_and_err("unsupported XZ header option");
case XZ_DATA_ERROR:
bb_error_msg_and_err("corrupted archive");
case XZ_BUF_ERROR:
bb_error_msg_and_err("corrupted buffer");
case XZ_BUF_FULL:
break;
default:
bb_error_msg_and_err("XZ decompression bug!");
}
@ -127,5 +131,10 @@ err:
xz_dec_end(s);
free(in);
free(out);
return (ret == XZ_OK)?n:-ret;
if (ret == XZ_OK)
return n;
else if (ret == XZ_BUF_FULL)
return xstate->mem_output_size_max;
else
return -ret;
}

View File

@ -33,20 +33,14 @@ ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf
if (xstate->mem_output_size_max != 0) {
size_t pos = xstate->mem_output_size;
size_t size;
size = (xstate->mem_output_size += bufsize);
if (size > xstate->mem_output_size_max) {
free(xstate->mem_output_buf);
xstate->mem_output_buf = NULL;
bb_perror_msg("buffer %u too small", (unsigned)xstate->mem_output_size_max);
nwrote = -1;
goto ret;
}
xstate->mem_output_buf = xrealloc(xstate->mem_output_buf, size + 1);
memcpy(xstate->mem_output_buf + pos, buf, bufsize);
xstate->mem_output_buf[size] = '\0';
nwrote = bufsize;
if ((pos + bufsize) > xstate->mem_output_size_max) {
bufsize = xstate->mem_output_size_max - pos;
// Use ENOSPC as an indicator that our buffer is full
nwrote = -ENOSPC;
}
memcpy(xstate->mem_output_buf + pos, buf, bufsize);
xstate->mem_output_size += bufsize;
} else {
nwrote = full_write(xstate->dst_fd, buf, (unsigned)bufsize);
if (nwrote != (ssize_t)bufsize) {
@ -59,15 +53,6 @@ ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf
return nwrote;
}
ssize_t FAST_FUNC xtransformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize)
{
ssize_t nwrote = transformer_write(xstate, buf, bufsize);
if (nwrote != (ssize_t)bufsize) {
xfunc_die();
}
return nwrote;
}
void check_errors_in_children(int signo)
{
int status;

View File

@ -125,7 +125,8 @@ enum xz_ret {
XZ_FORMAT_ERROR,
XZ_OPTIONS_ERROR,
XZ_DATA_ERROR,
XZ_BUF_ERROR
XZ_BUF_ERROR,
XZ_BUF_FULL
};
/**

View File

@ -661,7 +661,7 @@ try_iso:
p_iso = iso9660_open_ext(src_iso, iso_extension_mask);
if (p_iso == NULL) {
uprintf("Unable to open '%s' as an ISO image.\n", src_iso);
uprintf("'%s' doesn't look like an ISO image\n", src_iso);
r = 1;
goto out;
}

View File

@ -263,7 +263,7 @@ static bool
check_pvd (const iso9660_pvd_t *p_pvd, cdio_log_level_t log_level)
{
if ( ISO_VD_PRIMARY != from_711(p_pvd->type) ) {
cdio_log (log_level, "unexpected PVD type %d", p_pvd->type);
// cdio_log (log_level, "unexpected PVD type %d", p_pvd->type);
return false;
}
@ -442,7 +442,7 @@ iso9660_ifs_read_pvd_loglevel (const iso9660_t *p_iso,
cdio_log_level_t log_level)
{
if (0 == iso9660_iso_seek_read (p_iso, p_pvd, ISO_PVD_SECTOR, 1)) {
cdio_log ( log_level, "error reading PVD sector (%d)", ISO_PVD_SECTOR );
// cdio_log ( log_level, "error reading PVD sector (%d)", ISO_PVD_SECTOR );
return false;
}
return check_pvd(p_pvd, log_level);

View File

@ -981,11 +981,14 @@ DWORD WINAPI ISOScanThread(LPVOID param)
SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0);
PrintInfoDebug(0, MSG_203);
safe_free(image_path);
PrintStatus(0, MSG_086);
SetMBRProps();
goto out;
}
if (iso_report.is_bootable_img) {
uprintf("Using bootable %s image: '%s'", iso_report.is_vhd?"VHD":"disk", image_path);
uprintf("'%s' is a %sbootable %s image", image_path,
(iso_report.compression_type != BLED_COMPRESSION_NONE)?"compressed ":"", iso_report.is_vhd?"VHD":"disk");
selection_default = DT_IMG;
} else {
DisplayISOProps();

View File

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.614"
CAPTION "Rufus 2.0.615"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.0.614"
CAPTION "Rufus 2.0.615"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
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 2.0.614"
CAPTION "Rufus 2.0.615"
FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
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 2.0.614"
CAPTION "Rufus 2.0.615"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
@ -671,8 +671,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,614,0
PRODUCTVERSION 2,0,614,0
FILEVERSION 2,0,615,0
PRODUCTVERSION 2,0,615,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -689,13 +689,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.0.614"
VALUE "FileVersion", "2.0.615"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.0.614"
VALUE "ProductVersion", "2.0.615"
END
END
BLOCK "VarFileInfo"

View File

@ -754,8 +754,15 @@ error:
BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue)
{
SetLGP_Params params = {bRestore, bExistingKey, szPath, szPolicy, dwValue};
HANDLE thread_id = CreateThread(NULL, 0, SetLGPThread, (LPVOID)&params, 0, NULL);
DWORD r = FALSE;
HANDLE thread_id;
if (ReadSettingBool(SETTING_DISABLE_LGP)) {
uprintf("LPG handling disabled, per settings");
return FALSE;
}
thread_id = CreateThread(NULL, 0, SetLGPThread, (LPVOID)&params, 0, NULL);
if (thread_id == NULL) {
uprintf("SetLGP: Unable to start thread");
return FALSE;

View File

@ -224,7 +224,7 @@ typedef struct {
bled_compression_type type;
} comp_assoc;
static comp_assoc blah[] = {
static comp_assoc file_assoc[] = {
{ ".xz", BLED_COMPRESSION_XZ },
{ ".gz", BLED_COMPRESSION_GZIP },
{ ".lzma", BLED_COMPRESSION_LZMA },
@ -233,11 +233,14 @@ static comp_assoc blah[] = {
};
// For now we consider that an image that matches a known extension is bootable
// TODO: uncompress header and check for bootable flag
#define MBR_SIZE 512 // Might need to review this once we see bootable 4k systems
BOOL IsCompressedBootableImage(const char* path)
{
char* p;
char *p;
unsigned char *buf = NULL;
int i;
BOOL r = FALSE;
int64_t dc;
iso_report.compression_type = BLED_COMPRESSION_NONE;
for (p = (char*)&path[strlen(path)-1]; (*p != '.') && (p != path); p--);
@ -245,10 +248,23 @@ BOOL IsCompressedBootableImage(const char* path)
if (p == path)
return FALSE;
for (i = 0; i<ARRAYSIZE(blah); i++) {
if (strcmp(p, blah[i].ext) == 0) {
iso_report.compression_type = blah[i].type;
return TRUE;
for (i = 0; i<ARRAYSIZE(file_assoc); i++) {
if (strcmp(p, file_assoc[i].ext) == 0) {
iso_report.compression_type = file_assoc[i].type;
buf = malloc(MBR_SIZE);
if (buf == NULL)
return FALSE;
FormatStatus = 0;
bled_init(_uprintf, NULL, &FormatStatus);
dc = bled_uncompress_to_buffer(path, (char*)buf, MBR_SIZE, file_assoc[i].type);
bled_exit();
if (dc != MBR_SIZE) {
free(buf);
return FALSE;
}
r = (buf[0x1FE] == 0x55) && (buf[0x1FF] == 0xAA);
free(buf);
return r;
}
}