static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu )
{
  char filename[ MAX_UDF_FILE_NAME_LEN ];
  uint32_t start, len;
  dvd_file_t *dvd_file;

  if( title == 0 ) {
    sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
  } else {
    sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );
  }
  if (dvd->isImageFile == 1)
	  start = UDFFindFile( dvd, filename, &len );
  else if (dvd->isImageFile == 2)
	  start = ISOFindFile( dvd, filename, &len );
  if( start == 0 ) return NULL;

  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
  if( !dvd_file ) return NULL;
  dvd_file->dvd = dvd;
  /*Hack*/ dvd_file->css_title = title << 1 | menu;
  dvd_file->lb_start = start;
  dvd_file->seek_pos = 0;
  memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
  memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;

  /* Calculate the complete file size for every file in the VOBS */
  if( !menu ) {
    int cur;

    for( cur = 2; cur < 10; cur++ ) {
      sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
	  if (dvd->isImageFile == 1)
	  {
		  if( !UDFFindFile( dvd, filename, &len ) )
			  break;
	  } else if (dvd->isImageFile == 2) {
		  if( !UDFFindFile( dvd, filename, &len ) )
			  break;
	  }
      dvd_file->filesize += len / DVD_VIDEO_LB_LEN;
    }
  }

  if( dvd->css_state == 1 /* Need key init */ ) {
    initAllCSSKeys( dvd );
    dvd->css_state = 2;
  }
  /*
  if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) {
      fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n",
               filename );
  }
  */

  return dvd_file;
}
Exemple #2
0
/**
 * Open an unencrypted file on a DVD image file.
 */
static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
{
  uint32_t start, len;
  dvd_file_t *dvd_file;

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

  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
  if( !dvd_file ) {
    fprintf( stderr, "libdvdnav:DVDOpenFileUDF:malloc failed\n" );
    return NULL;
  }
  dvd_file->dvd = dvd;
  dvd_file->lb_start = start;
  dvd_file->seek_pos = 0;
  memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
  memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;

  return dvd_file;
}
Exemple #3
0
/**
 * Open a DVD image or block device file.
 * Checks if the root directory in the udf image file can be found.
 * If not it assumes this isn't a valid udf image and returns NULL
 */
static dvd_reader_t *DVDOpenImageFile( const char *location, int have_css )
{
  dvd_reader_t *dvd;
  dvd_input_t dev;
  int verbose;

  verbose = get_verbose();

  dev = dvdinput_open( location );
  if( !dev ) {
    if(verbose >= 1) {
      fprintf( stderr, "libdvdread: Can't open '%s' for reading: %s\n",
               location, strerror(errno));
    }
    return NULL;
  }

  dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) );
  if( !dvd ) {
    int tmp_errno = errno;
    dvdinput_close(dev);
    errno = tmp_errno;
    return NULL;
  }
  dvd->verbose = verbose;
  dvd->isImageFile = 1;
  dvd->dev = dev;
  dvd->path_root = NULL;
    
  dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL;
  dvd->udfcache = NULL;

  dvd->align = NULL;

  if( have_css ) {
    /* Only if DVDCSS_METHOD = title, a bit if it's disc or if
     * DVDCSS_METHOD = key but region missmatch. Unfortunaly we
     * don't have that information. */
    
    dvd->css_state = 1; /* Need key init. */
  }
  dvd->css_title = 0;
  
  /* sanity check, is it a valid UDF image, can we find the root dir */
  if(!UDFFindFile(dvd, "/", NULL)) {
    dvdinput_close(dvd->dev);
    if(dvd->udfcache) {
      FreeUDFCache(dvd, dvd->udfcache);
    }
    if(dvd->align) {
      if(dvd->verbose >= 0) {
        fprintf(stderr, "libdvdread: DVDOpenImageFile(): Memory leak in align functions 1\n");
      }
    }
    free(dvd);
    return NULL;
  }
  return dvd;
}
Exemple #4
0
static int DVDFileStatVOBUDF( dvd_reader_t *dvd, int title,
                              int menu, dvd_stat_t *statbuf )
{
  char filename[ MAX_UDF_FILE_NAME_LEN ];
  uint32_t size;
  off_t tot_size;
  off_t parts_size[ 9 ];
  int nr_parts = 0;
  int n;

  if( title == 0 )
    strcpy( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
  else
    sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 );

  if( !UDFFindFile( dvd, filename, &size ) )
    return -1;

  tot_size = size;
  nr_parts = 1;
  parts_size[ 0 ] = size;

  if( !menu ) {
    int cur;

    for( cur = 2; cur < 10; cur++ ) {
      sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur );
      if( !UDFFindFile( dvd, filename, &size ) )
        break;

      parts_size[ nr_parts ] = size;
      tot_size += size;
      nr_parts++;
    }
  }

  statbuf->size = tot_size;
  statbuf->nr_parts = nr_parts;
  for( n = 0; n < nr_parts; n++ )
    statbuf->parts_size[ n ] = parts_size[ n ];

  return 0;
}
Exemple #5
0
/**
 * Open an unencrypted file on a DVD image file.
 */
static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename )
{
  uint32_t start, len;
  dvd_file_t *dvd_file;

  start = UDFFindFile( dvd, filename, &len );
  if( !start ) return 0;

  dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) );
  if( !dvd_file ) return 0;
  dvd_file->dvd = dvd;
  dvd_file->lb_start = start;
  dvd_file->seek_pos = 0;
  memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) );
  memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) );
  dvd_file->filesize = len / DVD_VIDEO_LB_LEN;

  return dvd_file;
}
Exemple #6
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;
}
Exemple #7
0
/* Loop over all titles and call dvdcss_title to crack the keys. */
static int initAllCSSKeys( dvd_reader_t *dvd )
{
  struct timeval all_s, all_e;
  struct timeval t_s, t_e;
  char filename[ MAX_UDF_FILE_NAME_LEN ];
  uint32_t start, len;
  int title;

  const char *nokeys_str = getenv("DVDREAD_NOKEYS");
  if(nokeys_str != NULL)
    return 0;

  fprintf( stderr, "\n" );
  fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" );
  fprintf( stderr, "libdvdread: This can take a _long_ time, "
           "please be patient\n\n" );
  gettimeofday(&all_s, NULL);

  for( title = 0; title < 100; title++ ) {
    gettimeofday( &t_s, NULL );
    if( title == 0 ) {
      sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" );
    } else {
      sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 );
    }
    start = UDFFindFile( dvd, filename, &len );
    if( start != 0 && len != 0 ) {
      /* Perform CSS key cracking for this title. */
      fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
               filename, start );
      if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
        fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start);
      }
      gettimeofday( &t_e, NULL );
      fprintf( stderr, "libdvdread: Elapsed time %ld\n",
               (long int) t_e.tv_sec - t_s.tv_sec );
    }

    if( title == 0 ) continue;

    gettimeofday( &t_s, NULL );
    sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 );
    start = UDFFindFile( dvd, filename, &len );
    if( start == 0 || len == 0 ) break;

    /* Perform CSS key cracking for this title. */
    fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n",
             filename, start );
    if( dvdinput_title( dvd->dev, (int)start ) < 0 ) {
      fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start);
    }
    gettimeofday( &t_e, NULL );
    fprintf( stderr, "libdvdread: Elapsed time %ld\n",
             (long int) t_e.tv_sec - t_s.tv_sec );
  }
  title--;

  fprintf( stderr, "libdvdread: Found %d VTS's\n", title );
  gettimeofday(&all_e, NULL);
  fprintf( stderr, "libdvdread: Elapsed time %ld\n",
           (long int) all_e.tv_sec - all_s.tv_sec );

  return 0;
}
Exemple #8
0
int DVDFileStat( dvd_reader_t *dvd, int titlenum,
                 dvd_read_domain_t domain, dvd_stat_t *statbuf )
{
  char filename[ MAX_UDF_FILE_NAME_LEN ];
  struct stat fileinfo;
  uint32_t size;

  /* Check arguments. */
  if( dvd == NULL || titlenum < 0 ) {
    errno = EINVAL;
    return -1;
  }

  switch( domain ) {
  case DVD_READ_INFO_FILE:
    if( titlenum == 0 )
      strcpy( filename, "/VIDEO_TS/VIDEO_TS.IFO" );
    else
      sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum );

    break;
  case DVD_READ_INFO_BACKUP_FILE:
    if( titlenum == 0 )
      strcpy( filename, "/VIDEO_TS/VIDEO_TS.BUP" );
    else
      sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum );

    break;
  case DVD_READ_MENU_VOBS:
    if( dvd->isImageFile )
      return DVDFileStatVOBUDF( dvd, titlenum, 1, statbuf );
    else
      return DVDFileStatVOBPath( dvd, titlenum, 1, statbuf );

    break;
  case DVD_READ_TITLE_VOBS:
    if( titlenum == 0 )
      return -1;

    if( dvd->isImageFile )
      return DVDFileStatVOBUDF( dvd, titlenum, 0, statbuf );
    else
      return DVDFileStatVOBPath( dvd, titlenum, 0, statbuf );

    break;
  default:
    fprintf( stderr, "libdvdread: Invalid domain for file stat.\n" );
    errno = EINVAL;
    return -1;
  }

  if( dvd->isImageFile ) {
    if( UDFFindFile( dvd, filename, &size ) ) {
      statbuf->size = size;
      statbuf->nr_parts = 1;
      statbuf->parts_size[ 0 ] = size;
      return 0;
    }
  } else {
    char full_path[ PATH_MAX + 1 ];

    if( findDVDFile( dvd, filename, full_path ) ) {
      if( mythfile_stat( full_path, &fileinfo ) < 0 )
        fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename );
      else {
        statbuf->size = fileinfo.st_size;
        statbuf->nr_parts = 1;
        statbuf->parts_size[ 0 ] = statbuf->size;
        return 0;
      }
    }
  }
  return -1;
}
Exemple #9
0
bool DVDStream::OpenFile(const QString &filename, uint /*retry_ms*/)
{
    rwlock.lockForWrite();

    const QString root = filename.section("/VIDEO_TS/", 0, 0);
    const QString path = filename.section(root, 1);

    if (m_reader)
        DVDClose(m_reader);

    m_reader = DVDOpen(qPrintable(root));
    if (!m_reader)
    {
        LOG(VB_GENERAL, LOG_ERR, QString("DVDStream DVDOpen(%1) failed").arg(filename));
        rwlock.unlock();
        return false;
    }

    if (!path.isEmpty())
    {
        // Locate the start block of the requested title
        uint32_t len;
        m_start = UDFFindFile(m_reader, const_cast<char*>(qPrintable(path)), &len);
        if (m_start == 0)
        {
            LOG(VB_GENERAL, LOG_ERR, QString("DVDStream(%1) UDFFindFile(%2) failed").
                arg(root).arg(path));
            DVDClose(m_reader);
            m_reader = 0;
            rwlock.unlock();
            return false;
        }
        else
        {
            m_list.append(BlockRange(0, Len2Blocks(len), 0));
        }
    }
    else
    {
        // Create a list of the possibly encrypted files
        uint32_t len, start;

        // Root menu
        char name[64] = "VIDEO_TS/VIDEO_TS.VOB";
        start = UDFFindFile(m_reader, name, &len);
        if( start != 0 && len != 0 )
            m_list.append(BlockRange(start, Len2Blocks(len), 0));

        const int kTitles = 100;
        for ( int title = 1; title < kTitles; ++title)
        {
            // Menu
            snprintf(name, sizeof name, "/VIDEO_TS/VTS_%02d_0.VOB", title);
            start = UDFFindFile(m_reader, name, &len);
            if( start != 0 && len != 0 )
                m_list.append(BlockRange(start, Len2Blocks(len), title));

            for ( int part = 1; part < 10; ++part)
            {
                // A/V track
                snprintf(name, sizeof name, "/VIDEO_TS/VTS_%02d_%d.VOB", title, part);
                start = UDFFindFile(m_reader, name, &len);
                if( start != 0 && len != 0 )
                    m_list.append(BlockRange(start, Len2Blocks(len), title + part * kTitles));
            }
        }

        qSort( m_list);

        // Open the root menu so that CSS keys are generated now
        dvd_file_t *file = DVDOpenFile(m_reader, 0, DVD_READ_MENU_VOBS);
        if (file)
            DVDCloseFile(file);
        else
            LOG(VB_GENERAL, LOG_ERR, "DVDStream DVDOpenFile(VOBS_1) failed");
    }

    rwlock.unlock();
    return true;
}