From 7e7c75169c2a14bc6e5ce51419c510802a5a2861 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Tue, 21 Feb 2012 19:46:28 +0000 Subject: [PATCH] [ui] enable setting of icon and extended label * Creates an UTF-16 autoconf.inf with label, as well as autoconf.ico * also fixed extended labels not displaying - closes #48 * also bumped version to rufus-next * also factorized iso props analysis * additional fixes --- configure | 20 +-- configure.ac | 2 +- src/.msvc/rufus_2010.vcxproj | 3 +- src/.msvc/rufus_2010.vcxproj.filters | 5 +- src/.msvc/rufus_sources | 1 + src/Makefile.am | 2 +- src/Makefile.in | 21 ++- src/drive.c | 16 ++- src/format.c | 22 ++- src/icon.c | 194 +++++++++++++++++++++++++++ src/iso.c | 104 +++++++------- src/msapi_utf8.h | 3 + src/resource.h | 1 + src/rufus.c | 44 +++--- src/rufus.h | 3 + src/rufus.rc | 30 +++-- src/stdio.c | 2 +- 17 files changed, 357 insertions(+), 116 deletions(-) create mode 100644 src/icon.c diff --git a/configure b/configure index df9cb199..e2681f5f 100644 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for rufus 1.1.1. +# Generated by GNU Autoconf 2.68 for rufus 1.1.2. # # Report bugs to . # @@ -559,8 +559,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rufus' PACKAGE_TARNAME='rufus' -PACKAGE_VERSION='1.1.1' -PACKAGE_STRING='rufus 1.1.1' +PACKAGE_VERSION='1.1.2' +PACKAGE_STRING='rufus 1.1.2' PACKAGE_BUGREPORT='https://github.com/pbatard/rufus/issues' PACKAGE_URL='http://rufus.akeo.ie' @@ -1204,7 +1204,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rufus 1.1.1 to adapt to many kinds of systems. +\`configure' configures rufus 1.1.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1270,7 +1270,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rufus 1.1.1:";; + short | recursive ) echo "Configuration of rufus 1.1.2:";; esac cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rufus configure 1.1.1 +rufus configure 1.1.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1418,7 +1418,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rufus $as_me 1.1.1, which was +It was created by rufus $as_me 1.1.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2233,7 +2233,7 @@ fi # Define the identity of the package. PACKAGE='rufus' - VERSION='1.1.1' + VERSION='1.1.2' cat >>confdefs.h <<_ACEOF @@ -4091,7 +4091,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rufus $as_me 1.1.1, which was +This file was extended by rufus $as_me 1.1.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4145,7 +4145,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -rufus config.status 1.1.1 +rufus config.status 1.1.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4cffa896..ebd0ab4d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([rufus], [1.1.1], [https://github.com/pbatard/rufus/issues], [rufus], [http://rufus.akeo.ie]) +AC_INIT([rufus], [1.1.2], [https://github.com/pbatard/rufus/issues], [rufus], [http://rufus.akeo.ie]) AM_INIT_AUTOMAKE([-Wno-portability foreign no-dist no-dependencies]) AC_CONFIG_SRCDIR([src/rufus.c]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/.msvc/rufus_2010.vcxproj b/src/.msvc/rufus_2010.vcxproj index 7edd7645..043a1aa6 100644 --- a/src/.msvc/rufus_2010.vcxproj +++ b/src/.msvc/rufus_2010.vcxproj @@ -1,4 +1,4 @@ - + @@ -163,6 +163,7 @@ + diff --git a/src/.msvc/rufus_2010.vcxproj.filters b/src/.msvc/rufus_2010.vcxproj.filters index 92e9e88c..892b67eb 100644 --- a/src/.msvc/rufus_2010.vcxproj.filters +++ b/src/.msvc/rufus_2010.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -45,6 +45,9 @@ Source Files + + Source Files + diff --git a/src/.msvc/rufus_sources b/src/.msvc/rufus_sources index d1119e31..b53984cb 100644 --- a/src/.msvc/rufus_sources +++ b/src/.msvc/rufus_sources @@ -32,6 +32,7 @@ SOURCES=rufus.c \ format.c \ stdio.c \ stdlg.c \ + icon.c \ iso.c \ dos.c \ dos_locale.c \ diff --git a/src/Makefile.am b/src/Makefile.am index a9f001f2..b9571418 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ pkg_v_rc_0 = @echo " RC $@"; %_rc.o: %.rc $(pkg_v_rc)$(WINDRES) $(AM_RCFLAGS) -i $< -o $@ -rufus_SOURCES = drive.c iso.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c +rufus_SOURCES = drive.c icon.c iso.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS) rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ diff --git a/src/Makefile.in b/src/Makefile.in index ec3eb872..ecb00b5e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -43,11 +43,12 @@ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-iso.$(OBJEXT) \ - rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \ - rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \ - rufus-format.$(OBJEXT) rufus-stdio.$(OBJEXT) \ - rufus-stdlg.$(OBJEXT) rufus-rufus.$(OBJEXT) +am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \ + rufus-iso.$(OBJEXT) rufus-dos.$(OBJEXT) \ + rufus-dos_locale.$(OBJEXT) rufus-badblocks.$(OBJEXT) \ + rufus-syslinux.$(OBJEXT) rufus-format.$(OBJEXT) \ + rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \ + rufus-rufus.$(OBJEXT) rufus_OBJECTS = $(am_rufus_OBJECTS) rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \ syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ @@ -184,7 +185,7 @@ SUBDIRS = ms-sys syslinux/libfat syslinux/libinstaller libcdio/iso9660 libcdio/u pkg_v_rc = $(pkg_v_rc_$(V)) pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY)) pkg_v_rc_0 = @echo " RC $@"; -rufus_SOURCES = drive.c iso.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c +rufus_SOURCES = drive.c icon.c iso.c dos.c dos_locale.c badblocks.c syslinux.c format.c stdio.c stdlg.c rufus.c rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS) rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ @@ -253,6 +254,14 @@ rufus-drive.obj: drive.c $(AM_V_CC) @AM_BACKSLASH@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-drive.obj `if test -f 'drive.c'; then $(CYGPATH_W) 'drive.c'; else $(CYGPATH_W) '$(srcdir)/drive.c'; fi` +rufus-icon.o: icon.c + $(AM_V_CC) @AM_BACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.o `test -f 'icon.c' || echo '$(srcdir)/'`icon.c + +rufus-icon.obj: icon.c + $(AM_V_CC) @AM_BACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-icon.obj `if test -f 'icon.c'; then $(CYGPATH_W) 'icon.c'; else $(CYGPATH_W) '$(srcdir)/icon.c'; fi` + rufus-iso.o: iso.c $(AM_V_CC) @AM_BACKSLASH@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.o `test -f 'iso.c' || echo '$(srcdir)/'`iso.c diff --git a/src/drive.c b/src/drive.c index c5253de9..5d989235 100644 --- a/src/drive.c +++ b/src/drive.c @@ -147,20 +147,22 @@ out: BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) { HANDLE hDrive; - char DrivePath[] = "#:\\"; - static char volume_label[MAX_PATH+1]; + wchar_t wDrivePath[] = L"#:\\"; + wchar_t wVolumeLabel[MAX_PATH+1]; + static char VolumeLabel[MAX_PATH+1]; *label = STR_NO_LABEL; - hDrive = GetDriveHandle(DriveIndex, DrivePath, FALSE, FALSE); + hDrive = GetDriveHandle(DriveIndex, letter, FALSE, FALSE); if (hDrive == INVALID_HANDLE_VALUE) return FALSE; safe_closehandle(hDrive); - *letter = DrivePath[0]; + wDrivePath[0] = *letter; - if (GetVolumeInformationA(DrivePath, volume_label, sizeof(volume_label), - NULL, NULL, NULL, NULL, 0) && *volume_label) { - *label = volume_label; + if (GetVolumeInformationW(wDrivePath, wVolumeLabel, sizeof(wVolumeLabel), + NULL, NULL, NULL, NULL, 0) && *wVolumeLabel) { + wchar_to_utf8_no_alloc(wVolumeLabel, VolumeLabel, sizeof(VolumeLabel)); + *label = VolumeLabel; } return TRUE; diff --git a/src/format.c b/src/format.c index 54f7bda0..3aa638cd 100644 --- a/src/format.c +++ b/src/format.c @@ -158,6 +158,11 @@ static void ToValidLabel(WCHAR* name, BOOL bFAT) found = TRUE; break; } } + // A FAT label that contains extended chars will be rejected + if (name[i] >= 0x80) { + name[k++] = '_'; + found = TRUE; + } if (found) continue; } found = FALSE; @@ -173,10 +178,20 @@ static void ToValidLabel(WCHAR* name, BOOL bFAT) name[k] = 0; if (bFAT) { name[11] = 0; + for (i=0, j=0; name[i]!=0; i++) + if (name[i] == '_') j++; + if (i<2*j) { + // If the final label is mostly underscore, use the proposed label + uprintf("FAT label is mostly undercores. Using '%s' label instead.\n", SelectedDrive.proposed_label); + for(i=0; SelectedDrive.proposed_label[i]!=0; i++) + name[i] = SelectedDrive.proposed_label[i]; + name[i] = 0; + } } else { name[32] = 0; } - /* Needed for disk by label isolinux.cfg workaround */ + + // Needed for disk by label isolinux.cfg workaround wchar_to_utf8_no_alloc(name, iso_report.usb_label, sizeof(iso_report.usb_label)); } @@ -616,6 +631,9 @@ DWORD WINAPI FormatThread(LPVOID param) } break; } + } else { + if (IsChecked(IDC_SET_ICON)) + SetAutorun(drive_name); } // We issue a complete remount of the filesystem at on account of: @@ -648,6 +666,8 @@ DWORD WINAPI FormatThread(LPVOID param) } break; } + if (IsChecked(IDC_SET_ICON)) + SetAutorun(drive_name); // Issue another complete remount before we exit, to ensure we're clean RemountVolume(drive_name[0]); } diff --git a/src/icon.c b/src/icon.c new file mode 100644 index 00000000..838a3a03 --- /dev/null +++ b/src/icon.c @@ -0,0 +1,194 @@ +/* + * Rufus: The Reliable USB Formatting Utility + * Extract icon from executable and set autorun.inf + * Copyright (c) 2012 Pete Batard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "msapi_utf8.h" +#include "rufus.h" +#include "resource.h" + +#pragma pack(push) +#pragma pack(2) + +typedef struct +{ + BYTE bWidth; // Width, in pixels, of the image + BYTE bHeight; // Height, in pixels, of the image + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved ( must be 0) + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // How many bytes in this resource? + DWORD dwImageOffset; // Where in the file is this image? +} ICONDIRENTRY, *LPICONDIRENTRY; + +typedef struct +{ + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource Type (1 for icons) + WORD idCount; // How many images? + ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em) +} ICONDIR, *LPICONDIR; + +typedef struct +{ + BITMAPINFOHEADER icHeader; // DIB header + RGBQUAD icColors[1]; // Color table + BYTE icXOR[1]; // DIB bits for XOR mask + BYTE icAND[1]; // DIB bits for AND mask +} ICONIMAGE, *LPICONIMAGE; + +typedef struct +{ + BYTE bWidth; // Width, in pixels, of the image + BYTE bHeight; // Height, in pixels, of the image + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // how many bytes in this resource? + WORD nID; // the ID +} GRPICONDIRENTRY, *LPGRPICONDIRENTRY; + +typedef struct +{ + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource type (1 for icons) + WORD idCount; // How many images? + GRPICONDIRENTRY idEntries[1]; // The entries for each image +} GRPICONDIR, *LPGRPICONDIR; + +#pragma pack(pop) + +/* + * Extract an icon set from the exe and save it as .ico + */ +static BOOL SaveIcon(const char* filename) +{ + HGLOBAL res_handle; + HRSRC res; + WORD i; + BYTE* res_data; + DWORD res_size, Size, offset; + HANDLE hFile = INVALID_HANDLE_VALUE; + BOOL r = FALSE; + GRPICONDIR* icondir; + + res = FindResource(hMainInstance, MAKEINTRESOURCE(IDI_ICON), RT_GROUP_ICON); + if (res == NULL) { + uprintf("Unable to locate icon resource: %s\n", WindowsErrorString()); + goto out; + } + res_handle = LoadResource(NULL, res); + if (res_handle == NULL) { + uprintf("Unable to load icon resource: %s\n", WindowsErrorString()); + goto out; + } + icondir = (GRPICONDIR*)LockResource(res_handle); + + hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, 0, 0); + if (hFile == INVALID_HANDLE_VALUE) { + uprintf("Unable to create icon '%s': %s.\n", filename, WindowsErrorString()); + goto out; + } + + // Write .ico header + if ((!WriteFile(hFile, icondir, 3*sizeof(WORD), &Size, NULL)) || (Size != 3*sizeof(WORD))) { + uprintf("Couldn't write icon header: %s.\n", WindowsErrorString()); + goto out; + } + + // Write icon data + offset = 3*sizeof(WORD) + icondir->idCount*sizeof(ICONDIRENTRY); + for (i=0; iidCount; i++) { + // wPlanes is set to 0 in the original .ico => fix it + icondir->idEntries[i].wPlanes = 0; // NB: this produces an exception which we don't care about + // Write the common part of ICONDIRENTRY + if ( (!WriteFile(hFile, &icondir->idEntries[i], sizeof(GRPICONDIRENTRY)-sizeof(WORD), &Size, NULL)) + || (Size != sizeof(GRPICONDIRENTRY)-sizeof(WORD)) ) { + uprintf("Couldn't write ICONDIRENTRY[%d]: %s.\n", i, WindowsErrorString()); + goto out; + } + res = FindResource(hMainInstance, MAKEINTRESOURCE(icondir->idEntries[i].nID), RT_ICON); + // Write the DWORD offset + if ( (!WriteFile(hFile, &offset, sizeof(offset), &Size, NULL)) || (Size != sizeof(offset)) ) { + uprintf("Couldn't write ICONDIRENTRY[%d] offset: %s.\n", i, WindowsErrorString()); + goto out; + } + offset += SizeofResource(NULL, res); + } + for (i=0; iidCount; i++) { + // Write icon data + res = FindResource(hMainInstance, MAKEINTRESOURCE(icondir->idEntries[i].nID), RT_ICON); + res_handle = LoadResource(NULL, res); + res_data = (BYTE*)LockResource(res_handle); + res_size = SizeofResource(NULL, res); + if ( (!WriteFile(hFile, res_data, res_size, &Size, NULL)) || (Size != res_size) ) { + uprintf("Couldn't write icon data #%d: %s.\n", i, WindowsErrorString()); + goto out; + } + } + uprintf("Created: %s\n", filename); + r = TRUE; + +out: + safe_closehandle(hFile); + return r; +} + +/* + * Create an autorun.inf, if none exists + * We use this to set the icon as well as labels that are longer than 11/32 chars or, + * in the case of FAT, contain non-English characters + */ +BOOL SetAutorun(const char* path) +{ + FILE* fd; + char filename[64]; + wchar_t wlabel[128], wRufusVersion[32]; + + safe_sprintf(filename, sizeof(filename), "%s\\autorun.inf", path); + fd = fopen(filename, "r"); // If there's an existing autorun, don't overwrite + if (fd != NULL) { + uprintf("An existing autorun.inf already exists - keeping it\n"); + fclose(fd); + return FALSE; + } + // No "/autorun.inf" => create a new one in UTF-16 LE mode + fd = fopen(filename, "w, ccs=UTF-16LE"); + if (fd == NULL) { + uprintf("Unable to create %s\n", filename); + return FALSE; + } + + GetWindowTextW(hLabel, wlabel, ARRAYSIZE(wlabel)); + GetWindowTextW(hMainDialog, wRufusVersion, ARRAYSIZE(wRufusVersion)); + fwprintf(fd, L"; Created by %s\n; " LTEXT(RUFUS_URL) L"\n", wRufusVersion); + fwprintf(fd, L"[autorun]\nlabel = %s\nicon = autorun.ico", wlabel); + fclose(fd); + uprintf("Created: %s\n", filename); + + // .inf -> .ico + filename[strlen(filename)-1] = 'o'; + filename[strlen(filename)-2] = 'c'; + return SaveIcon(filename); +} diff --git a/src/iso.c b/src/iso.c index ba9d7eb9..99680523 100644 --- a/src/iso.c +++ b/src/iso.c @@ -151,12 +151,54 @@ static void process_config(char* buf, size_t buf_size, const char* cfg_name) buf[buf_size] = last_char; } +/* + * Scan and set ISO properties + * Returns true if the the current file does not need to be processed further + */ +static __inline BOOL check_iso_props(BOOL is_root, BOOL* is_syslinux_cfg, int64_t i_file_length, + const char* psz_basename, char* psz_fullpath) +{ + size_t i; + + // Check for an isolinux/syslinux config file anywhere + *is_syslinux_cfg = FALSE; + for (i=0; i= FOUR_GIGABYTES) + iso_report.has_4GB_file = TRUE; + // Compute projected size needed + total_blocks += i_file_length/UDF_BLOCKSIZE; + // NB: ISO_BLOCKSIZE = UDF_BLOCKSIZE + if ((i_file_length != 0) && (i_file_length%ISO_BLOCKSIZE == 0)) // + total_blocks++; + return TRUE; + } + // In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours + if (is_root && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { + uprintf("skipping % file from ISO image\n", ldlinux_name); + return TRUE; + } + return FALSE; +} + // Returns 0 on success, nonzero on error static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path) { HANDLE file_handle = NULL; DWORD buf_size, wr_size; - BOOL r, cfg_file; + BOOL r, is_syslinux_cfg; int i_length; size_t i, nul_pos; char* psz_fullpath = NULL; @@ -190,33 +232,9 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha } } else { i_file_length = udf_get_file_length(p_udf_dirent); - // Check for an isolinux config file anywhere - cfg_file = FALSE; - for (i=0; i= FOUR_GIGABYTES) - iso_report.has_4GB_file = TRUE; - total_blocks += i_file_length/UDF_BLOCKSIZE; - if ((i_file_length != 0) && (i_file_length%UDF_BLOCKSIZE == 0)) - total_blocks++; + if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, i_file_length, psz_basename, psz_fullpath)) { safe_free(psz_fullpath); continue; - } else { - // In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours - if ((*psz_path == 0) && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { - uprintf("skipping % file from ISO image\n", ldlinux_name); - continue; - } } // Replace slashes with backslashes and append the size to the path for UI display nul_pos = safe_strlen(psz_fullpath); @@ -241,7 +259,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha goto out; } buf_size = (DWORD)MIN(i_file_length, i_read); - if (cfg_file) + if (is_syslinux_cfg) process_config((char*)buf, (size_t)buf_size, psz_fullpath); ISO_BLOCKING(r = WriteFile(file_handle, buf, buf_size, &wr_size, NULL)); if ((!r) || (buf_size != wr_size)) { @@ -277,7 +295,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) { HANDLE file_handle = NULL; DWORD buf_size, wr_size; - BOOL s, cfg_file; + BOOL s, is_syslinux_cfg; int i_length, r = 1; char psz_fullpath[1024], *psz_basename; const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)]; @@ -317,32 +335,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) goto out; } else { i_file_length = p_statbuf->size; - // Check for an isolinux config file anywhere - cfg_file = FALSE; - for (i=0; i= FOUR_GIGABYTES) - iso_report.has_4GB_file = TRUE; - total_blocks += i_file_length/ISO_BLOCKSIZE; - if ((i_file_length != 0) && (i_file_length%ISO_BLOCKSIZE == 0)) - total_blocks++; + if (check_iso_props((*psz_path == 0), &is_syslinux_cfg, i_file_length, psz_basename, psz_fullpath)) { continue; - } else { - // In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours - if ((*psz_path == 0) && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { - uprintf("Skipping % file from ISO image\n", ldlinux_name); - continue; - } } // Replace slashes with backslashes and append the size to the path for UI display nul_pos = safe_strlen(psz_fullpath); @@ -369,7 +363,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) goto out; } buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE); - if (cfg_file) + if (is_syslinux_cfg) process_config((char*)buf, (size_t)buf_size, psz_fullpath); ISO_BLOCKING(s = WriteFile(file_handle, buf, buf_size, &wr_size, NULL)); if ((!s) || (buf_size != wr_size)) { @@ -502,7 +496,6 @@ out: uprintf("Unable to create %s - booting from USB will not work\n", syslinux_path); r = 1; } else { - uprintf("Creating: %s\n", syslinux_path); fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", iso_report.cfg_path); for (i=safe_strlen(iso_report.cfg_path); (i>0)&&(iso_report.cfg_path[i]!='/'); i--); if (i>0) { @@ -510,6 +503,7 @@ out: fprintf(fd, " APPEND %s/\n", iso_report.cfg_path); iso_report.cfg_path[i] = '/'; } + uprintf("Created: %s\n", syslinux_path); } } fclose(fd); diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index ba0aac7a..9546e304 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -31,6 +31,9 @@ extern "C" { #endif +#define _LTEXT(txt) L##txt +#define LTEXT(txt) _LTEXT(txt) + #define wchar_to_utf8_no_alloc(wsrc, dest, dest_size) \ WideCharToMultiByte(CP_UTF8, 0, wsrc, -1, dest, dest_size, NULL, NULL) #define utf8_to_wchar_no_alloc(src, wdest, wdest_size) \ diff --git a/src/resource.h b/src/resource.h index 3ebb7308..2b201193 100644 --- a/src/resource.h +++ b/src/resource.h @@ -55,6 +55,7 @@ #define IDC_NBPASSES 1014 #define IDC_TEST 1015 #define IDC_SELECT_ISO 1016 +#define IDC_SET_ICON 1017 #define IDC_ISO_PROGRESS 1020 #define IDC_ISO_FILENAME 1021 #define IDC_ISO_ABORT 1022 diff --git a/src/rufus.c b/src/rufus.c index 91fc451d..6cc0b6bf 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -411,7 +411,7 @@ static BOOL PopulateProperties(int ComboIndex) double HumanReadableSize; char capacity[64]; static char *suffix[] = { "KB", "MB", "GB", "TB", "PB"}; - char proposed_label[16], no_label[] = STR_NO_LABEL; + char no_label[] = STR_NO_LABEL; int i; IGNORE_RETVAL(ComboBox_ResetContent(hCapacity)); @@ -446,20 +446,24 @@ static BOOL PopulateProperties(int ComboIndex) IGNORE_RETVAL(ComboBox_SetCurSel(hCapacity, 0)); hDeviceTooltip = CreateTooltip(hDeviceList, DriveID.Table[ComboIndex], -1); + // Set a proposed label according to the size (eg: "256MB", "8GB") + if (HumanReadableSize < 1.0) { + HumanReadableSize *= 1024.0; + i--; + } + // If we're beneath the tolerance, round proposed label to an integer, if not, show one decimal point + if (fabs(HumanReadableSize / ceil(HumanReadableSize) - 1.0) < PROPOSEDLABEL_TOLERANCE) { + safe_sprintf(SelectedDrive.proposed_label, sizeof(SelectedDrive.proposed_label), + "%0.0f%s", ceil(HumanReadableSize), suffix[i]); + } else { + safe_sprintf(SelectedDrive.proposed_label, sizeof(SelectedDrive.proposed_label), + "%0.1f%s", HumanReadableSize, suffix[i]); + } + // If no existing label is available and no ISO is selected, propose one according to the size (eg: "256MB", "8GB") if ((iso_path == NULL) || (iso_report.label[0] == 0)) { if (safe_strcmp(no_label, DriveLabel.Table[ComboIndex]) == 0) { - if (HumanReadableSize < 1.0) { - HumanReadableSize *= 1024.0; - i--; - } - // If we're beneath the tolerance, round proposed label to an integer, if not, show one decimal point - if (fabs(HumanReadableSize / ceil(HumanReadableSize) - 1.0) < PROPOSEDLABEL_TOLERANCE) { - safe_sprintf(proposed_label, sizeof(proposed_label), "%0.0f%s", ceil(HumanReadableSize), suffix[i]); - } else { - safe_sprintf(proposed_label, sizeof(proposed_label), "%0.1f%s", HumanReadableSize, suffix[i]); - } - SetWindowTextU(hLabel, proposed_label); + SetWindowTextU(hLabel, SelectedDrive.proposed_label); } else { SetWindowTextU(hLabel, DriveLabel.Table[ComboIndex]); } @@ -908,6 +912,7 @@ static void EnableControls(BOOL bEnable) EnableWindow(GetDlgItem(hMainDialog, IDC_START), bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_SELECT_ISO), bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_NBPASSES), bEnable); + EnableWindow(GetDlgItem(hMainDialog, IDC_SET_ICON), bEnable); SetDlgItemTextA(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel"); } @@ -1119,9 +1124,10 @@ void InitDialog(HWND hDlg) // Create the string array StrArrayCreate(&DriveID, MAX_DRIVES); StrArrayCreate(&DriveLabel, MAX_DRIVES); - // Set the quick format & create DOS disk checkboxes + // Set the Quick format, Create bootable and Set icon checkboxes CheckDlgButton(hDlg, IDC_QUICKFORMAT, BST_CHECKED); CheckDlgButton(hDlg, IDC_DOS, BST_CHECKED); + CheckDlgButton(hDlg, IDC_SET_ICON, BST_CHECKED); // Load system icons (NB: Use the excellent http://www.nirsoft.net/utils/iconsext.html to find icon IDs) hDllInst = LoadLibraryA("shell32.dll"); @@ -1138,6 +1144,8 @@ void InitDialog(HWND hDlg) SendMessage(GetDlgItem(hDlg, IDC_SELECT_ISO), 0x1602, 0, (LPARAM)&bi); // BCM_SETIMAGELIST hISOToolTip = CreateTooltip(hSelectISO, "Click to select...", -1); + CreateTooltip(GetDlgItem(hDlg, IDC_SET_ICON), "Create an autorun.inf on the target drive, to set the icon. " + "Also allow the display of non-English labels.", 10000); } /* @@ -1148,7 +1156,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA DRAWITEMSTRUCT* pDI; int nDeviceIndex, fs, dt; static DWORD DeviceNum = 0; - char str[MAX_PATH], tmp[128]; + wchar_t wtmp[128], wstr[MAX_PATH]; static UINT uDOSChecked = BST_CHECKED; switch (message) { @@ -1359,10 +1367,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA } } } - GetWindowTextA(hDeviceList, tmp, sizeof(tmp)); - safe_sprintf(str, sizeof(str), "WARNING: ALL DATA ON DEVICE %s\r\nWILL BE DESTROYED.\r\n" - "To continue with this operation, click OK. To quit click CANCEL.", tmp); - if (MessageBoxA(hMainDialog, str, "Rufus", MB_OKCANCEL|MB_ICONWARNING) == IDOK) { + GetWindowTextW(hDeviceList, wtmp, ARRAYSIZE(wtmp)); + _snwprintf(wstr, ARRAYSIZE(wstr), L"WARNING: ALL DATA ON DEVICE %s\r\nWILL BE DESTROYED.\r\n" + L"To continue with this operation, click OK. To quit click CANCEL.", wtmp); + if (MessageBoxW(hMainDialog, wstr, L"Rufus", MB_OKCANCEL|MB_ICONWARNING) == IDOK) { // Disable all controls except cancel EnableControls(FALSE); DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); diff --git a/src/rufus.h b/src/rufus.h index a302287f..97b7c4d5 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -136,6 +136,7 @@ typedef struct { LONGLONG DiskSize; DISK_GEOMETRY Geometry; DWORD FirstSector; + char proposed_label[16]; int FSType; struct { ULONG Allowed; @@ -152,6 +153,7 @@ typedef struct { BOOL has_4GB_file; BOOL has_bootmgr; BOOL has_isolinux; + BOOL has_autorun; } RUFUS_ISO_REPORT; /* @@ -195,6 +197,7 @@ extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAcc extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); extern BOOL UnmountDrive(HANDLE hDrive); extern BOOL CreateProgress(void); +extern BOOL SetAutorun(const char* path); extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc); __inline static BOOL UnlockDrive(HANDLE hDrive) diff --git a/src/rufus.rc b/src/rufus.rc index d9a1ac61..364997f6 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -30,14 +30,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // Dialog // -IDD_DIALOG DIALOGEX 12, 12, 206, 278 +IDD_DIALOG DIALOGEX 12, 12, 206, 289 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.1.1.141" +CAPTION "Rufus v1.1.2.142" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Start",IDC_START,94,236,50,14 - PUSHBUTTON "Close",IDCANCEL,148,236,50,14 + DEFPUSHBUTTON "Start",IDC_START,94,248,50,14 + PUSHBUTTON "Close",IDCANCEL,148,248,50,14 COMBOBOX IDC_DEVICE,8,17,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8 COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -46,18 +46,19 @@ BEGIN LTEXT "Capacity",IDC_STATIC,9,35,29,8 COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Cluster size",IDC_STATIC,9,93,105,10 - PUSHBUTTON "About...",IDC_ABOUT,8,236,50,14 - GROUPBOX "Format Options",IDC_STATIC,7,149,189,52 + PUSHBUTTON "About...",IDC_ABOUT,8,248,50,14 + GROUPBOX "Format Options",IDC_STATIC,7,149,189,64 EDITTEXT IDC_LABEL,7,131,190,13,ES_AUTOHSCROLL CONTROL "Check device for bad blocks:",IDC_BADBLOCKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,161,101,10 CONTROL "Quick Format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,58,10 CONTROL "Create a bootable disk using:",IDC_DOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,185,104,10 + CONTROL "Set icon and extended label",IDC_SET_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,197,105,10 LTEXT "New volume label",IDC_STATIC,9,121,105,10 - CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,7,210,189,9 - COMBOBOX IDC_DOSTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,7,221,189,9 COMBOBOX IDC_NBPASSES,119,159,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test",IDC_TEST,62,236,20,14,NOT WS_VISIBLE + COMBOBOX IDC_DOSTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "...",IDC_SELECT_ISO,171,182,22,14,BS_ICON + PUSHBUTTON "Test",IDC_TEST,62,248,20,14,NOT WS_VISIBLE END IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195 @@ -71,7 +72,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.1.1 (Build 141)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.1.2 (Build 142)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -192,6 +193,7 @@ GUIDELINES DESIGNINFO BEGIN IDD_DIALOG, DIALOG BEGIN + BOTTOMMARGIN, 288 END IDD_ABOUTBOX, DIALOG @@ -220,8 +222,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,1,1,141 - PRODUCTVERSION 1,1,1,141 + FILEVERSION 1,1,2,142 + PRODUCTVERSION 1,1,2,142 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -238,13 +240,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.1.1.141" + VALUE "FileVersion", "1.1.2.142" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.1.1.141" + VALUE "ProductVersion", "1.1.2.142" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index d5029ea7..d4f4169e 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -49,7 +49,7 @@ void _uprintf(const char *format, ...) p += (n < 0)?sizeof(buf)-3:n; - while((p>buf) && (isspace(p[-1]))) + while((p>buf) && (isspace((unsigned char)p[-1]))) *--p = '\0'; *p++ = '\r';