Commit 3b0d4f61c917c4612b561d75b33a11f4da00738b

Authored by bellard
1 parent 87f48e6a

OS X: support for the built in CD-ROM drive (Mike Kronenberg)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1583 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 107 additions and 1 deletions
... ... @@ -32,9 +32,79 @@
32 32 #include <sys/disk.h>
33 33 #endif
34 34  
  35 +#ifdef CONFIG_COCOA
  36 +#include <paths.h>
  37 +#include <sys/param.h>
  38 +#include <IOKit/IOKitLib.h>
  39 +#include <IOKit/IOBSD.h>
  40 +#include <IOKit/storage/IOMediaBSDClient.h>
  41 +#include <IOKit/storage/IOMedia.h>
  42 +#include <IOKit/storage/IOCDMedia.h>
  43 +//#include <IOKit/storage/IOCDTypes.h>
  44 +#include <CoreFoundation/CoreFoundation.h>
  45 +#endif
  46 +
35 47 static BlockDriverState *bdrv_first;
36 48 static BlockDriver *first_drv;
37 49  
  50 +#ifdef CONFIG_COCOA
  51 +static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
  52 +static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
  53 +
  54 +kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
  55 +{
  56 + kern_return_t kernResult;
  57 + mach_port_t masterPort;
  58 + CFMutableDictionaryRef classesToMatch;
  59 +
  60 + kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
  61 + if ( KERN_SUCCESS != kernResult ) {
  62 + printf( "IOMasterPort returned %d\n", kernResult );
  63 + }
  64 +
  65 + classesToMatch = IOServiceMatching( kIOCDMediaClass );
  66 + if ( classesToMatch == NULL ) {
  67 + printf( "IOServiceMatching returned a NULL dictionary.\n" );
  68 + } else {
  69 + CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
  70 + }
  71 + kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
  72 + if ( KERN_SUCCESS != kernResult )
  73 + {
  74 + printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
  75 + }
  76 +
  77 + return kernResult;
  78 +}
  79 +
  80 +kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
  81 +{
  82 + io_object_t nextMedia;
  83 + kern_return_t kernResult = KERN_FAILURE;
  84 + *bsdPath = '\0';
  85 + nextMedia = IOIteratorNext( mediaIterator );
  86 + if ( nextMedia )
  87 + {
  88 + CFTypeRef bsdPathAsCFString;
  89 + bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
  90 + if ( bsdPathAsCFString ) {
  91 + size_t devPathLength;
  92 + strcpy( bsdPath, _PATH_DEV );
  93 + strcat( bsdPath, "r" );
  94 + devPathLength = strlen( bsdPath );
  95 + if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
  96 + kernResult = KERN_SUCCESS;
  97 + }
  98 + CFRelease( bsdPathAsCFString );
  99 + }
  100 + IOObjectRelease( nextMedia );
  101 + }
  102 +
  103 + return kernResult;
  104 +}
  105 +
  106 +#endif
  107 +
38 108 void bdrv_register(BlockDriver *bdrv)
39 109 {
40 110 bdrv->next = first_drv;
... ... @@ -118,6 +188,12 @@ static BlockDriver *find_image_format(const char *filename)
118 188 bufsize = sectorsize;
119 189 }
120 190 #endif
  191 +#ifdef CONFIG_COCOA
  192 + u_int32_t blockSize = 512;
  193 + if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
  194 + bufsize = blockSize;
  195 + }
  196 +#endif
121 197 buf = qemu_malloc(bufsize);
122 198 if (!buf)
123 199 return NULL;
... ... @@ -145,6 +221,32 @@ static BlockDriver *find_image_format(const char *filename)
145 221  
146 222 int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
147 223 {
  224 +#ifdef CONFIG_COCOA
  225 + if ( strncmp( filename, "/dev/cdrom", 10 ) == 0 ) {
  226 + kern_return_t kernResult;
  227 + io_iterator_t mediaIterator;
  228 + char bsdPath[ MAXPATHLEN ];
  229 + int fd;
  230 +
  231 + kernResult = FindEjectableCDMedia( &mediaIterator );
  232 + kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
  233 +
  234 + if ( bsdPath[ 0 ] != '\0' ) {
  235 + strcat(bsdPath,"s0");
  236 + /* some CDs don't have a partition 0 */
  237 + fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
  238 + if (fd < 0) {
  239 + bsdPath[strlen(bsdPath)-1] = '1';
  240 + } else {
  241 + close(fd);
  242 + }
  243 + filename = bsdPath;
  244 + }
  245 +
  246 + if ( mediaIterator )
  247 + IOObjectRelease( mediaIterator );
  248 + }
  249 +#endif
148 250 return bdrv_open2(bs, filename, snapshot, NULL);
149 251 }
150 252  
... ... @@ -567,7 +669,11 @@ static int raw_open(BlockDriverState *bs, const char *filename)
567 669 #ifdef DIOCGMEDIASIZE
568 670 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
569 671 #endif
570   - size = lseek(fd, 0LL, SEEK_END);
  672 +#ifdef CONFIG_COCOA
  673 + size = LONG_LONG_MAX;
  674 +#else
  675 + size = lseek(fd, 0LL, SEEK_END);
  676 +#endif
571 677 } else
572 678 #endif
573 679 {
... ...