32 |
#include <sys/disk.h> |
#include <sys/disk.h> |
33 |
#endif |
#endif |
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 |
|
|
47 |
static BlockDriverState *bdrv_first; |
static BlockDriverState *bdrv_first; |
48 |
static BlockDriver *first_drv; |
static BlockDriver *first_drv; |
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 |
|
|
108 |
void bdrv_register(BlockDriver *bdrv) |
void bdrv_register(BlockDriver *bdrv) |
109 |
{ |
{ |
110 |
bdrv->next = first_drv; |
bdrv->next = first_drv; |
188 |
bufsize = sectorsize; |
bufsize = sectorsize; |
189 |
} |
} |
190 |
#endif |
#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 |
197 |
buf = qemu_malloc(bufsize); |
buf = qemu_malloc(bufsize); |
198 |
if (!buf) |
if (!buf) |
199 |
return NULL; |
return NULL; |
221 |
|
|
222 |
int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot) |
int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot) |
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 |
250 |
return bdrv_open2(bs, filename, snapshot, NULL); |
return bdrv_open2(bs, filename, snapshot, NULL); |
251 |
} |
} |
252 |
|
|
669 |
#ifdef DIOCGMEDIASIZE |
#ifdef DIOCGMEDIASIZE |
670 |
if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) |
if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) |
671 |
#endif |
#endif |
672 |
size = lseek(fd, 0LL, SEEK_END); |
#ifdef CONFIG_COCOA |
673 |
|
size = LONG_LONG_MAX; |
674 |
|
#else |
675 |
|
size = lseek(fd, 0LL, SEEK_END); |
676 |
|
#endif |
677 |
} else |
} else |
678 |
#endif |
#endif |
679 |
{ |
{ |