IOReturn IOCDBlockStorageDriver::cacheTocInfo(void) { IOBufferMemoryDescriptor *buffer; IOReturn result; CDTOC *toc; UInt16 tocSize; assert(sizeof(CDTOC) == 4); /* (compiler/platform check) */ assert(sizeof(CDTOCDescriptor) == 11); /* (compiler/platform check) */ assert(_toc == NULL); /* Read the TOC header: */ buffer = IOBufferMemoryDescriptor::withCapacity(sizeof(CDTOC),kIODirectionIn); if (buffer == NULL) { return(kIOReturnNoMemory); } result = getProvider()->readTOC(buffer); if (result != kIOReturnSuccess) { buffer->release(); return(result); } toc = (CDTOC *) buffer->getBytesNoCopy(); tocSize = OSSwapBigToHostInt16(toc->length) + sizeof(toc->length); buffer->release(); /* Reject the TOC if its size is too small: */ if (tocSize <= sizeof(CDTOC)) { return(kIOReturnNotFound); } /* Read the TOC in full: */ buffer = IOBufferMemoryDescriptor::withCapacity(tocSize,kIODirectionIn); if (buffer == NULL) { return(kIOReturnNoMemory); } result = getProvider()->readTOC(buffer); if (result != kIOReturnSuccess) { buffer->release(); return(result); } toc = (CDTOC *) IOMalloc(tocSize); if (toc == NULL) { buffer->release(); return(kIOReturnNoMemory); } if (buffer->readBytes(0,toc,tocSize) != tocSize) { buffer->release(); IOFree(toc,tocSize); return(kIOReturnNoMemory); } _toc = toc; _tocSize = tocSize; buffer->release(); return(result); }