mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[iso] add basic El-Torito image parsing to libcdio
* Based on El-Torito specs found at https://pdos.csail.mit.edu/6.828/2014/readings/boot-cdrom.pdf. * Follows 7-zip's virtual '[BOOT]/#...' naming conventions (though we don't check for the full name). * Limited to 8 NoEmul images.
This commit is contained in:
		
							parent
							
								
									2cebf914fd
								
							
						
					
					
						commit
						ae6732c07b
					
				
					 3 changed files with 87 additions and 7 deletions
				
			
		|  | @ -162,6 +162,7 @@ extern enum iso_vd_enum_s { | |||
| extern const char ISO_STANDARD_ID[sizeof("CD001")-1]; | ||||
| 
 | ||||
| #define ISO_STANDARD_ID      "CD001" | ||||
| #define EL_TORITO_ID         "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0" | ||||
| 
 | ||||
| #define CDIO_EXTENT_BLOCKS(size) ((size + (ISO_BLOCKSIZE - 1)) / ISO_BLOCKSIZE) | ||||
| 
 | ||||
|  | @ -506,6 +507,37 @@ struct iso9660_svd_s { | |||
| 
 | ||||
| typedef struct iso9660_svd_s  iso9660_svd_t; | ||||
| 
 | ||||
| /*!
 | ||||
|   \brief ISO-9660 Boot Record Volume Descriptor. | ||||
|  */ | ||||
| struct iso9660_brvd_s { | ||||
|     uint8_t          type;                         /**< ISO_VD_BOOT_RECORD - 0 */ | ||||
|     char             id[5];                        /**< ISO_STANDARD_ID "CD001" */ | ||||
|     uint8_t          version;                      /**< value 1 for El Torito */ | ||||
|     char             system_id[ISO_MAX_SYSTEM_ID]; /**< Boot system ID */ | ||||
|     uint8_t          unused1[32];                  /**< unused - value 0 */ | ||||
|     uint32_t         boot_catalog_sector;          /**< first sector of boot catalog */ | ||||
|     uint8_t          unused2[1973];                /**< Unused - value 0 */ | ||||
| } GNUC_PACKED; | ||||
| 
 | ||||
| typedef struct iso9660_brvd_s  iso9660_brvd_t; | ||||
| 
 | ||||
| /*!
 | ||||
|   \brief ISO-9660 Boot Record Volume Descriptor. | ||||
|  */ | ||||
| struct iso9660_br_s { | ||||
|     uint8_t          boot_id;                      /**< Boot indicator - 0x88 */ | ||||
|     uint8_t          media_type;                   /**< Boot media type - 0 for no emul. */ | ||||
|     uint16_t         load_seg;                     /**< Load segment for x86 */ | ||||
|     uint8_t          system_type;                  /**< System type - 0 for x86 */ | ||||
|     uint8_t          unused1; | ||||
|     uint16_t         num_sectors;                  /**< Sector count of the image */ | ||||
|     uint32_t         image_lsn;                    /**< Start address of the image */ | ||||
|     uint8_t          unused2[20]; | ||||
| } GNUC_PACKED; | ||||
| 
 | ||||
| typedef struct iso9660_br_s  iso9660_br_t; | ||||
| 
 | ||||
| PRAGMA_END_PACKED | ||||
| 
 | ||||
| /*! \brief A data type for a list of ISO9660
 | ||||
|  | @ -582,7 +614,8 @@ extern enum iso_extension_enum_s { | |||
|   ISO_EXTENSION_JOLIET_LEVEL2 = 0x02, | ||||
|   ISO_EXTENSION_JOLIET_LEVEL3 = 0x04, | ||||
|   ISO_EXTENSION_ROCK_RIDGE    = 0x08, | ||||
|   ISO_EXTENSION_HIGH_SIERRA   = 0x10 | ||||
|   ISO_EXTENSION_HIGH_SIERRA   = 0x10, | ||||
|   ISO_EXTENSION_EL_TORITO     = 0x20 | ||||
| } iso_extension_enums; | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,6 +59,8 @@ | |||
| #include "_cdio_stdio.h" | ||||
| #include "cdio_private.h" | ||||
| 
 | ||||
| #define MAX_BOOT_IMAGES     8 | ||||
| 
 | ||||
| /** Implementation of iso9660_t type */ | ||||
| struct _iso9660_s { | ||||
|   cdio_header_t header;     /**< Internal header - MUST come first. */ | ||||
|  | @ -83,6 +85,10 @@ struct _iso9660_s { | |||
| 			        be CDIO_CD_FRAMESIZE_RAW (2352) or | ||||
| 			        M2RAW_SECTOR_SIZE (2336). | ||||
|                             */ | ||||
|   struct { | ||||
|     uint32_t lsn;	    /**< Start LSN of an El-Torito bootable image */ | ||||
|     uint32_t num_sectors;   /**< Number of sectors of a bootable image */ | ||||
|   } boot_img[MAX_BOOT_IMAGES]; | ||||
|   int i_fuzzy_offset;       /**< Adjustment in bytes to make ISO_STANDARD_ID
 | ||||
| 			         ("CD001") come out as ISO_PVD_SECTOR | ||||
| 			         (frame 16).  Normally this should be 0 | ||||
|  | @ -505,7 +511,8 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso, | |||
| 			     iso_extension_mask_t iso_extension_mask) | ||||
| { | ||||
|   iso9660_svd_t p_svd;  /* Secondary volume descriptor. */ | ||||
|   int i; | ||||
|   iso9660_brvd_t* p_brvd = (iso9660_brvd_t*)&p_svd;  /* Boot record volume descriptor. */ | ||||
|   int i, j, k; | ||||
| 
 | ||||
|   if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd))) | ||||
|     return false; | ||||
|  | @ -516,6 +523,24 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso, | |||
|   for (i=1; (0 != iso9660_iso_seek_read (p_iso, &p_svd, ISO_PVD_SECTOR+i, 1)); i++) { | ||||
|     if (ISO_VD_END == from_711(p_svd.type) ) /* Last SVD */ | ||||
|       break; | ||||
|     if (iso_extension_mask & ISO_EXTENSION_EL_TORITO) { | ||||
|       /* Check for an El-Torito boot volume descriptor */ | ||||
|       if (ISO_VD_BOOT_RECORD == from_711(p_svd.type) && | ||||
| 	  (memcmp(p_brvd->system_id, EL_TORITO_ID, ISO_MAX_SYSTEM_ID) == 0)) { | ||||
| 	/* Perform very basic parsing of boot entries to fill an image table */ | ||||
| 	iso9660_br_t br[ISO_BLOCKSIZE / sizeof(iso9660_br_t)]; | ||||
| 	if (iso9660_iso_seek_read(p_iso, &br, p_brvd->boot_catalog_sector, 1) == ISO_BLOCKSIZE) { | ||||
| 	  for (j = 0, k = 0; | ||||
| 	       j < (ISO_BLOCKSIZE / sizeof(iso9660_br_t)) && k < MAX_BOOT_IMAGES; | ||||
| 	       j++) { | ||||
| 	    if (br[j].boot_id == 0x88 && br[j].media_type == 0) { | ||||
| 	      p_iso->boot_img[k].lsn = br[j].image_lsn; | ||||
| 	      p_iso->boot_img[k++].num_sectors = br[j].num_sectors; | ||||
| 	    } | ||||
| 	  } | ||||
| 	} | ||||
|       } | ||||
|     } | ||||
|     if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd.type) ) { | ||||
|       /* We're only interested in Joliet => make sure the SVD isn't overwritten */ | ||||
|       if (p_iso->u_joliet_level == 0) | ||||
|  | @ -1441,6 +1466,28 @@ iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[]) | |||
| iso9660_stat_t * | ||||
| iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[]) | ||||
| { | ||||
|   /* Special case for virtual El-Torito boot images ('[BOOT]/#.img') */ | ||||
|   if (psz_path && (strncmp(psz_path, "[BOOT]/", 7) == 0)) { | ||||
|     int index = psz_path[7] - '0'; | ||||
|     iso9660_stat_t* p_stat; | ||||
|     if (strlen(psz_path) < 8) | ||||
|       return NULL; | ||||
|     if ((psz_path[7] < '0') || (psz_path[7] > '0' + MAX_BOOT_IMAGES - 1)) | ||||
|       return NULL; | ||||
|     if (p_iso->boot_img[index].lsn == 0 || p_iso->boot_img[index].num_sectors == 0) | ||||
|       return NULL; | ||||
|     p_stat = calloc(1, sizeof(iso9660_stat_t) + strlen(psz_path)); | ||||
|     if (!p_stat) { | ||||
|       cdio_warn("Couldn't calloc(1, %d)", (int)sizeof(iso9660_stat_t)); | ||||
|       return NULL; | ||||
|     } | ||||
|     p_stat->lsn = p_iso->boot_img[index].lsn; | ||||
|     p_stat->total_size = p_iso->boot_img[index].num_sectors * ISO_BLOCKSIZE; | ||||
|     p_stat->type = _STAT_FILE; | ||||
|     strcpy(p_stat->filename, psz_path); | ||||
|     return p_stat; | ||||
|   } | ||||
| 
 | ||||
|   return fs_stat_translate(p_iso, (stat_root_t *) _ifs_stat_root, | ||||
| 			   (stat_traverse_t *) _fs_iso_stat_traverse, | ||||
| 			   psz_path); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_ACCEPTFILES | ||||
| CAPTION "Rufus 4.4.2099" | ||||
| CAPTION "Rufus 4.4.2100" | ||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||
| BEGIN | ||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||
|  | @ -392,8 +392,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 4,4,2099,0 | ||||
|  PRODUCTVERSION 4,4,2099,0 | ||||
|  FILEVERSION 4,4,2100,0 | ||||
|  PRODUCTVERSION 4,4,2100,0 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -411,13 +411,13 @@ BEGIN | |||
|             VALUE "Comments", "https://rufus.ie" | ||||
|             VALUE "CompanyName", "Akeo Consulting" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "4.4.2099" | ||||
|             VALUE "FileVersion", "4.4.2100" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||
|             VALUE "OriginalFilename", "rufus-4.4.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "4.4.2099" | ||||
|             VALUE "ProductVersion", "4.4.2100" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue