1/* 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// AppleCDDAFileSystemUtilities.cpp created by CJS on Fri 19-May-2000 25 26// Project Includes 27#ifndef __APPLE_CDDA_FS_UTILS_H__ 28#include "AppleCDDAFileSystemUtils.h" 29#endif 30 31#ifndef __APPLE_CDDA_FS_DEBUG_H__ 32#include "AppleCDDAFileSystemDebug.h" 33#endif 34 35// System Includes 36#include <libkern/c++/OSData.h> 37#include <libkern/c++/OSObject.h> 38#include <libkern/c++/OSIterator.h> 39#include <libkern/c++/OSDictionary.h> 40#include <IOKit/IOLib.h> 41#include <IOKit/IOService.h> 42#include <IOKit/storage/IOCDMedia.h> 43#include <IOKit/IORegistryEntry.h> 44 45 46//----------------------------------------------------------------------------- 47// Static Function Prototypes 48//----------------------------------------------------------------------------- 49 50 51static QTOCDataFormat10Ptr CreateBufferFromData ( OSData * theData ); 52static IOCDMedia * GetCDMediaObjectFromName ( const char * ioBSDNamePtr ); 53 54 55//----------------------------------------------------------------------------- 56// CreateBufferFromIORegistry - Allocates memory for a C-string and copies 57// the contents of the IORegistryEntry to it. 58// 59// NB: The calling function should dispose of the memory by calling IOFree 60//----------------------------------------------------------------------------- 61 62QTOCDataFormat10Ptr 63CreateBufferFromIORegistry ( mount_t mountPtr ) 64{ 65 66 QTOCDataFormat10Ptr TOCDataPtr = NULL; 67 OSObject * objectPtr = NULL; 68 OSData * dataPtr = NULL; 69 IOCDMedia * cdMediaPtr = NULL; 70 char * ioBSDNamePtr = NULL; 71 72 DebugLog ( ( "CreateBufferFromIORegistry: Entering...\n" ) ); 73 74 DebugAssert ( ( mountPtr != NULL ) ); 75 76 ioBSDNamePtr = vfs_statfs ( mountPtr )->f_mntfromname; 77 DebugAssert ( ( ioBSDNamePtr != NULL ) ); 78 79 cdMediaPtr = GetCDMediaObjectFromName ( ioBSDNamePtr ); 80 DebugAssert ( ( cdMediaPtr != NULL ) ); 81 82 if ( cdMediaPtr != NULL ) 83 { 84 85 // Get the TOC property 86 objectPtr = cdMediaPtr->getProperty ( kIOCDMediaTOCKey ); 87 if ( objectPtr == NULL ) 88 { 89 90 DebugLog ( ( "CreateBufferFromIORegistry: objectPtr is NULL.\n" ) ); 91 return NULL; 92 93 } 94 95 // Cast it to an OSData * 96 dataPtr = OSDynamicCast ( OSData, objectPtr ); 97 if ( dataPtr == NULL ) 98 { 99 100 DebugLog ( ( "CreateBufferFromIORegistry: dataPtr is NULL.\n" ) ); 101 return NULL; 102 103 } 104 105 // Get the data from the registry entry 106 TOCDataPtr = CreateBufferFromData ( dataPtr ); 107 108 DebugLog ( ( "Releasing refcsount on IOCDMedia.\n" ) ); 109 cdMediaPtr->release ( ); 110 111 } 112 113 DebugLog ( ( "CreateBufferFromIORegistry: exiting...\n" ) ); 114 115 return TOCDataPtr; 116 117} 118 119 120//----------------------------------------------------------------------------- 121// DisposeBufferFromIORegistry - Frees memory occupied by data structure 122//----------------------------------------------------------------------------- 123 124void 125DisposeBufferFromIORegistry ( QTOCDataFormat10Ptr TOCDataPtr ) 126{ 127 128 DebugLog ( ( "DisposeBufferFromIORegistry: Entering...\n" ) ); 129 130 DebugAssert ( ( TOCDataPtr != NULL ) ); 131 132 // Free the correct number of bytes. The TOCData has a length word 133 // for its first field, so we free the number of bytes specified by 134 // the length word, plus the length word itself. 135 IOFree ( TOCDataPtr, 136 ( OSSwapBigToHostInt16 ( TOCDataPtr->TOCDataLength ) + sizeof ( TOCDataPtr->TOCDataLength ) ) ); 137 138 DebugLog ( ( "DisposeBufferFromIORegistry: Exiting...\n" ) ); 139 140} 141 142#if 0 143#pragma mark - 144#endif 145 146 147//----------------------------------------------------------------------------- 148// CreateBufferFromData - Allocates memory for a C-string and copies 149// the contents of the IORegistryEntry to it. 150// 151// NB: The calling function should dispose of the memory by calling IOFree 152//----------------------------------------------------------------------------- 153 154QTOCDataFormat10Ptr 155CreateBufferFromData ( OSData * theData ) 156{ 157 158 vm_size_t bufferLength = 0; 159 QTOCDataFormat10Ptr buffer = NULL; 160 161 DebugLog ( ( "CreateBufferFromData: Entering...\n" ) ); 162 163 DebugAssert ( ( theData != NULL ) ); 164 165 if ( theData == NULL ) 166 { 167 168 DebugLog ( ( "CreateBufferFromData: theData is NULL.\n" ) ); 169 return NULL; 170 171 } 172 173 bufferLength = theData->getLength ( ); 174 buffer = ( QTOCDataFormat10Ptr ) IOMalloc ( bufferLength ); 175 176 if ( buffer != NULL ) 177 { 178 179 // Copy the bytes into the buffer 180 bcopy ( theData->getBytesNoCopy ( ), buffer, bufferLength ); 181 182 } 183 184 DebugLog ( ( "CreateBufferFromData: exiting.\n" ) ); 185 186 return buffer; 187 188} 189 190 191//----------------------------------------------------------------------------- 192// GetCDMediaObjectFromName - Uses the BSD name to get a reference to the 193// corresponding IOCDMedia object 194//----------------------------------------------------------------------------- 195 196IOCDMedia * 197GetCDMediaObjectFromName ( const char * ioBSDNamePtr ) 198{ 199 200 OSIterator * iteratorPtr = NULL; 201 IORegistryEntry * registryEntryPtr = NULL; 202 IOCDMedia * objectPtr = NULL; 203 OSDictionary * matchingDictPtr = NULL; 204 205 DebugLog ( ( "GetCDMediaObjectFromName: Entering...\n" ) ); 206 207 DebugAssert ( ( ioBSDNamePtr != NULL ) ); 208 209 DebugLog ( ( "GetCDMediaObjectFromName: On enter ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); 210 211 // Check to see if we need to strip off any leading stuff 212 if ( !strncmp ( ioBSDNamePtr, "/dev/r", 6 ) ) 213 { 214 215 // Strip off the /dev/r from /dev/rdiskX 216 ioBSDNamePtr = &ioBSDNamePtr[6]; 217 218 } 219 220 else if ( !strncmp ( ioBSDNamePtr, "/dev/", 5 ) ) 221 { 222 223 // Strip off the /dev/ from /dev/diskX 224 ioBSDNamePtr = &ioBSDNamePtr[5]; 225 226 } 227 228 if ( strncmp ( ioBSDNamePtr, "disk", 4 ) ) 229 { 230 231 // Not in correct format, return NULL 232 DebugLog ( ( "GetCDMediaObjectFromName: not in correct format, ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); 233 234 return NULL; 235 236 } 237 238 DebugLog ( ( "GetCDMediaObjectFromName: ioBSDNamePtr = %s.\n", ioBSDNamePtr ) ); 239 240 // Get a dictionary which describes the bsd device 241 matchingDictPtr = IOBSDNameMatching ( ioBSDNamePtr ); 242 243 // Get an iterator of registry entries 244 iteratorPtr = IOService::getMatchingServices ( matchingDictPtr ); 245 if ( iteratorPtr == NULL ) 246 { 247 248 DebugLog ( ( "GetCDMediaObjectFromName: iteratorPtr is NULL.\n" ) ); 249 return NULL; 250 251 } 252 253 // Release the dictionary 254 matchingDictPtr->release ( ); 255 256 DebugLog ( ( "Acquired refcount on iterator and media.\n" ) ); 257 258 // Get the object out of the iterator (NB: we're guaranteed only one object in the iterator 259 // because there is a 1:1 correspondence between BSD Names for devices and IOKit objects 260 registryEntryPtr = ( IORegistryEntry * ) iteratorPtr->getNextObject ( ); 261 if ( registryEntryPtr == NULL ) 262 { 263 264 DebugLog ( ( "GetCDMediaObjectFromName: registryEntryPtr is NULL.\n" ) ); 265 return NULL; 266 267 } 268 269 // Cast it to the correct type 270 objectPtr = OSDynamicCast ( IOCDMedia, registryEntryPtr ); 271 if ( objectPtr == NULL ) 272 { 273 274 // Cast failed...spew an error 275 DebugLog ( ( "GetCDMediaObjectFromName: objectPtr is NULL, Dynamic Cast failed.\n" ) ); 276 277 } 278 279 DebugLog ( ( "GetCDMediaObjectFromName: exiting...\n" ) ); 280 281 // Bump the refcount on the CDMedia so that when we release the iterator 282 // we still have a refcount on it. 283 if ( objectPtr != NULL ) 284 { 285 286 objectPtr->retain ( ); 287 288 } 289 290 // Release the iterator 291 iteratorPtr->release ( ); 292 293 return ( objectPtr ); 294 295} 296 297 298//----------------------------------------------------------------------------- 299// End Of File 300//----------------------------------------------------------------------------- 301