/* Accept a new piece of media, doing whatever's necessary to make it * show up properly to the system. */ IOReturn IODVDBlockStorageDriver::acceptNewMedia(void) { IOReturn result; if (getMediaType() < kDVDMediaTypeMin || getMediaType() > kDVDMediaTypeMax) { return super::acceptNewMedia(); } /* Obtain disc status: */ switch (getMediaType()) { case kDVDMediaTypeR: case kDVDMediaTypeRW: { bool checkIsWritable = false; DVDDiscInfo discInfo; DVDRZoneInfo rzoneInfo; result = reportDiscInfo(&discInfo); if (result != kIOReturnSuccess) { break; } switch (discInfo.discStatus) { case 0x01: /* is disc incomplete? */ checkIsWritable = true; break; case 0x02: /* is disc complete? */ checkIsWritable = discInfo.erasable ? true : false; break; } /* Obtain rzone status: */ if (checkIsWritable) { UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | discInfo.lastRZoneNumberInLastBorderLSB; result = reportRZoneInfo(rzoneLast,&rzoneInfo); if (result != kIOReturnSuccess) { break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ _maxBlockNumber = max( _maxBlockNumber, max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); } if (rzoneInfo.incremental) { /* is rzone incremental? */ _writeProtected = false; break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ if (rzoneInfo.blank) { /* is rzone invisible? */ UInt16 rzoneFirst = (discInfo.firstRZoneNumberInLastBorderMSB << 8) | discInfo.firstRZoneNumberInLastBorderLSB; if (rzoneFirst < rzoneLast) { result = reportRZoneInfo(rzoneLast - 1,&rzoneInfo); if (result != kIOReturnSuccess) { break; } if (rzoneInfo.incremental) { /* is rzone incremental? */ _writeProtected = false; break; } } } } } break; } case kDVDMediaTypePlusR: case kDVDMediaTypeHDR: { DVDDiscInfo discInfo; DVDRZoneInfo rzoneInfo; IOReturn result; result = reportDiscInfo(&discInfo); if (result != kIOReturnSuccess) { break; } /* Obtain rzone status: */ if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ UInt16 rzoneLast = (discInfo.lastRZoneNumberInLastBorderMSB << 8) | discInfo.lastRZoneNumberInLastBorderLSB; _writeProtected = false; result = reportRZoneInfo(rzoneLast,&rzoneInfo); if (result != kIOReturnSuccess) { break; } _maxBlockNumber = max( _maxBlockNumber, max( OSSwapBigToHostInt32(rzoneInfo.rzoneStartAddress) + OSSwapBigToHostInt32(rzoneInfo.rzoneSize), 1 ) - 1 ); } break; } } return IOBlockStorageDriver::acceptNewMedia(); }
/* Accept a new piece of media, doing whatever's necessary to make it * show up properly to the system. The arbitration lock is assumed to * be held during the call. */ IOReturn IOCDBlockStorageDriver::acceptNewMedia(void) { IOReturn result; int i; int nentries; int nAudioTracks; /* First, we cache information about the tracks on the disc: */ result = cacheTocInfo(); if (result != kIOReturnSuccess) { assert(_toc == NULL); } /* Scan thru the track list, counting up the number of Data and Audio tracks. */ nAudioTracks = 0; _minBlockNumberAudio = 0xFFFFFFFF; _maxBlockNumberAudio = 0xFFFFFFFF; if (_toc) { nentries = CDTOCGetDescriptorCount(_toc); for (i = 0; i < nentries; i++) { UInt32 lba = CDConvertMSFToClippedLBA(_toc->descriptors[i].p); /* tracks 1-99, not leadout or skip intervals */ if (_toc->descriptors[i].point <= 99 && _toc->descriptors[i].adr == 1) { if ((_toc->descriptors[i].control & 0x04)) { /* it's a data track */ _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba ? (lba - 1) : 0); } else { nAudioTracks++; _minBlockNumberAudio = min(_minBlockNumberAudio, lba); } /* leadout */ } else if (_toc->descriptors[i].point == 0xA2 && _toc->descriptors[i].adr == 1) { _maxBlockNumber = max(_maxBlockNumber, lba ? (lba - 1) : 0); _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba ? (lba - 1) : 0); } } if (_maxBlockNumberAudio < _minBlockNumberAudio) { _maxBlockNumberAudio = 0xFFFFFFFF; /* find first data track or leadout after the audio tracks */ for (i = 0; i < nentries; i++) { UInt32 lba = CDConvertMSFToClippedLBA(_toc->descriptors[i].p); /* tracks 1-99, not leadout or skip intervals */ if (_toc->descriptors[i].point <= 99 && _toc->descriptors[i].adr == 1) { if ((_toc->descriptors[i].control & 0x04)) { /* it's a data track */ if (lba > _minBlockNumberAudio) { _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba - 1); } } /* leadout */ } else if (_toc->descriptors[i].point == 0xA2 && _toc->descriptors[i].adr == 1) { if (lba > _minBlockNumberAudio) { _maxBlockNumberAudio = min(_maxBlockNumberAudio, lba - 1); } } } } } /* Obtain disc status: */ switch (getMediaType()) { case kCDMediaTypeR: case kCDMediaTypeRW: { bool checkIsWritable = false; CDDiscInfo discInfo; CDTrackInfo trackInfo; result = reportDiscInfo(&discInfo); if (result != kIOReturnSuccess) { break; } switch (discInfo.discStatus) { case 0x01: /* is disc incomplete? */ checkIsWritable = true; break; case 0x02: /* is disc complete? */ checkIsWritable = discInfo.erasable ? true : false; break; } /* Obtain track status: */ if (checkIsWritable) { UInt16 trackLast = discInfo.lastTrackNumberInLastSessionLSB; result = reportTrackInfo(trackLast,&trackInfo); if (result != kIOReturnSuccess) { break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ _maxBlockNumber = CDConvertMSFToClippedLBA(discInfo.lastPossibleStartTimeOfLeadOut); } if (trackInfo.packet) { /* is track incremental? */ _writeProtected = false; break; } if (discInfo.discStatus == 0x01) { /* is disc incomplete? */ if (trackInfo.blank) { /* is track invisible? */ UInt16 trackFirst = discInfo.firstTrackNumberInLastSessionLSB; if (trackFirst < trackLast) { result = reportTrackInfo(trackLast - 1,&trackInfo); if (result != kIOReturnSuccess) { break; } if (trackInfo.packet) { /* is track incremental? */ _writeProtected = false; break; } } } } } break; } } /* Instantiate a media object and attach it to ourselves. */ result = super::acceptNewMedia(); if (result != kIOReturnSuccess) { return(result); /* give up now */ } return(result); }