diff --git a/src/bled/.msvc/bled.vcxproj b/src/bled/.msvc/bled.vcxproj index 4fa303d0..0cc0e286 100644 --- a/src/bled/.msvc/bled.vcxproj +++ b/src/bled/.msvc/bled.vcxproj @@ -29,6 +29,7 @@ + diff --git a/src/bled/.msvc/bled.vcxproj.filters b/src/bled/.msvc/bled.vcxproj.filters index 26bfc876..5aae9f16 100644 --- a/src/bled/.msvc/bled.vcxproj.filters +++ b/src/bled/.msvc/bled.vcxproj.filters @@ -81,6 +81,9 @@ Source Files + + Source Files + diff --git a/src/bled/.msvc/bled_sources b/src/bled/.msvc/bled_sources index 36cb75fe..1ae0c441 100644 --- a/src/bled/.msvc/bled_sources +++ b/src/bled/.msvc/bled_sources @@ -14,7 +14,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \ $(SDK_LIB_PATH)\user32.lib SOURCES=bled.c crc32.c data_align.c data_extract_all.c data_skip.c decompress_bunzip2.c \ - decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c \ + decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c decompress_unzip.c \ filter_accept_all.c filter_accept_list.c filter_accept_reject_list.c find_list_entry.c \ header_list.c header_skip.c header_verbose_list.c init_handle.c open_transformer.c \ seek_by_jump.c seek_by_read.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c diff --git a/src/bled/Makefile.am b/src/bled/Makefile.am index b0e5c984..cc6a6fe8 100644 --- a/src/bled/Makefile.am +++ b/src/bled/Makefile.am @@ -1,7 +1,7 @@ noinst_LIBRARIES = libbled.a libbled_a_SOURCES = bled.c crc32.c data_align.c data_extract_all.c data_skip.c decompress_bunzip2.c \ - decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c \ + decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c decompress_unzip.c \ filter_accept_all.c filter_accept_list.c filter_accept_reject_list.c find_list_entry.c \ header_list.c header_skip.c header_verbose_list.c init_handle.c open_transformer.c \ seek_by_jump.c seek_by_read.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c diff --git a/src/bled/Makefile.in b/src/bled/Makefile.in index 02303fda..c65a2042 100644 --- a/src/bled/Makefile.in +++ b/src/bled/Makefile.in @@ -102,6 +102,7 @@ am_libbled_a_OBJECTS = libbled_a-bled.$(OBJEXT) \ libbled_a-decompress_uncompress.$(OBJEXT) \ libbled_a-decompress_unlzma.$(OBJEXT) \ libbled_a-decompress_unxz.$(OBJEXT) \ + libbled_a-decompress_unzip.$(OBJEXT) \ libbled_a-filter_accept_all.$(OBJEXT) \ libbled_a-filter_accept_list.$(OBJEXT) \ libbled_a-filter_accept_reject_list.$(OBJEXT) \ @@ -264,7 +265,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LIBRARIES = libbled.a libbled_a_SOURCES = bled.c crc32.c data_align.c data_extract_all.c data_skip.c decompress_bunzip2.c \ - decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c \ + decompress_gunzip.c decompress_uncompress.c decompress_unlzma.c decompress_unxz.c decompress_unzip.c \ filter_accept_all.c filter_accept_list.c filter_accept_reject_list.c find_list_entry.c \ header_list.c header_skip.c header_verbose_list.c init_handle.c open_transformer.c \ seek_by_jump.c seek_by_read.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c @@ -385,6 +386,12 @@ libbled_a-decompress_unxz.o: decompress_unxz.c libbled_a-decompress_unxz.obj: decompress_unxz.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbled_a_CFLAGS) $(CFLAGS) -c -o libbled_a-decompress_unxz.obj `if test -f 'decompress_unxz.c'; then $(CYGPATH_W) 'decompress_unxz.c'; else $(CYGPATH_W) '$(srcdir)/decompress_unxz.c'; fi` +libbled_a-decompress_unzip.o: decompress_unzip.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbled_a_CFLAGS) $(CFLAGS) -c -o libbled_a-decompress_unzip.o `test -f 'decompress_unzip.c' || echo '$(srcdir)/'`decompress_unzip.c + +libbled_a-decompress_unzip.obj: decompress_unzip.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbled_a_CFLAGS) $(CFLAGS) -c -o libbled_a-decompress_unzip.obj `if test -f 'decompress_unzip.c'; then $(CYGPATH_W) 'decompress_unzip.c'; else $(CYGPATH_W) '$(srcdir)/decompress_unzip.c'; fi` + libbled_a-filter_accept_all.o: filter_accept_all.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libbled_a_CFLAGS) $(CFLAGS) -c -o libbled_a-filter_accept_all.o `test -f 'filter_accept_all.c' || echo '$(srcdir)/'`filter_accept_all.c diff --git a/src/bled/bb_archive.h b/src/bled/bb_archive.h index ac30cfb1..132a4baa 100644 --- a/src/bled/bb_archive.h +++ b/src/bled/bb_archive.h @@ -184,6 +184,7 @@ char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_tar_xz(archive_handle_t *archive_handle) FAST_FUNC; void seek_by_jump(int fd, off_t amount) FAST_FUNC; void seek_by_read(int fd, off_t amount) FAST_FUNC; @@ -225,9 +226,11 @@ 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; +IF_DESKTOP(long long) int unpack_zip_stream(transformer_state_t *xstate) FAST_FUNC; IF_DESKTOP(long long) int unpack_Z_stream(transformer_state_t *xstate) FAST_FUNC; IF_DESKTOP(long long) int unpack_gz_stream(transformer_state_t *xstate) FAST_FUNC; IF_DESKTOP(long long) int unpack_bz2_stream(transformer_state_t *xstate) FAST_FUNC; diff --git a/src/bled/bled.c b/src/bled/bled.c index 72a0b40d..98273a50 100644 --- a/src/bled/bled.c +++ b/src/bled/bled.c @@ -34,7 +34,7 @@ static long long int unpack_none(transformer_state_t *xstate) unpacker_t unpacker[BLED_COMPRESSION_MAX] = { unpack_none, - unpack_none, + unpack_zip_stream, unpack_Z_stream, unpack_gz_stream, unpack_lzma_stream, diff --git a/src/bled/decompress_unxz.c b/src/bled/decompress_unxz.c index ecc88155..cf4cd572 100644 --- a/src/bled/decompress_unxz.c +++ b/src/bled/decompress_unxz.c @@ -1,5 +1,5 @@ /* - * unxz implementation for busybox + * unxz implementation for Bled/busybox * * Copyright © 2014-2015 Pete Batard * Based on xz-embedded © Lasse Collin - Public Domain diff --git a/src/bled/decompress_unzip.c b/src/bled/decompress_unzip.c new file mode 100644 index 00000000..d3ce61dd --- /dev/null +++ b/src/bled/decompress_unzip.c @@ -0,0 +1,340 @@ +/* + * unzip implementation for Bled/busybox + * + * Copyright © 2015 Pete Batard + * Based on mini unzip implementation for busybox © Ed Clark + * Loosely based on original busybox unzip applet © Laurence Anderson. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +/* The following are not currently supported: + * - Store (uncompressed) + * - Zip64 + */ + +#include "libbb.h" +#include "bb_archive.h" + +enum { +#if BB_BIG_ENDIAN + ZIP_FILEHEADER_MAGIC = 0x504b0304, + ZIP_CDF_MAGIC = 0x504b0102, /* central directory's file header */ + ZIP_CDE_MAGIC = 0x504b0506, /* "end of central directory" record */ + ZIP_DD_MAGIC = 0x504b0708, +#else + ZIP_FILEHEADER_MAGIC = 0x04034b50, + ZIP_CDF_MAGIC = 0x02014b50, + ZIP_CDE_MAGIC = 0x06054b50, + ZIP_DD_MAGIC = 0x08074b50, +#endif +}; + +#define ZIP_HEADER_LEN 26 + +PRAGMA_BEGIN_PACKED +typedef union { + uint8_t raw[ZIP_HEADER_LEN]; + struct { + uint16_t version; /* 0-1 */ + uint16_t zip_flags; /* 2-3 */ + uint16_t method; /* 4-5 */ + uint16_t modtime; /* 6-7 */ + uint16_t moddate; /* 8-9 */ + uint32_t crc32; /* 10-13 */ + uint32_t cmpsize; /* 14-17 */ + uint32_t ucmpsize; /* 18-21 */ + uint16_t filename_len; /* 22-23 */ + uint16_t extra_len; /* 24-25 */ + } PACKED formatted; +} PACKED zip_header_t; +PRAGMA_END_PACKED + +/* Check the offset of the last element, not the length. This leniency + * allows for poor packing, whereby the overall struct may be too long, + * even though the elements are all in the right place. + */ +struct BUG_zip_header_must_be_26_bytes { + char BUG_zip_header_must_be_26_bytes[ + offsetof(zip_header_t, formatted.extra_len) + 2 + == ZIP_HEADER_LEN ? 1 : -1]; +}; + +#define FIX_ENDIANNESS_ZIP(zip_header) do { \ + (zip_header).formatted.version = SWAP_LE16((zip_header).formatted.version ); \ + (zip_header).formatted.method = SWAP_LE16((zip_header).formatted.method ); \ + (zip_header).formatted.modtime = SWAP_LE16((zip_header).formatted.modtime ); \ + (zip_header).formatted.moddate = SWAP_LE16((zip_header).formatted.moddate ); \ + (zip_header).formatted.crc32 = SWAP_LE32((zip_header).formatted.crc32 ); \ + (zip_header).formatted.cmpsize = SWAP_LE32((zip_header).formatted.cmpsize ); \ + (zip_header).formatted.ucmpsize = SWAP_LE32((zip_header).formatted.ucmpsize ); \ + (zip_header).formatted.filename_len = SWAP_LE16((zip_header).formatted.filename_len); \ + (zip_header).formatted.extra_len = SWAP_LE16((zip_header).formatted.extra_len ); \ +} while (0) + +#define CDF_HEADER_LEN 42 + +PRAGMA_BEGIN_PACKED +typedef union { + uint8_t raw[CDF_HEADER_LEN]; + struct { + /* uint32_t signature; 50 4b 01 02 */ + uint16_t version_made_by; /* 0-1 */ + uint16_t version_needed; /* 2-3 */ + uint16_t cdf_flags; /* 4-5 */ + uint16_t method; /* 6-7 */ + uint16_t mtime; /* 8-9 */ + uint16_t mdate; /* 10-11 */ + uint32_t crc32; /* 12-15 */ + uint32_t cmpsize; /* 16-19 */ + uint32_t ucmpsize; /* 20-23 */ + uint16_t file_name_length; /* 24-25 */ + uint16_t extra_field_length; /* 26-27 */ + uint16_t file_comment_length; /* 28-29 */ + uint16_t disk_number_start; /* 30-31 */ + uint16_t internal_file_attributes; /* 32-33 */ + uint32_t external_file_attributes; /* 34-37 */ + uint32_t relative_offset_of_local_header; /* 38-41 */ + } PACKED formatted; +} cdf_header_t; +PRAGMA_END_PACKED + +struct BUG_cdf_header_must_be_42_bytes { + char BUG_cdf_header_must_be_42_bytes[ + offsetof(cdf_header_t, formatted.relative_offset_of_local_header) + 4 + == CDF_HEADER_LEN ? 1 : -1]; +}; + +#define FIX_ENDIANNESS_CDF(cdf_header) do { \ + (cdf_header).formatted.crc32 = SWAP_LE32((cdf_header).formatted.crc32 ); \ + (cdf_header).formatted.cmpsize = SWAP_LE32((cdf_header).formatted.cmpsize ); \ + (cdf_header).formatted.ucmpsize = SWAP_LE32((cdf_header).formatted.ucmpsize ); \ + (cdf_header).formatted.file_name_length = SWAP_LE16((cdf_header).formatted.file_name_length); \ + (cdf_header).formatted.extra_field_length = SWAP_LE16((cdf_header).formatted.extra_field_length); \ + (cdf_header).formatted.file_comment_length = SWAP_LE16((cdf_header).formatted.file_comment_length); \ + IF_DESKTOP( \ + (cdf_header).formatted.version_made_by = SWAP_LE16((cdf_header).formatted.version_made_by); \ + (cdf_header).formatted.external_file_attributes = SWAP_LE32((cdf_header).formatted.external_file_attributes); \ + ) \ +} while (0) + +#define CDE_HEADER_LEN 16 + +PRAGMA_BEGIN_PACKED +typedef union { + uint8_t raw[CDE_HEADER_LEN]; + struct { + /* uint32_t signature; 50 4b 05 06 */ + uint16_t this_disk_no; + uint16_t disk_with_cdf_no; + uint16_t cdf_entries_on_this_disk; + uint16_t cdf_entries_total; + uint32_t cdf_size; + uint32_t cdf_offset; + /* uint16_t file_comment_length; */ + /* .ZIP file comment (variable size) */ + } PACKED formatted; +} cde_header_t; +PRAGMA_END_PACKED + +struct BUG_cde_header_must_be_16_bytes { + char BUG_cde_header_must_be_16_bytes[ + sizeof(cde_header_t) == CDE_HEADER_LEN ? 1 : -1]; +}; + +#define FIX_ENDIANNESS_CDE(cde_header) do { \ + (cde_header).formatted.cdf_offset = SWAP_LE32((cde_header).formatted.cdf_offset); \ +} while (0) + + +#if ENABLE_DESKTOP + +/* Seen in the wild: + * Self-extracting PRO2K3XP_32.exe contains 19078464 byte zip archive, + * where CDE was nearly 48 kbytes before EOF. + * (Surprisingly, it also apparently has *another* CDE structure + * closer to the end, with bogus cdf_offset). + * To make extraction work, bumped PEEK_FROM_END from 16k to 64k. + */ +#define PEEK_FROM_END (64*1024) + +/* This value means that we failed to find CDF */ +#define BAD_CDF_OFFSET ((uint32_t)0xffffffff) + +/* NB: does not preserve file position! */ +static uint32_t find_cdf_offset(void) +{ + cde_header_t cde_header; + unsigned char *p; + off_t end; + unsigned char *buf = xzalloc(PEEK_FROM_END); + + end = xlseek(zip_fd, 0, SEEK_END); + end -= PEEK_FROM_END; + if (end < 0) + end = 0; + xlseek(zip_fd, end, SEEK_SET); + full_read(zip_fd, buf, PEEK_FROM_END); + + cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + p = buf; + while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { + if (*p != 'P') { + p++; + continue; + } + if (*++p != 'K') + continue; + if (*++p != 5) + continue; + if (*++p != 6) + continue; + /* we found CDE! */ + memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN); + FIX_ENDIANNESS_CDE(cde_header); + /* + * I've seen .ZIP files with seemingly valid CDEs + * where cdf_offset points past EOF - ?? + * Ignore such CDEs: + */ + if (cde_header.formatted.cdf_offset < end + (p - buf)) + break; + cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + } + free(buf); + return cde_header.formatted.cdf_offset; +}; + +static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) +{ + off_t org; + + org = xlseek(zip_fd, 0, SEEK_CUR); + + if (!cdf_offset) + cdf_offset = find_cdf_offset(); + + if (cdf_offset != BAD_CDF_OFFSET) { + xlseek(zip_fd, cdf_offset + 4, SEEK_SET); + xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); + FIX_ENDIANNESS_CDF(*cdf_ptr); + cdf_offset += 4 + CDF_HEADER_LEN + + cdf_ptr->formatted.file_name_length + + cdf_ptr->formatted.extra_field_length + + cdf_ptr->formatted.file_comment_length; + } + + xlseek(zip_fd, org, SEEK_SET); + return cdf_offset; +}; +#endif + +static void unzip_skip(int zip_fd, off_t skip) +{ + if (skip != 0) + if (lseek(zip_fd, skip, SEEK_CUR) == (off_t)-1) + bb_copyfd_exact_size(zip_fd, -1, skip); +} + +IF_DESKTOP(long long) int FAST_FUNC unpack_zip_stream(transformer_state_t *xstate) +{ + IF_DESKTOP(long long) int n = -EFAULT; + zip_header_t zip_header; + char *filename = NULL; +#if ENABLE_DESKTOP + uint32_t cdf_offset = 0; +#endif + + while (1) { + uint32_t magic; + /* Check magic number */ + safe_read(xstate->src_fd, &magic, 4); + /* Central directory? It's at the end, so exit */ + if (magic == ZIP_CDF_MAGIC) + break; +#if ENABLE_DESKTOP + /* Data descriptor? It was a streaming file, go on */ + if (magic == ZIP_DD_MAGIC) { + /* skip over duplicate crc32, cmpsize and ucmpsize */ + unzip_skip(xstate->src_fd, 3 * 4); + continue; + } +#endif + if (magic != ZIP_FILEHEADER_MAGIC) + bb_error_msg_and_err("invalid zip magic %08X", (int)magic); + + /* Read the file header */ + safe_read(xstate->src_fd, zip_header.raw, ZIP_HEADER_LEN); + FIX_ENDIANNESS_ZIP(zip_header); + if (zip_header.formatted.method != 8) { + bb_error_msg_and_err("zip method method %d is not supported", zip_header.formatted.method); + } +#if !ENABLE_DESKTOP + if (zip_header.formatted.zip_flags & SWAP_LE16(0x0009)) { + bb_error_msg_and_err("zip flags 1 and 8 are not supported"); + } +#else + if (zip_header.formatted.zip_flags & SWAP_LE16(0x0001)) { + /* 0x0001 - encrypted */ + bb_error_msg_and_die("zip flag 1 (encryption) is not supported"); + } + + if (cdf_offset != BAD_CDF_OFFSET) { + cdf_header_t cdf_header; + cdf_offset = read_next_cdf(cdf_offset, &cdf_header); + /* + * Note: cdf_offset can become BAD_CDF_OFFSET after the above call. + */ + if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) { + /* 0x0008 - streaming. [u]cmpsize can be reliably gotten + * only from Central Directory. See unzip_doc.txt + */ + zip_header.formatted.crc32 = cdf_header.formatted.crc32; + zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize; + zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize; + } + if ((cdf_header.formatted.version_made_by >> 8) == 3) { + /* This archive is created on Unix */ + dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16); + } + } + if (cdf_offset == BAD_CDF_OFFSET + && (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) + ) { + /* If it's a streaming zip, we _require_ CDF */ + bb_error_msg_and_die("can't find file table"); + } +#endif + + /* Read filename */ + filename = xzalloc(zip_header.formatted.filename_len + 1); + safe_read(xstate->src_fd, filename, zip_header.formatted.filename_len); + bb_printf("processing archive file '%s'", filename); + free(filename); + + /* Skip extra header bytes */ + unzip_skip(xstate->src_fd, zip_header.formatted.extra_len); + + /* Method 8 - inflate */ + xstate->bytes_in = zip_header.formatted.cmpsize; + n = inflate_unzip(xstate); + + /* Validate decompression */ + if (n >= 0) { + if (zip_header.formatted.ucmpsize != xstate->bytes_out) + bb_error_msg_and_err("bad length"); + else if (zip_header.formatted.crc32 != (xstate->crc32 ^ 0xffffffffL)) + bb_error_msg_and_err("crc error"); + } else if (n != -ENOSPC) { + bb_error_msg_and_err("inflate error"); + } + } + +err: + if (n > 0) + return xstate->bytes_out; + else if (n == -ENOSPC) + return xstate->mem_output_size_max; + else + return n; +} diff --git a/src/bled/open_transformer.c b/src/bled/open_transformer.c index 11dd66d9..3f38983a 100644 --- a/src/bled/open_transformer.c +++ b/src/bled/open_transformer.c @@ -53,6 +53,15 @@ 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; @@ -169,6 +178,13 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) goto found_magic; } + if (ENABLE_FEATURE_SEAMLESS_Z + && magic.b16[0] == COMPRESS_MAGIC + ) { + xstate->xformer = unpack_Z_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";) + goto found_magic; + } if (ENABLE_FEATURE_SEAMLESS_BZ2 && magic.b16[0] == BZIP2_MAGIC ) { diff --git a/src/bled/platform.h b/src/bled/platform.h index 5dad0cb6..7345703a 100644 --- a/src/bled/platform.h +++ b/src/bled/platform.h @@ -266,6 +266,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING; * a lvalue. This makes it more likely to not swap them by mistake */ #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) +# define BB_UNALIGNED_MEMACCESS_OK 1 # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) # define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp)) # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) @@ -274,6 +275,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING; # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v)) /* #elif ... - add your favorite arch today! */ #else +# define BB_UNALIGNED_MEMACCESS_OK 0 /* performs reasonably well (gcc usually inlines memcpy here) */ # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) # define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) @@ -411,10 +413,12 @@ typedef unsigned smalluint; #define HAVE_DPRINTF 1 #define HAVE_MEMRCHR 1 #define HAVE_MKDTEMP 1 +#define HAVE_TTYNAME_R 1 #define HAVE_PTSNAME_R 1 #define HAVE_SETBIT 1 #define HAVE_SIGHANDLER_T 1 #define HAVE_STPCPY 1 +#define HAVE_MEMPCPY 1 #define HAVE_STRCASESTR 1 #define HAVE_STRCHRNUL 1 #define HAVE_STRSEP 1 @@ -524,6 +528,8 @@ typedef unsigned smalluint; #endif #if defined(__FreeBSD__) +/* users say mempcpy is not present in FreeBSD 9.x */ +# undef HAVE_MEMPCPY # undef HAVE_CLEARENV # undef HAVE_FDATASYNC # undef HAVE_MNTENT_H @@ -548,9 +554,17 @@ typedef unsigned smalluint; #endif #if defined(ANDROID) || defined(__ANDROID__) -# undef HAVE_DPRINTF -# undef HAVE_GETLINE -# undef HAVE_STPCPY +# if __ANDROID_API__ < 8 +# undef HAVE_DPRINTF +# else +# define dprintf fdprintf +# endif +# if __ANDROID_API__ < 21 +# undef HAVE_TTYNAME_R +# undef HAVE_GETLINE +# undef HAVE_STPCPY +# endif +# undef HAVE_MEMPCPY # undef HAVE_STRCHRNUL # undef HAVE_STRVERSCMP # undef HAVE_UNLOCKED_LINE_OPS @@ -574,6 +588,11 @@ extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC; extern char *mkdtemp(char *template) FAST_FUNC; #endif +#ifndef HAVE_TTYNAME_R +#define ttyname_r bb_ttyname_r +extern int ttyname_r(int fd, char *buf, size_t buflen); +#endif + #ifndef HAVE_SETBIT # define setbit(a, b) ((a)[(b) >> 3] |= 1 << ((b) & 7)) # define clrbit(a, b) ((a)[(b) >> 3] &= ~(1 << ((b) & 7))) @@ -587,6 +606,18 @@ typedef void (*sighandler_t)(int); extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; #endif +#ifndef HAVE_MEMPCPY +#include +/* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have + * mempcpy(), avoid colliding with it: + */ +#define mempcpy bb__mempcpy +static ALWAYS_INLINE void *mempcpy(void *dest, const void *src, size_t len) +{ + return memcpy(dest, src, len) + len; +} +#endif + #ifndef HAVE_STRCASESTR extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC; #endif diff --git a/src/rufus.c b/src/rufus.c index 5128820f..0410961d 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -1022,6 +1022,7 @@ DWORD WINAPI ISOScanThread(LPVOID param) (iso_report.compression_type != BLED_COMPRESSION_NONE)?"compressed ":"", iso_report.is_vhd?"VHD":"disk"); selection_default = DT_IMG; } else { + selection_default = DT_ISO; DisplayISOProps(); } if ( (!iso_report.has_bootmgr) && (!HAS_SYSLINUX(iso_report)) && (!IS_WINPE(iso_report.winpe)) && (!IS_GRUB(iso_report)) @@ -1960,7 +1961,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA int nDeviceIndex, fs, bt, i, nWidth, nHeight, nb_devices, selected_language, offset; char tmp[128]; loc_cmd* lcmd = NULL; - EXT_DECL(img_ext, NULL, __VA_GROUP__("*.img;*.vhd;*.gz;*.bzip2;*.xz;*.lzma;*.Z"), __VA_GROUP__(lmprintf(MSG_095))); + EXT_DECL(img_ext, NULL, __VA_GROUP__("*.img;*.vhd;*.gz;*.bzip2;*.xz;*.lzma;*.Z;*.zip"), __VA_GROUP__(lmprintf(MSG_095))); EXT_DECL(iso_ext, NULL, __VA_GROUP__("*.iso"), __VA_GROUP__(lmprintf(MSG_036))); LPNMTOOLBAR lpnmtb; @@ -2288,8 +2289,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; } } - selection_default = DT_ISO; - CreateTooltip(hSelectISO, image_path, -1); FormatStatus = 0; if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, NULL) == NULL) { uprintf("Unable to start ISO scanning thread"); diff --git a/src/rufus.rc b/src/rufus.rc index d955d7a8..53210cb9 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -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.3.676" +CAPTION "Rufus 2.3.677" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -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.3.676" +CAPTION "Rufus 2.3.677" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -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.3.676" +CAPTION "Rufus 2.3.677" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -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.3.676" +CAPTION "Rufus 2.3.677" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -671,8 +671,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,676,0 - PRODUCTVERSION 2,3,676,0 + FILEVERSION 2,3,677,0 + PRODUCTVERSION 2,3,677,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.3.676" + VALUE "FileVersion", "2.3.677" 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.3.676" + VALUE "ProductVersion", "2.3.677" END END BLOCK "VarFileInfo" diff --git a/src/vhd.c b/src/vhd.c index c352b3dc..e0693dc7 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -225,11 +225,12 @@ typedef struct { } comp_assoc; static comp_assoc file_assoc[] = { - { ".xz", BLED_COMPRESSION_XZ }, + { ".zip", BLED_COMPRESSION_ZIP }, + { ".Z", BLED_COMPRESSION_LZW }, { ".gz", BLED_COMPRESSION_GZIP }, { ".lzma", BLED_COMPRESSION_LZMA }, { ".bz2", BLED_COMPRESSION_BZIP2 }, - { ".Z", BLED_COMPRESSION_LZW }, + { ".xz", BLED_COMPRESSION_XZ }, }; // For now we consider that an image that matches a known extension is bootable