Beispiel #1
0
/**
 * Internal, but used from dvd_udf.c 
 *
 * @param device A read handle.
 * @param lb_number Logical block number to start read from.
 * @param block_count Number of logical blocks to read.
 * @param data Pointer to buffer where read data should be stored.
 *             This buffer must be large enough to hold lb_number*2048 bytes.
 *             The pointer must be aligned to the logical block size when
 *             reading from a raw/O_DIRECT device.
 * @param encrypted 0 if no decryption shall be performed,
 *                  1 if decryption shall be performed
 * @param return Returns number of blocks read on success, negative on error
 */
int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
                      size_t block_count, unsigned char *data, 
                      int encrypted )
{
  int ret;

  if( !device->dev ) {
    if(device->verbose >= 1) {
      fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
    }
    return 0;
  }

  ret = dvdinput_seek( device->dev, (int) lb_number );
  if( ret != (int) lb_number ) {
    if(device->verbose >= 1) {
      fprintf( stderr,
               "libdvdread: UDFReadBlocksRaw: Can't seek to block %u\n",
               lb_number );
    }
    return 0;
  }

  return dvdinput_read( device->dev, (char *) data, 
                        (int) block_count, encrypted );
}
Beispiel #2
0
/* Internal, but used from dvd_udf.c */
int InternalUDFReadBlocksRaw( const dvd_reader_t *device, uint32_t lb_number,
                      size_t block_count, unsigned char *data,
                      int encrypted )
{
  int ret;

  if( !device->dev ) {
    fprintf( stderr, "libdvdread: Fatal error in block read.\n" );
    return 0;
  }

  ret = dvdinput_seek( device->dev, (int) lb_number, encrypted & DVDCSS_SEEK_KEY );
  if( ret != (int) lb_number ) {
    fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number );
    return 0;
  }

  ret = dvdinput_read( device->dev, (char *) data,
                       (int) block_count, encrypted & DVDINPUT_READ_DECRYPT );
  return ret;
}
Beispiel #3
0
/* This is using possibly several inputs and starting from an offset of '0'.
 *
 * 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 DVDReadBlocksPath( const dvd_file_t *dvd_file, unsigned int offset,
                              size_t block_count, unsigned char *data,
                              int encrypted )
{
  int i;
  int ret, ret2, off;

  ret = 0;
  ret2 = 0;
  for( i = 0; i < TITLES_MAX; ++i ) {
    if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */

    if( offset < dvd_file->title_sizes[ i ] ) {
      if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) {
        off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset, DVDINPUT_NOFLAGS );
        if( off < 0 || off != (int)offset ) {
          fprintf( stderr, "libdvdread: Can't seek to block %u\n",
                   offset );
          return off < 0 ? off : 0;
        }
        ret = dvdinput_read( dvd_file->title_devs[ i ], data,
                             (int)block_count, encrypted );
        break;
      } else {
        size_t part1_size = dvd_file->title_sizes[ i ] - offset;
        /* FIXME: Really needs to be a while loop.
         * (This is only true if you try and read >1GB at a time) */

        /* Read part 1 */
        off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset, DVDINPUT_NOFLAGS );
        if( off < 0 || off != (int)offset ) {
          fprintf( stderr, "libdvdread: Can't seek to block %u\n",
                   offset );
          return off < 0 ? off : 0;
        }
        ret = dvdinput_read( dvd_file->title_devs[ i ], data,
                             (int)part1_size, encrypted );
        if( ret < 0 ) return ret;
        /* FIXME: This is wrong if i is the last file in the set.
         * also error from this read will not show in ret. */

        /* Does the next part exist? If not then return now. */
        if( i + 1 >= TITLES_MAX || !dvd_file->title_devs[ i + 1 ] )
          return ret;

        /* Read part 2 */
        off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0, DVDINPUT_NOFLAGS );
        if( off < 0 || off != 0 ) {
          fprintf( stderr, "libdvdread: Can't seek to block %d\n",
                   0 );
          return off < 0 ? off : 0;
        }
        ret2 = dvdinput_read( dvd_file->title_devs[ i + 1 ],
                              data + ( part1_size
                                       * (int64_t)DVD_VIDEO_LB_LEN ),
                              (int)(block_count - part1_size),
                              encrypted );
        if( ret2 < 0 ) return ret2;
        break;
      }
    } else {
      offset -= dvd_file->title_sizes[ i ];
    }
  }

  return ret + ret2;
}