[iso] bootable NTFS from ISO image [EXPERIMENTAL]

* bootmgr ISOs only
* extraction and ISO support UI improvements
* UTF8 support through CreateFileU
* cancellation on ISO file extraction
* switch to using CreateThread
This commit is contained in:
Pete Batard 2012-02-07 02:05:58 +00:00
parent 22276ccb5a
commit 472db8b592
7 changed files with 232 additions and 117 deletions

View file

@ -371,7 +371,8 @@ static BOOL WritePBR(HANDLE hLogicalVolume, BOOL bFreeDOS)
uprintf("Confirmed new volume has an NTFS boot sector\n"); uprintf("Confirmed new volume has an NTFS boot sector\n");
if (!write_ntfs_br(&fake_fd)) break; if (!write_ntfs_br(&fake_fd)) break;
// Note: NTFS requires a full remount after writing the PBR. We dismount when we lock // Note: NTFS requires a full remount after writing the PBR. We dismount when we lock
// so that's not an issue, but if you don't remount, you don't boot! // and also go through a forced remount, so that shouldn't be an issue.
// But with NTFS, if you don't remount, you don't boot!
return TRUE; return TRUE;
default: default:
uprintf("unsupported FS for FS BR processing\n"); uprintf("unsupported FS for FS BR processing\n");
@ -384,7 +385,7 @@ static BOOL WritePBR(HANDLE hLogicalVolume, BOOL bFreeDOS)
/* /*
* Standalone thread for the formatting operation * Standalone thread for the formatting operation
*/ */
void __cdecl FormatThread(void* param) DWORD WINAPI FormatThread(LPVOID param)
{ {
DWORD num = (DWORD)(uintptr_t)param; DWORD num = (DWORD)(uintptr_t)param;
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
@ -397,11 +398,6 @@ void __cdecl FormatThread(void* param)
FILE* log_fd; FILE* log_fd;
int r; int r;
#ifdef RUFUS_TEST
ExtractISO(ISO_IMAGE, ISO_DEST, FALSE);
goto out;
#endif
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
if (hPhysicalDrive == INVALID_HANDLE_VALUE) { if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
@ -542,21 +538,29 @@ void __cdecl FormatThread(void* param)
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) != DT_ISO) { if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) != DT_ISO) {
PrintStatus(0, TRUE, "Copying DOS files..."); PrintStatus(0, TRUE, "Copying DOS files...");
if (!ExtractDOS(drive_name)) { if (!ExtractDOS(drive_name)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; if (!FormatStatus)
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
goto out; goto out;
} }
} else if (iso_path != NULL) {
PrintStatus(0, TRUE, "Copying ISO files...");
drive_name[2] = 0;
if ( (!ExtractISO(iso_path, drive_name, FALSE)) && (!FormatStatus)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
}
drive_name[2] = '\\';
} }
break; break;
// Syslinux requires patching of the PBR after the files have been extracted // Syslinux requires patching of the PBR after the files have been extracted
case DT_SYSLINUX: case DT_SYSLINUX:
if (!InstallSyslinux(num, drive_name)) { if (!InstallSyslinux(num, drive_name)) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
goto out;
} }
break; break;
} }
} }
// TODO: the only way to properly recover from a cancel will be through a device reset
// We issue a complete remount of the filesystem at the end on account of: // We issue a complete remount of the filesystem at the end on account of:
// - Ensuring the file explorer properly detects that the volume was updated // - Ensuring the file explorer properly detects that the volume was updated
// - Ensuring that an NTFS system will be reparsed so that it becomes bootable // - Ensuring that an NTFS system will be reparsed so that it becomes bootable
@ -579,5 +583,5 @@ out:
safe_unlockclose(hLogicalVolume); safe_unlockclose(hLogicalVolume);
safe_unlockclose(hPhysicalDrive); safe_unlockclose(hPhysicalDrive);
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
_endthread(); ExitThread(0);
} }

164
src/iso.c
View file

@ -52,8 +52,9 @@
#endif #endif
// How often should we update the progress bar (in 2K blocks) as updating // How often should we update the progress bar (in 2K blocks) as updating
// the progress bar for every block will bring extraction to a crawl // the progress bar for every block will bring extraction to a crawl
#define PROGRESS_UPDATE 1024 #define PROGRESS_THRESHOLD 1024
#define FOUR_GIGABYTES 4294967296LL #define THREADED_CLOSE_THRESHOLD (20 * 1024 * 1024) // 20 MB
#define FOUR_GIGABYTES 4294967296LL
// Needed for UDF ISO access // Needed for UDF ISO access
CdIo_t* cdio_open (const char *psz_source, driver_id_t driver_id) {return NULL;} CdIo_t* cdio_open (const char *psz_source, driver_id_t driver_id) {return NULL;}
@ -64,12 +65,52 @@ static const char *psz_extract_dir;
static uint64_t total_blocks, nb_blocks; static uint64_t total_blocks, nb_blocks;
static BOOL scan_only = FALSE; static BOOL scan_only = FALSE;
// TODO: Unicode support, timestamp & permissions preservation // TODO: Timestamp & permissions preservation
// Convert a file size to human readable
static __inline char* size_to_hr(int64_t size)
{
int suffix = 0;
static char str_size[24];
const char* sizes[] = { "bytes", "KB", "MB", "GB", "TB", "PB" };
double hr_size = (double)size;
while ((suffix < ARRAYSIZE(sizes)) && (hr_size >= 1024.0)) {
hr_size /= 1024.0;
suffix++;
}
safe_sprintf(str_size, sizeof(str_size), " (%0.1f %s)", hr_size, sizes[suffix]);
return str_size;
}
// Interruptible thread for handle closure on large files
DWORD WINAPI ISOCloseHandleThread(LPVOID param)
{
CloseHandle((HANDLE)param);
ExitThread(0);
}
#define SAFE_CLOSEHANDLE_THREADED(handle) \
if (!threaded_close) { \
safe_closehandle(handle); \
} else { \
thid = CreateThread(NULL, 0, ISOCloseHandleThread, (LPVOID)handle, 0, NULL); \
while (WaitForSingleObject(thid, 1000) == WAIT_TIMEOUT) { \
if (!FormatStatus) continue; \
safe_closehandle(thid); \
break; \
} \
handle = NULL; \
threaded_close = 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) static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path)
{ {
FILE *fd = NULL; HANDLE thid, file_handle = NULL;
DWORD buf_size, wr_size;
BOOL threaded_close = FALSE;
int i_length; int i_length;
size_t i, nul_pos;
char* psz_fullpath; char* psz_fullpath;
const char* psz_basename; const char* psz_basename;
udf_dirent_t *p_udf_dirent2; udf_dirent_t *p_udf_dirent2;
@ -82,19 +123,24 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) { while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
psz_basename = udf_get_filename(p_udf_dirent); psz_basename = udf_get_filename(p_udf_dirent);
i_length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir)); i_length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir) + 24);
psz_fullpath = (char*)calloc(sizeof(char), i_length); psz_fullpath = (char*)calloc(sizeof(char), i_length);
if (psz_fullpath == NULL) { if (psz_fullpath == NULL) {
uprintf("Error allocating file name\n"); uprintf("Error allocating file name\n");
goto out; goto out;
} }
i_length = _snprintf(psz_fullpath, i_length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename); i_length = safe_sprintf(psz_fullpath, i_length, "%s%s/%s", psz_extract_dir, psz_path, psz_basename);
if (i_length < 0) { if (i_length < 0) {
goto out; goto out;
} }
if (udf_is_dir(p_udf_dirent)) { if (udf_is_dir(p_udf_dirent)) {
if (!scan_only) if (!scan_only) {
_mkdir(psz_fullpath); _mkdir(psz_fullpath);
} else {
// Check for an "isolinux\" dir in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, "isolinux") == 0))
iso_report.has_isolinux = TRUE;
}
p_udf_dirent2 = udf_opendir(p_udf_dirent); p_udf_dirent2 = udf_opendir(p_udf_dirent);
if (p_udf_dirent2 != NULL) { if (p_udf_dirent2 != NULL) {
if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)])) if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)]))
@ -103,6 +149,9 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
} else { } else {
i_file_length = udf_get_file_length(p_udf_dirent); i_file_length = udf_get_file_length(p_udf_dirent);
if (scan_only) { if (scan_only) {
// Check for a "bootmgr" file in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, "bootmgr") == 0))
iso_report.has_bootmgr = TRUE;
if (i_file_length >= FOUR_GIGABYTES) if (i_file_length >= FOUR_GIGABYTES)
iso_report.has_4GB_file = TRUE; iso_report.has_4GB_file = TRUE;
total_blocks += i_file_length/UDF_BLOCKSIZE; total_blocks += i_file_length/UDF_BLOCKSIZE;
@ -111,13 +160,25 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
safe_free(psz_fullpath); safe_free(psz_fullpath);
continue; continue;
} }
// Replace slashes with backslashes and append the size to the path for UI display
nul_pos = safe_strlen(psz_fullpath);
for (i=0; i<nul_pos; i++) {
if (psz_fullpath[i] == '/')
psz_fullpath[i] = '\\';
}
safe_strcpy(&psz_fullpath[nul_pos], 24, size_to_hr(i_file_length));
uprintf("Extracting: %s\n", psz_fullpath); uprintf("Extracting: %s\n", psz_fullpath);
SetWindowTextU(hISOFileName, psz_fullpath); SetWindowTextU(hISOFileName, psz_fullpath);
fd = fopen(psz_fullpath, "wb"); // Remove the appended size for extraction
if (fd == NULL) { psz_fullpath[nul_pos] = 0;
uprintf(" Unable to create file\n"); file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
uprintf(" Unable to create file: %s\n", WindowsErrorString());
goto out; goto out;
} }
threaded_close = (i_file_length > THREADED_CLOSE_THRESHOLD);
if (threaded_close) uprintf("will use threaded close\n");
while (i_file_length > 0) { while (i_file_length > 0) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
memset(buf, 0, UDF_BLOCKSIZE); memset(buf, 0, UDF_BLOCKSIZE);
@ -126,17 +187,23 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
uprintf(" Error reading UDF file %s\n", &psz_fullpath[strlen(psz_extract_dir)]); uprintf(" Error reading UDF file %s\n", &psz_fullpath[strlen(psz_extract_dir)]);
goto out; goto out;
} }
fwrite(buf, (size_t)MIN(i_file_length, i_read), 1, fd); buf_size = (DWORD)MIN(i_file_length, i_read);
if (ferror(fd)) { if (!WriteFile(file_handle, buf, buf_size, &wr_size, NULL) || (buf_size != wr_size)) {
uprintf(" Error writing file\n"); uprintf(" Error writing file: %s\n", WindowsErrorString());
goto out; goto out;
} }
i_file_length -= i_read; i_file_length -= i_read;
if (nb_blocks++ % PROGRESS_UPDATE == 0) if (nb_blocks++ % PROGRESS_THRESHOLD == 0) {
SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0);
}
} }
fclose(fd); // If you have a fast USB 3.0 device, the default Windows buffering does an
fd = NULL; // excellent job at compensating for our small blocks read/writes to max out the
// device's bandwidth.
// The drawback however is with cancellation. With a large file, CloseHandle()
// may take forever to complete on a large file and is not an interruptible
// operation. To compensate for this, we create a thread when needed.
SAFE_CLOSEHANDLE_THREADED(file_handle);
} }
safe_free(psz_fullpath); safe_free(psz_fullpath);
} }
@ -145,30 +212,32 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
out: out:
if (p_udf_dirent != NULL) if (p_udf_dirent != NULL)
udf_dirent_free(p_udf_dirent); udf_dirent_free(p_udf_dirent);
if (fd != NULL) SAFE_CLOSEHANDLE_THREADED(file_handle);
fclose(fd);
safe_free(psz_fullpath); safe_free(psz_fullpath);
return 1; return 1;
} }
// Returns 0 on success, nonzero on error
static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
{ {
FILE *fd = NULL; HANDLE thid, file_handle = NULL;
DWORD buf_size, wr_size;
BOOL threaded_close = FALSE;
int i_length, r = 1; int i_length, r = 1;
char psz_fullpath[4096], *psz_basename; char psz_fullpath[1024], *psz_basename;
const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)]; const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
unsigned char buf[ISO_BLOCKSIZE]; unsigned char buf[ISO_BLOCKSIZE];
CdioListNode_t* p_entnode; CdioListNode_t* p_entnode;
iso9660_stat_t *p_statbuf; iso9660_stat_t *p_statbuf;
CdioList_t* p_entlist; CdioList_t* p_entlist;
size_t i; size_t i, nul_pos;
lsn_t lsn; lsn_t lsn;
int64_t i_file_length; int64_t i_file_length;
if ((p_iso == NULL) || (psz_path == NULL)) if ((p_iso == NULL) || (psz_path == NULL))
return 1; return 1;
i_length = _snprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path); i_length = safe_sprintf(psz_fullpath, sizeof(psz_fullpath), "%s%s/", psz_extract_dir, psz_path);
if (i_length < 0) if (i_length < 0)
return 1; return 1;
psz_basename = &psz_fullpath[i_length]; psz_basename = &psz_fullpath[i_length];
@ -186,13 +255,21 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
continue; continue;
iso9660_name_translate(p_statbuf->filename, psz_basename); iso9660_name_translate(p_statbuf->filename, psz_basename);
if (p_statbuf->type == _STAT_DIR) { if (p_statbuf->type == _STAT_DIR) {
if (!scan_only) if (!scan_only) {
_mkdir(psz_fullpath); _mkdir(psz_fullpath);
} else {
// Check for an "isolinux\" dir in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, "isolinux") == 0))
iso_report.has_isolinux = TRUE;
}
if (iso_extract_files(p_iso, psz_iso_name)) if (iso_extract_files(p_iso, psz_iso_name))
goto out; goto out;
} else { } else {
i_file_length = p_statbuf->size; i_file_length = p_statbuf->size;
if (scan_only) { if (scan_only) {
// Check for a "bootmgr" file in root (psz_path = "")
if ((*psz_path == 0) && (safe_strcmp(psz_basename, "bootmgr") == 0))
iso_report.has_bootmgr = TRUE;
if (i_file_length >= FOUR_GIGABYTES) if (i_file_length >= FOUR_GIGABYTES)
iso_report.has_4GB_file = TRUE; iso_report.has_4GB_file = TRUE;
total_blocks += i_file_length/ISO_BLOCKSIZE; total_blocks += i_file_length/ISO_BLOCKSIZE;
@ -200,12 +277,23 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
total_blocks++; total_blocks++;
continue; continue;
} }
// Replace slashes with backslashes and append the size to the path for UI display
nul_pos = safe_strlen(psz_fullpath);
for (i=0; i<nul_pos; i++) {
if (psz_fullpath[i] == '/')
psz_fullpath[i] = '\\';
}
safe_strcpy(&psz_fullpath[nul_pos], 24, size_to_hr(i_file_length));
uprintf("Extracting: %s\n", psz_fullpath); uprintf("Extracting: %s\n", psz_fullpath);
fd = fopen(psz_fullpath, "wb"); SetWindowTextU(hISOFileName, psz_fullpath);
if (fd == NULL) { psz_fullpath[nul_pos] = 0;
uprintf(" Unable to create file\n"); file_handle = CreateFileU(psz_fullpath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
uprintf(" Unable to create file: %s\n", WindowsErrorString());
goto out; goto out;
} }
threaded_close = (i_file_length > THREADED_CLOSE_THRESHOLD);
for (i = 0; i_file_length > 0; i++) { for (i = 0; i_file_length > 0; i++) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
memset(buf, 0, ISO_BLOCKSIZE); memset(buf, 0, ISO_BLOCKSIZE);
@ -215,24 +303,23 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
psz_iso_name, (long unsigned int)lsn); psz_iso_name, (long unsigned int)lsn);
goto out; goto out;
} }
fwrite(buf, (size_t)MIN(i_file_length, ISO_BLOCKSIZE), 1, fd); buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
if (ferror(fd)) { if (!WriteFile(file_handle, buf, buf_size, &wr_size, NULL) || (buf_size != wr_size)) {
uprintf(" Error writing file\n"); uprintf(" Error writing file: %s\n", WindowsErrorString());
goto out; goto out;
} }
i_file_length -= ISO_BLOCKSIZE; i_file_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_UPDATE == 0) if (nb_blocks++ % PROGRESS_THRESHOLD == 0) {
SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0);
}
} }
fclose(fd); SAFE_CLOSEHANDLE_THREADED(file_handle);
fd = NULL;
} }
} }
r = 0; r = 0;
out: out:
if (fd != NULL) SAFE_CLOSEHANDLE_THREADED(file_handle);
fclose(fd);
_cdio_list_free(p_entlist, true); _cdio_list_free(p_entlist, true);
return r; return r;
} }
@ -254,10 +341,11 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan)
psz_extract_dir = dest_dir; psz_extract_dir = dest_dir;
progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE); progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE);
if (scan_only) { if (scan_only) {
uprintf(scan_text);
total_blocks = 0; total_blocks = 0;
iso_report.projected_size = 0; iso_report.projected_size = 0;
iso_report.has_4GB_file = FALSE; iso_report.has_4GB_file = FALSE;
iso_report.has_bootmgr = FALSE;
iso_report.has_isolinux = FALSE;
// Change the Window title and static text // Change the Window title and static text
SetWindowTextU(hISOProgressDlg, scan_text); SetWindowTextU(hISOProgressDlg, scan_text);
SetWindowTextU(hISOFileName, scan_text); SetWindowTextU(hISOFileName, scan_text);
@ -282,6 +370,7 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan)
p_udf = udf_open(src_iso); p_udf = udf_open(src_iso);
if (p_udf == NULL) if (p_udf == NULL)
goto try_iso; goto try_iso;
uprintf("Disc image is an UDF image\n");
p_udf_root = udf_get_root(p_udf, true, 0); p_udf_root = udf_get_root(p_udf, true, 0);
if (p_udf_root == NULL) { if (p_udf_root == NULL) {
@ -297,6 +386,7 @@ try_iso:
uprintf("Unable to open image '%s'.\n", src_iso); uprintf("Unable to open image '%s'.\n", src_iso);
goto out; goto out;
} }
uprintf("Disc image is an ISO9660 image\n");
r = iso_extract_files(p_iso, ""); r = iso_extract_files(p_iso, "");
out: out:
@ -310,6 +400,6 @@ out:
if (p_udf != NULL) if (p_udf != NULL)
udf_close(p_udf); udf_close(p_udf);
if ((r != 0) && (FormatStatus == 0)) if ((r != 0) && (FormatStatus == 0))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT));
return r; return (r == 0);
} }

View file

@ -674,8 +674,10 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
const unsigned int i_len = p_udf_dirent->fid->i_file_id; const unsigned int i_len = p_udf_dirent->fid->i_file_id;
if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &p_udf_dirent->fe, p_udf->i_part_start if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &p_udf_dirent->fe, p_udf->i_part_start
+ p_udf_dirent->fid->icb.loc.lba, 1)) + p_udf_dirent->fid->icb.loc.lba, 1)) {
udf_dirent_free(p_udf_dirent);
return NULL; return NULL;
}
if (strlen(p_udf_dirent->psz_name) < i_len) if (strlen(p_udf_dirent->psz_name) < i_len)
p_udf_dirent->psz_name = (char *) p_udf_dirent->psz_name = (char *)
@ -687,6 +689,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
} }
return p_udf_dirent; return p_udf_dirent;
} }
udf_dirent_free(p_udf_dirent);
return NULL; return NULL;
} }

View file

@ -53,19 +53,20 @@ static BOOL existing_key = FALSE;
HINSTANCE hMainInstance; HINSTANCE hMainInstance;
HWND hMainDialog; HWND hMainDialog;
char szFolderPath[MAX_PATH]; char szFolderPath[MAX_PATH];
char* iso_path = NULL;
float fScale = 1.0f; float fScale = 1.0f;
int default_fs; int default_fs;
HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses; HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName; HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName;
BOOL bWithFreeDOS, bWithSyslinux; BOOL bWithFreeDOS, bWithSyslinux;
static HANDLE format_thid = NULL;
static HWND hDeviceTooltip = NULL, hFSTooltip = NULL, hProgress = NULL; static HWND hDeviceTooltip = NULL, hFSTooltip = NULL, hProgress = NULL;
static HWND hDOS = NULL, hSelectISO = NULL, hISOToolTip = NULL; static HWND hDOS = NULL, hSelectISO = NULL, hISOToolTip = NULL;
static HICON hIconDisc; static HICON hIconDisc;
static StrArray DriveID, DriveLabel; static StrArray DriveID, DriveLabel;
static char szTimer[10] = "00:00:00"; static char szTimer[12] = "00:00:00";
static unsigned int timer; static unsigned int timer;
static char* iso_path = NULL;
/* /*
* The following is used to allocate slots within the progress bar * The following is used to allocate slots within the progress bar
@ -905,8 +906,10 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
case IDC_ISO_ABORT: case IDC_ISO_ABORT:
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
PrintStatus(0, FALSE, "Cancelling - please wait..."); // if (format_thid != NULL)
uprintf("ISO: USER CANCEL\n"); // CancelSynchronousIo(format_thid);
PrintStatus(0, FALSE, "Cancelling - This might take a while...");
uprintf("Cancelling (ISO)\n");
return TRUE; return TRUE;
} }
case WM_CLOSE: // prevent closure using Alt-F4 case WM_CLOSE: // prevent closure using Alt-F4
@ -916,16 +919,27 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
} }
// The scanning process can be blocking for message processing => use a thread // The scanning process can be blocking for message processing => use a thread
void __cdecl ISOScanThread(void* param) DWORD WINAPI ISOScanThread(LPVOID param)
{ {
int i; size_t i;
// ExtractISO(ISO_IMAGE, ISO_DEST, TRUE);
PrintStatus(0, TRUE, "Scanning ISO image...\n"); PrintStatus(0, TRUE, "Scanning ISO image...\n");
ExtractISO(iso_path, "", TRUE); if (!ExtractISO(iso_path, "", TRUE)) {
uprintf("Projected size: %lld\nHas 4GB: %s\n", iso_report.projected_size, iso_report.has_4GB_file?"TRUE":"FALSE"); PrintStatus(0, TRUE, "Failed to scan ISO image.");
for (i=safe_strlen(iso_path); (i>=0)&&(iso_path[i] != '\\'); i--); goto out;
PrintStatus(0, TRUE, "Using ISO: '%s'\n", &iso_path[i+1]); }
_endthread(); uprintf("ISO size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c\n", iso_report.projected_size,
iso_report.has_4GB_file?'Y':'N', iso_report.has_bootmgr?'Y':'N', iso_report.has_isolinux?'Y':'N');
if (!iso_report.has_bootmgr) {
MessageBoxU(hMainDialog, "This version of Rufus supports only\n"
"ISO images that rely on 'bootmgr' - sorry.", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
safe_free(iso_path);
} else {
for (i=safe_strlen(iso_path); (i>=0)&&(iso_path[i] != '\\'); i--);
PrintStatus(0, TRUE, "Using ISO: '%s'\n", &iso_path[i+1]);
}
out:
ExitThread(0);
} }
// Helper function to obtain a handle to a DLL // Helper function to obtain a handle to a DLL
@ -965,6 +979,10 @@ void InitDialog(HWND hDlg)
HICON hSmallIcon, hBigIcon; HICON hSmallIcon, hBigIcon;
char tmp[128]; char tmp[128];
#ifdef RUFUS_TEST
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_SHOW);
#endif
// Quite a burden to carry around as parameters // Quite a burden to carry around as parameters
hMainDialog = hDlg; hMainDialog = hDlg;
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
@ -1009,8 +1027,7 @@ void InitDialog(HWND hDlg)
IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 1)); IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 1));
// Fill up the DOS type dropdown // Fill up the DOS type dropdown
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME)); IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME));
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO"), DT_ISO)); IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, DT_WINME));
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, bWithFreeDOS?DT_FREEDOS:DT_WINME));
// Create the string array // Create the string array
StrArrayCreate(&DriveID, MAX_DRIVES); StrArrayCreate(&DriveID, MAX_DRIVES);
StrArrayCreate(&DriveLabel, MAX_DRIVES); StrArrayCreate(&DriveLabel, MAX_DRIVES);
@ -1044,13 +1061,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
int nDeviceIndex, fs, dt; int nDeviceIndex, fs, dt;
DWORD DeviceNum; DWORD DeviceNum;
char str[MAX_PATH], tmp[128]; char str[MAX_PATH], tmp[128];
static uintptr_t format_thid = -1L;
static UINT uDOSChecked = BST_CHECKED; static UINT uDOSChecked = BST_CHECKED;
switch (message) { switch (message) {
case WM_DEVICECHANGE: case WM_DEVICECHANGE:
if ( (format_thid == -1L) && if ( (format_thid == NULL) &&
((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) ) { ((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) ) {
GetUSBDevices(); GetUSBDevices();
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
@ -1079,15 +1095,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
switch(LOWORD(wParam)) { switch(LOWORD(wParam)) {
case IDOK: // close application case IDOK: // close application
case IDCANCEL: case IDCANCEL:
if (format_thid != -1L) { if (format_thid != NULL) {
if (MessageBoxA(hMainDialog, "Cancelling may leave the device in an UNUSABLE state.\r\n" if (MessageBoxA(hMainDialog, "Cancelling may leave the device in an UNUSABLE state.\r\n"
"If you are sure you want to cancel, click YES. Otherwise, click NO.", "If you are sure you want to cancel, click YES. Otherwise, click NO.",
RUFUS_CANCELBOX_TITLE, MB_YESNO|MB_ICONWARNING) == IDYES) { RUFUS_CANCELBOX_TITLE, MB_YESNO|MB_ICONWARNING) == IDYES) {
// Operation may have completed in the meantime // Operation may have completed in the meantime
if (format_thid != -1L) { if (format_thid != NULL) {
// CancelSynchronousIo(format_thid);
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
PrintStatus(0, FALSE, "Cancelling - please wait..."); PrintStatus(0, FALSE, "Cancelling - Please wait...");
uprintf("USER CANCEL\n"); uprintf("Cancelling (General)\n");
} }
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
@ -1103,19 +1120,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break; break;
#ifdef RUFUS_TEST #ifdef RUFUS_TEST
case IDC_TEST: case IDC_TEST:
FormatStatus = 0;
// You'd think that Windows would let you instantiate a modeless dialog wherever
// but you'd be wrong. It has to be done in the main callback!
if (!IsWindow(hISOProgressDlg)) {
hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT),
hDlg, (DLGPROC)ISOProc);
// The window is not visible by default but takes focus => restore it
SetFocus(hDlg);
}
if (_beginthread(ISOScanThread, 0, NULL) == -1L) {
uprintf("Unable to start ISO scanning thread");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
}
break; break;
#endif #endif
case IDC_DEVICE: case IDC_DEVICE:
@ -1150,7 +1154,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if (bWithSyslinux) if (bWithSyslinux)
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "Syslinux"), DT_SYSLINUX)); IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "Syslinux"), DT_SYSLINUX));
} }
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO"), DT_ISO)); if (fs == FS_NTFS) {
// Only allow ISO with NTFS for the time being
IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO..."), DT_ISO));
}
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, (bWithFreeDOS && (fs != FS_NTFS))?1:0)); IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, (bWithFreeDOS && (fs != FS_NTFS))?1:0));
if (!IsWindowEnabled(hDOS)) { if (!IsWindowEnabled(hDOS)) {
EnableWindow(hDOS, TRUE); EnableWindow(hDOS, TRUE);
@ -1189,18 +1196,31 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// The window is not visible by default but takes focus => restore it // The window is not visible by default but takes focus => restore it
SetFocus(hDlg); SetFocus(hDlg);
} }
if (_beginthread(ISOScanThread, 0, NULL) == -1L) { if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, 0) == NULL) {
uprintf("Unable to start ISO scanning thread"); uprintf("Unable to start ISO scanning thread");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
} }
break; break;
case IDC_START: case IDC_START:
if (format_thid != -1L) { if (format_thid != NULL) {
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
FormatStatus = 0; FormatStatus = 0;
nDeviceIndex = ComboBox_GetCurSel(hDeviceList); nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
if (nDeviceIndex != CB_ERR) { if (nDeviceIndex != CB_ERR) {
if (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_ISO) {
if (iso_path == NULL) {
MessageBoxA(hMainDialog, "Please click on the disc button to select a bootable ISO,\n"
"or unselect the \"Create bootable disk...\" checkbox.",
"No ISO image selected...", MB_OK|MB_ICONERROR);
break;
}
if (iso_report.projected_size > (uint64_t)SelectedDrive.DiskSize) {
MessageBoxA(hMainDialog, "This ISO image is too big "
"for the selected target.", "ISO image too big...", MB_OK|MB_ICONERROR);
break;
}
}
GetWindowTextA(hDeviceList, tmp, sizeof(tmp)); GetWindowTextA(hDeviceList, tmp, sizeof(tmp));
safe_sprintf(str, sizeof(str), "WARNING: ALL DATA ON DEVICE %s\r\nWILL BE DESTROYED.\r\n" 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); "To continue with this operation, click OK. To quit click CANCEL.", tmp);
@ -1216,8 +1236,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// The window is not visible by default but takes focus => restore it // The window is not visible by default but takes focus => restore it
SetFocus(hDlg); SetFocus(hDlg);
} }
format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum); format_thid = CreateThread(NULL, 0, FormatThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL);
if (format_thid == -1L) { if (format_thid == NULL) {
uprintf("Unable to start formatting thread"); uprintf("Unable to start formatting thread");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
@ -1236,16 +1256,14 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
case WM_CLOSE: case WM_CLOSE:
if (format_thid != -1L) { if (format_thid != NULL) {
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
DestroyAllTooltips();
safe_free(iso_path);
PostQuitMessage(0); PostQuitMessage(0);
break; break;
case UM_FORMAT_COMPLETED: case UM_FORMAT_COMPLETED:
format_thid = -1L; format_thid = NULL;
// Stop the timer // Stop the timer
KillTimer(hMainDialog, TID_APP_TIMER); KillTimer(hMainDialog, TID_APP_TIMER);
// Close the cancel MessageBox if active // Close the cancel MessageBox if active
@ -1256,7 +1274,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
PrintStatus(0, FALSE, "DONE"); PrintStatus(0, FALSE, "DONE");
} else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) { } else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) {
PrintStatus(0, FALSE, "Cancelled"); PrintStatus(0, FALSE, "Cancelled");
Notification(MSG_INFO, "Cancelled", "Operation cancelled by the user."); Notification(MSG_INFO, "Cancelled", "Operation cancelled by the user.\n"
"If you aborted during file extraction, you should replug the drive...");
} else { } else {
PrintStatus(0, FALSE, "FAILED"); PrintStatus(0, FALSE, "FAILED");
Notification(MSG_ERROR, "Error", "Error: %s", StrError(FormatStatus)); Notification(MSG_ERROR, "Error", "Error: %s", StrError(FormatStatus));
@ -1321,10 +1340,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
MessageBoxA(NULL, "Could not create Window", "DialogBox failure", MB_ICONSTOP); MessageBoxA(NULL, "Could not create Window", "DialogBox failure", MB_ICONSTOP);
goto out; goto out;
} }
// CenterDialog(hDlg);
#ifndef RUFUS_TEST
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_HIDE);
#endif
ShowWindow(hDlg, SW_SHOWNORMAL); ShowWindow(hDlg, SW_SHOWNORMAL);
UpdateWindow(hDlg); UpdateWindow(hDlg);
@ -1346,6 +1361,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
} }
out: out:
DestroyAllTooltips();
safe_free(iso_path);
#ifdef DISABLE_AUTORUN #ifdef DISABLE_AUTORUN
SetLGP(TRUE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0); SetLGP(TRUE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0);
#endif #endif

View file

@ -27,12 +27,6 @@
/* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */ /* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */
//#define RUFUS_TEST //#define RUFUS_TEST
//#define ISO_DEST "D:/tmp/iso"
//#define ISO_IMAGE "D:\\Incoming\\Windows 8 Preview\\WindowsDeveloperPreview-64bit-English-Developer.iso"
//#define ISO_IMAGE "D:\\fd11src.iso", "D:/tmp/iso"
//#define ISO_IMAGE "D:\\Incoming\\GRMSDKX_EN_DVD.iso"
//#define ISO_IMAGE "D:\\Incoming\\en_windows_driver_kit_3790.iso"
//#define ISO_IMAGE "D:\\Incoming\\en_windows_7_ultimate_with_sp1_x64_dvd_618240.iso"
#define STR_NO_LABEL "NO_LABEL" #define STR_NO_LABEL "NO_LABEL"
#define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation" #define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation"
@ -152,6 +146,8 @@ typedef struct {
typedef struct { typedef struct {
uint64_t projected_size; uint64_t projected_size;
BOOL has_4GB_file; BOOL has_4GB_file;
BOOL has_bootmgr;
BOOL has_isolinux;
} RUFUS_ISO_REPORT; } RUFUS_ISO_REPORT;
/* /*
@ -163,6 +159,7 @@ extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName; extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName;
extern float fScale; extern float fScale;
extern char szFolderPath[MAX_PATH]; extern char szFolderPath[MAX_PATH];
extern char* iso_path;
extern DWORD FormatStatus; extern DWORD FormatStatus;
extern RUFUS_DRIVE_INFO SelectedDrive; extern RUFUS_DRIVE_INFO SelectedDrive;
extern const int nb_steps[FS_MAX]; extern const int nb_steps[FS_MAX];
@ -187,7 +184,7 @@ extern BOOL Notification(int type, char* title, char* format, ...);
extern BOOL ExtractDOS(const char* path); extern BOOL ExtractDOS(const char* path);
extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
extern BOOL InstallSyslinux(DWORD num, const char* drive_name); extern BOOL InstallSyslinux(DWORD num, const char* drive_name);
extern void __cdecl FormatThread(void* param); DWORD WINAPI FormatThread(void* param);
extern BOOL CreatePartition(HANDLE hDrive); extern BOOL CreatePartition(HANDLE hDrive);
extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive); extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive);
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);

View file

@ -8,7 +8,7 @@
// Generated from the TEXTINCLUDE 2 resource. // Generated from the TEXTINCLUDE 2 resource.
// //
#include <windows.h> #include <windows.h>
#ifndef __GNUC__ #ifndef __MINGW32__
#include "../ms-config.h" #include "../ms-config.h"
#endif #endif
#ifndef IDC_STATIC #ifndef IDC_STATIC
@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 278 IDD_DIALOG DIALOGEX 12, 12, 206, 278
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.0.7.126" CAPTION "Rufus v1.0.7.127"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,236,50,14 DEFPUSHBUTTON "Start",IDC_START,94,236,50,14
@ -56,7 +56,7 @@ BEGIN
CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,7,210,189,9 CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,7,210,189,9
COMBOBOX IDC_DOSTYPE,118,183,45,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_DOSTYPE,118,183,45,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_NBPASSES,118,159,45,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_NBPASSES,118,159,45,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Test",IDC_TEST,62,236,20,14 PUSHBUTTON "Test",IDC_TEST,62,236,20,14,NOT WS_VISIBLE
PUSHBUTTON "...",IDC_SELECT_ISO,168,182,23,14,BS_ICON | NOT WS_VISIBLE PUSHBUTTON "...",IDC_SELECT_ISO,168,182,23,14,BS_ICON | NOT WS_VISIBLE
END END
@ -71,7 +71,7 @@ BEGIN
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
"SysLink",WS_TABSTOP,46,47,114,9 "SysLink",WS_TABSTOP,46,47,114,9
LTEXT "Version 1.0.7 (Build 126)",IDC_STATIC,46,19,78,8 LTEXT "Version 1.0.7 (Build 127)",IDC_STATIC,46,19,78,8
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP 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 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 LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
@ -92,14 +92,14 @@ BEGIN
DEFPUSHBUTTON "Close",IDCANCEL,211,44,50,14 DEFPUSHBUTTON "Close",IDCANCEL,211,44,50,14
END END
IDD_ISO_EXTRACT DIALOGEX 0, 0, 262, 73 IDD_ISO_EXTRACT DIALOGEX 0, 0, 262, 66
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
CAPTION "Extracting Files..." CAPTION "Copying ISO files..."
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
LTEXT "",IDC_ISO_FILENAME,14,9,232,14 LTEXT "",IDC_ISO_FILENAME,8,10,246,13,SS_PATHELLIPSIS
CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,14,32,231,8 CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,7,26,247,8
PUSHBUTTON "Abort",IDC_ISO_ABORT,112,50,50,14 PUSHBUTTON "Cancel",IDC_ISO_ABORT,111,43,50,14
END END
IDD_LICENSE DIALOGEX 0, 0, 335, 205 IDD_LICENSE DIALOGEX 0, 0, 335, 205
@ -126,7 +126,7 @@ END
2 TEXTINCLUDE 2 TEXTINCLUDE
BEGIN BEGIN
"#include <windows.h>\r\n" "#include <windows.h>\r\n"
"#ifndef __GNUC__\r\n" "#ifndef __MINGW32__\r\n"
"#include ""../ms-config.h""\r\n" "#include ""../ms-config.h""\r\n"
"#endif\r\n" "#endif\r\n"
"#ifndef IDC_STATIC\r\n" "#ifndef IDC_STATIC\r\n"
@ -207,6 +207,7 @@ BEGIN
IDD_ISO_EXTRACT, DIALOG IDD_ISO_EXTRACT, DIALOG
BEGIN BEGIN
BOTTOMMARGIN, 65
END END
IDD_LICENSE, DIALOG IDD_LICENSE, DIALOG
@ -222,8 +223,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,7,126 FILEVERSION 1,0,7,127
PRODUCTVERSION 1,0,7,126 PRODUCTVERSION 1,0,7,127
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -240,13 +241,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "akeo.ie" VALUE "CompanyName", "akeo.ie"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.0.7.126" VALUE "FileVersion", "1.0.7.127"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe" VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.0.7.126" VALUE "ProductVersion", "1.0.7.127"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -213,7 +213,7 @@ const char* StrError(DWORD error_code)
case ERROR_PARTITION_FAILURE: case ERROR_PARTITION_FAILURE:
return "Error while partitioning drive"; return "Error while partitioning drive";
case ERROR_CANNOT_COPY: case ERROR_CANNOT_COPY:
return "Could not copy MS-DOS files"; return "Could not copy files to target drive";
case ERROR_CANCELLED: case ERROR_CANCELLED:
return "Cancelled by user"; return "Cancelled by user";
case ERROR_CANT_START_THREAD: case ERROR_CANT_START_THREAD:
@ -224,6 +224,9 @@ const char* StrError(DWORD error_code)
return "ISO image scan failure"; return "ISO image scan failure";
case ERROR_ISO_EXTRACT: case ERROR_ISO_EXTRACT:
return "ISO image scan failure"; return "ISO image scan failure";
case ERROR_CANT_REMOUNT_VOLUME:
return "Unable to remount volume. You may have to use the\n"
"mountvol.exe command to make your device accessible again";
default: default:
uprintf("Unknown error: %08X\n", error_code); uprintf("Unknown error: %08X\n", error_code);
SetLastError(error_code); SetLastError(error_code);