File indexing completed on 2025-03-16 04:29:56
0001 /* 0002 SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #ifndef K3BDEVICE_H 0007 #define K3BDEVICE_H 0008 0009 #include "k3bdevicetypes.h" 0010 #include "k3bdiskinfo.h" 0011 #include "k3bcdtext.h" 0012 #include "k3bmsf.h" 0013 #include "k3bdevice_export.h" 0014 0015 #include <qglobal.h> 0016 #include <QVarLengthArray> 0017 0018 #if defined(__FreeBSD_kernel__) 0019 #undef Q_OS_LINUX 0020 #define Q_OS_FREEBSD 1 0021 #endif 0022 0023 #ifdef Q_OS_FREEBSD 0024 struct cam_device; 0025 #endif 0026 0027 #ifdef Q_OS_WIN32 0028 #include <windows.h> 0029 #endif 0030 0031 namespace Solid { 0032 class Device; 0033 class StorageAccess; 0034 } 0035 0036 namespace K3b { 0037 namespace Device 0038 { 0039 class Toc; 0040 0041 typedef QVarLengthArray< unsigned char > UByteArray; 0042 0043 /** 0044 * \brief The main class representing a device. 0045 * 0046 * Devices are constructed by the DeviceManager. 0047 * 0048 * All methods except for open and close in Device are thread-safe which basically means that 0049 * no two commands are sent to the device at the same time. 0050 */ 0051 // FIXME: all methods are const which makes no sense at all! 0052 class LIBK3BDEVICE_EXPORT Device 0053 { 0054 public: 0055 #if defined(Q_OS_FREEBSD) 0056 typedef struct cam_device* Handle; 0057 #elif defined(Q_OS_WIN32) 0058 // file handle 0059 typedef HANDLE Handle; 0060 #else 0061 // file descriptor 0062 typedef int Handle; 0063 #endif 0064 0065 ~Device(); 0066 0067 Solid::Device solidDevice() const; 0068 0069 /** 0070 * Gives interface for dics volume. 0071 * Keep in mind that it can return empty pointer when no disc is inserted. 0072 * 0073 * @return Interface for disc volume. 0074 */ 0075 Solid::StorageAccess* solidStorage() const; 0076 0077 /** 0078 * \deprecated use readCapabilities() and writeCapabilities() 0079 * The device type. 0080 * 0081 * @return A bitwise or of K3b::Device::DeviceType. 0082 */ 0083 DeviceTypes type() const; 0084 0085 /** 0086 * The mediatypes this device is able to read. 0087 * 0088 * \return A bitwise or of K3b::Device::MediaType 0089 */ 0090 MediaTypes readCapabilities() const; 0091 0092 /** 0093 * The media types this device is able to write. 0094 * 0095 * \return A bitwise or of K3b::Device::MediaType 0096 */ 0097 MediaTypes writeCapabilities() const; 0098 0099 /** 0100 * \return Vendor string as reported by the device's firmware. 0101 */ 0102 QString vendor() const; 0103 0104 /** 0105 * \return Description string as reported by the device's firmware. 0106 */ 0107 QString description() const; 0108 0109 /** 0110 * \return Version string as reported by the device's firmware. 0111 */ 0112 QString version() const; 0113 0114 /** 0115 * Shortcut for \code writesCd() || writesDvd() \endcode 0116 * 0117 * \return true if the device is able to burn media. 0118 */ 0119 bool burner() const; 0120 0121 /** 0122 * Shortcut for \code type() & DEVICE_CD_R \endcode 0123 * 0124 * \return true if the device is able to burn CD-R media. 0125 */ 0126 bool writesCd() const; 0127 0128 /** 0129 * Shortcut for \code type() & DEVICE_CD_RW \endcode 0130 * 0131 * \return true if the device is able to burn CD-RW media. 0132 */ 0133 bool writesCdrw() const; 0134 0135 /** 0136 * Shortcut for \code writesDvdMinus() || writesDvdPlus() \endcode 0137 * 0138 * \return true if the device is able to burn DVD media. 0139 */ 0140 bool writesDvd() const; 0141 0142 0143 /** 0144 * Shortcut for \code type() & (DEVICE_DVD_PLUS_R|DEVICE_DVD_PLUS_RW) \endcode 0145 * 0146 * \return true if the device is able to burn DVD+R or DVD+RW media. 0147 */ 0148 bool writesDvdPlus() const; 0149 0150 /** 0151 * Shortcut for \code type() & (DEVICE_DVD_R|DEVICE_DVD_RW) \endcode 0152 * 0153 * \return true if the device is able to burn DVD-R or DVD-RW media. 0154 */ 0155 bool writesDvdMinus() const; 0156 0157 /** 0158 * Shortcut for \code type() & DEVICE_DVD_ROM \endcode 0159 * 0160 * \return true if the device is able to read DVD media. 0161 */ 0162 bool readsDvd() const; 0163 0164 /** 0165 * @deprecated Use burnfree() 0166 */ 0167 bool burnproof() const; 0168 0169 /** 0170 * @return true is the device is a writer and supports buffer underrun free recording (BURNFREE) 0171 */ 0172 bool burnfree() const; 0173 0174 /** 0175 * Shortcut for \code writingModes() & WRITINGMODE_SAO \endcode 0176 * 0177 * \deprecated use supportsWritingMode() 0178 */ 0179 bool dao() const; 0180 0181 /** 0182 * Check if the device supports a certain writing mode. 0183 * 0184 * \return true if the device supports the requested writing mode or false otherwise. 0185 */ 0186 bool supportsWritingMode( WritingMode mode ) const { return (writingModes() & mode); } 0187 0188 /** 0189 * Shortcut for 0190 * \code 0191 * writingModes() & (WRITINGMODE_RAW|WRITINGMODE_RAW_R16|WRITINGMODE_RAW_R96P|WRITINGMODE_RAW_R96R) 0192 * \endcode 0193 */ 0194 bool supportsRawWriting() const; 0195 0196 /** 0197 * @return true if the device is a DVD-R(W) writer which supports test writing. 0198 */ 0199 bool dvdMinusTestwrite() const; 0200 0201 int maxReadSpeed() const; 0202 int currentWriteSpeed() const; 0203 0204 /** 0205 * Size of the device's internal writing buffer. 0206 * 0207 * \return The size of the buffer in KB. 0208 */ 0209 int bufferSize() const; 0210 0211 /** 0212 * for SCSI devices this should be something like /dev/scd0 or /dev/sr0 0213 * for IDE device this should be something like /dev/hdb1 0214 */ 0215 QString blockDeviceName() const; 0216 0217 int maxWriteSpeed() const; 0218 0219 /** 0220 * internal K3b value. 0221 * \deprecated This should not be handled here. 0222 */ 0223 void setCurrentWriteSpeed( int s ); 0224 0225 /** 0226 * Use this if the speed was not detected correctly. 0227 */ 0228 void setMaxReadSpeed( int s ); 0229 0230 /** 0231 * Use this if the speed was not detected correctly. 0232 */ 0233 void setMaxWriteSpeed( int s ); 0234 0235 /** 0236 * checks if unit is ready (medium inserted and ready for command) 0237 * 0238 * Refers to the MMC command: TEST UNIT READY 0239 */ 0240 bool testUnitReady() const; 0241 0242 /** 0243 * checks if disk is empty, returns @p K3b::Device::State 0244 */ 0245 int isEmpty() const; 0246 0247 /** 0248 * @return true if inserted media is rewritable. 0249 */ 0250 bool rewritable() const; 0251 0252 /** 0253 * Check if the inserted media is a DVD. 0254 * 0255 * \return true if the inserted media is a DVD. 0256 */ 0257 bool isDVD() const; 0258 0259 /** 0260 * @return The number of sessions on the media. 0261 */ 0262 int numSessions() const; 0263 0264 /** 0265 * @return The toc of the media or an empty (invalid) K3b::Device::Toc if 0266 * no or an empty media is inserted. 0267 */ 0268 Toc readToc() const; 0269 0270 /** 0271 * Append ISRC and MCN to the TOC if found 0272 * This has been moved to a separate method since it can take a very long time 0273 * to scan for all ISRCs. 0274 */ 0275 void readIsrcMcn( Toc& toc ) const; 0276 0277 /** 0278 * Read the raw CD-Text data without decoding it. 0279 * \return An array of bytes as read from the device, suitable to be used in 0280 * CdText( const QByteArray& ) 0281 * 0282 * \sa readCdText 0283 */ 0284 QByteArray readRawCdText( bool* success = 0 ) const; 0285 0286 /** 0287 * Read the CD-TEXT of an audio or mixed-mode CD. 0288 * 0289 * \return A CdText object filled with the CD-TEXT values or an empty one in case of 0290 * pure data media or if the CD does not contain CD-TEXT. 0291 * 0292 * \sa readRawCdText 0293 */ 0294 CdText readCdText() const; 0295 0296 /** 0297 * @return The K3b::Device::Track::DataMode of the track. 0298 * @see K3b::Device::Track 0299 */ 0300 Track::DataMode getTrackDataMode( const Track& track ) const; 0301 0302 /** 0303 * @return the mode of a data track. K3b::Device::Track::MODE1, K3b::Device::Track::MODE2, 0304 * K3b::Device::Track::XA_FORM1, or K3b::Device::Track::XA_FORM2. 0305 */ 0306 Track::DataMode getDataMode( const K3b::Msf& sector ) const; 0307 0308 /** 0309 * block or unblock the drive's tray 0310 * \return true on success and false on error. 0311 * \see eject() 0312 */ 0313 bool block( bool ) const; 0314 0315 /** 0316 * Eject the media. 0317 * \return true on success and false on error. 0318 * \see load() 0319 */ 0320 bool eject() const; 0321 0322 /** 0323 * Load the media. 0324 * @return true on success and false on error. 0325 */ 0326 bool load() const; 0327 0328 /** 0329 * Enable or disable auto-ejecting. For now this is a no-op on non-Linux systems. 0330 * \param enabled if true auto-ejecting will be enabled, otherwise disabled. 0331 * \return true if the operation was successful, false otherwise 0332 */ 0333 bool setAutoEjectEnabled( bool enabled ) const; 0334 0335 /** 0336 * The supported writing modes. 0337 * 0338 * \return A bitwise or of K3b::Device::WritingMode or 0 in case of a read-only device. 0339 */ 0340 WritingModes writingModes() const; 0341 0342 bool readSectorsRaw(unsigned char *buf, int start, int count) const; 0343 0344 /** 0345 * Get a list of supported profiles. See enumeration MediaType. 0346 */ 0347 int supportedProfiles() const; 0348 0349 /** 0350 * Tries to get the current profile from the drive. 0351 * @returns -1 on error (command failed or unknown profile) 0352 * MediaType otherwise (MEDIA_NONE means: no current profile) 0353 */ 0354 int currentProfile() const; 0355 0356 /** 0357 * Check if a certain feature is current. 0358 * \see k3bdevicetypes.h for feature constants. 0359 * \return 1 if the feature is current, 0 if not, -1 on error 0360 */ 0361 int featureCurrent( unsigned int feature ) const; 0362 0363 /** 0364 * This is the method to use! 0365 */ 0366 DiskInfo diskInfo() const; 0367 0368 /** 0369 * Refers to MMC command READ CAPACITY 0370 */ 0371 bool readCapacity( K3b::Msf& ) const; 0372 0373 /** 0374 * Refers to MMC command READ FORMAT CAPACITY 0375 * 0376 * @param wantedFormat The requested format type. 0377 * @param result If true is returned this contains the requested value. 0378 * @param currentMax If not 0 this will be filled with the Current/Maximum Descriptor value. 0379 * @param currentMax If not 0 this will be filled with the Current/Maximum Format Type. 0380 */ 0381 bool readFormatCapacity( int wantedFormat, K3b::Msf& result, 0382 K3b::Msf* currentMax = 0, int* currentMaxFormat = 0 ) const; 0383 0384 /** 0385 * Determine the type of the currently mounted medium 0386 * 0387 * @returns K3b::Device::MediaType 0388 */ 0389 MediaType mediaType() const; 0390 0391 /** 0392 * Returns the list of supported writing speeds as reported by 0393 * mode page 2Ah. 0394 * 0395 * This only works with MMC3 compliant drives. 0396 */ 0397 QList<int> determineSupportedWriteSpeeds() const; 0398 0399 /** 0400 * @returns the speed in kb/s or 0 on failure. 0401 */ 0402 int determineMaximalWriteSpeed() const; 0403 0404 /** 0405 * Open the device for access via a file descriptor. 0406 * @return true on success or if the device is already open. 0407 * @see close() 0408 * 0409 * Be aware that this method is not thread-safe. 0410 */ 0411 bool open( bool write = false ) const; 0412 0413 /** 0414 * Close the files descriptor. 0415 * @see open() 0416 * 0417 * Be aware that this method is not thread-safe. 0418 */ 0419 void close() const; 0420 0421 /** 0422 * @return true if the device was successfully opened via @p open() 0423 */ 0424 bool isOpen() const; 0425 0426 /** 0427 * fd on linux, cam on bsd 0428 */ 0429 Handle handle() const; 0430 0431 /** 0432 * \return \li -1 on error (no DVD) 0433 * \li 1 (CSS/CPPM) 0434 * \li 2 (CPRM) if scrambled 0435 * \li 0 otherwise 0436 */ 0437 int copyrightProtectionSystemType() const; 0438 0439 // MMC commands 0440 0441 /** 0442 * SET SPEED command 0443 * 0444 * @param readingSpeed The preferred reading speed (0x0000-0xFFFE). 0xFFFF requests 0445 * fot the logical unit to select the optimal speed. 0446 * @param writingSpeed The preferred writing speed (0x0000-0xFFFE). 0xFFFF requests 0447 * fot the logical unit to select the optimal speed. 0448 * @param cav Is the speed pure CAV? 0449 */ 0450 bool setSpeed( unsigned int readingSpeed, 0451 unsigned int writingSpeed, 0452 bool cav = false ) const; 0453 0454 /** 0455 * if true is returned \param data is resized. 0456 */ 0457 bool readDiscInformation( UByteArray& data ) const; 0458 0459 /** 0460 * @param pf If false all fields in the descriptor data is vendor specific. Default should be true. 0461 */ 0462 bool modeSelect( UByteArray& pageData, bool pf, bool sp ) const; 0463 0464 /** 0465 * if true is returned \param pageData is resized. 0466 */ 0467 bool modeSense( UByteArray& pageData, int page ) const; 0468 0469 /** 0470 * if true is returned \param data is resized. 0471 */ 0472 bool readTocPmaAtip( UByteArray& data, int format, bool msf, int track ) const; 0473 0474 /** 0475 * @param type specifies what value means: 0476 * \li 00b - value refers to a logical block address 0477 * \li 01b - value refers to a track number where 0 will treat the lead-in as if it 0478 * were a logical track and ffh will read the invisible or incomplete track. 0479 * \li 10b - value refers to a session number 0480 * 0481 */ 0482 bool readTrackInformation( UByteArray& data, int type, int value ) const; 0483 0484 /** 0485 * if true is returned \param data is resized. 0486 */ 0487 bool readDiscStructure( UByteArray& data, 0488 unsigned int mediaType = 0x0, 0489 unsigned int format = 0x0, 0490 unsigned int layer = 0x0, 0491 unsigned long address = 0, 0492 unsigned int agid = 0x0 ) const; 0493 0494 /** 0495 * In MMC5 readDvdStructure was renamed to readDiscStructure. This method does the same 0496 * like the above. 0497 */ 0498 bool readDvdStructure( UByteArray& data, 0499 unsigned int format = 0x0, 0500 unsigned int layer = 0x0, 0501 unsigned long address = 0, 0502 unsigned int agid = 0x0 ) const; 0503 0504 /** 0505 * if true is returned \param data is resized. 0506 */ 0507 bool mechanismStatus( UByteArray& data ) const; 0508 0509 /** 0510 * Read a single feature. 0511 * data will be filled with the feature header and the descriptor 0512 */ 0513 bool getFeature( UByteArray& data, unsigned int feature ) const; 0514 0515 0516 /** 0517 * if true is returned \param data is resized. 0518 */ 0519 bool getPerformance( UByteArray& data, 0520 unsigned int type, 0521 unsigned int dataType, 0522 unsigned int lba = 0 ) const; 0523 0524 /** 0525 * @param sectorType: \li 000b - all types 0526 * \li 001b - CD-DA 0527 * \li 010b - Mode 1 0528 * \li 011b - Mode 2 formless 0529 * \li 100b - Mode 2 form 1 0530 * \li 101b - Mode 2 form 2 0531 * 0532 * @param startAdress Lba 0 is mapped to msf 00:00:00 so this method uses 0533 * startAdress+150 as the starting msf. 0534 * 0535 * @param endAdress This is the ending address which is NOT included in the read operation. 0536 * Lba 0 is mapped to msf 00:00:00 so this method uses 0537 * endAdress+150 as the ending msf. 0538 * 0539 * @param c2: \li 00b - No error info 0540 * \li 01b - 294 bytes, one bit for every byte of the 2352 bytes 0541 * \li 10b - 296 bytes, xor of all c2 bits, zero pad bit, 294 c2 bits 0542 * 0543 * @param subChannel: \li 000b - No Sub-channel data 0544 * \li 001b - RAW P-W Sub-channel (96 bytes) 0545 * \li 010b - Formatted Q Sub-channel (16 bytes) 0546 * \li 100b - Corrected and de-interleaved R-W Sub-channel (96 bytes) 0547 */ 0548 bool readCdMsf( unsigned char* data, 0549 unsigned int dataLen, 0550 int sectorType, 0551 bool dap, 0552 const K3b::Msf& startAdress, 0553 const K3b::Msf& endAdress, 0554 bool sync, 0555 bool header, 0556 bool subHeader, 0557 bool userData, 0558 bool edcEcc, 0559 int c2, 0560 int subChannel ) const; 0561 0562 /** 0563 * @param sectorType: \li 000b - all types 0564 * \li 001b - CD-DA 0565 * \li 010b - Mode 1 0566 * \li 011b - Mode 2 formless 0567 * \li 100b - Mode 2 form 1 0568 * \li 101b - Mode 2 form 2 0569 * 0570 * @param c2: \li 00b - No error info 0571 * \li 01b - 294 bytes, one bit for every byte of the 2352 bytes 0572 * \li 10b - 296 bytes, xor of all c2 bits, zero pad bit, 294 c2 bits 0573 * 0574 * @param subChannel: \li 000b - No Sub-channel data 0575 * \li 001b - RAW P-W Sub-channel (96 bytes) 0576 * \li 010b - Formatted Q Sub-channel (16 bytes) 0577 * \li 100b - Corrected and de-interleaved R-W Sub-channel (96 bytes) 0578 */ 0579 bool readCd( unsigned char* data, 0580 unsigned int dataLen, 0581 int sectorType, 0582 bool dap, 0583 unsigned long startAdress, 0584 unsigned long length, 0585 bool sync, 0586 bool header, 0587 bool subHeader, 0588 bool userData, 0589 bool edcEcc, 0590 int c2, 0591 int subChannel ) const; 0592 0593 bool read10( unsigned char* data, 0594 unsigned int dataLen, 0595 unsigned long startAdress, 0596 unsigned int length, 0597 bool fua = false ) const; 0598 0599 bool read12( unsigned char* data, 0600 unsigned int dataLen, 0601 unsigned long startAdress, 0602 unsigned long length, 0603 bool streaming = false, 0604 bool fua = false ) const; 0605 0606 /** 0607 * @param subchannelParam: 01h - CD current position 0608 * 02h - Media Catalog number (UPC/bar code) 0609 * 03h - ISRC 0610 * @param trackNumber only valid if subchannelParam == 03h 0611 */ 0612 bool readSubChannel( UByteArray& data, 0613 unsigned int subchannelParam, 0614 unsigned int trackNumber ) const; 0615 0616 bool readIsrc( unsigned int track, QByteArray& isrc ) const; 0617 0618 bool readMcn( QByteArray& mcn ) const; 0619 0620 /** 0621 * MMC command Read Buffer Capacity 0622 * 0623 * \return \see ScsiCommand::transport() 0624 */ 0625 int readBufferCapacity( long long& bufferLength, long long& bufferAvail ) const; 0626 0627 /** 0628 * @returns the index number on success 0629 * -1 on general error 0630 * and -2 if there is no index info in that frame 0631 */ 0632 int getIndex( unsigned long lba ) const; 0633 0634 bool searchIndex0( unsigned long startSec, unsigned long endSec, long& pregapStart ) const; 0635 0636 /** 0637 * For now this just searches index 0 for all tracks and sets 0638 * the value in the tracks. 0639 * In the future this should scan for all indices. 0640 */ 0641 bool indexScan( Toc& toc ) const; 0642 0643 /** 0644 * Seek to the specified sector. 0645 */ 0646 bool seek( unsigned long lba ) const; 0647 0648 bool getNextWritableAdress( unsigned int& lastSessionStart, unsigned int& nextWritableAdress ) const; 0649 0650 /** 0651 * Retrieve the next writable address from the currently mounted writable medium. 0652 * \return The next writable address if the medium is empty or appendable or -1 0653 * if an error occurred. 0654 */ 0655 int nextWritableAddress() const; 0656 0657 /** 0658 * Locks the device for usage. This means that no MMC command can be performed 0659 * until usageUnlock is called. 0660 * 0661 * Locking a device is useful when an external application or library is called 0662 * that opens the device itself. 0663 * 0664 * \sa usageUnlock 0665 */ 0666 void usageLock() const; 0667 0668 /** 0669 * Unlock the device after a call to usageLock. 0670 */ 0671 void usageUnlock() const; 0672 0673 /** 0674 * Thread-safe ioctl call for this device for Linux and Net-BSD systems. 0675 * Be aware that so far this does not include opening the device 0676 */ 0677 // int ioctl( int request, ... ) const; 0678 0679 protected: 0680 bool furtherInit(); 0681 0682 #ifdef Q_OS_LINUX 0683 /** 0684 * Fallback method that uses the evil cdrom.h stuff 0685 */ 0686 bool readTocLinux( Toc& ) const; 0687 #endif 0688 0689 /** 0690 * The preferred toc reading method for all CDs. Also reads session info. 0691 * undefined for DVDs. 0692 */ 0693 bool readRawToc( Toc& ) const; 0694 bool readFormattedToc( Toc&, int mediaType ) const; 0695 0696 /** 0697 * Fixes the last block on CD-Extra disks. This is needed if the readRawToc failed since 0698 * in that case the first sector of the last session's first track is used as the previous 0699 * session's last track's last sector which is wrong. There is a 11400 block session lead-in 0700 * between them. This method fixes this only for the last session and only on linux. 0701 */ 0702 bool fixupToc( Toc& ) const; 0703 0704 private: 0705 /** 0706 * A Device can only be constructed by the DeviceManager. 0707 */ 0708 Device( const Solid::Device& dev ); 0709 0710 /** 0711 * Determines the device's capabilities. This needs to be called once before 0712 * using the device. 0713 * 0714 * Should only be used by the DeviceManager. 0715 * 0716 * @param checkWritingModes if true the CD writing modes will be checked using 0717 * MMC_MODE_SELECT. 0718 */ 0719 bool init( bool checkWritingModes = true ); 0720 0721 void searchIndexTransitions( long start, long end, K3b::Device::Track& track ) const; 0722 void checkWritingModes(); 0723 void checkFeatures(); 0724 void checkForJustLink(); 0725 void checkFor2AFeatures(); 0726 void checkForAncientWriters(); 0727 0728 /** 0729 * Internal method which checks if the raw toc data has bcd values or hex. 0730 * @return 0 if hex, 1 if bcd, -1 if none 0731 */ 0732 int rawTocDataWithBcdValues( const UByteArray& data ) const; 0733 0734 bool getSupportedWriteSpeedsVia2A( QList<int>& list, MediaType type ) const; 0735 bool getSupportedWriteSpeedsViaGP( QList<int>& list, MediaType type ) const; 0736 0737 int getMaxWriteSpeedVia2A() const; 0738 0739 QByteArray mediaId( int mediaType ) const; 0740 0741 class Private; 0742 Private* d; 0743 0744 friend class DeviceManager; 0745 }; 0746 0747 /** 0748 * This should always be used to open a device since it 0749 * uses the resmgr 0750 * 0751 * @internal 0752 */ 0753 K3b::Device::Device::Handle openDevice( const char* name, bool write = false ); 0754 } 0755 } 0756 0757 #endif