Exemplo n.º 1
0
int DVDISOVolumeInfo( dvd_reader_t *dvd,
                      char *volid, unsigned int volid_size,
                      unsigned char *volsetid, unsigned int volsetid_size )
{
  unsigned char *buffer, *buffer_base;
  int ret;

  /* Check arguments. */
  if( dvd == NULL )
    return 0;

  if( dvd->dev == NULL ) {
    /* No block access, so no ISO... */
    return -1;
  }

  buffer_base = malloc( DVD_VIDEO_LB_LEN + 2048 );

  if( buffer_base == NULL ) {
    fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
             "allocate memory for file read!\n" );
    return -1;
  }

  buffer = (unsigned char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048);

  ret = InternalUDFReadBlocksRaw( dvd, 16, 1, buffer, 0 );
  if( ret != 1 ) {
    fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to "
             "read ISO9660 Primary Volume Descriptor!\n" );
    free( buffer_base );
    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_base );
  return 0;
}
Exemplo n.º 2
0
/**
 * Open an unencrypted file on a DVD image file.
 */
static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, const char *filename,
                                   int do_cache )
{
  uint32_t start, len;
  dvd_file_t *dvd_file;

  start = UDFFindFile( dvd, filename, &len );
  if( !start ) {
    fprintf( stderr, "libdvdread:DVDOpenFileUDF:UDFFindFile %s failed\n", filename );
    return NULL;
  }

  dvd_file = calloc( 1, sizeof( dvd_file_t ) );
  if( !dvd_file ) {
    fprintf( stderr, "libdvdread:DVDOpenFileUDF:malloc failed\n" );
    return NULL;
  }
  dvd_file->dvd = dvd;
  dvd_file->lb_start = start;
  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;

  /* Read the whole file in cache (unencrypted) if asked and if it doesn't
   * exceed 128KB */
  if( do_cache && len < 64 * DVD_VIDEO_LB_LEN ) {
    int ret;

    dvd_file->cache = malloc( len );
    if( !dvd_file->cache )
        return dvd_file;

    ret = InternalUDFReadBlocksRaw( dvd, dvd_file->lb_start,
                                    dvd_file->filesize, dvd_file->cache,
                                    DVDINPUT_NOFLAGS );
    if( ret != dvd_file->filesize ) {
        free( dvd_file->cache );
        dvd_file->cache = NULL;
    }
  }

  return dvd_file;
}
Exemplo n.º 3
0
/* It's required to either fail or deliver all the blocks asked for. */
static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
                         size_t block_count, unsigned char *data,
                         int encrypted )
{
  size_t count = block_count;

  while(count > 0) {
    int ret;

    ret = InternalUDFReadBlocksRaw(device, lb_number, count, data + DVD_VIDEO_LB_LEN * (block_count - count), encrypted);

    if(ret <= 0) {
      /* One of the reads failed or nothing more to read, too bad.
       * We won't even bother returning the reads that went ok. */
      return ret;
    }

    count -= (size_t)ret;
    lb_number += (uint32_t)ret;
  }

  return block_count;
}
Exemplo n.º 4
0
/* This is using a single input and starting from 'dvd_file->lb_start' offset.
 *
 * Reads 'block_count' blocks from 'dvd_file' at block offset 'offset'
 * into the buffer located at 'data' and if 'encrypted' is set
 * descramble the data if it's encrypted.  Returning either an
 * negative error or the number of blocks read. */
static int DVDReadBlocksUDF( const dvd_file_t *dvd_file, uint32_t offset,
                             size_t block_count, unsigned char *data,
                             int encrypted )
{
  /* If the cache is present and we don't need to decrypt, use the cache to
   * feed the data */
  if( dvd_file->cache && (encrypted & DVDINPUT_READ_DECRYPT) == 0 ) {
    /* Check if we don't exceed the cache (or file) size */
    if( block_count + offset > (size_t) dvd_file->filesize )
      return 0;

    /* Copy the cache at a specified offset into data. offset and block_count
     * must be converted into bytes */
    memcpy( data, dvd_file->cache + (off_t)offset * (off_t)DVD_VIDEO_LB_LEN,
            (off_t)block_count * (off_t)DVD_VIDEO_LB_LEN );

    /* return the amount of blocks copied */
    return block_count;
  } else {
    /* use dvdinput access */
    return InternalUDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset,
                             block_count, data, encrypted );
  }
}
Exemplo n.º 5
0
//virtual
int DVDStream::safe_read(void *data, uint size)
{
    uint32_t lb = size / DVD_VIDEO_LB_LEN;
    if (lb < 1)
    {
        LOG(VB_GENERAL, LOG_ERR, "DVDStream::safe_read too small");
        return -1;
    }

    if (!m_reader)
        return -1;

    int ret = 0;

    // Are any blocks in the range encrypted?
    list_t::const_iterator it;
    it = std::lower_bound(m_list.begin(), m_list.end(), BlockRange(m_pos, lb, -1));
    uint32_t b = it == m_list.end() ? lb : m_pos < it->Start() ? it->Start() - m_pos : 0;
    if (b)
    {
        // Read the beginning unencrypted blocks
        ret = InternalUDFReadBlocksRaw(m_reader, m_pos, b, (unsigned char*)data, DVDINPUT_NOFLAGS);
        if (ret == -1)
        {
            LOG(VB_GENERAL, LOG_ERR, "DVDStream::safe_read DVDReadBlocks error");
            return -1;
        }

        m_pos += ret;
        lb -= ret;
        if (it == m_list.end())
            return ret * DVD_VIDEO_LB_LEN;

        data = (unsigned char*)data + ret * DVD_VIDEO_LB_LEN;
    }

    b = it->End() - m_pos;
    if (b > lb)
        b = lb;

    // Request new key if change in title
    int flags = DVDINPUT_READ_DECRYPT;
    if (it->Title() != m_title)
    {
        m_title = it->Title();
        flags |= DVDCSS_SEEK_KEY;
    }

    // Read the encrypted blocks
    int ret2 = InternalUDFReadBlocksRaw(m_reader, m_pos + m_start, b, (unsigned char*)data, flags);
    if (ret2 == -1)
    {
        LOG(VB_GENERAL, LOG_ERR, "DVDStream::safe_read DVDReadBlocks error");
        m_title = -1;
        return -1;
    }

    m_pos += ret2;
    ret += ret2;
    lb -= ret2;
    data = (unsigned char*)data + ret2 * DVD_VIDEO_LB_LEN;

    if (lb > 0 && m_start == 0)
    {
        // Read the last unencrypted blocks
        ret2 = InternalUDFReadBlocksRaw(m_reader, m_pos, lb, (unsigned char*)data, DVDINPUT_NOFLAGS);
        if (ret2 == -1)
        {
            LOG(VB_GENERAL, LOG_ERR, "DVDStream::safe_read DVDReadBlocks error");
            return -1;
        }

        m_pos += ret2;
        ret += ret2;;
    }

    return ret * DVD_VIDEO_LB_LEN;
}