mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[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:
parent
22276ccb5a
commit
472db8b592
7 changed files with 232 additions and 117 deletions
24
src/format.c
24
src/format.c
|
@ -371,7 +371,8 @@ static BOOL WritePBR(HANDLE hLogicalVolume, BOOL bFreeDOS)
|
|||
uprintf("Confirmed new volume has an NTFS boot sector\n");
|
||||
if (!write_ntfs_br(&fake_fd)) break;
|
||||
// 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;
|
||||
default:
|
||||
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
|
||||
*/
|
||||
void __cdecl FormatThread(void* param)
|
||||
DWORD WINAPI FormatThread(LPVOID param)
|
||||
{
|
||||
DWORD num = (DWORD)(uintptr_t)param;
|
||||
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
||||
|
@ -397,11 +398,6 @@ void __cdecl FormatThread(void* param)
|
|||
FILE* log_fd;
|
||||
int r;
|
||||
|
||||
#ifdef RUFUS_TEST
|
||||
ExtractISO(ISO_IMAGE, ISO_DEST, FALSE);
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
||||
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
|
||||
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) {
|
||||
PrintStatus(0, TRUE, "Copying DOS files...");
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
// Syslinux requires patching of the PBR after the files have been extracted
|
||||
case DT_SYSLINUX:
|
||||
if (!InstallSyslinux(num, drive_name)) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_INSTALL_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
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:
|
||||
// - Ensuring the file explorer properly detects that the volume was updated
|
||||
// - Ensuring that an NTFS system will be reparsed so that it becomes bootable
|
||||
|
@ -579,5 +583,5 @@ out:
|
|||
safe_unlockclose(hLogicalVolume);
|
||||
safe_unlockclose(hPhysicalDrive);
|
||||
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
||||
_endthread();
|
||||
ExitThread(0);
|
||||
}
|
||||
|
|
164
src/iso.c
164
src/iso.c
|
@ -52,8 +52,9 @@
|
|||
#endif
|
||||
// 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
|
||||
#define PROGRESS_UPDATE 1024
|
||||
#define FOUR_GIGABYTES 4294967296LL
|
||||
#define PROGRESS_THRESHOLD 1024
|
||||
#define THREADED_CLOSE_THRESHOLD (20 * 1024 * 1024) // 20 MB
|
||||
#define FOUR_GIGABYTES 4294967296LL
|
||||
|
||||
// Needed for UDF ISO access
|
||||
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 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)
|
||||
{
|
||||
FILE *fd = NULL;
|
||||
HANDLE thid, file_handle = NULL;
|
||||
DWORD buf_size, wr_size;
|
||||
BOOL threaded_close = FALSE;
|
||||
int i_length;
|
||||
size_t i, nul_pos;
|
||||
char* psz_fullpath;
|
||||
const char* psz_basename;
|
||||
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) {
|
||||
if (FormatStatus) goto out;
|
||||
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);
|
||||
if (psz_fullpath == NULL) {
|
||||
uprintf("Error allocating file name\n");
|
||||
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) {
|
||||
goto out;
|
||||
}
|
||||
if (udf_is_dir(p_udf_dirent)) {
|
||||
if (!scan_only)
|
||||
if (!scan_only) {
|
||||
_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);
|
||||
if (p_udf_dirent2 != NULL) {
|
||||
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 {
|
||||
i_file_length = udf_get_file_length(p_udf_dirent);
|
||||
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)
|
||||
iso_report.has_4GB_file = TRUE;
|
||||
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);
|
||||
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);
|
||||
SetWindowTextU(hISOFileName, psz_fullpath);
|
||||
fd = fopen(psz_fullpath, "wb");
|
||||
if (fd == NULL) {
|
||||
uprintf(" Unable to create file\n");
|
||||
// Remove the appended size for extraction
|
||||
psz_fullpath[nul_pos] = 0;
|
||||
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;
|
||||
}
|
||||
threaded_close = (i_file_length > THREADED_CLOSE_THRESHOLD);
|
||||
if (threaded_close) uprintf("will use threaded close\n");
|
||||
while (i_file_length > 0) {
|
||||
if (FormatStatus) goto out;
|
||||
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)]);
|
||||
goto out;
|
||||
}
|
||||
fwrite(buf, (size_t)MIN(i_file_length, i_read), 1, fd);
|
||||
if (ferror(fd)) {
|
||||
uprintf(" Error writing file\n");
|
||||
buf_size = (DWORD)MIN(i_file_length, i_read);
|
||||
if (!WriteFile(file_handle, buf, buf_size, &wr_size, NULL) || (buf_size != wr_size)) {
|
||||
uprintf(" Error writing file: %s\n", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
fd = NULL;
|
||||
// If you have a fast USB 3.0 device, the default Windows buffering does an
|
||||
// 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);
|
||||
}
|
||||
|
@ -145,30 +212,32 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
|
|||
out:
|
||||
if (p_udf_dirent != NULL)
|
||||
udf_dirent_free(p_udf_dirent);
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
SAFE_CLOSEHANDLE_THREADED(file_handle);
|
||||
safe_free(psz_fullpath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns 0 on success, nonzero on error
|
||||
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;
|
||||
char psz_fullpath[4096], *psz_basename;
|
||||
char psz_fullpath[1024], *psz_basename;
|
||||
const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
|
||||
unsigned char buf[ISO_BLOCKSIZE];
|
||||
CdioListNode_t* p_entnode;
|
||||
iso9660_stat_t *p_statbuf;
|
||||
CdioList_t* p_entlist;
|
||||
size_t i;
|
||||
size_t i, nul_pos;
|
||||
lsn_t lsn;
|
||||
int64_t i_file_length;
|
||||
|
||||
if ((p_iso == NULL) || (psz_path == NULL))
|
||||
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)
|
||||
return 1;
|
||||
psz_basename = &psz_fullpath[i_length];
|
||||
|
@ -186,13 +255,21 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
|
|||
continue;
|
||||
iso9660_name_translate(p_statbuf->filename, psz_basename);
|
||||
if (p_statbuf->type == _STAT_DIR) {
|
||||
if (!scan_only)
|
||||
if (!scan_only) {
|
||||
_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))
|
||||
goto out;
|
||||
} else {
|
||||
i_file_length = p_statbuf->size;
|
||||
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)
|
||||
iso_report.has_4GB_file = TRUE;
|
||||
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++;
|
||||
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);
|
||||
fd = fopen(psz_fullpath, "wb");
|
||||
if (fd == NULL) {
|
||||
uprintf(" Unable to create file\n");
|
||||
SetWindowTextU(hISOFileName, psz_fullpath);
|
||||
psz_fullpath[nul_pos] = 0;
|
||||
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;
|
||||
}
|
||||
threaded_close = (i_file_length > THREADED_CLOSE_THRESHOLD);
|
||||
for (i = 0; i_file_length > 0; i++) {
|
||||
if (FormatStatus) goto out;
|
||||
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);
|
||||
goto out;
|
||||
}
|
||||
fwrite(buf, (size_t)MIN(i_file_length, ISO_BLOCKSIZE), 1, fd);
|
||||
if (ferror(fd)) {
|
||||
uprintf(" Error writing file\n");
|
||||
buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
|
||||
if (!WriteFile(file_handle, buf, buf_size, &wr_size, NULL) || (buf_size != wr_size)) {
|
||||
uprintf(" Error writing file: %s\n", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
fclose(fd);
|
||||
fd = NULL;
|
||||
SAFE_CLOSEHANDLE_THREADED(file_handle);
|
||||
}
|
||||
}
|
||||
r = 0;
|
||||
|
||||
out:
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
SAFE_CLOSEHANDLE_THREADED(file_handle);
|
||||
_cdio_list_free(p_entlist, true);
|
||||
return r;
|
||||
}
|
||||
|
@ -254,10 +341,11 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan)
|
|||
psz_extract_dir = dest_dir;
|
||||
progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE);
|
||||
if (scan_only) {
|
||||
uprintf(scan_text);
|
||||
total_blocks = 0;
|
||||
iso_report.projected_size = 0;
|
||||
iso_report.has_4GB_file = FALSE;
|
||||
iso_report.has_bootmgr = FALSE;
|
||||
iso_report.has_isolinux = FALSE;
|
||||
// Change the Window title and static text
|
||||
SetWindowTextU(hISOProgressDlg, 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);
|
||||
if (p_udf == NULL)
|
||||
goto try_iso;
|
||||
uprintf("Disc image is an UDF image\n");
|
||||
|
||||
p_udf_root = udf_get_root(p_udf, true, 0);
|
||||
if (p_udf_root == NULL) {
|
||||
|
@ -297,6 +386,7 @@ try_iso:
|
|||
uprintf("Unable to open image '%s'.\n", src_iso);
|
||||
goto out;
|
||||
}
|
||||
uprintf("Disc image is an ISO9660 image\n");
|
||||
r = iso_extract_files(p_iso, "");
|
||||
|
||||
out:
|
||||
|
@ -310,6 +400,6 @@ out:
|
|||
if (p_udf != NULL)
|
||||
udf_close(p_udf);
|
||||
if ((r != 0) && (FormatStatus == 0))
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT);
|
||||
return r;
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR((scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT));
|
||||
return (r == 0);
|
||||
}
|
||||
|
|
|
@ -674,8 +674,10 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
|
|||
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
|
||||
+ p_udf_dirent->fid->icb.loc.lba, 1))
|
||||
+ p_udf_dirent->fid->icb.loc.lba, 1)) {
|
||||
udf_dirent_free(p_udf_dirent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strlen(p_udf_dirent->psz_name) < i_len)
|
||||
p_udf_dirent->psz_name = (char *)
|
||||
|
@ -687,6 +689,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
|
|||
}
|
||||
return p_udf_dirent;
|
||||
}
|
||||
udf_dirent_free(p_udf_dirent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
111
src/rufus.c
111
src/rufus.c
|
@ -53,19 +53,20 @@ static BOOL existing_key = FALSE;
|
|||
HINSTANCE hMainInstance;
|
||||
HWND hMainDialog;
|
||||
char szFolderPath[MAX_PATH];
|
||||
char* iso_path = NULL;
|
||||
float fScale = 1.0f;
|
||||
int default_fs;
|
||||
HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
|
||||
HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName;
|
||||
BOOL bWithFreeDOS, bWithSyslinux;
|
||||
|
||||
static HANDLE format_thid = NULL;
|
||||
static HWND hDeviceTooltip = NULL, hFSTooltip = NULL, hProgress = NULL;
|
||||
static HWND hDOS = NULL, hSelectISO = NULL, hISOToolTip = NULL;
|
||||
static HICON hIconDisc;
|
||||
static StrArray DriveID, DriveLabel;
|
||||
static char szTimer[10] = "00:00:00";
|
||||
static char szTimer[12] = "00:00:00";
|
||||
static unsigned int timer;
|
||||
static char* iso_path = NULL;
|
||||
|
||||
/*
|
||||
* 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)) {
|
||||
case IDC_ISO_ABORT:
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
|
||||
PrintStatus(0, FALSE, "Cancelling - please wait...");
|
||||
uprintf("ISO: USER CANCEL\n");
|
||||
// if (format_thid != NULL)
|
||||
// CancelSynchronousIo(format_thid);
|
||||
PrintStatus(0, FALSE, "Cancelling - This might take a while...");
|
||||
uprintf("Cancelling (ISO)\n");
|
||||
return TRUE;
|
||||
}
|
||||
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
|
||||
void __cdecl ISOScanThread(void* param)
|
||||
DWORD WINAPI ISOScanThread(LPVOID param)
|
||||
{
|
||||
int i;
|
||||
// ExtractISO(ISO_IMAGE, ISO_DEST, TRUE);
|
||||
size_t i;
|
||||
PrintStatus(0, TRUE, "Scanning ISO image...\n");
|
||||
ExtractISO(iso_path, "", TRUE);
|
||||
uprintf("Projected size: %lld\nHas 4GB: %s\n", iso_report.projected_size, iso_report.has_4GB_file?"TRUE":"FALSE");
|
||||
for (i=safe_strlen(iso_path); (i>=0)&&(iso_path[i] != '\\'); i--);
|
||||
PrintStatus(0, TRUE, "Using ISO: '%s'\n", &iso_path[i+1]);
|
||||
_endthread();
|
||||
if (!ExtractISO(iso_path, "", TRUE)) {
|
||||
PrintStatus(0, TRUE, "Failed to scan ISO image.");
|
||||
goto out;
|
||||
}
|
||||
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
|
||||
|
@ -965,6 +979,10 @@ void InitDialog(HWND hDlg)
|
|||
HICON hSmallIcon, hBigIcon;
|
||||
char tmp[128];
|
||||
|
||||
#ifdef RUFUS_TEST
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_SHOW);
|
||||
#endif
|
||||
|
||||
// Quite a burden to carry around as parameters
|
||||
hMainDialog = hDlg;
|
||||
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
|
||||
|
@ -1009,8 +1027,7 @@ void InitDialog(HWND hDlg)
|
|||
IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 1));
|
||||
// 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, "ISO"), DT_ISO));
|
||||
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, bWithFreeDOS?DT_FREEDOS:DT_WINME));
|
||||
IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, DT_WINME));
|
||||
// Create the string array
|
||||
StrArrayCreate(&DriveID, 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;
|
||||
DWORD DeviceNum;
|
||||
char str[MAX_PATH], tmp[128];
|
||||
static uintptr_t format_thid = -1L;
|
||||
static UINT uDOSChecked = BST_CHECKED;
|
||||
|
||||
switch (message) {
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
if ( (format_thid == -1L) &&
|
||||
if ( (format_thid == NULL) &&
|
||||
((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) ) {
|
||||
GetUSBDevices();
|
||||
return (INT_PTR)TRUE;
|
||||
|
@ -1079,15 +1095,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
switch(LOWORD(wParam)) {
|
||||
case IDOK: // close application
|
||||
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 you are sure you want to cancel, click YES. Otherwise, click NO.",
|
||||
RUFUS_CANCELBOX_TITLE, MB_YESNO|MB_ICONWARNING) == IDYES) {
|
||||
// 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;
|
||||
PrintStatus(0, FALSE, "Cancelling - please wait...");
|
||||
uprintf("USER CANCEL\n");
|
||||
PrintStatus(0, FALSE, "Cancelling - Please wait...");
|
||||
uprintf("Cancelling (General)\n");
|
||||
}
|
||||
}
|
||||
return (INT_PTR)TRUE;
|
||||
|
@ -1103,19 +1120,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
break;
|
||||
#ifdef RUFUS_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;
|
||||
#endif
|
||||
case IDC_DEVICE:
|
||||
|
@ -1150,7 +1154,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
if (bWithSyslinux)
|
||||
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));
|
||||
if (!IsWindowEnabled(hDOS)) {
|
||||
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
|
||||
SetFocus(hDlg);
|
||||
}
|
||||
if (_beginthread(ISOScanThread, 0, NULL) == -1L) {
|
||||
if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, 0) == NULL) {
|
||||
uprintf("Unable to start ISO scanning thread");
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
|
||||
}
|
||||
break;
|
||||
case IDC_START:
|
||||
if (format_thid != -1L) {
|
||||
if (format_thid != NULL) {
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
FormatStatus = 0;
|
||||
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
|
||||
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));
|
||||
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);
|
||||
|
@ -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
|
||||
SetFocus(hDlg);
|
||||
}
|
||||
format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum);
|
||||
if (format_thid == -1L) {
|
||||
format_thid = CreateThread(NULL, 0, FormatThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL);
|
||||
if (format_thid == NULL) {
|
||||
uprintf("Unable to start formatting thread");
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
|
||||
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;
|
||||
|
||||
case WM_CLOSE:
|
||||
if (format_thid != -1L) {
|
||||
if (format_thid != NULL) {
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
DestroyAllTooltips();
|
||||
safe_free(iso_path);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case UM_FORMAT_COMPLETED:
|
||||
format_thid = -1L;
|
||||
format_thid = NULL;
|
||||
// Stop the timer
|
||||
KillTimer(hMainDialog, TID_APP_TIMER);
|
||||
// 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");
|
||||
} else if (SCODE_CODE(FormatStatus) == ERROR_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 {
|
||||
PrintStatus(0, FALSE, "FAILED");
|
||||
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);
|
||||
goto out;
|
||||
}
|
||||
// CenterDialog(hDlg);
|
||||
#ifndef RUFUS_TEST
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_HIDE);
|
||||
#endif
|
||||
ShowWindow(hDlg, SW_SHOWNORMAL);
|
||||
UpdateWindow(hDlg);
|
||||
|
||||
|
@ -1346,6 +1361,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
}
|
||||
|
||||
out:
|
||||
DestroyAllTooltips();
|
||||
safe_free(iso_path);
|
||||
#ifdef DISABLE_AUTORUN
|
||||
SetLGP(TRUE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0);
|
||||
#endif
|
||||
|
|
11
src/rufus.h
11
src/rufus.h
|
@ -27,12 +27,6 @@
|
|||
|
||||
/* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */
|
||||
//#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 RUFUS_CANCELBOX_TITLE "Rufus - Cancellation"
|
||||
|
@ -152,6 +146,8 @@ typedef struct {
|
|||
typedef struct {
|
||||
uint64_t projected_size;
|
||||
BOOL has_4GB_file;
|
||||
BOOL has_bootmgr;
|
||||
BOOL has_isolinux;
|
||||
} RUFUS_ISO_REPORT;
|
||||
|
||||
/*
|
||||
|
@ -163,6 +159,7 @@ extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
|
|||
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName;
|
||||
extern float fScale;
|
||||
extern char szFolderPath[MAX_PATH];
|
||||
extern char* iso_path;
|
||||
extern DWORD FormatStatus;
|
||||
extern RUFUS_DRIVE_INFO SelectedDrive;
|
||||
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 ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
|
||||
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 HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive);
|
||||
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
|
||||
|
|
29
src/rufus.rc
29
src/rufus.rc
|
@ -8,7 +8,7 @@
|
|||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include <windows.h>
|
||||
#ifndef __GNUC__
|
||||
#ifndef __MINGW32__
|
||||
#include "../ms-config.h"
|
||||
#endif
|
||||
#ifndef IDC_STATIC
|
||||
|
@ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
IDD_DIALOG DIALOGEX 12, 12, 206, 278
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Rufus v1.0.7.126"
|
||||
CAPTION "Rufus v1.0.7.127"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
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
|
||||
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
|
||||
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
|
||||
END
|
||||
|
||||
|
@ -71,7 +71,7 @@ BEGIN
|
|||
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,
|
||||
"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
|
||||
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
|
||||
|
@ -92,14 +92,14 @@ BEGIN
|
|||
DEFPUSHBUTTON "Close",IDCANCEL,211,44,50,14
|
||||
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
|
||||
CAPTION "Extracting Files..."
|
||||
CAPTION "Copying ISO files..."
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "",IDC_ISO_FILENAME,14,9,232,14
|
||||
CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,14,32,231,8
|
||||
PUSHBUTTON "Abort",IDC_ISO_ABORT,112,50,50,14
|
||||
LTEXT "",IDC_ISO_FILENAME,8,10,246,13,SS_PATHELLIPSIS
|
||||
CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,7,26,247,8
|
||||
PUSHBUTTON "Cancel",IDC_ISO_ABORT,111,43,50,14
|
||||
END
|
||||
|
||||
IDD_LICENSE DIALOGEX 0, 0, 335, 205
|
||||
|
@ -126,7 +126,7 @@ END
|
|||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include <windows.h>\r\n"
|
||||
"#ifndef __GNUC__\r\n"
|
||||
"#ifndef __MINGW32__\r\n"
|
||||
"#include ""../ms-config.h""\r\n"
|
||||
"#endif\r\n"
|
||||
"#ifndef IDC_STATIC\r\n"
|
||||
|
@ -207,6 +207,7 @@ BEGIN
|
|||
|
||||
IDD_ISO_EXTRACT, DIALOG
|
||||
BEGIN
|
||||
BOTTOMMARGIN, 65
|
||||
END
|
||||
|
||||
IDD_LICENSE, DIALOG
|
||||
|
@ -222,8 +223,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,7,126
|
||||
PRODUCTVERSION 1,0,7,126
|
||||
FILEVERSION 1,0,7,127
|
||||
PRODUCTVERSION 1,0,7,127
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -240,13 +241,13 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "akeo.ie"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "1.0.7.126"
|
||||
VALUE "FileVersion", "1.0.7.127"
|
||||
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.0.7.126"
|
||||
VALUE "ProductVersion", "1.0.7.127"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -213,7 +213,7 @@ const char* StrError(DWORD error_code)
|
|||
case ERROR_PARTITION_FAILURE:
|
||||
return "Error while partitioning drive";
|
||||
case ERROR_CANNOT_COPY:
|
||||
return "Could not copy MS-DOS files";
|
||||
return "Could not copy files to target drive";
|
||||
case ERROR_CANCELLED:
|
||||
return "Cancelled by user";
|
||||
case ERROR_CANT_START_THREAD:
|
||||
|
@ -224,6 +224,9 @@ const char* StrError(DWORD error_code)
|
|||
return "ISO image scan failure";
|
||||
case ERROR_ISO_EXTRACT:
|
||||
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:
|
||||
uprintf("Unknown error: %08X\n", error_code);
|
||||
SetLastError(error_code);
|
||||
|
|
Loading…
Reference in a new issue