From 7ee5b355510494e97aa5ce64ee52b52d1e410778 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 3 Mar 2012 23:12:48 +0000 Subject: [PATCH] v1.1.4 (#150) * closes #49 * closes #60 * closes #64 * should address #59 * set default doe ISOs with bot bootmgr and isolinux to syslinux * other improvements --- src/format.c | 27 +++---- src/iso.c | 4 +- src/libcdio/cdio/util.h | 6 ++ src/libcdio/driver/_cdio_stdio.c | 55 ++++++++++---- src/libcdio/driver/utf8.c | 121 ++++++++++++++++--------------- src/libcdio/driver/util.c | 25 +++++++ src/msapi_utf8.h | 10 +++ src/parser.c | 5 +- src/rufus.c | 114 +++++++++++++++++------------ src/rufus.h | 3 +- src/rufus.rc | 12 +-- 11 files changed, 233 insertions(+), 149 deletions(-) diff --git a/src/format.c b/src/format.c index 190c085aa6f..de89fa83eaf 100644 --- a/src/format.c +++ b/src/format.c @@ -314,6 +314,7 @@ static BOOL ClearMBR(HANDLE hPhysicalDrive) static BOOL WriteMBR(HANDLE hPhysicalDrive) { BOOL r = FALSE; + int dt, fs; unsigned char* buf = NULL; size_t SecSize = SelectedDrive.Geometry.BytesPerSector; size_t nSecs = (0x200 + SecSize -1) / SecSize; @@ -367,7 +368,9 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive) fake_fd._ptr = (char*)hPhysicalDrive; fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; - if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_ISO_FAT) { + fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); + dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + if ((dt == DT_ISO) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { r = write_syslinux_mbr(&fake_fd); } else { r = write_95b_mbr(&fake_fd); @@ -484,7 +487,7 @@ DWORD WINAPI FormatThread(LPVOID param) char bb_msg[512]; char logfile[MAX_PATH], *userdir; FILE* log_fd; - int r; + int r, fs, dt; hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); if (hPhysicalDrive == INVALID_HANDLE_VALUE) { @@ -601,11 +604,10 @@ DWORD WINAPI FormatThread(LPVOID param) } UpdateProgress(OP_FIX_MBR, -1.0f); + fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); + dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); if (IsChecked(IDC_DOS)) { - switch(ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) { - case DT_WINME: - case DT_FREEDOS: - case DT_ISO_NTFS: + if ((dt == DT_WINME) || (dt == DT_FREEDOS) || ((dt == DT_ISO) && (fs == FS_NTFS))) { // We still have a lock, which we need to modify the volume boot record // => no need to reacquire the lock... hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); @@ -624,13 +626,11 @@ DWORD WINAPI FormatThread(LPVOID param) } // We must close and unlock the volume to write files to it safe_unlockclose(hLogicalVolume); - break; - case DT_ISO_FAT: + } else if ((dt == DT_ISO) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { PrintStatus(0, TRUE, "Installing Syslinux..."); if (!InstallSyslinux(num, drive_name)) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE; } - break; } } else { if (IsChecked(IDC_SET_ICON)) @@ -645,18 +645,14 @@ DWORD WINAPI FormatThread(LPVOID param) if (IsChecked(IDC_DOS)) { UpdateProgress(OP_DOS, -1.0f); - switch(ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) { - case DT_WINME: - case DT_FREEDOS: + if ((dt == DT_WINME) || (dt == DT_FREEDOS)) { PrintStatus(0, TRUE, "Copying DOS files..."); if (!ExtractDOS(drive_name)) { if (!FormatStatus) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; goto out; } - break; - case DT_ISO_NTFS: - case DT_ISO_FAT: + } else if (dt == DT_ISO) { if (iso_path != NULL) { PrintStatus(0, TRUE, "Copying ISO files..."); drive_name[2] = 0; @@ -666,7 +662,6 @@ DWORD WINAPI FormatThread(LPVOID param) goto out; } } - break; } if (IsChecked(IDC_SET_ICON)) SetAutorun(drive_name); diff --git a/src/iso.c b/src/iso.c index ee375a3ae74..f344d03242d 100644 --- a/src/iso.c +++ b/src/iso.c @@ -177,7 +177,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha goto out; } if (udf_is_dir(p_udf_dirent)) { - if (!scan_only) _mkdir(psz_fullpath); + if (!scan_only) _mkdirU(psz_fullpath); p_udf_dirent2 = udf_opendir(p_udf_dirent); if (p_udf_dirent2 != NULL) { if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)])) @@ -287,7 +287,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) continue; iso9660_name_translate_ext(p_statbuf->filename, psz_basename, i_joliet_level); if (p_statbuf->type == _STAT_DIR) { - if (!scan_only) _mkdir(psz_fullpath); + if (!scan_only) _mkdirU(psz_fullpath); if (iso_extract_files(p_iso, psz_iso_name)) goto out; } else { diff --git a/src/libcdio/cdio/util.h b/src/libcdio/cdio/util.h index 6ebf35f40a0..37010a74095 100644 --- a/src/libcdio/cdio/util.h +++ b/src/libcdio/cdio/util.h @@ -98,6 +98,12 @@ _cdio_memdup (const void *mem, size_t count); char * _cdio_strdup_upper (const char str[]); +/* Duplicate path and make it platform compliant. Typically needed for + MinGW/MSYS where a "/c/..." path must be translated to "c:/..." for + use with fopen(), etc. Returned string must be freed by the caller. */ +char * +_cdio_strdup_fixpath (const char path[]); + void _cdio_strfreev(char **strv); diff --git a/src/libcdio/driver/_cdio_stdio.c b/src/libcdio/driver/_cdio_stdio.c index d9853c6aad9..4d696170100 100644 --- a/src/libcdio/driver/_cdio_stdio.c +++ b/src/libcdio/driver/_cdio_stdio.c @@ -56,11 +56,43 @@ #define CDIO_FSEEK fseek #endif +/* Windows'd fopen is not UTF-8 compliant - make it so */ +#if !defined(_WIN32) +#define CDIO_FOPEN fopen +#else +#define CDIO_FOPEN fopenU +extern wchar_t* cdio_utf8_to_wchar(const char* str); +static inline FILE* fopenU(const char* filename, const char* mode) +{ + FILE* ret = NULL; + wchar_t* wfilename = cdio_utf8_to_wchar(filename); + wchar_t* wmode = cdio_utf8_to_wchar(mode); + ret = _wfopen(wfilename, wmode); + free(wfilename); + free(wmode); + return ret; +} +#endif + /* Use _stati64 if needed, on platforms that don't have transparent LFS support */ #if defined(HAVE__STATI64) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) -#define CDIO_STAT _stati64 +#define CDIO_STAT_STRUCT _stati64 +#if !defined(_WIN32) +#define CDIO_STAT_CALL _stati64 +#else +#define CDIO_STAT_CALL _stati64U +/* Once more, we have to provide an UTF-8 compliant version on Windows */ +static inline int _stati64U(const char *path, struct _stati64 *buffer) { + int ret; + wchar_t* wpath = cdio_utf8_to_wchar(path); + ret = _wstati64(wpath, buffer); + free(wpath); + return ret; +} +#endif #else -#define CDIO_STAT stat +#define CDIO_STAT_STRUCT stat +#define CDIO_STAT_CALL stat #endif #define _STRINGIFY(a) #a @@ -81,8 +113,8 @@ static int _stdio_open (void *user_data) { _UserData *const ud = user_data; - - if ((ud->fd = fopen (ud->pathname, "rb"))) + + if ((ud->fd = CDIO_FOPEN (ud->pathname, "rb"))) { ud->fd_buf = calloc (1, CDIO_STDIO_BUFSIZE); setvbuf (ud->fd, ud->fd_buf, _IOFBF, CDIO_STDIO_BUFSIZE); @@ -225,25 +257,18 @@ cdio_stdio_new(const char pathname[]) CdioDataSource_t *new_obj = NULL; cdio_stream_io_functions funcs = { NULL, NULL, NULL, NULL, NULL, NULL }; _UserData *ud = NULL; - struct CDIO_STAT statbuf; + struct CDIO_STAT_STRUCT statbuf; char* pathdup; if (pathname == NULL) return NULL; - pathdup = strdup(pathname); + /* MinGW may require a translated path */ + pathdup = _cdio_strdup_fixpath(pathname); if (pathdup == NULL) return NULL; -#ifdef __MINGW32__ - /* _stati64 requires using native Windows paths => convert "/c/..." to "c:/..." */ - if ((strlen(pathdup) > 3) && (pathdup[0] == '/') && (pathdup[2] == '/') && (isalpha(pathdup[1]))) - { - pathdup[0] = pathdup[1]; - pathdup[1] = ':'; - } -#endif - if (CDIO_STAT (pathdup, &statbuf) == -1) + if (CDIO_STAT_CALL (pathdup, &statbuf) == -1) { cdio_warn ("could not retrieve file info for `%s': %s", pathdup, strerror (errno)); diff --git a/src/libcdio/driver/utf8.c b/src/libcdio/driver/utf8.c index 3b32bda00ec..51647d48843 100644 --- a/src/libcdio/driver/utf8.c +++ b/src/libcdio/driver/utf8.c @@ -23,7 +23,6 @@ # include "config.h" #endif -#ifdef HAVE_JOLIET #ifdef HAVE_STRING_H # include #endif @@ -43,7 +42,66 @@ #include #endif -// TODO: also remove the need for iconv on MinGW +/* Windows requires some basic UTF-8 support outside of Joliet */ +#if defined(_WIN32) +#include + +#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) \ + MultiByteToWideChar(CP_UTF8, 0, src, -1, wdest, wdest_size) + +/* + * Converts an UTF-16 string to UTF8 (allocate returned string) + * Returns NULL on error + */ +char* cdio_wchar_to_utf8(const wchar_t* wstr) + { + int size = 0; + char* str = NULL; + + /* Find out the size we need to allocate for our converted string */ + size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + if (size <= 1) /* An empty string would be size 1 */ + return NULL; + + if ((str = (char*)calloc(size, 1)) == NULL) + return NULL; + + if (wchar_to_utf8_no_alloc(wstr, str, size) != size) { + free(str); + return NULL; + } + + return str; + } + +/* + * Converts an UTF8 string to UTF-16 (allocate returned string) + * Returns NULL on error + */ +wchar_t* cdio_utf8_to_wchar(const char* str) + { + int size = 0; + wchar_t* wstr = NULL; + + /* Find out the size we need to allocate for our converted string */ + size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + if (size <= 1) /* An empty string would be size 1 */ + return NULL; + + if ((wstr = (wchar_t*)calloc(size, sizeof(wchar_t))) == NULL) + return NULL; + + if (utf8_to_wchar_no_alloc(str, wstr, size) != size) { + free(wstr); + return NULL; + } + return wstr; + } +#endif + +#ifdef HAVE_JOLIET #ifdef HAVE_ICONV #include struct cdio_charset_coverter_s @@ -210,61 +268,6 @@ bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst, return result; } #elif defined(_WIN32) -#include - -#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) \ - MultiByteToWideChar(CP_UTF8, 0, src, -1, wdest, wdest_size) - -/* - * Converts an UTF-16 string to UTF8 (allocate returned string) - * Returns NULL on error - */ -static inline char* wchar_to_utf8(const wchar_t* wstr) - { - int size = 0; - char* str = NULL; - - /* Find out the size we need to allocate for our converted string */ - size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); - if (size <= 1) /* An empty string would be size 1 */ - return NULL; - - if ((str = (char*)calloc(size, 1)) == NULL) - return NULL; - - if (wchar_to_utf8_no_alloc(wstr, str, size) != size) { - free(str); - return NULL; - } - - return str; - } - -/* - * Converts an UTF8 string to UTF-16 (allocate returned string) - * Returns NULL on error - */ -static inline wchar_t* utf8_to_wchar(const char* str) - { - int size = 0; - wchar_t* wstr = NULL; - - /* Find out the size we need to allocate for our converted string */ - size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); - if (size <= 1) /* An empty string would be size 1 */ - return NULL; - - if ((wstr = (wchar_t*)calloc(size, sizeof(wchar_t))) == NULL) - return NULL; - - if (utf8_to_wchar_no_alloc(str, wstr, size) != size) { - free(wstr); - return NULL; - } - return wstr; - } bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst, int * dst_len, const char * dst_charset) @@ -276,7 +279,7 @@ bool cdio_charset_from_utf8(cdio_utf8_t * src, char ** dst, return false; /* Eliminate empty strings */ - le_dst = utf8_to_wchar(src); + le_dst = cdio_utf8_to_wchar(src); if ((le_dst == NULL) || (le_dst[0] == 0)) { free(le_dst); return false; @@ -323,7 +326,7 @@ bool cdio_charset_to_utf8(char *src, size_t src_len, cdio_utf8_t **dst, ((char*)le_src)[2*i+1] = src[2*i]; } le_src[src_len] = 0; - *dst = wchar_to_utf8(le_src); + *dst = cdio_wchar_to_utf8(le_src); free(le_src); return (*dst != NULL); diff --git a/src/libcdio/driver/util.c b/src/libcdio/driver/util.c index d2a295f6ec6..bb17079258a 100644 --- a/src/libcdio/driver/util.c +++ b/src/libcdio/driver/util.c @@ -38,6 +38,8 @@ #include "inttypes.h" #endif +#include + #include "cdio_assert.h" #include #include @@ -136,6 +138,29 @@ _cdio_strdup_upper (const char str[]) return new_str; } +/* Convert MinGW/MSYS paths that start in "/c/..." to "c:/..." + so that they can be used with fopen(), stat(), etc. */ +char * +_cdio_strdup_fixpath (const char path[]) +{ + char *new_path = NULL; + + if (path) + { + new_path = strdup (path); +#if defined(_WIN32) + if (new_path && (strlen (new_path) >= 3) && (new_path[0] == '/') && + (new_path[2] == '/') && (isalpha (new_path[1]))) + { + new_path[0] = new_path[1]; + new_path[1] = ':'; + } +#endif + } + + return new_path; +} + uint8_t cdio_to_bcd8 (uint8_t n) { diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index 9546e304f4b..a03225514b5 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -24,6 +24,7 @@ #include #include #include +#include #pragma once @@ -618,6 +619,15 @@ static __inline char* getenvU(const char* varname) return ret; } +static __inline int _mkdirU(const char* dirname) +{ + wconvert(dirname); + int ret; + ret = _wmkdir(wdirname); + wfree(dirname); + return ret; +} + #ifdef __cplusplus } #endif diff --git a/src/parser.c b/src/parser.c index 2796f87575a..a6946f2db12 100644 --- a/src/parser.c +++ b/src/parser.c @@ -63,10 +63,7 @@ char* get_token_data(const char* filename, const char* token) goto out; } fd = _wfopen(wfilename, L"r, ccs=UNICODE"); - if (fd == NULL) { - uprintf("Could not open file '%s'\n", filename); - goto out; - } + if (fd == NULL) goto out; // Process individual lines. NUL is always appended. // Ideally, we'd check that our buffer fits the line diff --git a/src/rufus.c b/src/rufus.c index 04815f7df86..06e95d7d590 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -46,6 +46,7 @@ static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes" "1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" }; static BOOL existing_key = FALSE; // For LGP set/restore static BOOL iso_size_check = TRUE; +static int selection_default; BOOL enable_fixed_disks = FALSE; /* @@ -387,19 +388,38 @@ static BOOL GetDriveInfo(void) static void SetFSFromISO(void) { - int i, fs; + int i, fs, selected_fs = FS_UNKNOWN; + uint32_t fs_mask = 0; if (iso_path == NULL) return; - for (i=ComboBox_GetCount(hFileSystem)-1; i>=0; i--) { + // Create a mask of all the FS's available + for (i=0; ihttp://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.1.4 (Build 149)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.1.4 (Build 150)",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 @@ -223,8 +223,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,1,4,149 - PRODUCTVERSION 1,1,4,149 + FILEVERSION 1,1,4,150 + PRODUCTVERSION 1,1,4,150 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -241,13 +241,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.1.4.149" + VALUE "FileVersion", "1.1.4.150" 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.4.149" + VALUE "ProductVersion", "1.1.4.150" END END BLOCK "VarFileInfo"