示例#1
0
/*!
  Read a data sector
  
  @param p_cdio object to read from

  @param p_buf place to read data into.  The caller should make sure
  this location can store at least ISO_BLOCKSIZE, M2RAW_SECTOR_SIZE,
  or M2F2_SECTOR_SIZE depending on the kind of sector getting read. If
  you don't know whether you have a Mode 1/2, Form 1/ Form 2/Formless
  sector best to reserve space for the maximum, M2RAW_SECTOR_SIZE.

  @param i_lsn sector to read

  @param i_blocksize size of block. Should be either ISO_BLOCKSIZE
  M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under
  p_buf.
  */
driver_return_code_t 
read_data_sectors_image ( void *p_user_data, void *p_buf, 
			  lsn_t i_lsn,  uint16_t i_blocksize,
			  uint32_t i_blocks )
{
  const _img_private_t *p_env = p_user_data;

  if (!p_env || !p_env->gen.cdio) return DRIVER_OP_UNINIT;
  
  {
    CdIo_t *p_cdio                = p_env->gen.cdio;
    track_t i_track               = cdio_get_track(p_cdio, i_lsn);
    track_format_t e_track_format = cdio_get_track_format(p_cdio, i_track);

    switch(e_track_format) {
    case TRACK_FORMAT_PSX:
    case TRACK_FORMAT_AUDIO:
    case TRACK_FORMAT_ERROR:
      return DRIVER_OP_ERROR;
    case TRACK_FORMAT_DATA:
      return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
    case TRACK_FORMAT_CDI:
    case TRACK_FORMAT_XA:
      return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
    }
  }
  return DRIVER_OP_ERROR;
}
示例#2
0
void * /* list of char* -- caller must free it */
iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2)
{
  iso9660_stat_t stat;

  cdio_assert (cdio != NULL);
  cdio_assert (pathname != NULL);

  if (iso9660_fs_stat (cdio, pathname, &stat, is_mode2))
    return NULL;

  if (stat.type != _STAT_DIR)
    return NULL;

  {
    unsigned offset = 0;
    uint8_t *_dirbuf = NULL;
    CdioList *retval = _cdio_list_new ();

    if (stat.size != ISO_BLOCKSIZE * stat.secsize)
      {
	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		   (unsigned) stat.size, 
		   (unsigned long int) ISO_BLOCKSIZE * stat.secsize);
      }

    _dirbuf = _cdio_malloc (stat.secsize * ISO_BLOCKSIZE);

    if (is_mode2) {
      if (cdio_read_mode2_sectors (cdio, _dirbuf, stat.lsn, false, 
				   stat.secsize))
	cdio_assert_not_reached ();
    } else {
      if (cdio_read_mode1_sectors (cdio, _dirbuf, stat.lsn, false,
				   stat.secsize))
	cdio_assert_not_reached ();
    }

    while (offset < (stat.secsize * ISO_BLOCKSIZE))
      {
	const iso9660_dir_t *idr = (void *) &_dirbuf[offset];

	if (!iso9660_get_dir_len(idr))
	  {
	    offset++;
	    continue;
	  }

	_cdio_list_append (retval, _idr2name (idr));

	offset += iso9660_get_dir_len(idr);
      }

    cdio_assert (offset == (stat.secsize * ISO_BLOCKSIZE));

    free (_dirbuf);
    return retval;
  }
}
示例#3
0
文件: read.c 项目: ngocphu811/rufus
/*!
  Reads a number of sectors (AKA blocks).

  @param p_buf place to read data into. The caller should make sure
  this location is large enough. See below for size information.
  @param read_mode the kind of "mode" to use in reading.
  @param i_lsn sector to read
  @param i_blocks number of sectors to read
  @return DRIVER_OP_SUCCESS (0) if no error, other (negative) enumerations
  are returned on error.

  If read_mode is CDIO_MODE_AUDIO,
    *p_buf should hold at least CDIO_FRAMESIZE_RAW * i_blocks bytes.

  If read_mode is CDIO_MODE_DATA,
    *p_buf should hold at least i_blocks times either ISO_BLOCKSIZE,
    M1RAW_SECTOR_SIZE or M2F2_SECTOR_SIZE depending on the kind of
    sector getting read. If you don't know whether you have a Mode 1/2,
    Form 1/ Form 2/Formless sector best to reserve space for the maximum
    which is M2RAW_SECTOR_SIZE.

  If read_mode is CDIO_MODE_M2F1,
    *p_buf should hold at least M2RAW_SECTOR_SIZE * i_blocks bytes.

  If read_mode is CDIO_MODE_M2F2,
    *p_buf should hold at least CDIO_CD_FRAMESIZE * i_blocks bytes.


*/
driver_return_code_t
cdio_read_sectors(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
                  cdio_read_mode_t read_mode, uint32_t i_blocks)
{
    switch(read_mode) {
    case CDIO_READ_MODE_AUDIO:
        return cdio_read_audio_sectors (p_cdio, p_buf, i_lsn, i_blocks);
    case CDIO_READ_MODE_M1F1:
        return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
    case CDIO_READ_MODE_M1F2:
        return cdio_read_mode1_sectors (p_cdio, p_buf, i_lsn, true,  i_blocks);
    case CDIO_READ_MODE_M2F1:
        return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, false, i_blocks);
    case CDIO_READ_MODE_M2F2:
        return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, true,  i_blocks);
    }
    /* Can't happen. Just to shut up gcc. */
    return DRIVER_OP_ERROR;
}
示例#4
0
文件: read.c 项目: ngocphu811/rufus
/*!
  Reads a mode 2 sector

  @param p_cdio object to read from
  @param buf place to read data into
  @param lsn sector to read
  @param b_form2 true for reading mode 2 form 2 sectors or false for
  mode 2 form 1 sectors.
*/
driver_return_code_t
cdio_read_mode2_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
                        bool b_form2)
{
    check_lsn(i_lsn);
    if (p_cdio->op.read_mode2_sector)
        return p_cdio->op.read_mode2_sector (p_cdio->env, p_buf, i_lsn, b_form2);

    /* fallback */
    if (p_cdio->op.read_mode2_sectors != NULL)
        return cdio_read_mode2_sectors (p_cdio, p_buf, i_lsn, b_form2, 1);
    return DRIVER_OP_UNSUPPORTED;
}
示例#5
0
/*!
   Reads a single mode2 sector from cd device into data starting
   from lsn. Returns 0 if no error. 
 */
int
cdio_read_mode2_sector (const CdIo *cdio, void *buf, lsn_t lsn, 
                        bool is_form2)
{
  cdio_assert (cdio != NULL);
  cdio_assert (buf != NULL);
  cdio_assert (cdio->op.read_mode2_sector != NULL 
	      || cdio->op.read_mode2_sectors != NULL);

  if (cdio->op.read_mode2_sector)
    return cdio->op.read_mode2_sector (cdio->env, buf, lsn, is_form2);

  /* fallback */
  if (cdio->op.read_mode2_sectors != NULL)
    return cdio_read_mode2_sectors (cdio, buf, lsn, is_form2, 1);
  return 1;
}
示例#6
0
static iso9660_stat_t *
_fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root, 
		   char **splitpath, bool b_mode2, bool translate)
{
  unsigned offset = 0;
  uint8_t *_dirbuf = NULL;
  iso9660_stat_t *p_stat;
  generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;

  if (!splitpath[0])
    {
      unsigned int len=sizeof(iso9660_stat_t) + strlen(_root->filename)+1;
      p_stat = _cdio_malloc(len);
      memcpy(p_stat, _root, len);
      return p_stat;
    }

  if (_root->type == _STAT_FILE)
    return NULL;

  cdio_assert (_root->type == _STAT_DIR);

  if (_root->size != ISO_BLOCKSIZE * _root->secsize)
    {
      cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		 (unsigned) _root->size, 
		 (unsigned long int) ISO_BLOCKSIZE * _root->secsize);
    }
  
  _dirbuf = _cdio_malloc (_root->secsize * ISO_BLOCKSIZE);

  if (b_mode2) {
    if (cdio_read_mode2_sectors (p_cdio, _dirbuf, _root->lsn, false, 
				 _root->secsize))
      return NULL;
  } else {
    if (cdio_read_mode1_sectors (p_cdio, _dirbuf, _root->lsn, false,
				 _root->secsize))
      return NULL;
  }
  
  while (offset < (_root->secsize * ISO_BLOCKSIZE))
    {
      iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
      iso9660_stat_t *p_stat;
      int cmp;

      if (!iso9660_get_dir_len(p_iso9660_dir))
	{
	  offset++;
	  continue;
	}
      
      p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, b_mode2, 
					p_env->i_joliet_level);

      if (translate) {
	char *trans_fname = malloc(strlen(p_stat->filename));
	int trans_len;
	
	if (trans_fname == NULL) {
	  cdio_warn("can't allocate %lu bytes", 
		    (long unsigned int) strlen(p_stat->filename));
	  return NULL;
	}
	trans_len = iso9660_name_translate_ext(p_stat->filename, trans_fname, 
					       p_env->i_joliet_level);
	cmp = strcmp(splitpath[0], trans_fname);
	free(trans_fname);
      } else {
	cmp = strcmp(splitpath[0], p_stat->filename);
      }
      
      if (!cmp) {
	iso9660_stat_t *ret_stat 
	  = _fs_stat_traverse (p_cdio, p_stat, &splitpath[1], b_mode2, 
			       translate);
	free(p_stat);
	free (_dirbuf);
	return ret_stat;
      }

      free(p_stat);
	  
      offset += iso9660_get_dir_len(p_iso9660_dir);
    }

  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));
  
  /* not found */
  free (_dirbuf);
  return NULL;
}
示例#7
0
/*! 
  Read pathname (a directory) and return a list of iso9660_stat_t
  of the files inside that. The caller must free the returned result.
*/
CdioList_t * 
iso9660_fs_readdir (CdIo_t *p_cdio, const char pathname[], bool b_mode2)
{
  iso9660_stat_t *p_stat;
  generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;

  if (!p_cdio)   return NULL;
  if (!pathname) return NULL;

  p_stat = iso9660_fs_stat (p_cdio, pathname);
  if (!p_stat) return NULL;

  if (p_stat->type != _STAT_DIR) {
    free(p_stat);
    return NULL;
  }

  {
    unsigned offset = 0;
    uint8_t *_dirbuf = NULL;
    CdioList_t *retval = _cdio_list_new ();

    if (p_stat->size != ISO_BLOCKSIZE * p_stat->secsize)
      {
	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		   (unsigned) p_stat->size, 
		   (unsigned long int) ISO_BLOCKSIZE * p_stat->secsize);
      }

    _dirbuf = _cdio_malloc (p_stat->secsize * ISO_BLOCKSIZE);

    if (b_mode2) {
      if (cdio_read_mode2_sectors (p_cdio, _dirbuf, p_stat->lsn, false, 
				   p_stat->secsize))
	cdio_assert_not_reached ();
    } else {
      if (cdio_read_mode1_sectors (p_cdio, _dirbuf, p_stat->lsn, false,
				   p_stat->secsize))
	cdio_assert_not_reached ();
    }

    while (offset < (p_stat->secsize * ISO_BLOCKSIZE))
      {
	iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
	iso9660_stat_t *p_iso9660_stat;
	
	if (!iso9660_get_dir_len(p_iso9660_dir))
	  {
	    offset++;
	    continue;
	  }

	p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, b_mode2, 
						 p_env->i_joliet_level);
	_cdio_list_append (retval, p_iso9660_stat);

	offset += iso9660_get_dir_len(p_iso9660_dir);
      }

    cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE));

    free (_dirbuf);
    free (p_stat);
    return retval;
  }
}
示例#8
0
static int
_fs_stat_traverse (const CdIo *cdio, const iso9660_stat_t *_root, 
		   char **splitpath, /*out*/ iso9660_stat_t *buf, 
		   bool is_mode2)
{
  unsigned offset = 0;
  uint8_t *_dirbuf = NULL;

  if (!splitpath[0])
    {
      *buf = *_root;
      return 0;
    }

  if (_root->type == _STAT_FILE)
    return -1;

  cdio_assert (_root->type == _STAT_DIR);

  if (_root->size != ISO_BLOCKSIZE * _root->secsize)
    {
      cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		 (unsigned) _root->size, 
		 (unsigned long int) ISO_BLOCKSIZE * _root->secsize);
    }
  
  _dirbuf = _cdio_malloc (_root->secsize * ISO_BLOCKSIZE);

  if (is_mode2) {
    if (cdio_read_mode2_sectors (cdio, _dirbuf, _root->lsn, false, 
				 _root->secsize))
      cdio_assert_not_reached ();
  } else {
    if (cdio_read_mode1_sectors (cdio, _dirbuf, _root->lsn, false,
				 _root->secsize))
      cdio_assert_not_reached ();
  }
  
  while (offset < (_root->secsize * ISO_BLOCKSIZE))
    {
      const iso9660_dir_t *idr = (void *) &_dirbuf[offset];
      iso9660_stat_t stat;
      char *name;

      if (!iso9660_get_dir_len(idr))
	{
	  offset++;
	  continue;
	}
      
      name = _idr2name (idr);
      _idr2statbuf (idr, &stat, is_mode2);

      if (!strcmp (splitpath[0], name))
	{
	  int retval = _fs_stat_traverse (cdio, &stat, &splitpath[1], buf,
					  is_mode2);
	  free (name);
	  free (_dirbuf);
	  return retval;
	}

      free (name);

      offset += iso9660_get_dir_len(idr);
    }

  cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE));
  
  /* not found */
  free (_dirbuf);
  return -1;
}