mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[cmp] further ZIP64 and overall Bled improvements
* The ZIP64 extra record may not be the first one, so add processing for all extra zip records. * Also add extra sanity checks to try to appease Coverity and properly detect short writes.
This commit is contained in:
parent
f233191d54
commit
c717c7789b
5 changed files with 102 additions and 47 deletions
|
@ -1197,9 +1197,13 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate)
|
||||||
if (header.formatted.flags & 0x18) {
|
if (header.formatted.flags & 0x18) {
|
||||||
while (1) {
|
while (1) {
|
||||||
do {
|
do {
|
||||||
|
/* None of our buffers should be larger than BB_BUFSIZE */
|
||||||
|
if (bytebuffer_offset > BB_BUFSIZE) {
|
||||||
|
bb_error_msg("buffer overflow");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (!top_up(PASS_STATE 1))
|
if (!top_up(PASS_STATE 1))
|
||||||
return 0;
|
return 0;
|
||||||
// coverity[tainted_data]
|
|
||||||
} while (bytebuffer[bytebuffer_offset++] != 0);
|
} while (bytebuffer[bytebuffer_offset++] != 0);
|
||||||
if ((header.formatted.flags & 0x18) != 0x18)
|
if ((header.formatted.flags & 0x18) != 0x18)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -140,6 +140,26 @@ do { if (BB_BIG_ENDIAN) { \
|
||||||
(cde).fmt.cdf_offset = SWAP_LE32((cde).fmt.cdf_offset); \
|
(cde).fmt.cdf_offset = SWAP_LE32((cde).fmt.cdf_offset); \
|
||||||
}} while (0)
|
}} while (0)
|
||||||
|
|
||||||
|
/* Extra records */
|
||||||
|
#define EXTRA_HEADER_LEN 4
|
||||||
|
|
||||||
|
PRAGMA_BEGIN_PACKED
|
||||||
|
typedef union {
|
||||||
|
uint8_t raw[EXTRA_HEADER_LEN];
|
||||||
|
struct {
|
||||||
|
uint16_t tag;
|
||||||
|
uint16_t length;
|
||||||
|
/* extra record follows */
|
||||||
|
} fmt PACKED;
|
||||||
|
} extra_header_t;
|
||||||
|
PRAGMA_END_PACKED
|
||||||
|
|
||||||
|
#define FIX_ENDIANNESS_EXTRA(ext) \
|
||||||
|
do { if (BB_BIG_ENDIAN) { \
|
||||||
|
(ext).fmt.tag = SWAP_LE16((ext).fmt.tag); \
|
||||||
|
(ext).fmt.length = SWAP_LE32((ext).fmt.length); \
|
||||||
|
}} while (0)
|
||||||
|
|
||||||
/* ZIP64 records */
|
/* ZIP64 records */
|
||||||
#define ZIP64_LEN 20
|
#define ZIP64_LEN 20
|
||||||
|
|
||||||
|
@ -147,8 +167,8 @@ PRAGMA_BEGIN_PACKED
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t raw[ZIP64_LEN];
|
uint8_t raw[ZIP64_LEN];
|
||||||
struct {
|
struct {
|
||||||
/* uint16_t signature; 00 01 */
|
/* uint16_t tag; 00 01 */
|
||||||
uint16_t signature;
|
uint16_t tag;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint64_t ucmpsize PACKED;
|
uint64_t ucmpsize PACKED;
|
||||||
uint64_t cmpsize PACKED;
|
uint64_t cmpsize PACKED;
|
||||||
|
@ -158,8 +178,6 @@ PRAGMA_END_PACKED
|
||||||
|
|
||||||
#define FIX_ENDIANNESS_ZIP64(z64) \
|
#define FIX_ENDIANNESS_ZIP64(z64) \
|
||||||
do { if (BB_BIG_ENDIAN) { \
|
do { if (BB_BIG_ENDIAN) { \
|
||||||
(z64).fmt.signature = SWAP_LE16((z64).fmt.signature); \
|
|
||||||
(z64).fmt.length = SWAP_LE32((z64).fmt.length); \
|
|
||||||
(z64).fmt.cmpsize = SWAP_LE64((z64).fmt.cmpsize); \
|
(z64).fmt.cmpsize = SWAP_LE64((z64).fmt.cmpsize); \
|
||||||
(z64).fmt.ucmpsize = SWAP_LE64((z64).fmt.ucmpsize); \
|
(z64).fmt.ucmpsize = SWAP_LE64((z64).fmt.ucmpsize); \
|
||||||
}} while (0)
|
}} while (0)
|
||||||
|
@ -191,25 +209,22 @@ do { if (BB_BIG_ENDIAN) { \
|
||||||
(c64).fmt.cdf_offset = SWAP_LE64((c64).fmt.cdf_offset); \
|
(c64).fmt.cdf_offset = SWAP_LE64((c64).fmt.cdf_offset); \
|
||||||
}} while (0)
|
}} while (0)
|
||||||
|
|
||||||
struct BUG {
|
inline void BUG() {
|
||||||
/* Check the offset of the last element, not the length. This leniency
|
/* Check the offset of the last element, not the length. This leniency
|
||||||
* allows for poor packing, whereby the overall struct may be too long,
|
* allows for poor packing, whereby the overall struct may be too long,
|
||||||
* even though the elements are all in the right place.
|
* even though the elements are all in the right place.
|
||||||
*/
|
*/
|
||||||
char BUG_zip_header_must_be_26_bytes[
|
BUILD_BUG_ON(
|
||||||
offsetof(zip_header_t, fmt.extra_len) + 2
|
offsetof(zip_header_t, fmt.extra_len) + 2
|
||||||
== ZIP_HEADER_LEN ? 1 : -1];
|
!= ZIP_HEADER_LEN);
|
||||||
char BUG_cdf_header_must_be_42_bytes[
|
BUILD_BUG_ON(
|
||||||
offsetof(cdf_header_t, fmt.relative_offset_of_local_header) + 4
|
offsetof(cdf_header_t, fmt.relative_offset_of_local_header) + 4
|
||||||
== CDF_HEADER_LEN ? 1 : -1];
|
!= CDF_HEADER_LEN);
|
||||||
char BUG_cde_must_be_16_bytes[
|
BUILD_BUG_ON(sizeof(cde_t) != CDE_LEN);
|
||||||
sizeof(cde_t) == CDE_LEN ? 1 : -1];
|
BUILD_BUG_ON(sizeof(extra_header_t) != EXTRA_HEADER_LEN);
|
||||||
char BUG_zip64_must_be_20_bytes[
|
BUILD_BUG_ON(sizeof(zip64_t) != ZIP64_LEN);
|
||||||
sizeof(zip64_t) == ZIP64_LEN ? 1 : -1];
|
BUILD_BUG_ON(sizeof(cde64_t) != CDE64_LEN);
|
||||||
char BUG_cde64_must_be_52_bytes[
|
}
|
||||||
sizeof(cde64_t) == CDE64_LEN ? 1 : -1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* This value means that we failed to find CDF */
|
/* This value means that we failed to find CDF */
|
||||||
#define BAD_CDF_OFFSET ((uint32_t)0xffffffff)
|
#define BAD_CDF_OFFSET ((uint32_t)0xffffffff)
|
||||||
|
@ -381,6 +396,8 @@ static void unzip_skip(int fd, off_t skip)
|
||||||
static void unzip_set_xstate(transformer_state_t* xstate, zip_header_t* zip)
|
static void unzip_set_xstate(transformer_state_t* xstate, zip_header_t* zip)
|
||||||
{
|
{
|
||||||
uint8_t* buf = NULL;
|
uint8_t* buf = NULL;
|
||||||
|
uint16_t i = 0;
|
||||||
|
extra_header_t* extra;
|
||||||
zip64_t* zip64;
|
zip64_t* zip64;
|
||||||
|
|
||||||
/* Set the default sizes for non ZIP64 content */
|
/* Set the default sizes for non ZIP64 content */
|
||||||
|
@ -396,20 +413,39 @@ static void unzip_set_xstate(transformer_state_t* xstate, zip_header_t* zip)
|
||||||
xstate->dst_name[zip->fmt.filename_len] = 0;
|
xstate->dst_name[zip->fmt.filename_len] = 0;
|
||||||
|
|
||||||
/* Read the extra data */
|
/* Read the extra data */
|
||||||
if (zip->fmt.extra_len != 0) {
|
if (zip->fmt.extra_len) {
|
||||||
|
dbg("Reading extra data");
|
||||||
buf = malloc(zip->fmt.extra_len);
|
buf = malloc(zip->fmt.extra_len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
xread(xstate->src_fd, buf, zip->fmt.extra_len);
|
xread(xstate->src_fd, buf, zip->fmt.extra_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the ZIP64 data */
|
/* Process the extra records */
|
||||||
zip64 = (zip64_t*)buf;
|
if (zip->fmt.extra_len < EXTRA_HEADER_LEN + 1)
|
||||||
FIX_ENDIANNESS_ZIP64(*zip64);
|
goto err;
|
||||||
if (zip->fmt.cmpsize == 0xffffffffL && zip->fmt.ucmpsize == 0xffffffffL &&
|
for (i = 0; i < zip->fmt.extra_len - EXTRA_HEADER_LEN; ) {
|
||||||
zip->fmt.extra_len >= sizeof(zip64_t) && zip64->fmt.signature == SWAP_LE16(0x0001)) {
|
extra = (extra_header_t*)&buf[i];
|
||||||
xstate->dst_size = zip64->fmt.ucmpsize;
|
FIX_ENDIANNESS_EXTRA(*extra);
|
||||||
xstate->bytes_in = zip64->fmt.cmpsize;
|
dbg(" tag:0x%04x len:%u",
|
||||||
|
(unsigned)extra->fmt.tag,
|
||||||
|
(unsigned)extra->fmt.length
|
||||||
|
);
|
||||||
|
i += EXTRA_HEADER_LEN + extra->fmt.length;
|
||||||
|
/* Process the ZIP64 data */
|
||||||
|
if (extra->fmt.tag == SWAP_LE16(0x0001)) {
|
||||||
|
zip64 = (zip64_t*)extra;
|
||||||
|
FIX_ENDIANNESS_ZIP64(*zip64);
|
||||||
|
if ((zip->fmt.cmpsize == 0xffffffffL || zip->fmt.ucmpsize == 0xffffffffL) &&
|
||||||
|
EXTRA_HEADER_LEN + zip64->fmt.length >= ZIP64_LEN) {
|
||||||
|
dbg("Actual cmpsize:0x%"OFF_FMT"x ucmpsize:0x%"OFF_FMT"x",
|
||||||
|
zip64->fmt.cmpsize,
|
||||||
|
zip64->fmt.ucmpsize
|
||||||
|
);
|
||||||
|
xstate->dst_size = zip64->fmt.ucmpsize;
|
||||||
|
xstate->bytes_in = zip64->fmt.cmpsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@ -448,7 +484,7 @@ unzip_extract(zip_header_t* zip, transformer_state_t* xstate)
|
||||||
* and will seek to the correct beginning of next file.
|
* and will seek to the correct beginning of next file.
|
||||||
*/
|
*/
|
||||||
xstate->bytes_out = unpack_bz2_stream(xstate);
|
xstate->bytes_out = unpack_bz2_stream(xstate);
|
||||||
if (xstate->bytes_out < 0)
|
if ((int64_t)xstate->bytes_out < 0)
|
||||||
bb_simple_error_msg_and_die("inflate error");
|
bb_simple_error_msg_and_die("inflate error");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -456,7 +492,7 @@ unzip_extract(zip_header_t* zip, transformer_state_t* xstate)
|
||||||
else if (zip->fmt.method == 14) {
|
else if (zip->fmt.method == 14) {
|
||||||
/* Not tested yet */
|
/* Not tested yet */
|
||||||
xstate->bytes_out = unpack_lzma_stream(xstate);
|
xstate->bytes_out = unpack_lzma_stream(xstate);
|
||||||
if (xstate->bytes_out < 0)
|
if ((int64_t)xstate->bytes_out < 0)
|
||||||
bb_simple_error_msg_and_die("inflate error");
|
bb_simple_error_msg_and_die("inflate error");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -464,7 +500,7 @@ unzip_extract(zip_header_t* zip, transformer_state_t* xstate)
|
||||||
else if (zip->fmt.method == 95) {
|
else if (zip->fmt.method == 95) {
|
||||||
/* Not tested yet */
|
/* Not tested yet */
|
||||||
xstate->bytes_out = unpack_xz_stream(xstate);
|
xstate->bytes_out = unpack_xz_stream(xstate);
|
||||||
if (xstate->bytes_out < 0)
|
if ((int64_t)xstate->bytes_out < 0)
|
||||||
bb_simple_error_msg_and_die("inflate error");
|
bb_simple_error_msg_and_die("inflate error");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -149,7 +149,6 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_vtsi_stream(transformer_state_t* xsta
|
||||||
buf = (uint8_t*)segment + footer.segment_num * sizeof(VTSI_SEGMENT);
|
buf = (uint8_t*)segment + footer.segment_num * sizeof(VTSI_SEGMENT);
|
||||||
|
|
||||||
lseek(src_fd, footer.segment_offset, SEEK_SET);
|
lseek(src_fd, footer.segment_offset, SEEK_SET);
|
||||||
/* coverity[tainted_data_argument] */
|
|
||||||
safe_read(src_fd, segment, footer.segment_num * sizeof(VTSI_SEGMENT));
|
safe_read(src_fd, segment, footer.segment_num * sizeof(VTSI_SEGMENT));
|
||||||
|
|
||||||
if (!check_vtsi_segment(&footer, segment))
|
if (!check_vtsi_segment(&footer, segment))
|
||||||
|
|
|
@ -39,24 +39,25 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#define BB_BUFSIZE 0x40000
|
#define BB_BUFSIZE 0x40000
|
||||||
|
#define ONE_TB 1099511627776ULL
|
||||||
|
|
||||||
#define ENABLE_DESKTOP 1
|
#define ENABLE_DESKTOP 1
|
||||||
#if ENABLE_DESKTOP
|
#if ENABLE_DESKTOP
|
||||||
#define IF_DESKTOP(x) x
|
#define IF_DESKTOP(x) x
|
||||||
#define IF_NOT_DESKTOP(x)
|
#define IF_NOT_DESKTOP(x)
|
||||||
#else
|
#else
|
||||||
#define IF_DESKTOP(x)
|
#define IF_DESKTOP(x)
|
||||||
#define IF_NOT_DESKTOP(x) x
|
#define IF_NOT_DESKTOP(x) x
|
||||||
#endif
|
#endif
|
||||||
#define IF_NOT_FEATURE_LZMA_FAST(x) x
|
#define IF_NOT_FEATURE_LZMA_FAST(x) x
|
||||||
#define ENABLE_FEATURE_UNZIP_CDF 1
|
#define ENABLE_FEATURE_UNZIP_CDF 1
|
||||||
#define ENABLE_FEATURE_UNZIP_BZIP2 1
|
#define ENABLE_FEATURE_UNZIP_BZIP2 1
|
||||||
#define ENABLE_FEATURE_UNZIP_LZMA 1
|
#define ENABLE_FEATURE_UNZIP_LZMA 1
|
||||||
#define ENABLE_FEATURE_UNZIP_XZ 1
|
#define ENABLE_FEATURE_UNZIP_XZ 1
|
||||||
|
|
||||||
#define uoff_t unsigned off_t
|
#define uoff_t unsigned off_t
|
||||||
#define OFF_FMT "ll"
|
#define OFF_FMT "ll"
|
||||||
|
|
||||||
#ifndef _MODE_T_
|
#ifndef _MODE_T_
|
||||||
#define _MODE_T_
|
#define _MODE_T_
|
||||||
|
@ -147,7 +148,7 @@ extern unsigned long* bled_cancel_request;
|
||||||
#define xfunc_die() longjmp(bb_error_jmp, 1)
|
#define xfunc_die() longjmp(bb_error_jmp, 1)
|
||||||
#define bb_printf(...) do { if (bled_printf != NULL) bled_printf(__VA_ARGS__); \
|
#define bb_printf(...) do { if (bled_printf != NULL) bled_printf(__VA_ARGS__); \
|
||||||
else { printf(__VA_ARGS__); putchar('\n'); } } while(0)
|
else { printf(__VA_ARGS__); putchar('\n'); } } while(0)
|
||||||
#define bb_error_msg(...) bb_printf("Error: " __VA_ARGS__)
|
#define bb_error_msg(...) bb_printf("\nError: " __VA_ARGS__)
|
||||||
#define bb_error_msg_and_die(...) do {bb_error_msg(__VA_ARGS__); xfunc_die();} while(0)
|
#define bb_error_msg_and_die(...) do {bb_error_msg(__VA_ARGS__); xfunc_die();} while(0)
|
||||||
#define bb_error_msg_and_err(...) do {bb_error_msg(__VA_ARGS__); goto err;} while(0)
|
#define bb_error_msg_and_err(...) do {bb_error_msg(__VA_ARGS__); goto err;} while(0)
|
||||||
#define bb_perror_msg bb_error_msg
|
#define bb_perror_msg bb_error_msg
|
||||||
|
@ -191,6 +192,11 @@ static inline int full_read(int fd, void *buf, unsigned int count) {
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/* None of our r/w buffers should be larger than BB_BUFSIZE */
|
||||||
|
if (count > BB_BUFSIZE) {
|
||||||
|
errno = E2BIG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if ((bled_cancel_request != NULL) && (*bled_cancel_request != 0)) {
|
if ((bled_cancel_request != NULL) && (*bled_cancel_request != 0)) {
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -215,6 +221,12 @@ static inline int full_read(int fd, void *buf, unsigned int count) {
|
||||||
|
|
||||||
static inline int full_write(int fd, const void* buffer, unsigned int count)
|
static inline int full_write(int fd, const void* buffer, unsigned int count)
|
||||||
{
|
{
|
||||||
|
/* None of our r/w buffers should be larger than BB_BUFSIZE */
|
||||||
|
if (count > BB_BUFSIZE) {
|
||||||
|
errno = E2BIG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return (bled_write != NULL) ? bled_write(fd, buffer, count) : _write(fd, buffer, count);
|
return (bled_write != NULL) ? bled_write(fd, buffer, count) : _write(fd, buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +238,10 @@ static inline void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
|
||||||
if (fd1 < 0 || fd2 < 0)
|
if (fd1 < 0 || fd2 < 0)
|
||||||
bb_error_msg_and_die("invalid fd");
|
bb_error_msg_and_die("invalid fd");
|
||||||
|
|
||||||
|
/* Enforce a 1 TB limit to keep Coverity happy */
|
||||||
|
if (size > ONE_TB)
|
||||||
|
bb_error_msg_and_die("too large");
|
||||||
|
|
||||||
buf = malloc(BB_BUFSIZE);
|
buf = malloc(BB_BUFSIZE);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
bb_error_msg_and_die("out of memory");
|
bb_error_msg_and_die("out of memory");
|
||||||
|
@ -246,7 +262,7 @@ static inline void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
|
||||||
free(buf);
|
free(buf);
|
||||||
bb_error_msg_and_die("write error");
|
bb_error_msg_and_die("write error");
|
||||||
}
|
}
|
||||||
if (w == 0) {
|
if (w != r) {
|
||||||
bb_error_msg("short write");
|
bb_error_msg("short write");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
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 4.2.2056"
|
CAPTION "Rufus 4.2.2057"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -392,8 +392,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 4,2,2056,0
|
FILEVERSION 4,2,2057,0
|
||||||
PRODUCTVERSION 4,2,2056,0
|
PRODUCTVERSION 4,2,2057,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -411,13 +411,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "4.2.2056"
|
VALUE "FileVersion", "4.2.2057"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-4.2.exe"
|
VALUE "OriginalFilename", "rufus-4.2.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "4.2.2056"
|
VALUE "ProductVersion", "4.2.2057"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Reference in a new issue