コード例 #1
0
ファイル: iso9660.c プロジェクト: 10se1ucgo/rufus
void
pathtable_get_size_and_entries (const void *pt,
                                unsigned int *size,
                                unsigned int *entries)
{
  const uint8_t *tmp = pt;
  unsigned int offset = 0;
  unsigned int count = 0;

  cdio_assert (pt != NULL);

  while (from_711 (*tmp))
    {
      offset += sizeof (iso_path_table_t);
      offset += from_711 (*tmp);
      if (offset % 2)
        offset++;
      tmp = (uint8_t *)pt + offset;
      count++;
    }

  if (size)
    *size = offset;

  if (entries)
    *entries = count;
}
コード例 #2
0
ファイル: iso9660.c プロジェクト: 10se1ucgo/rufus
static const iso_path_table_t *
pathtable_get_entry (const void *pt, unsigned int entrynum)
{
  const uint8_t *tmp = pt;
  unsigned int offset = 0;
  unsigned int count = 0;

  cdio_assert (pt != NULL);

  while (from_711 (*tmp))
    {
      if (count == entrynum)
        break;

      cdio_assert (count < entrynum);

      offset += sizeof (iso_path_table_t);
      offset += from_711 (*tmp);
      if (offset % 2)
        offset++;
      tmp = (uint8_t *)pt + offset;
      count++;
    }

  if (!from_711 (*tmp))
    return NULL;

  return (const void *) tmp;
}
コード例 #3
0
ファイル: iso9660_fs.c プロジェクト: flyingtime/boxee
/*!
  Read the Super block of an ISO 9660 image. This is the 
  Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume 
  Descriptor if (Joliet) extensions are acceptable.
*/
bool 
iso9660_fs_read_superblock (CdIo_t *p_cdio, 
			    iso_extension_mask_t iso_extension_mask)
{
  if (!p_cdio) return false;
  
  {
    generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;
    iso9660_pvd_t         *p_pvd = &(p_env->pvd);
    iso9660_svd_t         *p_svd = &(p_env->svd);
    char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
    driver_return_code_t driver_return;

    if ( !iso9660_fs_read_pvd(p_cdio, p_pvd) )
      return false;
    
    p_env->i_joliet_level = 0;
    
    driver_return = 
      cdio_read_data_sectors ( p_cdio, buf, ISO_PVD_SECTOR+1, ISO_BLOCKSIZE,
			       1 );

    if (DRIVER_OP_SUCCESS == driver_return) {
      /* The size of a PVD or SVD is smaller than a sector. So we
	 allocated a bigger block above (buf) and now we'll copy just
	 the part we need to save.
      */
      cdio_assert (sizeof(buf) >= sizeof (iso9660_svd_t));
      memcpy(p_svd, buf, sizeof(iso9660_svd_t));
  
      if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd->type) ) {
	if (p_svd->escape_sequences[0] == 0x25 
	    && p_svd->escape_sequences[1] == 0x2f) {
	  switch (p_svd->escape_sequences[2]) {
	  case 0x40:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1) 
	      p_env->i_joliet_level = 1;
	    break;
	  case 0x43:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL2) 
	      p_env->i_joliet_level = 2;
	    break;
	  case 0x45:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL3) 
	      p_env->i_joliet_level = 3;
	    break;
	  default:
	    cdio_info("Supplementary Volume Descriptor found, but not Joliet");
	  }
	  if (p_env->i_joliet_level > 0) {
	    cdio_info("Found Extension: Joliet Level %d", 
		      p_env->i_joliet_level);
	  }
	}
      }
    }
  }

  return true;
}
コード例 #4
0
ファイル: iso9660_fs.c プロジェクト: MehmetaliKuran/rufus
/*!
  Read the Super block of an ISO 9660 image. This is the
  Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
  Descriptor if (Joliet) extensions are acceptable.
*/
bool
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;

  if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd)))
    return false;

  p_iso->u_joliet_level = 0;

  /* There may be multiple Secondary Volume Descriptors (eg. El Torito + Joliet) */
  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_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)
        memcpy(&(p_iso->svd), &p_svd, sizeof(iso9660_svd_t));
      if (p_svd.escape_sequences[0] == 0x25
	  && p_svd.escape_sequences[1] == 0x2f) {
	switch (p_svd.escape_sequences[2]) {
	case 0x40:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1)
	    p_iso->u_joliet_level = 1;
	  break;
	case 0x43:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL2)
	    p_iso->u_joliet_level = 2;
	  break;
	case 0x45:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL3)
	    p_iso->u_joliet_level = 3;
	  break;
	default:
	  cdio_info("Supplementary Volume Descriptor found, but not Joliet");
	}
	if (p_iso->u_joliet_level > 0) {
	  cdio_info("Found Extension: Joliet Level %d", p_iso->u_joliet_level);
	}
      }
    }
  }

  return true;
}
コード例 #5
0
ファイル: iso9660_fs.c プロジェクト: flyingtime/boxee
static bool
check_pvd (const iso9660_pvd_t *p_pvd, cdio_log_level_t log_level) 
{
  if ( ISO_VD_PRIMARY != from_711(p_pvd->type) ) {
    cdio_log (log_level, "unexpected PVD type %d", p_pvd->type);
    return false;
  }
  
  if (strncmp (p_pvd->id, ISO_STANDARD_ID, strlen (ISO_STANDARD_ID)))
    {
      cdio_log (log_level, "unexpected ID encountered (expected `"
		ISO_STANDARD_ID "', got `%.5s'", p_pvd->id);
      return false;
    }
  return true;
}
コード例 #6
0
ファイル: iso9660_fs.c プロジェクト: flyingtime/boxee
/*!
  Read the Super block of an ISO 9660 image. This is the 
  Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume 
  Descriptor if (Joliet) extensions are acceptable.
*/
bool 
iso9660_ifs_read_superblock (iso9660_t *p_iso, 
			     iso_extension_mask_t iso_extension_mask)
{
  iso9660_svd_t *p_svd;  /* Secondary volume descriptor. */
  
  if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd)))
    return false;

  p_svd = &(p_iso->svd);
  p_iso->i_joliet_level = 0;

  if (0 != iso9660_iso_seek_read (p_iso, p_svd, ISO_PVD_SECTOR+1, 1)) {
    if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd->type) ) {
      if (p_svd->escape_sequences[0] == 0x25 
	  && p_svd->escape_sequences[1] == 0x2f) {
	switch (p_svd->escape_sequences[2]) {
	case 0x40:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1) 
	    p_iso->i_joliet_level = 1;
	  break;
	case 0x43:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL2) 
	    p_iso->i_joliet_level = 2;
	  break;
	case 0x45:
	  if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL3) 
	    p_iso->i_joliet_level = 3;
	  break;
	default:
	  cdio_info("Supplementary Volume Descriptor found, but not Joliet");
	}
	if (p_iso->i_joliet_level > 0) {
	  cdio_info("Found Extension: Joliet Level %d", p_iso->i_joliet_level);
	}
      }
    }
  }
  
  return true;
}
コード例 #7
0
ファイル: rock.c プロジェクト: 3aychonok/libcdio
/*! 
  Get
  @return length of name field; 0: not found, -1: to be ignored 
*/
int 
get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, 
			/*out*/ char * psz_name, 
			/*in/out*/ iso9660_stat_t *p_stat)
{
  int len;
  unsigned char *chr;
  int symlink_len = 0;
  CONTINUE_DECLS;
  int i_namelen = 0;
  int truncate=0;

  if (!p_stat || nope == p_stat->rr.b3_rock) return 0;
  *psz_name = 0;

  SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
  /*repeat:*/
  {
    iso_extension_record_t * rr;
    int sig;
    int rootflag;
    
    while (len > 1){ /* There may be one byte for padding somewhere */
      rr = (iso_extension_record_t *) chr;
      if (rr->len == 0) goto out; /* Something got screwed up here */
      sig = *chr+(*(chr+1) << 8);
      chr += rr->len; 
      len -= rr->len;

      switch(sig){
      case SIG('S','P'):
	CHECK_SP(goto out);
	break;
      case SIG('C','E'): 
	{
	  iso711_t i_fname = from_711(p_iso9660_dir->filename.len);
	  if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
	    break;
	  if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
	    break;
	}
	CHECK_CE;
	break;
      case SIG('E','R'):
	p_stat->rr.b3_rock = yep;
	cdio_debug("ISO 9660 Extensions: ");
	{ 
	  int p;
	  for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
	}
	break;
      case SIG('N','M'):
	/* Alternate name */
	p_stat->rr.b3_rock = yep;
	if (truncate) break;
	if (rr->u.NM.flags & ISO_ROCK_NM_PARENT) {
	  i_namelen = sizeof("..");
	  strncat(psz_name, "..", i_namelen);
	} else if (rr->u.NM.flags & ISO_ROCK_NM_CURRENT) {
	  i_namelen = sizeof(".");
	  strncat(psz_name, ".", i_namelen);
	  break;
	}

	if (rr->u.NM.flags & ~1) {
	  cdio_info("Unsupported NM flag settings (%d)",rr->u.NM.flags);
	  break;
	}
	if((strlen(psz_name) + rr->len - 5) >= 254) {
	  truncate = 1;
	  break;
	}
	strncat(psz_name, rr->u.NM.name, rr->len - 5);
	i_namelen += rr->len - 5;
	break;
      case SIG('P','X'):
	/* POSIX file attributes */
	p_stat->rr.st_mode   = from_733(rr->u.PX.st_mode);
	p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
	p_stat->rr.st_uid    = from_733(rr->u.PX.st_uid);
	p_stat->rr.st_gid    = from_733(rr->u.PX.st_gid);
	p_stat->rr.b3_rock    = yep;
	break;
      case SIG('S','L'):
	{
	  /* Symbolic link */
	  uint8_t slen;
	  iso_rock_sl_part_t * p_sl;
	  iso_rock_sl_part_t * p_oldsl;
	  slen = rr->len - 5;
	  p_sl = &rr->u.SL.link;
	  p_stat->rr.i_symlink = symlink_len;
	  while (slen > 1){
	    rootflag = 0;
	    switch(p_sl->flags &~1){
	    case 0:
	      realloc_symlink(p_stat, p_sl->len);
	      memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
		     p_sl->text, p_sl->len);
	      p_stat->rr.i_symlink += p_sl->len;
	      break;
	    case 4:
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
	      /* continue into next case. */
	    case 2:
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
	      break;
	    case 8:
	      rootflag = 1;
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
	      break;
	    default:
	      cdio_warn("Symlink component flag not implemented");
	    }
	    slen -= p_sl->len + 2;
	    p_oldsl = p_sl;
	    p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2);
	    
	    if (slen < 2) {
	      if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0)) 
		p_stat->rr.i_symlink += 1;
	      break;
	    }
	    
	    /*
	     * If this component record isn't continued, then append a '/'.
	     */
	    if (!rootflag && (p_oldsl->flags & 1) == 0) {
	      realloc_symlink(p_stat, 1);
	      p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
	    }
	  }
	}
	symlink_len = p_stat->rr.i_symlink;
	realloc_symlink(p_stat, 1);
	p_stat->rr.psz_symlink[symlink_len]='\0';
	break;
      case SIG('R','E'):
	free(buffer);
	return -1;
      case SIG('T','F'): 
	/* Time stamp(s) for a file */
	{
	  int cnt = 0;
	  add_time(ISO_ROCK_TF_CREATE,     create);
	  add_time(ISO_ROCK_TF_MODIFY,     modify);
	  add_time(ISO_ROCK_TF_ACCESS,     access);
	  add_time(ISO_ROCK_TF_ATTRIBUTES, attributes);
	  add_time(ISO_ROCK_TF_BACKUP,     backup);
	  add_time(ISO_ROCK_TF_EXPIRATION, expiration);
	  add_time(ISO_ROCK_TF_EFFECTIVE,  effective);
	  p_stat->rr.b3_rock = yep;
	  break;
	}
      default:
	break;
      }
    }
  }
  free(buffer);
  return i_namelen; /* If 0, this file did not have a NM field */
 out:
  free(buffer);
  return 0;
}
コード例 #8
0
ファイル: iso9660_fs.c プロジェクト: flyingtime/boxee
static iso9660_stat_t *
_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa, 
			 uint8_t i_joliet_level)
{
  uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
  iso711_t i_fname;
  unsigned int stat_len;
  iso9660_stat_t *p_stat;

  if (!dir_len) return NULL;

  i_fname  = from_711(p_iso9660_dir->filename_len);

  /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
  stat_len      = sizeof(iso9660_stat_t)+i_fname+2;

  p_stat          = calloc(1, stat_len);
  if (!p_stat)
    {
    cdio_warn("Couldn't calloc(1, %d)", stat_len);
    return NULL;
    }
  p_stat->type    = (p_iso9660_dir->file_flags & ISO_DIRECTORY) 
    ? _STAT_DIR : _STAT_FILE;
  p_stat->lsn     = from_733 (p_iso9660_dir->extent);
  p_stat->size    = from_733 (p_iso9660_dir->size);
  p_stat->secsize = _cdio_len2blocks (p_stat->size, ISO_BLOCKSIZE);
  p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
  p_stat->b_xa    = false; 

  {
    char rr_fname[256] = "";

    int  i_rr_fname = 
#ifdef HAVE_ROCK
      get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat);
#else
      0;
#endif
    
    if (i_rr_fname > 0) {
      if (i_rr_fname > i_fname) {
	/* realloc gives valgrind errors */
	iso9660_stat_t *p_stat_new = 
	  calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2);
        if (!p_stat_new)
          {
          cdio_warn("Couldn't calloc(1, %d)", sizeof(iso9660_stat_t)+i_rr_fname+2);
          return NULL;
          }
	memcpy(p_stat_new, p_stat, stat_len);
	free(p_stat);
	p_stat = p_stat_new;
      }
      strncpy(p_stat->filename, rr_fname, i_rr_fname+1);
    } else {
      if ('\0' == p_iso9660_dir->filename[0] && 1 == i_fname)
	strncpy (p_stat->filename, ".", sizeof("."));
      else if ('\1' == p_iso9660_dir->filename[0] && 1 == i_fname)
	strncpy (p_stat->filename, "..", sizeof(".."));
#ifdef HAVE_JOLIET
      else if (i_joliet_level) {
	int i_inlen = i_fname;
	cdio_utf8_t *p_psz_out = NULL;
	if (cdio_charset_to_utf8(p_iso9660_dir->filename, i_inlen,
                             &p_psz_out, "UCS-2BE")) {
          strncpy(p_stat->filename, p_psz_out, i_fname);
          free(p_psz_out);
        }
        else {
          return NULL;
        }
      }
#endif /*HAVE_JOLIET*/
      else {
	strncpy (p_stat->filename, p_iso9660_dir->filename, i_fname);
      }
    }
  }
  

  iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm));

  if (dir_len < sizeof (iso9660_dir_t)) {
    free(p_stat->rr.psz_symlink);
    free(p_stat);
    return NULL;
  }
  

  {
    int su_length = iso9660_get_dir_len(p_iso9660_dir) 
      - sizeof (iso9660_dir_t);
    su_length -= i_fname;
    
    if (su_length % 2)
      su_length--;
    
    if (su_length < 0 || su_length < sizeof (iso9660_xa_t))
      return p_stat;
    
    if (nope == b_xa) {
      return p_stat;
    } else {
      iso9660_xa_t *xa_data = 
	(void *) (((char *) p_iso9660_dir)  
		  + (iso9660_get_dir_len(p_iso9660_dir) - su_length));
      cdio_log_level_t loglevel = (yep == b_xa) 
	? CDIO_LOG_WARN : CDIO_LOG_INFO;
      
      if (xa_data->signature[0] != 'X' 
	  || xa_data->signature[1] != 'A')
	{
	  cdio_log (loglevel, 
		    "XA signature not found in ISO9660's system use area;"
		     " ignoring XA attributes for this file entry.");
	  cdio_debug ("%d %d %d, '%c%c' (%d, %d)", 
		      iso9660_get_dir_len(p_iso9660_dir), 
		      i_fname,
		      su_length,
		      xa_data->signature[0], xa_data->signature[1],
		      xa_data->signature[0], xa_data->signature[1]);
	  return p_stat;
	}
      p_stat->b_xa = true;
      p_stat->xa   = *xa_data;
    }
  }
  return p_stat;
    
}
コード例 #9
0
ファイル: iso9660.c プロジェクト: 10se1ucgo/rufus
void
iso9660_dir_add_entry_su(void *dir,
                         const char filename[],
                         uint32_t extent,
                         uint32_t size,
                         uint8_t file_flags,
                         const void *su_data,
                         unsigned int su_size,
                         const time_t *entry_time)
{
  iso9660_dir_t *idr = dir;
  uint8_t *dir8 = dir;
  unsigned int offset = 0;
  uint32_t dsize = from_733(idr->size);
  int length, su_offset;
  struct tm temp_tm;
  cdio_assert (sizeof(iso9660_dir_t) == 33);

  if (!dsize && !idr->length)
    dsize = ISO_BLOCKSIZE; /* for when dir lacks '.' entry */

  cdio_assert (dsize > 0 && !(dsize % ISO_BLOCKSIZE));
  cdio_assert (dir != NULL);
  cdio_assert (extent > 17);
  cdio_assert (filename != NULL);
  cdio_assert (strlen(filename) <= MAX_ISOPATHNAME);

  length = sizeof(iso9660_dir_t);
  length += strlen(filename);
  length = _cdio_ceil2block (length, 2); /* pad to word boundary */
  su_offset = length;
  length += su_size;
  length = _cdio_ceil2block (length, 2); /* pad to word boundary again */

  /* find the last entry's end */
  {
    unsigned int ofs_last_rec = 0;

    offset = 0;
    while (offset < dsize)
      {
        if (!dir8[offset])
          {
            offset++;
            continue;
          }

        offset += dir8[offset];
        ofs_last_rec = offset;
      }

    cdio_assert (offset == dsize);

    offset = ofs_last_rec;
  }

  /* be sure we don't cross sectors boundaries */
  offset = _cdio_ofs_add (offset, length, ISO_BLOCKSIZE);
  offset -= length;

  cdio_assert (offset + length <= dsize);

  idr = (iso9660_dir_t *) &dir8[offset];

  cdio_assert (offset+length < dsize);

  memset(idr, 0, length);

  idr->length = to_711(length);
  idr->extent = to_733(extent);
  idr->size = to_733(size);

  gmtime_r(entry_time, &temp_tm);
  iso9660_set_dtime (&temp_tm, &(idr->recording_time));

  idr->file_flags = to_711(file_flags);

  idr->volume_sequence_number = to_723(1);

  idr->filename.len = to_711(strlen(filename)
                             ? strlen(filename) : 1); /* working hack! */

  memcpy(&idr->filename.str[1], filename, from_711(idr->filename.len));
  memcpy(&dir8[offset] + su_offset, su_data, su_size);
}
コード例 #10
0
ファイル: iso9660_fs.c プロジェクト: AaronDnz/xbmc
static iso9660_stat_t *
_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, 
			 bool b_mode2, uint8_t i_joliet_level)
{
  iso9660_xa_t *xa_data = NULL;
  uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
  unsigned int filename_len;
  unsigned int stat_len;
  iso9660_stat_t *stat;

  if (!dir_len) return NULL;

  filename_len  = from_711(p_iso9660_dir->filename_len);

  /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
  stat_len      = sizeof(iso9660_stat_t)+filename_len+2;

  stat          = _cdio_malloc(stat_len);
  stat->type    = (p_iso9660_dir->file_flags & ISO_DIRECTORY) 
    ? _STAT_DIR : _STAT_FILE;
  stat->lsn     = from_733 (p_iso9660_dir->extent);
  stat->size    = from_733 (p_iso9660_dir->size);
  stat->secsize = _cdio_len2blocks (stat->size, ISO_BLOCKSIZE);

  if ('\0' == p_iso9660_dir->filename[0] && 1 == filename_len)
    strcpy (stat->filename, ".");
	else if ('\1' == p_iso9660_dir->filename[0] && 1 == filename_len)
    strcpy (stat->filename, "..");
  else {
#ifdef HAVE_JOLIET
    if (i_joliet_level) {
      int i_inlen = filename_len;
      int i_outlen = (i_inlen / 2);
      char *p_psz_out = NULL;
      ucs2be_to_locale(p_iso9660_dir->filename, i_inlen, 
		       &p_psz_out, i_outlen);
      strncpy(stat->filename, p_psz_out, filename_len);
      free(p_psz_out);
    } else
#endif /*HAVE_JOLIET*/
      strncpy (stat->filename, p_iso9660_dir->filename, filename_len);
  }


  iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(stat->tm));

  cdio_assert (dir_len >= sizeof (iso9660_dir_t));

  if (b_mode2) {
    int su_length = iso9660_get_dir_len(p_iso9660_dir) 
      - sizeof (iso9660_dir_t);
    su_length -= filename_len;
    
    if (su_length % 2)
      su_length--;
    
    if (su_length < 0 || su_length < sizeof (iso9660_xa_t))
      return stat;
    
    xa_data = (void *) (((char *) p_iso9660_dir) 
			+ (iso9660_get_dir_len(p_iso9660_dir) - su_length));
    
    if (xa_data->signature[0] != 'X' 
	|| xa_data->signature[1] != 'A')
    {
      cdio_warn ("XA signature not found in ISO9660's system use area;"
		 " ignoring XA attributes for this file entry.");
      cdio_debug ("%d %d %d, '%c%c' (%d, %d)", 
		  iso9660_get_dir_len(p_iso9660_dir), 
		  filename_len,
		  su_length,
		  xa_data->signature[0], xa_data->signature[1],
		  xa_data->signature[0], xa_data->signature[1]);
      return stat;
    }
    stat->xa = *xa_data;
  }
  return stat;
    
}
コード例 #11
0
ファイル: iso9660_fs.c プロジェクト: AaronDnz/xbmc
/*!
  Read the Super block of an ISO 9660 image. This is the 
  Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume 
  Descriptor if (Joliet) extensions are acceptable.
*/
bool 
iso9660_fs_read_superblock (CdIo_t *p_cdio, 
			    iso_extension_mask_t iso_extension_mask)
{
  if (!p_cdio) return false;
  
  {
    generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;
    iso9660_pvd_t         *p_pvd = &(p_env->pvd);
    iso9660_svd_t         *p_svd = &(p_env->svd);
    char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
    bool                   b_mode2;
    int i_rc;

    /* A bit of a hack, we'll assume track 1 contains ISO_PVD_SECTOR.*/
    switch(cdio_get_track_format(p_cdio, 1)) {
    case TRACK_FORMAT_CDI:
    case TRACK_FORMAT_XA:
      b_mode2 = true;
      break;
    case TRACK_FORMAT_DATA:
      b_mode2 = false;
      break;
    case TRACK_FORMAT_AUDIO: 
    case TRACK_FORMAT_PSX: 
    case TRACK_FORMAT_ERROR: 
    default:
      return false;
    }
  
    if ( !iso9660_fs_read_pvd(p_cdio, p_pvd) )
      return false;
    
    p_env->i_joliet_level = 0;
    
    i_rc = (b_mode2)
      ? cdio_read_mode2_sector (p_cdio, buf, ISO_PVD_SECTOR+1, false)
      : cdio_read_mode1_sector (p_cdio, buf, ISO_PVD_SECTOR+1, false);

    if (0 == i_rc) {
      /* The size of a PVD or SVD is smaller than a sector. So we
	 allocated a bigger block above (buf) and now we'll copy just
	 the part we need to save.
      */
      cdio_assert (sizeof(buf) >= sizeof (iso9660_svd_t));
      memcpy(p_svd, buf, sizeof(iso9660_svd_t));
  
      if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd->type) ) {
	if (p_svd->escape_sequences[0] == 0x25 
	    && p_svd->escape_sequences[1] == 0x2f) {
	  switch (p_svd->escape_sequences[2]) {
	  case 0x40:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL1) 
	      p_env->i_joliet_level = 1;
	    break;
	  case 0x43:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL2) 
	      p_env->i_joliet_level = 2;
	    break;
	  case 0x45:
	    if (iso_extension_mask & ISO_EXTENSION_JOLIET_LEVEL3) 
	      p_env->i_joliet_level = 3;
	    break;
	  default:
	    cdio_info("Supplementary Volume Descriptor found, but not Joliet");
	  }
	  if (p_env->i_joliet_level > 0) {
	    cdio_info("Found Extension: Joliet Level %d", 
		      p_env->i_joliet_level);
	  }
	}
      }
    }
  }

  return true;
}