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"); | 		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
									
										
									
									
									
								
							
							
						
						
									
										164
									
								
								src/iso.c
									
										
									
									
									
								
							|  | @ -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); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										111
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										111
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										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! */ | /* 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); | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -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" | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue