mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[iso] Set drive label according to the one from ISO
* required for Linux distros such as Arch Linux * also added udf_get_logical_volume_id to libcdio and other fixes * also prevents overwrite of ldlinux.sys from ISO * closes #36
This commit is contained in:
		
							parent
							
								
									36be65ed23
								
							
						
					
					
						commit
						e17de3312f
					
				
					 8 changed files with 110 additions and 22 deletions
				
			
		|  | @ -3,7 +3,7 @@ Rufus: The Reliable USB Formatting Utility | |||
| Features: | ||||
| - Formats USB flash drives to FAT/FAT32/NTFS/exFAT | ||||
| - Creates DOS bootable USB drives, with no external files required | ||||
| - Creates bootable USB drives from ISOs, such as Windows installation media | ||||
| - Creates bootable USB drives from ISOs, such as Windows or Linux installation media | ||||
| - Twice as fast as Microsoft's USB/DVD tool or UNetbootin, on ISO->USB (1) | ||||
| - Bad blocks check | ||||
| - Modern UI, with UAC elevation for Windows Vista and later | ||||
|  |  | |||
							
								
								
									
										38
									
								
								src/iso.c
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								src/iso.c
									
										
									
									
									
								
							|  | @ -64,6 +64,7 @@ int64_t iso_blocking_status = -1; | |||
| #define ISO_BLOCKING(x) do {x; iso_blocking_status++; } while(0) | ||||
| static const char *psz_extract_dir; | ||||
| static const char *bootmgr_name = "bootmgr"; | ||||
| static const char *ldlinux_name = "ldlinux.sys"; | ||||
| static const char *isolinux_name[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"}; | ||||
| static uint64_t total_blocks, nb_blocks; | ||||
| static BOOL scan_only = FALSE; | ||||
|  | @ -89,11 +90,15 @@ static __inline char* size_to_hr(int64_t size) | |||
| 	return str_size; | ||||
| } | ||||
| 
 | ||||
| // Interruptible thread for handle closure on large files
 | ||||
| DWORD WINAPI ISOCloseHandleThread(LPVOID param) | ||||
| static void log_handler (cdio_log_level_t level, const char *message) | ||||
| { | ||||
| 	CloseHandle((HANDLE)param); | ||||
| 	ExitThread(0); | ||||
| 	switch(level) { | ||||
| 	case CDIO_LOG_DEBUG: | ||||
| 	case CDIO_LOG_INFO: | ||||
| 		return; | ||||
| 	default: | ||||
| 		uprintf("libcdio: %s\n", message); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Returns 0 on success, nonzero on error
 | ||||
|  | @ -151,6 +156,12 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha | |||
| 					total_blocks++; | ||||
| 				safe_free(psz_fullpath); | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				// In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours
 | ||||
| 				if ((*psz_path == 0) && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { | ||||
| 					uprintf("skipping % file from ISO image\n", ldlinux_name); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			// Replace slashes with backslashes and append the size to the path for UI display
 | ||||
| 			nul_pos = safe_strlen(psz_fullpath); | ||||
|  | @ -262,6 +273,12 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) | |||
| 				if ((i_file_length != 0) && (i_file_length%ISO_BLOCKSIZE == 0)) | ||||
| 					total_blocks++; | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				// In case there's an ldlinux.sys on the ISO, prevent it from overwriting ours
 | ||||
| 				if ((*psz_path == 0) && (safe_strcmp(psz_basename, ldlinux_name) == 0)) { | ||||
| 					uprintf("skipping % file from ISO image\n", ldlinux_name); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			// Replace slashes with backslashes and append the size to the path for UI display
 | ||||
| 			nul_pos = safe_strlen(psz_fullpath); | ||||
|  | @ -316,13 +333,14 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan) | |||
| 	udf_t* p_udf = NULL;  | ||||
| 	udf_dirent_t* p_udf_root; | ||||
| 	LONG progress_style; | ||||
| 	char* vol_id; | ||||
| 	const char* scan_text = "Scanning ISO image...\n"; | ||||
| 
 | ||||
| 	if ((src_iso == NULL) || (dest_dir == NULL)) | ||||
| 		return FALSE; | ||||
| 
 | ||||
| 	scan_only = scan; | ||||
| 	cdio_loglevel_default = CDIO_LOG_DEBUG; | ||||
| 	cdio_log_set_handler(log_handler); | ||||
| 	psz_extract_dir = dest_dir; | ||||
| 	progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE); | ||||
| 	if (scan_only) { | ||||
|  | @ -363,6 +381,10 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan) | |||
| 		uprintf("Couldn't locate UDF root directory\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (scan_only) { | ||||
| 		if (udf_get_logical_volume_id(p_udf, iso_report.label, sizeof(iso_report.label)) <= 0) | ||||
| 			iso_report.label[0] = 0; | ||||
| 	} | ||||
| 	r = udf_extract_files(p_udf, p_udf_root, ""); | ||||
| 	goto out; | ||||
| 
 | ||||
|  | @ -373,6 +395,12 @@ try_iso: | |||
| 		goto out; | ||||
| 	} | ||||
| 	uprintf("Disc image is an ISO9660 image\n"); | ||||
| 	if (scan_only) { | ||||
| 		if (iso9660_ifs_get_volume_id(p_iso, &vol_id)) | ||||
| 			safe_strcpy(iso_report.label, sizeof(iso_report.label), vol_id); | ||||
| 		else | ||||
| 			iso_report.label[0] = 0; | ||||
| 	} | ||||
| 	r = iso_extract_files(p_iso, ""); | ||||
| 
 | ||||
| out: | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ extern "C" { | |||
|   /**
 | ||||
|    * Gets the Volume Identifier string, in 8bit unicode (latin-1) | ||||
|    * psz_volid, place to put the string | ||||
|    * i_volid_size, size of the buffer volid points to | ||||
|    * i_volid, size of the buffer psz_volid points to | ||||
|    * returns the size of buffer needed for all data | ||||
|    */ | ||||
|   int udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid,   | ||||
|  | @ -125,14 +125,24 @@ extern "C" { | |||
|    * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) | ||||
|    * WARNING This is not a null terminated string | ||||
|    * volsetid, place to put the data | ||||
|    * volsetid_size, size of the buffer volsetid points to  | ||||
|    * i_volsetid, size of the buffer psz_volsetid points to  | ||||
|    * the buffer should be >=128 bytes to store the whole volumesetidentifier | ||||
|    * returns the size of the available volsetid information (128) | ||||
|    * or 0 on error | ||||
|    */ | ||||
|   int udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid, | ||||
|                            unsigned int i_volsetid); | ||||
|    | ||||
| 
 | ||||
|   /**
 | ||||
|    * Gets the Logical Volume Identifier string, in 8bit unicode (latin-1) | ||||
|    * psz_logvolid, place to put the string | ||||
|    * i_logvolid, size of the buffer psz_logvolid points to | ||||
|    * returns the size of buffer needed for all data | ||||
|    * A call to udf_get_root() should have been issued before this call | ||||
|    */ | ||||
|   int udf_get_logical_volume_id(udf_t *p_udf, /*out*/ char *psz_logvolid,   | ||||
|                         unsigned int i_logvolid); | ||||
| 
 | ||||
|   /*!
 | ||||
|     Return a file pointer matching psz_name.  | ||||
|   */ | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ | |||
| #ifdef HAVE_ERRNO_H | ||||
| #include <errno.h> | ||||
| #endif | ||||
| #include <ctype.h> | ||||
| 
 | ||||
| #include <cdio/logging.h> | ||||
| #include <cdio/util.h> | ||||
|  | @ -225,17 +226,34 @@ cdio_stdio_new(const char pathname[]) | |||
|   cdio_stream_io_functions funcs = { NULL, NULL, NULL, NULL, NULL, NULL }; | ||||
|   _UserData *ud = NULL; | ||||
|   struct CDIO_STAT statbuf; | ||||
|    | ||||
|   if (CDIO_STAT (pathname, &statbuf) == -1)  | ||||
|   char* pathdup; | ||||
| 
 | ||||
|   if (pathname == NULL) | ||||
|     return NULL; | ||||
| 
 | ||||
|   pathdup = strdup(pathname); | ||||
|   if (pathdup == NULL) | ||||
|     return NULL; | ||||
| 
 | ||||
| #ifdef __MINGW32__ | ||||
|   /* _stati64 requires using native Windows paths => convert "/c/..." to "c:/..." */ | ||||
|   if ((strlen(pathdup) > 3) && (pathdup[0] == '/') && (pathdup[2] == '/') && (isalpha(pathdup[1]))) | ||||
|     { | ||||
|       pathdup[0] = pathdup[1]; | ||||
|       pathdup[1] = ':'; | ||||
|     } | ||||
| #endif | ||||
|   if (CDIO_STAT (pathdup, &statbuf) == -1)  | ||||
|     { | ||||
|       cdio_warn ("could not retrieve file info for `%s': %s",  | ||||
|                  pathname, strerror (errno)); | ||||
|                  pathdup, strerror (errno)); | ||||
|       free(pathdup); | ||||
|       return NULL; | ||||
|     } | ||||
| 
 | ||||
|   ud = calloc (1, sizeof (_UserData)); | ||||
| 
 | ||||
|   ud->pathname = strdup(pathname); | ||||
|   ud->pathname = pathdup; | ||||
|   ud->st_size  = statbuf.st_size; /* let's hope it doesn't change... */ | ||||
| 
 | ||||
|   funcs.open   = _stdio_open; | ||||
|  |  | |||
|  | @ -427,7 +427,7 @@ udf_open (const char *psz_path) | |||
| /**
 | ||||
|  * Gets the Volume Identifier string, in 8bit unicode (latin-1) | ||||
|  * psz_volid, place to put the string | ||||
|  * i_volid_size, size of the buffer volid points to | ||||
|  * i_volid, size of the buffer psz_volid points to | ||||
|  * returns the size of buffer needed for all data | ||||
|  */ | ||||
| int  | ||||
|  | @ -458,7 +458,7 @@ udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid,  unsigned int i_volid) | |||
|  * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) | ||||
|  * WARNING This is not a null terminated string | ||||
|  * volsetid, place to put the data | ||||
|  * volsetid_size, size of the buffer volsetid points to  | ||||
|  * i_volsetid, size of the buffer psz_volsetid points to  | ||||
|  * the buffer should be >=128 bytes to store the whole volumesetidentifier | ||||
|  * returns the size of the available volsetid information (128) | ||||
|  * or 0 on error | ||||
|  | @ -483,6 +483,31 @@ udf_get_volumeset_id(udf_t *p_udf, /*out*/ uint8_t *volsetid, | |||
|   return UDF_VOLSET_ID_SIZE; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the Logical Volume Identifier string, in 8bit unicode (latin-1) | ||||
|  * psz_logvolid, place to put the string (should be at least 64 bytes) | ||||
|  * i_logvolid, size of the buffer psz_logvolid points to | ||||
|  * returns the size of buffer needed for all data | ||||
|  * A call to udf_get_root() should have been issued before this call | ||||
|  */ | ||||
| int  | ||||
| udf_get_logical_volume_id(udf_t *p_udf, /*out*/ char *psz_logvolid,  unsigned int i_logvolid) | ||||
| { | ||||
|   uint8_t data[UDF_BLOCKSIZE]; | ||||
|   logical_vol_desc_t *p_logvol = (logical_vol_desc_t *) &data; | ||||
|   int logvolid_len; | ||||
| 
 | ||||
|   if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, p_logvol, p_udf->lvd_lba, 1) )  | ||||
|     return 0; | ||||
| 
 | ||||
|   logvolid_len = (p_logvol->logvol_id[127]+1)/2; | ||||
|   if (i_logvolid > logvolid_len) | ||||
|     i_logvolid = logvolid_len; | ||||
| 
 | ||||
|   unicode16_decode((uint8_t *) p_logvol->logvol_id, 2*i_logvolid, psz_logvolid); | ||||
|   return logvolid_len; | ||||
| } | ||||
| 
 | ||||
| /*!
 | ||||
|   Get the root in p_udf. If b_any_partition is false then | ||||
|   the root must be in the given partition. | ||||
|  |  | |||
|  | @ -963,7 +963,8 @@ DWORD WINAPI ISOScanThread(LPVOID param) | |||
| 		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, | ||||
| 	uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, isolinux:%c\n", | ||||
| 		iso_report.label, 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) && (!iso_report.has_isolinux)) { | ||||
| 		MessageBoxU(hMainDialog, "This version of Rufus only supports bootable ISOs\n" | ||||
|  | @ -973,6 +974,11 @@ DWORD WINAPI ISOScanThread(LPVOID param) | |||
| 	} else { | ||||
| 		for (i=(int)safe_strlen(iso_path); (i>0)&&(iso_path[i]!='\\'); i--); | ||||
| 		PrintStatus(0, TRUE, "Using ISO: '%s'\n", &iso_path[i+1]); | ||||
| 		// Some Linux distros, such as Arch Linux, require the USB drive to have
 | ||||
| 		// a specific label => copy the one we got from the ISO image
 | ||||
| 		if (iso_report.label[0] != 0) { | ||||
| 			SetWindowTextU(hLabel, iso_report.label); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
|  |  | |||
|  | @ -145,6 +145,7 @@ typedef struct { | |||
| 
 | ||||
| /* ISO details that the application may want */ | ||||
| typedef struct { | ||||
| 	char label[64]; | ||||
| 	uint64_t projected_size; | ||||
| 	BOOL has_4GB_file; | ||||
| 	BOOL has_bootmgr; | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -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.1.0.132" | ||||
| CAPTION "Rufus v1.1.0.133" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,236,50,14 | ||||
|  | @ -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.1.0 (Build 132)",IDC_STATIC,46,19,78,8 | ||||
|     LTEXT           "Version 1.1.0 (Build 133)",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 | ||||
|  | @ -222,8 +222,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 1,1,0,132 | ||||
|  PRODUCTVERSION 1,1,0,132 | ||||
|  FILEVERSION 1,1,0,133 | ||||
|  PRODUCTVERSION 1,1,0,133 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -240,13 +240,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "akeo.ie" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "1.1.0.132" | ||||
|             VALUE "FileVersion", "1.1.0.133" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "1.1.0.132" | ||||
|             VALUE "ProductVersion", "1.1.0.133" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue