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]; | extern const char ISO_STANDARD_ID[sizeof("CD001")-1]; | ||||||
| 
 | 
 | ||||||
| #define ISO_STANDARD_ID      "CD001" | #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) | #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; | 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 | PRAGMA_END_PACKED | ||||||
| 
 | 
 | ||||||
| /*! \brief A data type for a list of ISO9660
 | /*! \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_LEVEL2 = 0x02, | ||||||
|   ISO_EXTENSION_JOLIET_LEVEL3 = 0x04, |   ISO_EXTENSION_JOLIET_LEVEL3 = 0x04, | ||||||
|   ISO_EXTENSION_ROCK_RIDGE    = 0x08, |   ISO_EXTENSION_ROCK_RIDGE    = 0x08, | ||||||
|   ISO_EXTENSION_HIGH_SIERRA   = 0x10 |   ISO_EXTENSION_HIGH_SIERRA   = 0x10, | ||||||
|  |   ISO_EXTENSION_EL_TORITO     = 0x20 | ||||||
| } iso_extension_enums; | } iso_extension_enums; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -59,6 +59,8 @@ | ||||||
| #include "_cdio_stdio.h" | #include "_cdio_stdio.h" | ||||||
| #include "cdio_private.h" | #include "cdio_private.h" | ||||||
| 
 | 
 | ||||||
|  | #define MAX_BOOT_IMAGES     8 | ||||||
|  | 
 | ||||||
| /** Implementation of iso9660_t type */ | /** Implementation of iso9660_t type */ | ||||||
| struct _iso9660_s { | struct _iso9660_s { | ||||||
|   cdio_header_t header;     /**< Internal header - MUST come first. */ |   cdio_header_t header;     /**< Internal header - MUST come first. */ | ||||||
|  | @ -83,6 +85,10 @@ struct _iso9660_s { | ||||||
| 			        be CDIO_CD_FRAMESIZE_RAW (2352) or | 			        be CDIO_CD_FRAMESIZE_RAW (2352) or | ||||||
| 			        M2RAW_SECTOR_SIZE (2336). | 			        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
 |   int i_fuzzy_offset;       /**< Adjustment in bytes to make ISO_STANDARD_ID
 | ||||||
| 			         ("CD001") come out as ISO_PVD_SECTOR | 			         ("CD001") come out as ISO_PVD_SECTOR | ||||||
| 			         (frame 16).  Normally this should be 0 | 			         (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) | 			     iso_extension_mask_t iso_extension_mask) | ||||||
| { | { | ||||||
|   iso9660_svd_t p_svd;  /* Secondary volume descriptor. */ |   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))) |   if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd))) | ||||||
|     return false; |     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++) { |   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 */ |     if (ISO_VD_END == from_711(p_svd.type) ) /* Last SVD */ | ||||||
|       break; |       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) ) { |     if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd.type) ) { | ||||||
|       /* We're only interested in Joliet => make sure the SVD isn't overwritten */ |       /* We're only interested in Joliet => make sure the SVD isn't overwritten */ | ||||||
|       if (p_iso->u_joliet_level == 0) |       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_stat_t * | ||||||
| iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[]) | 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, |   return fs_stat_translate(p_iso, (stat_root_t *) _ifs_stat_root, | ||||||
| 			   (stat_traverse_t *) _fs_iso_stat_traverse, | 			   (stat_traverse_t *) _fs_iso_stat_traverse, | ||||||
| 			   psz_path); | 			   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 | IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_ACCEPTFILES | EXSTYLE WS_EX_ACCEPTFILES | ||||||
| CAPTION "Rufus 4.4.2099" | CAPTION "Rufus 4.4.2100" | ||||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP |     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||||
|  | @ -392,8 +392,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 4,4,2099,0 |  FILEVERSION 4,4,2100,0 | ||||||
|  PRODUCTVERSION 4,4,2099,0 |  PRODUCTVERSION 4,4,2100,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -411,13 +411,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://rufus.ie" |             VALUE "Comments", "https://rufus.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "4.4.2099" |             VALUE "FileVersion", "4.4.2100" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||||
|             VALUE "OriginalFilename", "rufus-4.4.exe" |             VALUE "OriginalFilename", "rufus-4.4.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "4.4.2099" |             VALUE "ProductVersion", "4.4.2100" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue