示例#1
0
static void
_idr2statbuf (const iso9660_dir_t *idr, iso9660_stat_t *stat, bool is_mode2)
{
  iso9660_xa_t *xa_data = NULL;
  uint8_t dir_len= iso9660_get_dir_len(idr);

  memset ((void *) stat, 0, sizeof (iso9660_stat_t));

  if (!dir_len) return;

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

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

  cdio_assert (dir_len >= sizeof (iso9660_dir_t));

  if (is_mode2) {
    int su_length = iso9660_get_dir_len(idr) - sizeof (iso9660_dir_t);
    su_length -= idr->filename_len;
    
    if (su_length % 2)
      su_length--;
    
    if (su_length < 0 || su_length < sizeof (iso9660_xa_t))
      return;
    
    xa_data = (void *) (((char *) idr) + (iso9660_get_dir_len(idr) - 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(idr), 
		  idr->filename_len,
		  su_length,
		  xa_data->signature[0], xa_data->signature[1],
		  xa_data->signature[0], xa_data->signature[1]);
      return;
    }
    stat->xa = *xa_data;
  }
    
}
示例#2
0
文件: iso9660.c 项目: 10se1ucgo/rufus
/*! Return the LSN of the root directory for pvd.
    If there is an error CDIO_INVALID_LSN is returned.
 */
lsn_t
iso9660_get_root_lsn(const iso9660_pvd_t *pvd)
{
  if (NULL == pvd)
    return CDIO_INVALID_LSN;
  else {
    const iso9660_dir_t *idr = &(pvd->root_directory_record);
    if (NULL == idr) return CDIO_INVALID_LSN;
    return(from_733 (idr->extent));
  }
}
示例#3
0
文件: rock.c 项目: 3aychonok/libcdio
static int
parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
			       iso9660_stat_t *p_stat, int regard_xa)
{
  int len;
  unsigned char * chr;
  int symlink_len = 0;
  CONTINUE_DECLS;

  if (nope == p_stat->rr.b3_rock) return 0;

  SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
  if (regard_xa)
    {
      chr+=14;
      len-=14;
      if (len<0) len=0;
    }
  
  /* repeat:*/
  {
    int sig;
    iso_extension_record_t * rr;
    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 = from_721(*chr);
      chr += rr->len; 
      len -= rr->len;
      
      switch(sig){
      case SIG('S','P'):
	CHECK_SP(goto out);
	break;
      case SIG('C','E'):
	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('P','X'):
	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);
	break;
      case SIG('P','N'):
	/* Device major,minor number */
	{ int32_t high, low;
	  high = from_733(rr->u.PN.dev_high);
	  low = from_733(rr->u.PN.dev_low);
	  /*
	   * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4,
	   * then the high field is unused, and the device number is completely
	   * stored in the low field.  Some writers may ignore this subtlety,
	   * and as a result we test to see if the entire device number is
	   * stored in the low field, and use that.
	   */
	  if((low & ~0xff) && high == 0) {
	    p_stat->rr.i_rdev = CDIO_MKDEV(low >> 8, low & 0xff);
	  } else {
	    p_stat->rr.i_rdev = CDIO_MKDEV(high, low);
	  }
	}
	break;
      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;
	}
      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++] = '/';
	      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'):
	cdio_warn("Attempt to read p_stat for relocated directory");
	goto out;
#ifdef FINISHED
      case SIG('C','L'): 
	{
	  iso9660_stat_t * reloc;
	  ISOFS_I(p_stat)->i_first_extent = from_733(rr->u.CL.location);
	  reloc = isofs_iget(p_stat->rr.i_sb, p_stat->rr.i_first_extent, 0);
	  if (!reloc)
	    goto out;
	  p_stat->rr.st_mode   = reloc->st_mode;
	  p_stat->rr.st_nlinks = reloc->st_nlinks;
	  p_stat->rr.st_uid    = reloc->st_uid;
	  p_stat->rr.st_gid    = reloc->st_gid;
	  p_stat->rr.i_rdev    = reloc->i_rdev;
	  p_stat->rr.i_symlink = reloc->i_symlink;
	  p_stat->rr.i_blocks  = reloc->i_blocks;
	  p_stat->rr.i_atime   = reloc->i_atime;
	  p_stat->rr.i_ctime   = reloc->i_ctime;
	  p_stat->rr.i_mtime   = reloc->i_mtime;
	  iput(reloc);
	}
	break;
#endif
      default:
	break;
      }
    }
示例#4
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;
}
示例#5
0
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;
    
}
示例#6
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);
}
示例#7
0
文件: iso9660.c 项目: 10se1ucgo/rufus
int
iso9660_get_pvd_space_size(const iso9660_pvd_t *pvd)
{
  if (NULL == pvd) return 0;
  return from_733(pvd->volume_space_size);
}
示例#8
0
文件: iso9660.c 项目: 10se1ucgo/rufus
uint8_t
iso9660_get_dir_size(const iso9660_dir_t *idr)
{
  if (NULL == idr) return 0;
  return from_733(idr->size);
}
示例#9
0
文件: iso9660.c 项目: 10se1ucgo/rufus
lsn_t
iso9660_get_dir_extent(const iso9660_dir_t *idr)
{
  if (NULL == idr) return 0;
  return from_733(idr->extent);
}
示例#10
0
void iso9660::Scan()
{
  if (m_hCDROM != NULL)
    return ;

  m_hCDROM = CIoSupport::OpenCDROM();
  CIoSupport::AllocReadBuffer();

  m_paths = 0;
  m_lastpath = 0;
  memset(&m_info, 0, sizeof(m_info));
  m_info.ISO_HANDLE = m_hCDROM ;
  m_info.Curr_dir_cache = 0;
  m_info.Curr_dir = (char*)malloc( 4096 );
  strcpy( m_info.Curr_dir, "\\" );

  CSingleLock lock(m_critSection);

  DWORD lpNumberOfBytesRead = 0;
  ::SetFilePointer( m_info.ISO_HANDLE, 0x8000, 0, FILE_BEGIN );

  ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL );

  if (strncmp(m_info.iso.szSignature, "CD001", 5))
  {
    CIoSupport::CloseCDROM( m_info.ISO_HANDLE);
    CIoSupport::FreeReadBuffer();
    m_info.ISO_HANDLE = NULL;
    m_hCDROM = NULL;
    m_info.iso9660 = 0;
    return ;
  }
  else
  {
    m_info.iso9660 = 1;
    m_info.joliet = 0;

    m_info.HeaderPos = 0x8000;
    int current = 0x8000;

    WORD wSectorSize = from_723(m_info.iso.logical_block_size);

    // first check if first file in the current VD has a rock-ridge NM. if it has, disable joliet
    iso9660_Directory *dirPointer = reinterpret_cast<iso9660_Directory*>(&m_info.iso.szRootDir);
    ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * from_733(dirPointer->extent), 0, FILE_BEGIN );

    DWORD lpNumberOfBytesRead;
    char* pCurr_dir_cache = (char*)malloc( 16*wSectorSize );
    iso9660_Directory isodir;
    BOOL bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache, wSectorSize, &lpNumberOfBytesRead, NULL );
    memcpy( &isodir, pCurr_dir_cache, sizeof(isodir));

    int iso9660searchpointer=0;
    if ( isodir.ucRecordLength )
      iso9660searchpointer += isodir.ucRecordLength;
    else
      iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize;

    memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, std::min(sizeof(isodir), sizeof(m_info.isodir)));
    free(pCurr_dir_cache);
    if (bResult && lpNumberOfBytesRead == wSectorSize)
      bResult = IsRockRidge(isodir);
    while ( m_info.iso.byOne != 255)
    {
      if ( ( m_info.iso.byZero3[0] == 0x25 ) && ( m_info.iso.byZero3[1] == 0x2f ) && !bResult )
      {
        switch ( m_info.iso.byZero3[2] )
        {
        case 0x45 :
        case 0x40 :
        case 0x43 : m_info.HeaderPos = current;
          m_info.joliet = 1;
        }
        //                        25 2f 45  or   25 2f 40   or 25 2f 43 = jouliet, and best fitted for reading
      }
      current += 0x800;
      ::SetFilePointer( m_info.ISO_HANDLE, current, 0, FILE_BEGIN );
      ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL );
    }
    ::SetFilePointer( m_info.ISO_HANDLE, m_info.HeaderPos, 0, FILE_BEGIN );
    ::ReadFile( m_info.ISO_HANDLE, &m_info.iso, sizeof(m_info.iso), &lpNumberOfBytesRead, NULL );
    memcpy( &m_info.isodir, m_info.iso.szRootDir, sizeof(m_info.isodir));
  }

  memcpy( &m_info.isodir, &m_info.iso.szRootDir, sizeof(m_info.isodir) );
  ReadRecursiveDirFromSector( from_733(m_info.isodir.extent), "\\" );
}
示例#11
0
//******************************************************************************************************************
struct iso_dirtree *iso9660::ReadRecursiveDirFromSector( DWORD sector, const char *path )
{
  struct iso_dirtree* pDir = NULL;
  struct iso_dirtree* pFile_Pointer = NULL;
  char* pCurr_dir_cache = NULL;
  DWORD iso9660searchpointer;
  struct iso9660_Directory isodir;
  struct iso9660_Directory curr_dir;
  WORD wSectorSize = from_723(m_info.iso.logical_block_size);


  struct iso_directories *point = m_lastpath;
  if (point)
  {
    while ( point->next )
    {
      if (strcmp(path, point->path) == 0) return NULL;
      point = point->next;
    }
  }


#ifdef _DEBUG_OUTPUT
  std::string strTmp;
  strTmp = StringUtils::Format("******************   Adding dir : %s\r", path);
  OutputDebugString( strTmp.c_str() );
#endif

  pDir = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree));
  if (!pDir)
    return NULL;

  pDir->next = NULL;
  pDir->path = NULL;
  pDir->name = NULL;
  pDir->dirpointer = NULL;
  pFile_Pointer = pDir;
  m_vecDirsAndFiles.push_back(pDir);


  ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * sector, 0, FILE_BEGIN );
  DWORD lpNumberOfBytesRead = 0;

  pCurr_dir_cache = (char*)malloc( 16*wSectorSize );
  if (!pCurr_dir_cache )
    return NULL;

  BOOL bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache, wSectorSize, &lpNumberOfBytesRead, NULL );
  if (!bResult || lpNumberOfBytesRead != wSectorSize)
  {
    CLog::Log(LOGERROR, "%s: unable to read", __FUNCTION__);
    free(pCurr_dir_cache);
    return NULL;
  }
  memcpy( &isodir, pCurr_dir_cache, sizeof(isodir) );
  memcpy( &curr_dir, pCurr_dir_cache, sizeof(isodir) );

  DWORD curr_dirSize = from_733(curr_dir.size);
  if ( curr_dirSize > wSectorSize )
  {
    free( pCurr_dir_cache );
    pCurr_dir_cache = (char*)malloc( 16 * from_733(isodir.size) );
    if (!pCurr_dir_cache )
      return NULL;

    ::SetFilePointer( m_info.ISO_HANDLE, wSectorSize * sector, 0, FILE_BEGIN );
    bResult = ::ReadFile( m_info.ISO_HANDLE, pCurr_dir_cache , curr_dirSize, &lpNumberOfBytesRead, NULL );
    if (!bResult || lpNumberOfBytesRead != curr_dirSize)
    {
      CLog::Log(LOGERROR, "%s: unable to read", __FUNCTION__);
      free(pCurr_dir_cache);
      return NULL;
    }
  }
  iso9660searchpointer = 0;

  if (!m_lastpath)
  {
    m_lastpath = m_paths;
    if ( !m_lastpath )
    {
      m_paths = (struct iso_directories *)malloc(sizeof(struct iso_directories));
      if (!m_paths )
      {
        free(pCurr_dir_cache);
        return NULL;
      }

      m_paths->path = NULL;
      m_paths->dir = NULL;
      m_paths->next = NULL;
      m_lastpath = m_paths;
    }
    else
    {
      while ( m_lastpath->next )
        m_lastpath = m_lastpath->next;
    }
  }
  m_lastpath->next = ( struct iso_directories *)malloc( sizeof( struct iso_directories ) );
  if (!m_lastpath->next )
  {
    free(pCurr_dir_cache);
    return NULL;
  }

  m_lastpath = m_lastpath->next;
  m_lastpath->next = NULL;
  m_lastpath->dir = pDir;
  m_lastpath->path = (char *)malloc(strlen(path) + 1);
  if (!m_lastpath->path )
  {
    free(pCurr_dir_cache);
    return NULL;
  }

  strcpy( m_lastpath->path, path );

  while ( 1 )
  {
    if ( isodir.ucRecordLength )
      iso9660searchpointer += isodir.ucRecordLength;
    else
    {
      iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize;
    }
    if ( curr_dirSize <= iso9660searchpointer )
    {
      break;
    }
    int isize = std::min(sizeof(isodir), sizeof(m_info.isodir));
    memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, isize);
    if (!isodir.ucRecordLength)
      continue;
    if ( !(isodir.byFlags & Flag_NotExist) )
    {
      if ( (!( isodir.byFlags & Flag_Directory )) && ( isodir.Len_Fi > 1) )
      {
        std::string temp_text ;
        bool bContinue = false;

        if ( m_info.joliet )
        {
          bContinue = true;
          isodir.FileName[isodir.Len_Fi] = isodir.FileName[isodir.Len_Fi + 1] = 0; //put terminator by its length
          temp_text = GetThinText(isodir.FileName, isodir.Len_Fi );
          //     temp_text.resize(isodir.Len_Fi);
        }

        if (!m_info.joliet && isodir.FileName[0] >= 0x20 )
        {
          temp_text = ParseName(isodir);
          bContinue = true;
        }
        if (bContinue)
        {
          int semipos = temp_text.find(";", 0);
          if (semipos >= 0)
            temp_text.erase(semipos, temp_text.length() - semipos);


          pFile_Pointer->next = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree));
          if (!pFile_Pointer->next)
            break;

          m_vecDirsAndFiles.push_back(pFile_Pointer->next);
          pFile_Pointer = pFile_Pointer->next;
          pFile_Pointer->next = 0;
          pFile_Pointer->dirpointer = NULL;
          pFile_Pointer->path = (char *)malloc(strlen(path) + 1);
          if (!pFile_Pointer->path)
          {
            free(pCurr_dir_cache);
            return NULL;
          }

          strcpy( pFile_Pointer->path, path );
          pFile_Pointer->name = (char *)malloc( temp_text.length() + 1);
          if (!pFile_Pointer->name)
          {
            free(pCurr_dir_cache);
            return NULL;
          }

          strcpy( pFile_Pointer->name , temp_text.c_str());
#ifdef _DEBUG_OUTPUT
          //std::string strTmp;
          //strTmp = StringUtils::Format("adding sector : %X, File : %s     size = %u     pos = %x\r",sector,temp_text.c_str(), isodir.dwFileLengthLE, isodir.dwFileLocationLE );
          //OutputDebugString( strTmp.c_str());
#endif

          pFile_Pointer->Location = from_733(isodir.extent);
          pFile_Pointer->dirpointer = NULL;
          pFile_Pointer ->Length = from_733(isodir.size);

          IsoDateTimeToFileTime(&isodir.DateTime, &pFile_Pointer->filetime);

          pFile_Pointer->type = 1;
        }
      }
    }
  }
  iso9660searchpointer = 0;
  memcpy( &curr_dir, pCurr_dir_cache, sizeof(isodir) );
  memcpy( &isodir, pCurr_dir_cache, sizeof(isodir) );
  while ( 1 )
  {
    if ( isodir.ucRecordLength )
      iso9660searchpointer += isodir.ucRecordLength;


    else
    {
      iso9660searchpointer = (iso9660searchpointer - (iso9660searchpointer % wSectorSize)) + wSectorSize;
    }
    if ( from_733(curr_dir.size) <= iso9660searchpointer )
    {
      free( pCurr_dir_cache );
      pCurr_dir_cache = NULL;
      return pDir;
    }
    memcpy( &isodir, pCurr_dir_cache + iso9660searchpointer, std::min(sizeof(isodir), sizeof(m_info.isodir)));
    if (!isodir.ucRecordLength)
      continue;
    if ( !(isodir.byFlags & Flag_NotExist) )
    {
      if ( (( isodir.byFlags & Flag_Directory )) && ( isodir.Len_Fi > 1) )
      {
        std::string temp_text ;
        bool bContinue = false;
        if ( m_info.joliet )
        {
          bContinue = true;
          isodir.FileName[isodir.Len_Fi] = isodir.FileName[isodir.Len_Fi + 1] = 0; //put terminator by its length
          temp_text = GetThinText(isodir.FileName, isodir.Len_Fi);
          //     temp_text.resize(isodir.Len_Fi);
        }
        if (!m_info.joliet && isodir.FileName[0] >= 0x20 )
        {
          temp_text = ParseName(isodir);
          bContinue = true;
        }
        if (bContinue)
        {

          //     int semipos = temp_text.find(";",0); //the directory is not seperate by ";",but by its length
          //     if (semipos >= 0)
          //       temp_text.erase(semipos,temp_text.length()-semipos);

          pFile_Pointer->next = (struct iso_dirtree *)malloc(sizeof(struct iso_dirtree));
          if (!pFile_Pointer->next)
          {
            free(pCurr_dir_cache);
            return NULL;
          }

          m_vecDirsAndFiles.push_back(pFile_Pointer->next);
          pFile_Pointer = pFile_Pointer->next;
          pFile_Pointer->next = 0;
          pFile_Pointer->dirpointer = NULL;
          pFile_Pointer->path = (char *)malloc(strlen(path) + 1);

          if (!pFile_Pointer->path)
          {
            free(pCurr_dir_cache);
            return NULL;
          }

          strcpy( pFile_Pointer->path, path );
          pFile_Pointer->name = (char *)malloc( temp_text.length() + 1);

          if (!pFile_Pointer->name)
          {
            free(pCurr_dir_cache);
            return NULL;
          }

          strcpy( pFile_Pointer->name , temp_text.c_str());

          DWORD dwFileLocation = from_733(isodir.extent);
#ifdef _DEBUG_OUTPUT
          std::string strTmp;
          strTmp = StringUtils::Format("adding directory sector : %X, File : %s     size = %u     pos = %x\r", sector, temp_text.c_str(), from_733(isodir.size), dwFileLocation );
          OutputDebugString( strTmp.c_str());
#endif

          pFile_Pointer->Location = dwFileLocation;
          pFile_Pointer->dirpointer = NULL;
          pFile_Pointer->Length = from_733(isodir.size);

          IsoDateTimeToFileTime(&isodir.DateTime, &pFile_Pointer->filetime);

          std::string strPath = path;
          if ( strlen( path ) > 1 ) strPath += "\\";
          strPath += temp_text;

          pFile_Pointer->dirpointer = ReadRecursiveDirFromSector( dwFileLocation, strPath.c_str() );

          pFile_Pointer->type = 2;
        }
      }
    }
  }
  return NULL;
}
示例#12
0
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;
    
}