Example #1
0
/**
 * Gets the Logical Volume Identifier string, as an UTF-8 string
 * psz_logvolid, place to put the string (should be at least 64 bytes)
 * i_logvolid, size of the buffer psz_logvolid points to
 * returns the size of buffer needed for all data, including NUL terminator
 * A call to udf_get_root() should have been issued before this call
 * Note: this call accepts a NULL psz_volid, to retrieve the length required.
 */
int
udf_get_logical_volume_id(udf_t *p_udf, /*out*/ char *psz_logvolid, unsigned int i_logvolid)
{
  uint8_t data[UDF_BLOCKSIZE];
  logical_vol_desc_t *p_logvol = (logical_vol_desc_t *) &data;
  char* r;
  int logvolid_len;

  /* clear the output to empty string */
  if (psz_logvolid != NULL)
    psz_logvolid[0] = 0;

  if (DRIVER_OP_SUCCESS != udf_read_sectors (p_udf, p_logvol, p_udf->lvd_lba, 1) )
    return 0;

  r = unicode16_decode((uint8_t *) p_logvol->logvol_id, p_logvol->logvol_id[127]);
  if (r == NULL)
    return 0;

  logvolid_len = strlen(r)+1;  /* +1 for NUL terminator */
  if (psz_logvolid != NULL) {
    strncpy(psz_logvolid, r, MIN(logvolid_len, i_logvolid));
    psz_logvolid[i_logvolid-1] = 0;    /* strncpy does not always terminate the dest */
  }
  free(r);

  return logvolid_len;
}
Example #2
0
/**
 * Gets the Volume Identifier, as an UTF-8 string
 * psz_volid, place to put the string
 * i_volid, size of the buffer psz_volid points to
 * returns the size of buffer needed for all data
 * Note: this call accepts a NULL psz_volid, to retrieve the length required.
 */
int
udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid, unsigned int i_volid)
{
  uint8_t data[UDF_BLOCKSIZE];
  const udf_pvd_t *p_pvd = (udf_pvd_t *) &data;
  char* r;
  unsigned int volid_len;

  /* clear the output to empty string */
  if (psz_volid != NULL)
    psz_volid[0] = 0;

  /* get primary volume descriptor */
  if ( DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &data, p_udf->pvd_lba, 1) )
    return 0;

  volid_len = p_pvd->vol_ident[UDF_VOLID_SIZE-1];
  if(volid_len > UDF_VOLID_SIZE-1) {
    /* this field is only UDF_VOLID_SIZE bytes something is wrong */
    volid_len = UDF_VOLID_SIZE-1;
  }

  r = unicode16_decode((uint8_t *) p_pvd->vol_ident, volid_len);
  if (r == NULL)
    return 0;

  volid_len = strlen(r)+1;     /* +1 for NUL terminator */
  if (psz_volid != NULL) {
    strncpy(psz_volid, r, MIN(volid_len, i_volid));
    psz_volid[i_volid-1] = 0;  /* strncpy does not always terminate the dest */
  }
  free(r);

  return volid_len;
}
Example #3
0
/**
 * Gets the Volume Identifier string, in 8bit unicode (latin-1)
 * psz_volid, place to put the string
 * i_volid_size, size of the buffer volid points to
 * returns the size of buffer needed for all data
 */
int 
udf_get_volume_id(udf_t *p_udf, /*out*/ char *psz_volid,  unsigned int i_volid)
{
  uint8_t data[UDF_BLOCKSIZE];
  const udf_pvd_t *p_pvd = (udf_pvd_t *) &data;
  unsigned int volid_len;

  /* get primary volume descriptor */
  if ( DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &data, p_udf->pvd_lba, 1) )
    return 0;

  volid_len = p_pvd->vol_ident[UDF_VOLID_SIZE-1];
  if(volid_len > UDF_VOLID_SIZE-1) {
    /* this field is only UDF_VOLID_SIZE bytes something is wrong */
    volid_len = UDF_VOLID_SIZE-1;
  }
  if(i_volid > volid_len) {
    i_volid = volid_len;
  }
  unicode16_decode((uint8_t *) p_pvd->vol_ident, i_volid, psz_volid);
  
  return volid_len;
}
Example #4
0
udf_dirent_t *
udf_readdir(udf_dirent_t *p_udf_dirent)
{
  udf_t *p_udf;
  uint8_t* p;

  if (p_udf_dirent->dir_left <= 0) {
    udf_dirent_free(p_udf_dirent);
    return NULL;
  }

  /* file position must be reset when accessing a new file */
  p_udf = p_udf_dirent->p_udf;
  p_udf->i_position = 0;

  if (p_udf_dirent->fid) {
    /* advance to next File Identifier Descriptor */
    /* FIXME: need to advance file entry (fe) as well.  */
    uint32_t ofs = 4 *
      ((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->u.i_imp_use
	+ p_udf_dirent->fid->i_file_id + 3) / 4);

    p_udf_dirent->fid =
      (udf_fileid_desc_t *)((uint8_t *)p_udf_dirent->fid + ofs);
  }

  if (!p_udf_dirent->fid) {
    uint32_t i_sectors =
      (p_udf_dirent->i_loc_end - p_udf_dirent->i_loc + 1);
    uint32_t size = UDF_BLOCKSIZE * i_sectors;
    driver_return_code_t i_ret;

    if (!p_udf_dirent->sector)
      p_udf_dirent->sector = (uint8_t*) malloc(size);
    i_ret = udf_read_sectors(p_udf, p_udf_dirent->sector,
			     p_udf_dirent->i_part_start+p_udf_dirent->i_loc,
			     i_sectors);
    if (DRIVER_OP_SUCCESS == i_ret)
      p_udf_dirent->fid = (udf_fileid_desc_t *) p_udf_dirent->sector;
    else
      p_udf_dirent->fid = NULL;
  }

  if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
    {
      uint32_t ofs =
	4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->u.i_imp_use
	      + p_udf_dirent->fid->i_file_id + 3) / 4);

      p_udf_dirent->dir_left -= ofs;
      p_udf_dirent->b_dir =
	(p_udf_dirent->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0;
      p_udf_dirent->b_parent =
	(p_udf_dirent->fid->file_characteristics & UDF_FILE_PARENT) != 0;

      {
	const unsigned int i_len = p_udf_dirent->fid->i_file_id;

	if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &p_udf_dirent->fe, p_udf->i_part_start
			 + uint32_from_le(p_udf_dirent->fid->icb.loc.lba), 1)) {
		udf_dirent_free(p_udf_dirent);
		return NULL;
	}

       free_and_null(p_udf_dirent->psz_name);
       p = (uint8_t*)p_udf_dirent->fid->u.imp_use.data + p_udf_dirent->fid->u.i_imp_use;
       p_udf_dirent->psz_name = unicode16_decode(p, i_len);
      }
      return p_udf_dirent;
    }
  udf_dirent_free(p_udf_dirent);
  return NULL;
}
Example #5
0
udf_dirent_t *
udf_readdir(udf_dirent_t *p_udf_dirent)
{
  udf_t *p_udf;
  
  if (p_udf_dirent->dir_left <= 0) {
    udf_dirent_free(p_udf_dirent);
    return NULL;
  }

  p_udf = p_udf_dirent->p_udf;
  if (p_udf_dirent->fid) { 
    /* advance to next File Identifier Descriptor */
    /* FIXME: need to advance file entry (fe) as well.  */
    uint32_t ofs = 4 * 
      ((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->i_imp_use 
	+ p_udf_dirent->fid->i_file_id + 3) / 4);
    
    p_udf_dirent->fid = 
      (udf_fileid_desc_t *)((uint8_t *)p_udf_dirent->fid + ofs);
  }
  
  if (!p_udf_dirent->fid) {
    uint32_t i_sectors = 
      (p_udf_dirent->i_loc_end - p_udf_dirent->i_loc + 1);
    uint32_t size = UDF_BLOCKSIZE * i_sectors;
    driver_return_code_t i_ret;

    if (!p_udf_dirent->sector)
      p_udf_dirent->sector = (uint8_t*) malloc(size);
    i_ret = udf_read_sectors(p_udf, p_udf_dirent->sector, 
			     p_udf_dirent->i_part_start+p_udf_dirent->i_loc, 
			     i_sectors);
    if (DRIVER_OP_SUCCESS == i_ret)
      p_udf_dirent->fid = (udf_fileid_desc_t *) p_udf_dirent->sector;
    else
      p_udf_dirent->fid = NULL;
  }
  
  if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
    {
      uint32_t ofs = 
	4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->i_imp_use 
	      + p_udf_dirent->fid->i_file_id + 3) / 4);
      
      p_udf_dirent->dir_left -= ofs;
      p_udf_dirent->b_dir = 
	(p_udf_dirent->fid->file_characteristics & UDF_FILE_DIRECTORY) != 0;
      p_udf_dirent->b_parent = 
	(p_udf_dirent->fid->file_characteristics & UDF_FILE_PARENT) != 0;

      {
	const unsigned int i_len = p_udf_dirent->fid->i_file_id;
	uint8_t data[UDF_BLOCKSIZE] = {0};
	udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) &data;

	if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start 
			 + p_udf_dirent->fid->icb.loc.lba, 1))
		return NULL;
      
	memcpy(&(p_udf_dirent->fe), p_udf_fe, 
	       sizeof(udf_file_entry_t) + p_udf_fe->i_alloc_descs 
	       + p_udf_fe->i_extended_attr );

	if (strlen(p_udf_dirent->psz_name) < i_len) 
	  p_udf_dirent->psz_name = (char *)
	    realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
	
	unicode16_decode(p_udf_dirent->fid->imp_use 
			 + p_udf_dirent->fid->i_imp_use, 
			 i_len, p_udf_dirent->psz_name);
      }
      return p_udf_dirent;
    }
  return NULL;
}