File indexing completed on 2024-04-28 04:49:52
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