File indexing completed on 2024-06-16 07:42:26

0001 /*
0002     SPDX-FileCopyrightText: 1998-2007 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3biso9660backend.h"
0007 #include "k3blibdvdcss.h"
0008 
0009 #include <unistd.h>
0010 #include <sys/types.h>
0011 #include <sys/stat.h>
0012 #include <fcntl.h>
0013 
0014 #include <QFile>
0015 
0016 #include "k3bdevice.h"
0017 
0018 
0019 //
0020 // K3b::Iso9660DeviceBackend -----------------------------------
0021 //
0022 
0023 K3b::Iso9660DeviceBackend::Iso9660DeviceBackend( K3b::Device::Device* dev )
0024     : m_device( dev ),
0025       m_isOpen(false)
0026 {
0027 }
0028 
0029 
0030 K3b::Iso9660DeviceBackend::~Iso9660DeviceBackend()
0031 {
0032     close();
0033 }
0034 
0035 
0036 bool K3b::Iso9660DeviceBackend::open()
0037 {
0038     if( m_isOpen )
0039         return true;
0040     else if( m_device->open() ) {
0041         // set optimal reading speed
0042         m_device->setSpeed( 0xffff, 0xffff );
0043         m_isOpen = true;
0044         return true;
0045     }
0046     else
0047         return false;
0048 }
0049 
0050 
0051 void K3b::Iso9660DeviceBackend::close()
0052 {
0053     if( m_isOpen ) {
0054         m_isOpen = false;
0055         m_device->close();
0056     }
0057 }
0058 
0059 
0060 int K3b::Iso9660DeviceBackend::read( unsigned int sector, char* data, int len )
0061 {
0062     if( isOpen() ) {
0063         //
0064         // split the number of sectors to be read
0065         // FIXME: use a "real" value, not some arbitrary one
0066         //
0067         static const int maxReadSectors = 20;
0068         int sectorsRead = 0;
0069         int retries = 10;  // TODO: no fixed value
0070         while( retries ) {
0071             int read = qMin(len-sectorsRead, maxReadSectors);
0072             if( !m_device->read10( (unsigned char*)(data+sectorsRead*2048),
0073                                    read*2048,
0074                                    sector+sectorsRead,
0075                                    read ) ) {
0076                 retries--;
0077             }
0078             else {
0079                 sectorsRead += read;
0080                 retries = 10; // new retires for every read part
0081                 if( sectorsRead == len )
0082                     return len;
0083             }
0084         }
0085     }
0086 
0087     return -1;
0088 }
0089 
0090 
0091 //
0092 // K3b::Iso9660FileBackend -----------------------------------
0093 //
0094 
0095 K3b::Iso9660FileBackend::Iso9660FileBackend( const QString& filename )
0096     : m_filename( filename ),
0097       m_fd( -1 ),
0098       m_closeFd( true )
0099 {
0100 }
0101 
0102 
0103 K3b::Iso9660FileBackend::Iso9660FileBackend( int fd )
0104     : m_fd( fd ),
0105       m_closeFd( false )
0106 {
0107 }
0108 
0109 
0110 K3b::Iso9660FileBackend::~Iso9660FileBackend()
0111 {
0112     close();
0113 }
0114 
0115 
0116 #ifndef O_LARGEFILE
0117 #define O_LARGEFILE 0
0118 #endif
0119 
0120 bool K3b::Iso9660FileBackend::open()
0121 {
0122     if( m_fd > 0 )
0123         return true;
0124     else {
0125         m_fd = ::open( QFile::encodeName( m_filename ), O_RDONLY|O_LARGEFILE|O_CLOEXEC );
0126         return ( m_fd > 0 );
0127     }
0128 }
0129 
0130 
0131 void K3b::Iso9660FileBackend::close()
0132 {
0133     if( m_closeFd && m_fd > 0 ) {
0134         ::close( m_fd );
0135         m_fd = -1;
0136     }
0137 }
0138 
0139 
0140 
0141 bool K3b::Iso9660FileBackend::isOpen() const
0142 {
0143     return ( m_fd > 0 );
0144 }
0145 
0146 
0147 int K3b::Iso9660FileBackend::read( unsigned int sector, char* data, int len )
0148 {
0149     int read = 0;
0150     if( ::lseek( m_fd, static_cast<unsigned long long>(sector)*2048, SEEK_SET ) != -1 )
0151         if( (read = ::read( m_fd, data, len*2048 )) != -1 )
0152             return read / 2048;
0153 
0154     return -1;
0155 }
0156 
0157 
0158 
0159 //
0160 // K3b::Iso9660LibDvdCssBackend -----------------------------------
0161 //
0162 
0163 K3b::Iso9660LibDvdCssBackend::Iso9660LibDvdCssBackend( K3b::Device::Device* dev )
0164     : m_device( dev ),
0165       m_libDvdCss( 0 )
0166 {
0167 }
0168 
0169 
0170 K3b::Iso9660LibDvdCssBackend::~Iso9660LibDvdCssBackend()
0171 {
0172     close();
0173 }
0174 
0175 
0176 bool K3b::Iso9660LibDvdCssBackend::open()
0177 {
0178     if( !m_libDvdCss ) {
0179         // open the libdvdcss stuff
0180         m_libDvdCss = K3b::LibDvdCss::create();
0181 
0182         if( m_libDvdCss ) {
0183 
0184             if( !m_libDvdCss->open( m_device ) ||
0185                 !m_libDvdCss->crackAllKeys() ) {
0186                 qDebug() << "(K3b::Iso9660LibDvdCssBackend) Failed to retrieve all CSS keys.";
0187                 close();
0188             }
0189         }
0190         else
0191             qDebug() << "(K3b::Iso9660LibDvdCssBackend) failed to open libdvdcss.";
0192     }
0193 
0194     return ( m_libDvdCss != 0 );
0195 }
0196 
0197 
0198 void K3b::Iso9660LibDvdCssBackend::close()
0199 {
0200     delete m_libDvdCss;
0201     m_libDvdCss = 0;
0202 }
0203 
0204 
0205 
0206 bool K3b::Iso9660LibDvdCssBackend::isOpen() const
0207 {
0208     return ( m_libDvdCss != 0 );
0209 }
0210 
0211 
0212 int K3b::Iso9660LibDvdCssBackend::read( unsigned int sector, char* data, int len )
0213 {
0214     int read = -1;
0215 
0216     if( isOpen() ) {
0217         int retries = 10;  // TODO: no fixed value
0218         while( retries && !m_libDvdCss->readWrapped( reinterpret_cast<void*>(data),
0219                                                      sector,
0220                                                      len ) )
0221             retries--;
0222 
0223         if( retries > 0 )
0224             read = len;
0225     }
0226 
0227     return read;
0228 }
0229