Ejemplo n.º 1
0
/*!
  Return the number of hard links of the file. Return 0 if error.
*/
uint16_t udf_get_link_count(const udf_dirent_t *p_udf_dirent) 
{
  if (p_udf_dirent) {
    return uint16_from_le(p_udf_dirent->fe.link_count);
  }
  return 0; /* Error. Non-error case handled above. */
}
Ejemplo n.º 2
0
void threecom3c505_device::do_receive_command()
{
	// receive pending and no other command is pending
	if (m_rx_pending > 0 && !m_command_pending)
	{
		if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.is_empty())
		{
			m_rx_fifo.get(&m_rx_data_buffer);
		}

		// receive data available ?
		if (m_rx_data_buffer.get_length() > 0)
		{
			LOG2(("do_receive_command - data_length=%x rx_pending=%d",
							m_rx_data_buffer.get_length(), m_rx_pending));

			m_rx_pending--;
			set_command_pending(1);

			// preset receive response PCB
			memcpy(&m_response, &m_rcv_response, sizeof(m_rcv_response));

//          m_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
//          m_response.length = 16;
//          m_response.data.rcv_resp.buf_ofs = htole16(0);
//          m_response.data.rcv_resp.buf_seg = htole16(0);
//          m_response.data.rcv_resp.buf_len = htole16(buf_len);

			// htole16 and friends are not portable beyond Linux.  It's named differently on *BSD and differently again on OS X.  Avoid!
			m_response.data.rcv_resp.pkt_len = uint16_to_le(m_rx_data_buffer.get_length());
			m_response.data.rcv_resp.timeout = 0; // successful completion
			m_response.data.rcv_resp.status  = uint16_to_le(m_rx_data_buffer.get_length() > 0 ? 0 : 0xffff);
			m_response.data.rcv_resp.timetag = 0; // TODO: time tag

			// compute and check no of bytes to be DMA'ed (must be even)
			UINT16 buf_len = uint16_from_le(m_response.data.rcv_resp.buf_len) & ~1;
			if (m_rx_data_buffer.get_length() > buf_len)
			{
				LOG1(("do_receive_command !!! buffer size too small (%d < %d)", buf_len, m_rx_data_buffer.get_length()));
				m_response.data.rcv_resp.pkt_len = uint16_to_le(buf_len);
				m_response.data.rcv_resp.status = 0xffff;
			}
			else
			{
				buf_len = (m_rx_data_buffer.get_length() + 1) & ~1;
				m_response.data.rcv_resp.buf_len = uint16_to_le(buf_len);
			}

			m_response_length = m_response.length + 2;
			m_response_index = 0;

			m_status |= ACRF; /* set adapter command register full */
			if (m_control & CMDE)
			{
				set_interrupt(ASSERT_LINE);
			}
		}
	}
}
Ejemplo n.º 3
0
Archivo: udf.c Proyecto: hanji/rufus
/*!
  Returns POSIX mode bitstring for a given file.
*/
mode_t 
udf_get_posix_filemode(const udf_dirent_t *p_udf_dirent) 
{
  udf_file_entry_t udf_fe;
  mode_t mode = 0;

  if (udf_get_file_entry(p_udf_dirent, &udf_fe)) {
    uint32_t i_perms;
#ifdef S_ISUID
    uint16_t i_flags;

    i_flags = uint16_from_le(udf_fe.icb_tag.flags);
#endif
    i_perms = uint32_from_le(udf_fe.permissions);

    if (i_perms & FE_PERM_U_READ)  mode |= S_IRUSR;
    if (i_perms & FE_PERM_U_WRITE) mode |= S_IWUSR;
    if (i_perms & FE_PERM_U_EXEC)  mode |= S_IXUSR;
    
#ifdef S_IRGRP
    if (i_perms & FE_PERM_G_READ)  mode |= S_IRGRP;
    if (i_perms & FE_PERM_G_WRITE) mode |= S_IWGRP;
    if (i_perms & FE_PERM_G_EXEC)  mode |= S_IXGRP;
#endif
    
#ifdef S_IROTH
    if (i_perms & FE_PERM_O_READ)  mode |= S_IROTH;
    if (i_perms & FE_PERM_O_WRITE) mode |= S_IWOTH;
    if (i_perms & FE_PERM_O_EXEC)  mode |= S_IXOTH;
#endif

    switch (udf_fe.icb_tag.file_type) {
    case ICBTAG_FILE_TYPE_DIRECTORY: 
      mode |= S_IFDIR;
      break;
    case ICBTAG_FILE_TYPE_REGULAR:
      mode |= S_IFREG;
      break;
#ifdef S_IFLNK
    case ICBTAG_FILE_TYPE_SYMLINK:
      mode |= S_IFLNK;
      break;
#endif
    case ICBTAG_FILE_TYPE_CHAR:
      mode |= S_IFCHR;
      break;
#ifdef S_IFSOCK
    case ICBTAG_FILE_TYPE_SOCKET:
      mode |= S_IFSOCK;
      break;
#endif
    case ICBTAG_FILE_TYPE_BLOCK:
      mode |= S_IFBLK;
      break;
    default: ;
    };
  
#ifdef S_ISUID
    if (i_flags & ICBTAG_FLAG_SETUID) mode |= S_ISUID;
    if (i_flags & ICBTAG_FLAG_SETGID) mode |= S_ISGID;
    if (i_flags & ICBTAG_FLAG_STICKY) mode |= S_ISVTX;
#endif
  }
  
  return mode;
  
}
Ejemplo n.º 4
0
/*
 * Translate a file offset into a logical block and then into a physical
 * block.
 */
static lba_t
offset_to_lba(const udf_dirent_t *p_udf_dirent, off_t i_offset, 
	      /*out*/ lba_t *pi_lba, /*out*/ uint32_t *pi_max_size)
{
  udf_t *p_udf = p_udf_dirent->p_udf;
  const udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) 
    &p_udf_dirent->fe;
  const udf_icbtag_t *p_icb_tag = &p_udf_fe->icb_tag;
  const uint16_t strat_type= uint16_from_le(p_icb_tag->strat_type);
  
  switch (strat_type) {
  case 4096:
    printf("Cannot deal with strategy4096 yet!\n");
    return CDIO_INVALID_LBA;
    break;
  case ICBTAG_STRATEGY_TYPE_4:
    {
      uint32_t icblen = 0;
      lba_t lsector;
      int ad_offset, ad_num = 0;
      uint16_t addr_ilk = uint16_from_le(p_icb_tag->flags&ICBTAG_FLAG_AD_MASK);
      
      switch (addr_ilk) {
      case ICBTAG_FLAG_AD_SHORT: 
	{
	  udf_short_ad_t *p_icb;
	  /*
	   * The allocation descriptor field is filled with short_ad's.
	   * If the offset is beyond the current extent, look for the
	   * next extent.
	   */
	  do {
	    i_offset -= icblen;
	    ad_offset = sizeof(udf_short_ad_t) * ad_num;
	    if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
	      printf("File offset out of bounds\n");
	      return CDIO_INVALID_LBA;
	    }
	    p_icb = (udf_short_ad_t *) 
	      GETICB( uint32_from_le(p_udf_fe->i_extended_attr) 
		      + ad_offset );
	    icblen = p_icb->len;
	    ad_num++;
	  } while(i_offset >= icblen);
	  
	  lsector = (i_offset / UDF_BLOCKSIZE) + p_icb->pos;
	  
	  *pi_max_size = p_icb->len;
	}
	break;
      case ICBTAG_FLAG_AD_LONG: 
	{
	  /*
	   * The allocation descriptor field is filled with long_ad's
	   * If the i_offset is beyond the current extent, look for the
	   * next extent.
	   */
	  udf_long_ad_t *p_icb;
	  do {
	    i_offset -= icblen;
	    ad_offset = sizeof(udf_long_ad_t) * ad_num;
	    if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
	      printf("File offset out of bounds\n");
	      return CDIO_INVALID_LBA;
	    }
	    p_icb = (udf_long_ad_t *) 
	      GETICB( uint32_from_le(p_udf_fe->i_extended_attr)
		      + ad_offset );
	    icblen = p_icb->len;
	    ad_num++;
	  } while(i_offset >= icblen);
	
	  lsector = (i_offset / UDF_BLOCKSIZE) +
	    uint32_from_le(((udf_long_ad_t *)(p_icb))->loc.lba);
	  
	  *pi_max_size = p_icb->len;
	}
	break;
      case ICBTAG_FLAG_AD_IN_ICB:
	/*
	 * This type means that the file *data* is stored in the
	 * allocation descriptor field of the file entry.
	 */
	*pi_max_size = 0;
	printf("Don't know how to data in ICB handle yet\n");
	return CDIO_INVALID_LBA;
      case ICBTAG_FLAG_AD_EXTENDED:
	printf("Don't know how to handle extended addresses yet\n");
	return CDIO_INVALID_LBA;
      default:
	printf("Unsupported allocation descriptor %d\n", addr_ilk);
	return CDIO_INVALID_LBA;
      }
      
      *pi_lba = lsector + p_udf->i_part_start;
      return *pi_lba;
    }
  default:
    printf("Unknown strategy type %d\n", strat_type);
    return DRIVER_OP_ERROR;
  }
}
Ejemplo n.º 5
0
/*!
  Get the root in p_udf. If b_any_partition is false then
  the root must be in the given partition.
  NULL is returned if the partition is not found or a root is not found or
  there is on error.

  Caller must free result - use udf_dirent_free for that.
*/
udf_dirent_t *
udf_get_root (udf_t *p_udf, bool b_any_partition, partition_num_t i_partition)
{
  const anchor_vol_desc_ptr_t *p_avdp = &p_udf->anchor_vol_desc_ptr;
  const uint32_t mvds_start =
    uint32_from_le(p_avdp->main_vol_desc_seq_ext.loc);
  const uint32_t mvds_end   = mvds_start +
    (uint32_from_le(p_avdp->main_vol_desc_seq_ext.len) - 1) / UDF_BLOCKSIZE;
  uint32_t i_lba;
  uint8_t data[UDF_BLOCKSIZE];

  /*
     Now we have the joy of finding the Partition Descriptor and the
     Logical Volume Descriptor for the Main Volume Descriptor
     Sequence. Once we've got that, we use the Logical Volume
     Descriptor to get a Fileset Descriptor and that has the Root
     Directory File Entry.
  */
  for (i_lba = mvds_start; i_lba < mvds_end; i_lba++) {
    uint8_t data2[UDF_BLOCKSIZE];

    partition_desc_t *p_partition = (partition_desc_t *) &data2;

    if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, p_partition, i_lba, 1) )
      return NULL;

    if (!udf_checktag(&p_partition->tag, TAGID_PARTITION)) {
      const partition_num_t i_partition_check
	= uint16_from_le(p_partition->number);
      if (b_any_partition || i_partition_check == i_partition) {
	/* Squirrel away some data regarding partition */
	p_udf->i_partition = uint16_from_le(p_partition->number);
	p_udf->i_part_start = uint32_from_le(p_partition->start_loc);
	if (p_udf->lvd_lba) break;
      }
    } else if (!udf_checktag(&p_partition->tag, TAGID_LOGVOL)) {
      /* Get fileset descriptor */
      logical_vol_desc_t *p_logvol = (logical_vol_desc_t *) &data2;
      bool b_valid =
	UDF_BLOCKSIZE == uint32_from_le(p_logvol->logical_blocksize);

      if (b_valid) {
	p_udf->lvd_lba = i_lba;
	p_udf->fsd_offset =
	  uint32_from_le(p_logvol->lvd_use.fsd_loc.loc.lba);
	if (p_udf->i_part_start) break;
      }
    }
  }
  if (p_udf->lvd_lba && p_udf->i_part_start) {
    udf_fsd_t *p_fsd = (udf_fsd_t *) &data;

    driver_return_code_t ret =
      udf_read_sectors(p_udf, p_fsd, p_udf->i_part_start + p_udf->fsd_offset,
		       1);

    if (DRIVER_OP_SUCCESS == ret && !udf_checktag(&p_fsd->tag, TAGID_FSD)) {
      udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;
      const uint32_t parent_icb = uint32_from_le(p_fsd->root_icb.loc.lba);

      /* Check partition numbers match of last-read block?  */

      ret = udf_read_sectors(p_udf, p_udf_fe,
			     p_udf->i_part_start + parent_icb, 1);
      if (ret == DRIVER_OP_SUCCESS &&
	  !udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {

	/* Check partition numbers match of last-read block? */

	/* We win! - Save root directory information. */
	return udf_new_dirent(p_udf_fe, p_udf, "/", true, false );
      }
    }
  }

  return NULL;
}