Am Samstag, den 04.12.2010, 00:10 +0100 schrieb Michael Karcher: > > Thanks a lot for investigating into that. I would very glad if we can > > drop libscg in favor of dvd+rw-tools. > I did not yet implement the suggested change, but I am quite confident > that it will work. The attached patch makes sending an INQUIRY command to the attached Hi-MD walkman work. I did not test it with a CD drive yet (I might have broken that, although I doubt it), as the current design has the problem that it only works on drive with inserted media (as you specify the device using /dev/rdiskN, and this device does not exist if no medium is installed...) and the CD drive of the only Mac I have (remote) access to is currently empty. I will add later a function that allows specification of the IOKit device ID for attachment. Regards, Michael Karcher
--- transport.hxx.orig 2010-12-03 02:43:34.000000000 +0100 +++ transport.hxx 2010-12-05 01:50:29.000000000 +0100 @@ -1478,7 +1478,7 @@ io_object_t scsiob=IO_OBJECT_NULL,parent; CFMutableDictionaryRef match,bsddev; CFNumberRef num; - int i; + int i,res; if (ref) sb = *ref; else if (stat(file,&sb)) return 0; @@ -1511,32 +1511,51 @@ if ((scsiob = IOServiceGetMatchingService(kIOMasterPortDefault,match)) == IO_OBJECT_NULL) return !(errno=ENXIO); - // traverse up to "SCSITaskAuthoringDevice" + // Find a plugin of type MMCDeviceUserClientType or + // SCSITaskDeviceUserClientType by traversing the tree upwards. kern_return_t kret; + int found = 0; + CFStringRef mmctype = CFUUIDCreateString(kCFAllocatorDefault, + kIOMMCDeviceUserClientTypeID); + CFStringRef tasktype = CFUUIDCreateString(kCFAllocatorDefault, + kIOSCSITaskDeviceUserClientTypeID); while ((kret=IORegistryEntryGetParentEntry(scsiob,kIOServicePlane, - &parent)) == kIOReturnSuccess) - { CFStringRef uclient; - const char *s; - int cmp; + &parent)) == kIOReturnSuccess && !found) + { CFDictionaryRef plugins; IOObjectRelease(scsiob); scsiob = parent; - uclient = (CFStringRef)IORegistryEntryCreateCFProperty(scsiob, - CFSTR(kIOPropertySCSITaskDeviceCategory), + plugins = (CFDictionaryRef)IORegistryEntryCreateCFProperty(scsiob, + CFSTR(kIOCFPlugInTypesKey), kCFAllocatorDefault,0); - if (uclient) - { s = CFStringGetCStringPtr(uclient,kCFStringEncodingMacRoman); - cmp = strcmp(s,kIOPropertySCSITaskAuthoringDevice); - CFRelease(uclient); - if (cmp==0) break; + if (plugins) + { if (CFDictionaryContainsKey(plugins,mmctype)) + { res = attachViaMMC(scsiob); + found = 1; + } + if (CFDictionaryContainsKey(plugins,tasktype)) + { res = attachViaSCSITask(scsiob); + found = 1; + } + CFRelease(plugins); } } - if (kret!=kIOReturnSuccess) + CFRelease(tasktype); + CFRelease(mmctype); + if (!found) { if (scsiob!=IO_OBJECT_NULL) IOObjectRelease(scsiob); return !(errno=ENXIO); } + if (res) + { filename=strdup(file); + this->scsiob = scsiob; + } + return res; + } - SInt32 score=0; +private: + int attachViaMMC(io_object_t scsiob) + { SInt32 score=0; if (IOCreatePlugInInterfaceForService(scsiob, kIOMMCDeviceUserClientTypeID, kIOCFPlugInInterfaceID, @@ -1573,10 +1592,43 @@ return !(errno=EBUSY); } - filename=strdup(file); + return 1; + } + + int attachViaSCSITask(io_object_t scsiob) + { SInt32 score=0; + if (IOCreatePlugInInterfaceForService(scsiob, + kIOSCSITaskDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugin,&score) != kIOReturnSuccess) + { IOObjectRelease(scsiob); + return !(errno=ENXIO); + } + if ((*plugin)->QueryInterface(plugin, + CFUUIDGetUUIDBytes(kIOSCSITaskDeviceInterfaceID), + (void**)&taskif) != S_OK) + { IODestroyPlugInInterface(plugin), plugin=NULL; + IOObjectRelease(scsiob); + return !(errno=ENXIO); + } + + // + // Note that in order to ObtainExclusiveAccess no corresponding + // /dev/[r]diskN may remain open by that time. For reference, + // acquiring exclusive access temporarily removes BSD block + // storage device from I/O registry as well as corresponding + // /dev entries. + // + if ((*taskif)->ObtainExclusiveAccess(taskif) != kIOReturnSuccess) + { (*taskif)->Release(taskif), taskif=NULL; + IODestroyPlugInInterface(plugin), plugin=NULL; + IOObjectRelease(scsiob), scsiob=IO_OBJECT_NULL; + return !(errno=EBUSY); + } return 1; } +public: unsigned char &operator[] (size_t i) { if (i==0) { memset (cdb,0,sizeof(cdb));