Exemple #1
0
/**
 * Allocates aligned memory (for use with reads from raw/O_DIRECT devices).
 * This memory must be freed with dvdalign_free()
 * The size of the memory that is allocate is num_lbs*2048 bytes.
 * The memory will be suitably aligned for use with
 * block reads from raw/O_DIRECT device.
 * @param num_lbs Number of logical blocks (2048 bytes) to allocate.
 * @return Returns pointer to allocated memory, or NULL on failure
 * This isn't supposed to be fast/efficient, if that is needed
 * this function should be rewritten to use posix_memalign or similar.
 * It's just needed for aligning memory for small block reads from
 * raw/O_DIRECT devices. 
 * We assume that 2048 is enough alignment for all systems at the moment.
 * Not thread safe. Only use this from one thread.
 * Depends on sizeof(unsigned long) being at least as large as sizeof(void *)
 */
static void *dvdalign_lbmalloc(dvd_reader_t *device, uint32_t num_lbs)
{
  void *m;
  int n;
  dvdalign_t *a;
  
  m = malloc((num_lbs+1)*DVD_VIDEO_LB_LEN);
  if(m == NULL) {
    return m;
  }
  a = (dvdalign_t *)GetAlignHandle(device);
  if(a == NULL) {
    a = malloc(sizeof(dvdalign_t));
    if(a == NULL) {
      return a;
    }
    a->ptrs = NULL;
    a->ptrs_in_use = 0;
    a->ptrs_max = 0;
    SetAlignHandle(device, (void *)a);
  }
  
  if(a->ptrs_in_use >= a->ptrs_max) {
    a->ptrs = realloc(a->ptrs, (a->ptrs_max+10)*sizeof(dvdalign_ptrs_t));
    if(a->ptrs == NULL) {
      free(m);
      return NULL;
    }
    a->ptrs_max+=10;
    for(n = a->ptrs_in_use; n < a->ptrs_max; n++) {
      a->ptrs[n].start = NULL;
      a->ptrs[n].aligned = NULL;
    }
    n = a->ptrs_in_use;
  } else {
    for(n = 0; n < a->ptrs_max; n++) {
      if(a->ptrs[n].start == NULL) {
        break;
      }
    }
  }

  a->ptrs[n].start = m;
  a->ptrs[n].aligned = DVD_ALIGN(m);

  a->ptrs_in_use++;

  /* If this function starts to be used too much print a warning.
     Either there is a memory leak somewhere or we need to rewrite this to
     a more efficient version.
  */
  return  a->ptrs[n].aligned;
}
Exemple #2
0
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
{
  unsigned char *secbuf_start;
  unsigned char *secbuf; //must be aligned to 2048-bytes for raw/O_DIRECT
  unsigned int numsec, seek_sector, seek_byte;
  int ret;
    
  /* Check arguments. */
  if( dvd_file == NULL || data == NULL ) {
    errno = EINVAL;
    return -1;
  }
  seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN;
  seek_byte   = dvd_file->seek_pos % DVD_VIDEO_LB_LEN;

  numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) +
    ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 );

  /* must align to 2048 bytes if we are reading from raw/O_DIRECT */
  secbuf_start = (unsigned char *) malloc( (numsec+1) * DVD_VIDEO_LB_LEN );
  if( !secbuf_start ) {
    /* errno will be set to ENOMEM by malloc */
    return -1;
  }

  secbuf = DVD_ALIGN(secbuf_start);

  if( dvd_file->dvd->isImageFile ) {
    ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector, 
                            (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
  } else {
    ret = DVDReadBlocksPath( dvd_file, seek_sector, 
                             (size_t) numsec, secbuf, DVDINPUT_NOFLAGS );
  }

  if( ret != (int) numsec ) {
    free( secbuf_start );
    return ret < 0 ? ret : 0;
  }

  memcpy( data, &(secbuf[ seek_byte ]), byte_size );
  free( secbuf_start );

  dvd_file->seek_pos += byte_size;
  return byte_size;
}
Exemple #3
0
int DVDISOVolumeInfo( dvd_reader_t *dvd,
                      char *volid, unsigned int volid_size,
                      unsigned char *volsetid, unsigned int volsetid_size )
{
  unsigned char *buffer; /* must be aligned to 2048 for raw/O_DIRECT */
  unsigned char *buffer_start; 
  int ret;

  /* Check arguments. */
  if( dvd == NULL ) {
    errno = EINVAL;
    return -1;
  }
  
  if( dvd->dev == NULL ) {
    /* No block access, so no ISO... */
    errno = EINVAL;
    return -1;
  }
  
  buffer_start = malloc( 2 * DVD_VIDEO_LB_LEN );
  if( buffer_start == NULL ) {
    return -1;
  }

  buffer = DVD_ALIGN(buffer_start);
  
  ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
  if( ret != 1 ) {
    if(dvd->verbose >= 1) {
      fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
               "read ISO9660 Primary Volume Descriptor!\n" );
    }
    free(buffer_start);
    return -1;
  }
  
  if( (volid != NULL) && (volid_size > 0) ) {
    unsigned int n;
    for(n = 0; n < 32; n++) {
      if(buffer[40+n] == 0x20) {
        break;
      }
    }
    
    if(volid_size > n+1) {
      volid_size = n+1;
    }

    memcpy(volid, &buffer[40], volid_size-1);
    volid[volid_size-1] = '\0';
  }
  
  if( (volsetid != NULL) && (volsetid_size > 0) ) {
    if(volsetid_size > 128) {
      volsetid_size = 128;
    }
    memcpy(volsetid, &buffer[190], volsetid_size);
  }
  free(buffer_start);

  return 0;
}