Logo Search packages:      
Sourcecode: k9copy version File versions  Download package

K3bDevice::DiskInfo K3bDevice::Device::diskInfo (  )  const

This is the method to use!

Definition at line 1641 of file k3bdevice.cpp.

References K3bDevice::DiskInfo::appendable(), K3bDevice::DiskInfo::bgFormatState(), blockDeviceName(), close(), K3bDevice::DiskInfo::currentProfile(), currentProfile(), K3bDevice::DiskInfo::diskState(), dvdMediaType(), K3bDevice::DiskInfo::empty(), isOpen(), K3b::Msf::lba(), K3bDevice::Toc::length(), K3bDevice::DiskInfo::m_bgFormatState, K3bDevice::DiskInfo::m_capacity, K3bDevice::DiskInfo::m_currentProfile, K3bDevice::DiskInfo::m_diskState, K3bDevice::DiskInfo::m_firstLayerSize, K3bDevice::DiskInfo::m_lastSessionState, K3bDevice::DiskInfo::m_mediaType, K3bDevice::DiskInfo::m_numLayers, K3bDevice::DiskInfo::m_numSessions, K3bDevice::DiskInfo::m_numTitles, K3bDevice::DiskInfo::m_rewritable, K3bDevice::DiskInfo::m_usedCapacity, K3bDevice::DiskInfo::mediaType(), K3b::Msf::mode1Bytes(), numSessions(), K3bDevice::DiskInfo::numTitles(), open(), readCapacity(), readDiscInfo(), readDvdStructure(), readFormatCapacity(), readToc(), readTrackInformation(), K3bDevice::DiskInfo::rewritable(), testUnitReady(), and K3b::Msf::toString().

{
  DiskInfo inf;
  inf.m_diskState = STATE_UNKNOWN;

  // if the device is already opened we do not close it
  // to allow fast multible method calls in a row
  bool needToClose = !isOpen();

  if( open() ) {

    unsigned char* data = 0;
    int dataLen = 0;

//     //
//     // Set writing mode to WRITINGMODE_TAO.
//     // In WRITINGMODE_RAW writing mode we do not get the values we want.
//     //
//     if( modeSense( &data, dataLen, 0x05 ) ) {
//       wr_param_page_05* mp = (struct wr_param_page_05*)(data+8);

//       // reset some stuff to be on the safe side
//       mp->PS = 0;
//       mp->BUFE = 0;
//       mp->multi_session = 0;
//       mp->test_write = 0;
//       mp->LS_V = 0;
//       mp->copy = 0;
//       mp->fp = 0;
//       mp->host_appl_code= 0;
//       mp->session_format = 0;
//       mp->audio_pause_len[0] = 0;
//       mp->audio_pause_len[1] = 150;

//       mp->write_type = 0x01;  // WRITINGMODE_TAO
//       mp->track_mode = 4;     // MMC-4 says: 5, cdrecord uses 4 ???
//       mp->dbtype = 8;         // Mode 1

//       if( !modeSelect( data, dataLen, 1, 0 ) ) {
//    kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
//            << ": modeSelect 0x05 failed!" << endl;
//       }

//       delete [] data;
//     }
//     else
//       kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
//          << ": modeSense 0x05 failed!" << endl;


    //
    // The first thing to do should be: checking if a media is loaded
    // We do this with requesting the current profile. If it is 0 no media
    // should be loaded. On an error we just go on.
    //
    if( !testUnitReady() ) {
      // no disk or tray open
      inf.m_diskState = STATE_NO_MEDIA;
      inf.m_mediaType = MEDIA_NONE;
    }
    else {
      int profile = currentProfile();
      if( profile == MEDIA_NONE ) {
      inf.m_diskState = STATE_NO_MEDIA;
      inf.m_mediaType = MEDIA_NONE;
      }
      inf.m_currentProfile = profile;
    }

    if( inf.diskState() != STATE_NO_MEDIA ) {

      if( readDiscInfo( &data, dataLen ) ) {
      disc_info_t* dInf = (disc_info_t*)data;
      //
      // Copy the needed values from the disk_info struct
      //
      switch( dInf->status ) {
      case 0:
        inf.m_diskState = STATE_EMPTY;
        break;
      case 1:
        inf.m_diskState = STATE_INCOMPLETE;
        break;
      case 2:
        inf.m_diskState = STATE_COMPLETE;
        break;
      default:
        inf.m_diskState = STATE_UNKNOWN;
        break;
      }

      switch( dInf->border ) {
      case 0x00:
        inf.m_lastSessionState = STATE_EMPTY;
        break;
      case 0x01:
        inf.m_lastSessionState = STATE_INCOMPLETE;
        break;
      case 0x11:
        inf.m_lastSessionState = STATE_COMPLETE;
        break;
      default:
        inf.m_lastSessionState = STATE_UNKNOWN;
        break;
      }

      inf.m_bgFormatState = dInf->bg_f_status&0x3;

      inf.m_numTitles = (dInf->last_track_l & 0xff) | (dInf->last_track_m<<8 & 0xff00);
      if( inf.diskState() == STATE_EMPTY )
        inf.m_numTitles = 0;
      else if( inf.diskState() == STATE_INCOMPLETE )
        inf.m_numTitles--;  // do not count the invisible track

      inf.m_rewritable = dInf->erasable;

      //
      // This is the Last Possible Lead-Out Start Adress in HMSF format
      // This is only valid for CD-R(W) and DVD+R media.
      // For complete media this shall be filled with 0xff
      //
      if( dInf->lead_out_m != 0xff &&
          dInf->lead_out_r != 0xff &&
          dInf->lead_out_s != 0xff &&
          dInf->lead_out_f != 0xff )
        inf.m_capacity = K3b::Msf( dInf->lead_out_m + dInf->lead_out_r*60,
                             dInf->lead_out_s,
                             dInf->lead_out_f ) - 150;

      //
      // This is the position where the next Session shall be recorded in HMSF format
      // This is only valid for CD-R(W) and DVD+R media.
      // For complete media this shall be filled with 0xff
      //
      if( dInf->lead_in_m != 0xff &&
          dInf->lead_in_r != 0xff &&
          dInf->lead_in_s != 0xff &&
          dInf->lead_in_f != 0xff )
        inf.m_usedCapacity = K3b::Msf( dInf->lead_in_m + dInf->lead_in_r*60,
                               dInf->lead_in_s,
                               dInf->lead_in_f ) - 4500;

      delete [] data;
      }



      //
      // The mediatype needs to be set
      //
      inf.m_mediaType = dvdMediaType();

      if( inf.m_mediaType == MEDIA_UNKNOWN ) {
      // probably it is a CD
      if( inf.rewritable() )
        inf.m_mediaType = MEDIA_CD_RW;
      else if( inf.empty() || inf.appendable() )
        inf.m_mediaType = MEDIA_CD_R;
      else
        inf.m_mediaType = MEDIA_CD_ROM;
      }
      else {
      if( readDvdStructure( &data, dataLen ) ) {
        // some debugging stuff
        K3b::Msf sda, eda, ea0;
        sda = ( data[4+5]<<16 | data[4+6] << 8 | data[4+7] );
        eda = ( data[4+9]<<16 | data[4+10] << 8 | data[4+11] );
        ea0 = ( data[4+13]<<16 | data[4+14] << 8 | data[4+15] );

        kdDebug() << "First sec data area: " << sda.toString()
                << " (LBA " << QString::number(sda.lba())
                << ") (" << QString::number(sda.mode1Bytes()) << " Bytes) ("
                << KIO::convertSize(sda.mode1Bytes()) << ")" << endl;
        kdDebug() << "Last sec data area: " << eda.toString()
                << " (LBA " << QString::number(eda.lba())
                << ") (" << QString::number(eda.mode1Bytes()) << " Bytes) ("
                << KIO::convertSize(eda.mode1Bytes()) << ")" << endl;
        kdDebug() << "Last sec layer 1: " << ea0.toString()
                << " (LBA " << QString::number(ea0.lba())
                << ") (" << QString::number(ea0.mode1Bytes()) << " Bytes) ("
                << KIO::convertSize(ea0.mode1Bytes()) << ")" << endl;


        K3b::Msf da0 = ea0 - sda + 1;
        K3b::Msf da1 = eda - ea0;
        kdDebug() << "Layer 1 length: " << da0.toString()
                << " (LBA " << QString::number(da0.lba())
                << ") (" << QString::number(da0.mode1Bytes()) << " Bytes) ("
                << KIO::convertSize(da0.mode1Bytes()) << ")" << endl;
        kdDebug() << "Layer 2 length: " << da1.toString()
                << " (LBA " << QString::number(da1.lba())
                << ") (" << QString::number(da1.mode1Bytes()) << " Bytes) ("
                << KIO::convertSize(da1.mode1Bytes()) << ")" << endl;

        inf.m_numLayers = ((data[6]&0x60) == 0 ? 1 : 2);
        inf.m_firstLayerSize = da0;

        delete [] data;
      }
      else {
        kdDebug() << "(K3bDevice::Device) Unable to read DVD structure for num of layers." << endl;
        inf.m_numLayers = ( (inf.m_mediaType & MEDIA_WRITABLE_DVD_DL) ? 2 : 1 );
      }
      }


      //
      // Number of sessions for non-empty disks
      //
      if( inf.diskState() != STATE_EMPTY ) {
      int sessions = numSessions();
      if( sessions >= 0 )
        inf.m_numSessions = sessions;
      else
        kdDebug() << "(K3bDevice::Device) could not get session info via READ TOC/PMA/ATIP." << endl;
      }
      else
      inf.m_numSessions = 0;


      //
      // Now we determine the size:

      // for all empty and appendable media READ FORMAT CAPACITIES should return the proper unformatted size
      // for complete disks we may use the READ_CAPACITY command or the start sector from the leadout
      //
      int media = inf.mediaType();
      //
      // Use the profile if available because DVD-ROM units need to treat DVD+-R(W) media as DVD-ROM
      // if supported at all
      //
      if( inf.currentProfile() == MEDIA_DVD_ROM )
      media = MEDIA_DVD_ROM;

      switch( media ) {
      case MEDIA_CD_R:
      case MEDIA_CD_RW:
      //
      // for empty and appendable media capacity and usedCapacity should be filled in from
      // diskinfo above. If not they are both still 0
      //
      if( inf.m_capacity != 0 &&
          ( inf.diskState() == STATE_EMPTY || inf.m_usedCapacity != 0 ) ) {
        // done.
        break;
      }

      default:
      case MEDIA_CD_ROM:
      if( inf.m_capacity > 0 && inf.m_usedCapacity == 0 )
        inf.m_usedCapacity = inf.m_capacity;

      if( inf.m_usedCapacity == 0 ) {
        K3b::Msf readCap;
        if( readCapacity( readCap ) ) {
          kdDebug() << "(K3bDevice::Device) READ CAPACITY: " << readCap.toString()
                  << " other capacity: " << inf.m_capacity.toString() << endl;
          //
          // READ CAPACITY returns the last written sector
          // that means the size is actually readCap + 1
          //
          inf.m_usedCapacity = readCap + 1;
        }
        else {
          kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
                  << " Falling back to readToc for capacity." << endl;
          inf.m_usedCapacity = readToc().length();
        }
      }

      case MEDIA_DVD_ROM: {
      K3b::Msf readCap;
      if( readCapacity( readCap ) ) {
        kdDebug() << "(K3bDevice::Device) READ CAPACITY: " << readCap.toString()
                << " other capacity: " << inf.m_capacity.toString() << endl;
        //
        // READ CAPACITY returns the last written sector
        // that means the size is actually readCap + 1
        //
        inf.m_usedCapacity = readCap + 1;
      }
      else {
        //
        // Only one track, use it's size
        //
        if( readTrackInformation( &data, dataLen, 0x1, 0x1 ) ) {
          track_info_t* trackInfo = (track_info_t*)data;
          inf.m_usedCapacity = from4Byte( trackInfo->track_size );
          delete [] data;
        }
        else
          kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
                  << "READ TRACK INFORMATION for DVD-ROM failed." << endl;
      }

      break;
      }

      case MEDIA_DVD_PLUS_R:
      case MEDIA_DVD_PLUS_R_DL:
      if( inf.appendable() || inf.empty() ) {
        //
        // get remaining space via the invisible track
        //
        if( readTrackInformation( &data, dataLen, 0x1, 0xff ) ) {
          track_info_t* trackInfo = (track_info_t*)data;
          inf.m_usedCapacity = from4Byte( trackInfo->track_start );
          inf.m_capacity = from4Byte( trackInfo->track_start ) + from4Byte( trackInfo->track_size );
          delete [] data;
        }
      }
      else {
        if( readTrackInformation( &data, dataLen, 0x1, inf.numTitles() ) ) {
          track_info_t* trackInfo = (track_info_t*)data;
          inf.m_capacity = inf.m_usedCapacity
            = from4Byte( trackInfo->track_start ) + from4Byte( trackInfo->track_size );
          delete [] data;
        }
      }
      break;

      case MEDIA_DVD_R:
      case MEDIA_DVD_R_SEQ:
      case MEDIA_DVD_R_DL:
      case MEDIA_DVD_R_DL_JUMP:
      case MEDIA_DVD_R_DL_SEQ:
      //
      // get data from the incomplete track (which is NOT the invisible track 0xff)
      // This will fail in case the media is complete!
      //
      if( readTrackInformation( &data, dataLen, 0x1, inf.numTitles()+1 ) ) {
        track_info_t* trackInfo = (track_info_t*)data;
        inf.m_usedCapacity = from4Byte( trackInfo->track_start );
        inf.m_capacity = from4Byte( trackInfo->free_blocks ) + from4Byte( trackInfo->track_start );
        delete [] data;
      }

      //
      // Get the "really" used space without border-out
      //
      if( !inf.empty() ) {
        K3b::Msf readCap;
        if( readCapacity( readCap ) ) {
          //
          // READ CAPACITY returns the last written sector
          // that means the size is actually readCap + 1
          //
          inf.m_usedCapacity = readCap + 1;
        }
        else
          kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
                  << " READ CAPACITY for DVD-R failed." << endl;
      }

      break;

      case MEDIA_DVD_RW:
      case MEDIA_DVD_RW_SEQ:
      // only one track on a DVD-RW media
      if( readTrackInformation( &data, dataLen, 0x1, 0x1 ) ) {
        track_info_t* trackInfo = (track_info_t*)data;
        if( inf.empty() )
          inf.m_capacity = from4Byte( trackInfo->track_size );
        else
          inf.m_usedCapacity = from4Byte( trackInfo->track_size );
        delete [] data;
      }
      break;

      case MEDIA_DVD_PLUS_RW: {
      K3b::Msf currentMax;
      int currentMaxFormat = 0;
      if( readFormatCapacity( 0x26, inf.m_capacity, &currentMax, &currentMaxFormat ) ) {
        if( inf.bgFormatState() != BG_FORMAT_NONE )
          inf.m_usedCapacity = currentMax;
        else
          inf.m_usedCapacity = 0;
            }
      else
        kdDebug() << "(K3bDevice::Device) " << blockDeviceName()
                << " READ FORMAT CAPACITIES for DVD+RW failed." << endl;

      break;
      }

      case MEDIA_DVD_RW_OVWR:
      inf.m_numSessions = 1;
      if( readTrackInformation( &data, dataLen, 0x1, 0x1 ) ) {
        track_info_t* trackInfo = (track_info_t*)data;
        inf.m_usedCapacity = inf.m_capacity = from4Byte( trackInfo->track_size );
        delete [] data;
      }
      break;
      }



//      // read next writable adress
//      if( readTrackInformation( &data, dataLen, 0x1, 0xff ) ) {
//        track_info_t* trackInfo = (track_info_t*)data;
//        if( trackInfo->nwa_v ) {
//          K3b::Msf nwa = from4Byte( trackInfo->next_writable );
//          kdDebug() << "(K3bDevice::Device) Next writale adress valid: " << nwa.toString() << endl;
//          inf.m_remaining = inf.m_capacity - nwa - 150;  // reserve space for pre-gap after lead-in (?)
//        }
//        else {
//          kdDebug() << "(K3bDevice::Device) Next writale adress invalid." << endl;
//        }

//        delete [] data;
//      }
//    }
//       }
//       else {
//    K3b::Msf readCap;
//    if( readCapacity( readCap ) ) {
//      kdDebug() << "(K3bDevice::Device) READ CAPACITY: " << readCap.toString()
//              << " other capacity: " << inf.m_capacity.toString() << endl;

//      //
//      // READ CAPACITY returns the last written sector
//      // that means the size is actually readCap + 1
//      //
//      inf.m_capacity = readCap + 1;
//    }
//    else {
//      kdDebug() << "(K3bDevice::Device) READ CAPACITY failed. Falling back to READ TRACK INFO." << endl;

//      if( readTrackInformation( &data, dataLen, 0x1, 0xff ) ) {
//        track_info_t* trackInfo = (track_info_t*)data;
//        inf.m_capacity = from4Byte( trackInfo->track_start );

//        delete [] data;
//      }
//      else {
//        kdDebug() << "(K3bDevice::Device) Falling back to readToc." << endl;
//        inf.m_capacity = readToc().length();
//      }
//    }
//       }
    }

    if( needToClose )
      close();
  }

  return inf;
}


Generated by  Doxygen 1.6.0   Back to index