Exemplo n.º 1
0
DADissenterRef BlockMount(DADiskRef disk, void *context)
{
	CFDictionaryRef description = DADiskCopyDescription(disk);
	CFStringRef name = description ? CFDictionaryGetValue(description, kDADiskDescriptionVolumeNameKey) : NULL;
	DADissenterRef dissenter = NULL;
	bool block = false;
	char *str = NULL;
	if (name) {
		int i;
		CFIndex length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8);
		str = alloca(length + 1);
		CFStringGetCString(name, str, length, kCFStringEncodingUTF8);
		for (i = 0; i < nameCount; i++) {
			if (CFEqual(name, names[i])) {
				block = true;
				break;
			}
		}
	}
	if (block) {
		dissenter = DADissenterCreate(kCFAllocatorDefault, kDAReturnNotPermitted, NULL);
		if(!quiet) if(!quiet) fprintf(stderr, "BLOCKED volume `%s'\n", str);
	} else {
		if(!quiet) if(!quiet) fprintf(stderr, "allowed volume `%s'\n", str);
	}
	if (description) {
		CFRelease(description);
	}
	return dissenter;
}
Exemplo n.º 2
0
static void
disk_appeared_cb(DADiskRef disk, void *ctx)
{
	CFDictionaryRef description = NULL;
	CFBooleanRef mountable;
	CFStringRef content = NULL;

	if (!ctx || !disk) return;

	description = DADiskCopyDescription(disk);
	if (!description) return;

	mountable = CFDictionaryGetValue(description, kDADiskDescriptionVolumeMountableKey);
	if (!mountable) goto out;
	content = CFDictionaryGetValue(description, kDADiskDescriptionMediaContentKey);
	if (!content) goto out;

	if (CFBooleanGetValue(mountable) &&
	        CFStringCompare(content, CFSTR("53746F72-6167-11AA-AA11-00306543ECAC"),
	        kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
	        CFStringCompare(content, CFSTR("426F6F74-0000-11AA-AA11-00306543ECAC"),
	        kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
		/* The disk is marked mountable and isn't CoreStorage or Apple_Boot,
		 * which means that it actually is mountable (since we lie and mark
		 * CoreStorage disks as mountable). */
		*((bool *)ctx) = true;
	}

out:
	if (description)
		CFRelease(description);
}
Exemplo n.º 3
0
void CDarwinStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives)
{
#if defined(TARGET_DARWIN_OSX)

  if (CDarwinUtils::IsLion())  
    return; //temp workaround for crash in Cocoa_GetVolumeNameFromMountPoint on 10.7.x  

  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  if (session)
  {
    unsigned i, count = 0;
    struct statfs *buf = NULL;
    std::string mountpoint, devicepath;

    count = getmntinfo(&buf, 0);
    for (i=0; i<count; i++)
    {
      mountpoint = buf[i].f_mntonname;
      devicepath = buf[i].f_mntfromname;

      DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, devicepath.c_str());
      if (disk)
      {
        CFDictionaryRef details = DADiskCopyDescription(disk);
        if (details)
        {
          if (kCFBooleanTrue == CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
          {
            CMediaSource share;

            share.strPath = mountpoint;
            Cocoa_GetVolumeNameFromMountPoint(mountpoint.c_str(), share.strName);
            share.m_ignore = true;
            // detect if its a cd or dvd
            // needs to be ejectable
            if (kCFBooleanTrue == CFDictionaryGetValue(details, kDADiskDescriptionMediaEjectableKey))
            {
              CFStringRef mediaKind = (CFStringRef)CFDictionaryGetValue(details, kDADiskDescriptionMediaKindKey);
              // and either cd or dvd kind of media in it
              if (mediaKind != NULL &&
                  (CFStringCompare(mediaKind, CFSTR(kIOCDMediaClass), 0) == kCFCompareEqualTo ||
                  CFStringCompare(mediaKind, CFSTR(kIODVDMediaClass), 0) == kCFCompareEqualTo))
                share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
            }
            removableDrives.push_back(share);
          }
          CFRelease(details);
        }
        CFRelease(disk);
      }
    }

    CFRelease(session);
  }
#endif
}
Exemplo n.º 4
0
void DiskArbitrationEventPublisher::DiskAppearedCallback(DADiskRef disk,
                                                         void* context) {
  auto ec = createEventContext();

  CFDictionaryRef disk_properties = DADiskCopyDescription(disk);
  CFTypeRef devicePathKey;
  if (!CFDictionaryGetValueIfPresent(
          disk_properties, kDADiskDescriptionDevicePathKey, &devicePathKey)) {
    CFRelease(disk_properties);
    return;
  }

  auto device_path = stringFromCFString((CFStringRef)devicePathKey);
  ec->device_path = device_path;

  auto entry =
      IORegistryEntryFromPath(kIOMasterPortDefault, device_path.c_str());
  if (entry == MACH_PORT_NULL) {
    CFRelease(disk_properties);
    return;
  }

  auto protocol_properties = (CFDictionaryRef)IORegistryEntryCreateCFProperty(
      entry,
      CFSTR(kIOPropertyProtocolCharacteristicsKey_),
      kCFAllocatorDefault,
      kNilOptions);

  if (protocol_properties != nullptr) {
    CFDataRef path = (CFDataRef)CFDictionaryGetValue(
        protocol_properties, CFSTR(kVirtualInterfaceLocation_));
    if (path != nullptr) {
      ec->path = stringFromCFData(path);
      // extract checksum once on the whole disk and not for every partition
      if (CFBooleanGetValue((CFBooleanRef)CFDictionaryGetValue(
              disk_properties, kDADiskDescriptionMediaWholeKey))) {
        ec->checksum = extractUdifChecksum(ec->path);
      }
    } else {
      // There was no interface location.
      ec->path = getProperty(kDADiskDescriptionDevicePathKey, disk_properties);
    }
    CFRelease(protocol_properties);
  } else {
    ec->path = "";
  }

  if (ec->path.find("/SSD0@0") == std::string::npos) {
    // This is not an internal SSD.
    fire("add", ec, disk_properties);
  }

  CFRelease(disk_properties);
  IOObjectRelease(entry);
}
Exemplo n.º 5
0
static void scan_disk_appeared_cb(DADiskRef disk, void *c)
{
    struct scan_context *context = (struct scan_context *) c;
    int ix = context->count;
    if (ix < context->max_devices) {
        sprintf(context->devices[ix].path, "/dev/r%s", DADiskGetBSDName(disk));

        CFDictionaryRef info = DADiskCopyDescription(disk);
        CFNumberRef cfsize = CFDictionaryGetValue(info, kDADiskDescriptionMediaSizeKey);
        int64_t size;
        CFNumberGetValue(cfsize, kCFNumberSInt64Type, &size);
        context->devices[ix].size = size;
        CFRelease(info);

        context->count++;
    }
}
Exemplo n.º 6
0
/*
 * Check if there are any mountable partitions on the disk. If there are any
 * mountable partitions, then we don't want to display the dialog. CoreStorage
 * and Apple_Boot partitions don't count as mountable for our purposes.
 */
static bool
check_all_partitions(char *devname)
{
	bool found_mountable_fs = false;
	SInt32 rc;
	CFNumberRef num = NULL;
	CFDictionaryRef description = NULL, matchDict = NULL;

	DASessionRef session = (DASessionRef)0;
	DADiskRef disk = (DADiskRef)0;

	session = DASessionCreate(kCFAllocatorDefault);
	if (session == (DASessionRef)0)
		goto exit;

	disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, devname);
	if (disk == (DADiskRef)0)
		goto exit;

	description = DADiskCopyDescription(disk);
	num = CFDictionaryGetValue(description, kDADiskDescriptionMediaBSDUnitKey);
	matchDict = CFDictionaryCreate(kCFAllocatorDefault,
	    (const void **)&kDADiskDescriptionMediaBSDUnitKey,
	    (const void **)&num, 1, &kCFTypeDictionaryKeyCallBacks,
	    &kCFTypeDictionaryValueCallBacks);

	DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
	DARegisterIdleCallback(session, idle_cb, &found_mountable_fs);
	DARegisterDiskAppearedCallback(session, matchDict, disk_appeared_cb, &found_mountable_fs);
	rc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
	DAUnregisterCallback(session, idle_cb, &found_mountable_fs);
	DAUnregisterCallback(session, disk_appeared_cb, &found_mountable_fs);
	DASessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

exit:
	if (disk)
		CFRelease(disk);
	if (session)
		CFRelease(session);
	if (description)
		CFRelease(description);
	if (matchDict)
		CFRelease(matchDict);

	return (!found_mountable_fs);
}
Exemplo n.º 7
0
void diskChangedCallback(DADiskRef disk, CFArrayRef keys, void *context)
{
    if (CFArrayContainsValue(keys, CFRangeMake(0, CFArrayGetCount(keys)),
                             kDADiskDescriptionVolumeNameKey))
    {
        const char     *BSDname = DADiskGetBSDName(disk);
        CFDictionaryRef details = DADiskCopyDescription(disk);
        char           *volName = getVolName(details);

        LOG(VB_MEDIA, LOG_INFO, QString("Disk %1 - changed name to '%2'.")
                          .arg(BSDname).arg(volName));

        reinterpret_cast<MonitorThreadDarwin *>(context)
            ->diskRename(BSDname, volName);
        CFRelease(details);
        free(volName);
    }
}
Exemplo n.º 8
0
QString DeviceInfo::deviceId() const
{
    QString uuid;

    DADiskRef disk;
    CFDictionaryRef descDict;
    DASessionRef session = DASessionCreate(NULL);

    if (session)
    {
        const char *mountPoint = "/";
        CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)mountPoint, strlen(mountPoint), TRUE);
        disk = DADiskCreateFromVolumePath(NULL, session, url);
        CFRelease(url);

        if (disk)
        {
            descDict = DADiskCopyDescription(disk);

            if (descDict)
            {
                CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(descDict,
                                                                  CFSTR("DAVolumeUUID"));
                CFStringRef strValue = CFStringCreateWithFormat(NULL, NULL,
                                                                CFSTR("%@"), value);

                uuid = QString::fromCFString(strValue);

                CFRelease(strValue);
                CFRelease(descDict);
            }

            CFRelease(disk);
        }

        CFRelease(session);
    }

    QCryptographicHash hash(QCryptographicHash::Sha224);
    hash.addData(uuid.toLatin1());

    return QString::fromLatin1(hash.result().toHex());
}
Exemplo n.º 9
0
void CDarwinStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives)
{
#if defined(TARGET_DARWIN_OSX)
  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  if (session)
  {
    unsigned i, count = 0;
    struct statfs *buf = NULL;
    std::string mountpoint, devicepath;

    count = getmntinfo(&buf, 0);
    for (i=0; i<count; i++)
    {
      mountpoint = buf[i].f_mntonname;
      devicepath = buf[i].f_mntfromname;

      DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, devicepath.c_str());
      if (disk)
      {
        CFDictionaryRef details = DADiskCopyDescription(disk);
        if (details)
        {
          if (kCFBooleanTrue == CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
          {
            CMediaSource share;

            share.strPath = mountpoint;
            Cocoa_GetVolumeNameFromMountPoint(mountpoint.c_str(), share.strName);
            share.m_ignore = true;
            removableDrives.push_back(share);
          }
          CFRelease(details);
        }
        CFRelease(disk);
      }
    }

    CFRelease(session);
  }
#endif
}
static bool weLikeTheDisk(DADiskRef disk)
{
    CFDictionaryRef     description = NULL;
    CFStringRef         protocol = NULL;
    bool                ret = false;

    /*
    We will create an ExternalMedia assertion if any of these disks are present.
    That will prevent deep sleep.     
      USB hard drive    : Protocol = USB
      USB thumb drive   : Protocol = USB 
      SD Card           : Protocol = USB, Protocol = Secure Digital 
      External drive    : Interconnect Location = External

    These disks do not cause us to create an ExternalMedia assertion;
      CD/DVD            : Protocol = ATAPI
      Disk Image        : Protocol = Disk Image
    */
    
    description = DADiskCopyDescription(disk);
    if (description) {
        
        if (CFDictionaryGetValue(description, kDADiskDescriptionDeviceInternalKey) == kCFBooleanFalse) {
            ret = true;
        } else {
            protocol = CFDictionaryGetValue(description, kDADiskDescriptionDeviceProtocolKey);

            if (protocol &&
                (CFEqual(protocol, CFSTR(kIOPropertyPhysicalInterconnectTypeUSB)) ||
                 CFEqual(protocol, CFSTR(kIOPropertyPhysicalInterconnectTypeSecureDigital))))
            {
                ret = true;
            }
        }

        CFRelease(description);
    }
    return ret;
}
Exemplo n.º 11
0
int
main(int argc, char **argv)
{
    int              ret      = -1;
    DASessionRef     session  = NULL;
    DADiskRef        disk     = NULL;
    CFDictionaryRef  diskInfo = NULL;
    char            *diskName = DEFAULT_DISK_NAME;
   
    // create a new Disk Arbitration session
    session = DASessionCreate(kCFAllocatorDefault);
    OUT_ON_NULL(session, "failed to create Disk Arbitration session");
   
    if (argc == 2)
        diskName = argv[1];
   
    // create a new disk object from the given BSD device name
    disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, diskName);
    OUT_ON_NULL(disk, "failed to create disk object");
   
    // obtain disk's description
    diskInfo = DADiskCopyDescription(disk);
    OUT_ON_NULL(diskInfo, "failed to retrieve disk description");
   
    ret = printDictionaryAsXML(diskInfo);
   
out:
    if (diskInfo)
        CFRelease(diskInfo);
    if (disk)
        CFRelease(disk);
    if (session)
        CFRelease(session);
   
    exit(ret);
}
Exemplo n.º 12
0
void CDarwinStorageProvider::GetLocalDrives(VECSOURCES &localDrives)
{
  CMediaSource share;

  // User home folder
  #ifdef TARGET_DARWIN_IOS
    share.strPath = "special://envhome/";
  #else
    share.strPath = getenv("HOME");
  #endif
  share.strName = g_localizeStrings.Get(21440);
  share.m_ignore = true;
  localDrives.push_back(share);

#if defined(TARGET_DARWIN_IOS)
  // iOS Inbox folder
  share.strPath = "special://envhome/Documents/Inbox";
  share.strName = "Inbox";
  share.m_ignore = true;
  localDrives.push_back(share);
#endif

#if defined(TARGET_DARWIN_OSX)
  // User desktop folder
  share.strPath = getenv("HOME");
  share.strPath += "/Desktop";
  share.strName = "Desktop";
  share.m_ignore = true;
  localDrives.push_back(share);

  // Volumes (all mounts are present here)
  share.strPath = "/Volumes";
  share.strName = "Volumes";
  share.m_ignore = true;
  localDrives.push_back(share);

  // This will pick up all local non-removable disks including the Root Disk.
  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  if (session)
  {
    unsigned i, count = 0;
    struct statfs *buf = NULL;
    std::string mountpoint, devicepath;

    count = getmntinfo(&buf, 0);
    for (i=0; i<count; i++)
    {
      mountpoint = buf[i].f_mntonname;
      devicepath = buf[i].f_mntfromname;

      DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, devicepath.c_str());
      if (disk)
      {
        CFDictionaryRef details = DADiskCopyDescription(disk);
        if (details)
        {
          if (kCFBooleanFalse == CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
          {
            CMediaSource share;

            share.strPath = mountpoint;
            Cocoa_GetVolumeNameFromMountPoint(mountpoint.c_str(), share.strName);
            share.m_ignore = true;
            localDrives.push_back(share);
          }
          CFRelease(details);
        }
        CFRelease(disk);
      }
    }

    CFRelease(session);
  }
#endif
}
Exemplo n.º 13
0
void diskAppearedCallback(DADiskRef disk, void *context)
{
    const char          *BSDname = DADiskGetBSDName(disk);
    CFDictionaryRef      details;
    bool                 isCDorDVD;
    MythMediaType        mediaType;
    QString              model;
    MonitorThreadDarwin *mtd;
    QString              msg = "diskAppearedCallback() - ";
    char                *volName;


    if (!BSDname)
    {
        LOG(VB_MEDIA, LOG_INFO, msg + "Skipping non-local device");
        return;
    }

    if (!context)
    {
        LOG(VB_GENERAL, LOG_ALERT, msg + "Error. Invoked with a NULL context.");
        return;
    }

    mtd = reinterpret_cast<MonitorThreadDarwin*>(context);


    // We want to monitor CDs/DVDs and USB cameras or flash drives,
    // but probably not hard disk or network drives. For now, ignore
    // any disk or partitions that are not on removable media.
    // Seems OK for hot-plug USB/FireWire disks (i.e. they are removable)

    details = DADiskCopyDescription(disk);

    if (kCFBooleanFalse ==
        CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
    {
        LOG(VB_MEDIA, LOG_INFO, msg + QString("Skipping non-removable %1")
            .arg(BSDname));
        CFRelease(details);
        return;
    }

    // Get the volume and model name for more user-friendly interaction
    volName = getVolName(details);
    if (!volName)
    {
        LOG(VB_MEDIA, LOG_INFO, msg + QString("No volume name for dev %1")
            .arg(BSDname));
        CFRelease(details);
        return;
    }

    model     = getModel(details);
    mediaType = MediaTypeForBSDName(BSDname);
    isCDorDVD = (mediaType == MEDIATYPE_DVD) || (mediaType == MEDIATYPE_AUDIO);


    // We know it is removable, and have guessed the type.
    // Call a helper function to create appropriate objects and insert 

    LOG(VB_MEDIA, LOG_INFO, QString("Found disk %1 - volume name '%2'.")
                      .arg(BSDname).arg(volName));

    mtd->diskInsert(BSDname, volName, model, isCDorDVD);

    CFRelease(details);
    free(volName);
}
Exemplo n.º 14
0
__private_extern__ DAReturn _DAAuthorize( DASessionRef session, _DAAuthorizeOptions options, DADiskRef disk, const char * right )
{
    DAReturn status;

    status = kDAReturnNotPrivileged;

    if ( status )
    {
        if ( ( options & _kDAAuthorizeOptionIsOwner ) )
        {
            uid_t diskUID;

            status = _DAServerDiskGetUserUID( _DADiskGetSessionID( disk ), _DADiskGetID( disk ), &diskUID );

            if ( status )
            {
                return status;
            }

            status = kDAReturnNotPrivileged;

            if ( diskUID == geteuid( ) )
            {
                status = kDAReturnSuccess;
            }
        }
    }

    if ( status )
    {
        AuthorizationRef authorization;

        authorization = _DASessionGetAuthorization( session );

        if ( authorization )
        {
            CFDictionaryRef description;

            description = DADiskCopyDescription( disk );

            if ( description )
            {
                AuthorizationFlags  flags;
                AuthorizationItem   item;
                char *              name;
                AuthorizationRights rights;

                flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize;

                {
                    CFTypeRef object;

                    object = CFDictionaryGetValue( description, kDADiskDescriptionDeviceProtocolKey );

                    if ( object && CFEqual( object, CFSTR( kIOPropertyPhysicalInterconnectTypeVirtual ) ) )
                    {
                        asprintf( &name, "system.volume.virtual.%s", right );
                    }
                    else
                    {
                        if ( CFDictionaryGetValue( description, kDADiskDescriptionMediaRemovableKey ) == kCFBooleanTrue )
                        {
                            asprintf( &name, "system.volume.removable.%s", right );
                        }
                        else
                        {
                            if ( CFDictionaryGetValue( description, kDADiskDescriptionDeviceInternalKey ) == kCFBooleanTrue )
                            {
                                asprintf( &name, "system.volume.internal.%s", right );
                            }
                            else
                            {
                                asprintf( &name, "system.volume.external.%s", right );
                            }
                        }
                    }
                }

                if ( name )
                {
                    item.flags       = 0;
                    item.name        = name;
                    item.value       = NULL;
                    item.valueLength = 0;

                    rights.count = 1;
                    rights.items = &item;

                    status = AuthorizationCopyRights( authorization, &rights, NULL, flags, NULL ); 

                    if ( status )
                    {
                        status = kDAReturnNotPrivileged;
                    }

                    free( name );
                }

                CFRelease( description );
            }
        }
    }

    return status;
}
// first look up the media object, then create a
// custom matching dictionary that should be persistent
// from boot to boot
int addMatchingInfoForBSDName(BLContextPtr context,
			      mach_port_t masterPort,
			      CFMutableDictionaryRef dict,
			      const char *bsdName,
                  bool shortForm)
{
    io_service_t                media = IO_OBJECT_NULL, checkMedia = IO_OBJECT_NULL;
    CFStringRef                 uuid = NULL;
    CFMutableDictionaryRef      propDict = NULL;
    kern_return_t               kret;
    CFStringRef			lastBSDName = NULL;

    lastBSDName = CFStringCreateWithCString(kCFAllocatorDefault,
					    bsdName,
					    kCFStringEncodingUTF8);

    propDict = IOBSDNameMatching(masterPort, 0, bsdName);
    CFDictionarySetValue(propDict, CFSTR(kIOProviderClassKey), CFSTR(kIOMediaClass));
    
    media = IOServiceGetMatchingService(masterPort,
                                        propDict);
    propDict = NULL;
    
    if(media == IO_OBJECT_NULL) {
        contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", bsdName);
        CFRelease(lastBSDName);
        return 1;
    }
    
    uuid = IORegistryEntryCreateCFProperty(media, CFSTR(kIOMediaUUIDKey),
                                           kCFAllocatorDefault, 0);
    if(uuid == NULL) {
        CFUUIDRef       fsuuid = NULL;
		CFStringRef     fsuuidstr = NULL;        
		io_string_t path;
#if USE_DISKARBITRATION
        DASessionRef    session = NULL;
        DADiskRef       dadisk = NULL;
		
        contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a partition %s\n",
                      bsdName, kIOMediaUUIDKey);
		
        session = DASessionCreate(kCFAllocatorDefault);
        if(session) {
            dadisk = DADiskCreateFromIOMedia(kCFAllocatorDefault, session, 
                                             media);
            if(dadisk) {
                CFDictionaryRef descrip = DADiskCopyDescription(dadisk);
                if(descrip) {
                    fsuuid = CFDictionaryGetValue(descrip, kDADiskDescriptionVolumeUUIDKey);
                    
                    if(fsuuid)
                        CFRetain(fsuuid);
                    CFRelease(descrip);
                }
                
                CFRelease(dadisk);
            }
            
            CFRelease(session);
        }
#endif // USE_DISKARBITRATION
		
        if(fsuuid) {
            char        fsuuidCString[64];
			
            fsuuidstr = CFUUIDCreateString(kCFAllocatorDefault, fsuuid);
            
            CFStringGetCString(fsuuidstr,fsuuidCString,sizeof(fsuuidCString),kCFStringEncodingUTF8);
            
            contextprintf(context, kBLLogLevelVerbose, "DADiskRef %s has Volume UUID %s\n",
                          bsdName, fsuuidCString);
            
            CFRelease(fsuuid);
		} else {
            contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have a Volume UUID\n",
                          bsdName);
		}
		
		
		// we have a volume UUID, but our primary matching mechanism will be the device path
		
		kret = IORegistryEntryGetPath(media, kIODeviceTreePlane,path);
		if(kret) {
			contextprintf(context, kBLLogLevelVerbose, "IOMedia %s does not have device tree path\n",
						  bsdName);
			
			propDict = IOServiceMatching(kIOMediaClass);
			CFDictionaryAddValue(propDict,  CFSTR(kIOBSDNameKey), lastBSDName);
			
			// add UUID as hint
			if(fsuuidstr)
				CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr);
			
		} else {
			CFStringRef blpath = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
			
			contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has path %s\n",
						  bsdName, path);
			
			propDict = IOServiceMatching(kIOMediaClass);
			CFDictionaryAddValue(propDict, CFSTR(kIOPathMatchKey), blpath);
			CFRelease(blpath);
			
			// add UUID as hint
			if(fsuuidstr)
				CFDictionaryAddValue(dict, CFSTR("BLVolumeUUID"), fsuuidstr);
			
			CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName);
		}
		
		if(fsuuidstr) {
			CFRelease(fsuuidstr);
		}
		
    } else {
      CFMutableDictionaryRef propMatch;

        contextprintf(context, kBLLogLevelVerbose, "IOMedia %s has UUID %s\n",
                      bsdName, BLGetCStringDescription(uuid));

        propMatch = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                              &kCFTypeDictionaryKeyCallBacks,
                              &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(propMatch, CFSTR(kIOMediaUUIDKey), uuid);

        propDict = IOServiceMatching(kIOMediaClass);
        CFDictionaryAddValue(propDict,  CFSTR(kIOPropertyMatchKey), propMatch);
        CFRelease(propMatch);

        // add a hint to the top-level dict
        CFDictionaryAddValue(dict, CFSTR("BLLastBSDName"), lastBSDName);

        CFRelease(uuid);
    }

    // verify the dictionary matches
    CFRetain(propDict); // consumed below
    checkMedia = IOServiceGetMatchingService(masterPort,
					     propDict);
    
    if(IO_OBJECT_NULL == checkMedia
       || !IOObjectIsEqualTo(media, checkMedia)) {
      contextprintf(context, kBLLogLevelVerbose, "Inconsistent registry entries for %s\n",
		    bsdName);
      
      if(IO_OBJECT_NULL != checkMedia) IOObjectRelease(checkMedia);
      IOObjectRelease(media);
      CFRelease(lastBSDName);
      CFRelease(propDict);
      
      return 2;
    }
    
    IOObjectRelease(checkMedia);
    IOObjectRelease(media);

    CFDictionaryAddValue(dict, CFSTR("IOMatch"), propDict);        
    CFRelease(lastBSDName);
    CFRelease(propDict);

    if(shortForm) {
        CFDictionaryAddValue(dict, CFSTR("IOEFIShortForm"), kCFBooleanTrue);
    }
    
    return 0;
}
Exemplo n.º 16
0
static int updateAppleBootIfPresent(BLContextPtr context, char *device, CFDataRef bootxData,
									CFDataRef labelData)
{
	char booterDev[MAXPATHLEN];
	io_service_t            service = 0;
	CFStringRef				name = NULL;
	int32_t					needsBooter	= 0;
	int32_t					isBooter	= 0;
	BLUpdateBooterFileSpec	*spec = NULL;
	int32_t					specCount = 0, currentCount = 0;
	
	int ret;
	
	strlcpy(booterDev, "/dev/", sizeof booterDev);
	
	ret = BLDeviceNeedsBooter(context, device,
							  &needsBooter,
							  &isBooter,
							  &service);
	if(ret) {
		blesscontextprintf(context, kBLLogLevelError,  "Could not determine if partition needs booter\n" );		
		return 1;
	}
	
	if(!(needsBooter || isBooter))
		return 0;
	
	for(;;) {
		char label[MAXPATHLEN];
#if USE_DISKARBITRATION
		DADiskRef disk = NULL;
		DASessionRef session = NULL;
		CFDictionaryRef props = NULL;
		CFStringRef	daName = NULL;

		
		if(labelData) break; // no need to generate
		
		session = DASessionCreate(kCFAllocatorDefault);
		if(session == NULL) {
			blesscontextprintf(context, kBLLogLevelVerbose, "Can't connect to DiskArb\n");
			break;
		}
		
		disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, device+5);
		if(disk == NULL) {
			CFRelease(session);
			blesscontextprintf(context, kBLLogLevelVerbose, "Can't create DADisk for %s\n",
						  device + 5);
			break;
		}
		
		props = DADiskCopyDescription(disk);
		if(props == NULL) {
			CFRelease(session);
			CFRelease(disk);
			blesscontextprintf(context, kBLLogLevelVerbose, "Can't get properties for %s\n",
						  device + 5);
			break;
		}
		
		daName = CFDictionaryGetValue(props, kDADiskDescriptionVolumeNameKey);
		if(daName == NULL) {
			CFRelease(props);
			CFRelease(disk);
			CFRelease(session);	
			blesscontextprintf(context, kBLLogLevelVerbose, "Can't get properties for %s\n",
							   device + 5);
			break;			
		}
		
		
		
		if(!CFStringGetCString(daName, label, sizeof(label),
							   kCFStringEncodingUTF8)) {
			CFRelease(props);
			CFRelease(disk);
			CFRelease(session);	
			break;
		}

		CFRelease(props);
		CFRelease(disk);
		CFRelease(session);	
#else // !USE_DISKARBITRATION
		strlcpy(label, "Unknown", sizeof(label));
#endif // !USE_DISKARBITRATION
		
		ret = BLGenerateLabelData(context, label, kBitmapScale_1x, &labelData);
		if(ret)
			labelData = NULL;
		
		break;
	}
	
	if(!(bootxData || labelData)) {
		IOObjectRelease(service);
		return 0;
	}
	
	name = IORegistryEntryCreateCFProperty( service, CFSTR(kIOBSDNameKey),
											kCFAllocatorDefault, 0);
	
	if(name == NULL || CFStringGetTypeID() != CFGetTypeID(name)) {
		IOObjectRelease(service);
		blesscontextprintf(context, kBLLogLevelError,  "Could not find bsd name for %x\n" , service);
		return 2;
	}
	
	IOObjectRelease(service); service = 0;
	
	if(!CFStringGetCString(name,booterDev+5,sizeof(booterDev)-5,kCFStringEncodingUTF8)) {
		CFRelease(name);
		blesscontextprintf(context, kBLLogLevelError,  "Could not find bsd name for %x\n" , service);
		return 3;
	}
	
	CFRelease(name);
	
	if(labelData) specCount += 2;
	if(bootxData) specCount += 1;
	
	spec = calloc(specCount, sizeof(spec[0]));
	
	if(labelData) {
	
		spec[currentCount+0].version = 0;
		spec[currentCount+0].reqType = kBL_OSTYPE_PPC_TYPE_OFLABEL;
		spec[currentCount+0].reqCreator = kBL_OSTYPE_PPC_CREATOR_CHRP;
		spec[currentCount+0].reqParentDir = 0;
		spec[currentCount+0].reqFilename = NULL;
		spec[currentCount+0].payloadData = labelData;
		spec[currentCount+0].postType = 0; // no type
		spec[currentCount+0].postCreator = 0; // no type
		spec[currentCount+0].foundFile = 0;
		spec[currentCount+0].updatedFile = 0;
		
		spec[currentCount+1].version = 0;
		spec[currentCount+1].reqType = kBL_OSTYPE_PPC_TYPE_OFLABEL_PLACEHOLDER;
		spec[currentCount+1].reqCreator = kBL_OSTYPE_PPC_CREATOR_CHRP;
		spec[currentCount+1].reqParentDir = 0;
		spec[currentCount+1].reqFilename = NULL;
		spec[currentCount+1].payloadData = labelData;
		spec[currentCount+1].postType = kBL_OSTYPE_PPC_TYPE_OFLABEL;
		spec[currentCount+1].postCreator = 0; // no type
		spec[currentCount+1].foundFile = 0;
		spec[currentCount+1].updatedFile = 0;
		
		currentCount += 2;
	}
	
	if(bootxData) {
		spec[currentCount+0].version = 0;
		spec[currentCount+0].reqType = kBL_OSTYPE_PPC_TYPE_BOOTX;
		spec[currentCount+0].reqCreator = kBL_OSTYPE_PPC_CREATOR_CHRP;
		spec[currentCount+0].reqParentDir = 0;
		spec[currentCount+0].reqFilename = NULL;
		spec[currentCount+0].payloadData = bootxData;
		spec[currentCount+0].postType = 0; // no type
		spec[currentCount+0].postCreator = 0; // no type
		spec[currentCount+0].foundFile = 0;
		spec[currentCount+0].updatedFile = 0;
	}
	
	ret = BLUpdateBooter(context, booterDev, spec, specCount);
	if(ret) {
		blesscontextprintf(context, kBLLogLevelError,  "Error enumerating HFS+ volume\n");		
		return 1;
	}
	
	if(bootxData) {
		if(!(spec[currentCount].foundFile)) {
			blesscontextprintf(context, kBLLogLevelError,  "No pre-existing BootX found in HFS+ volume\n");
			return 2;
		}			

		if(!(spec[currentCount].updatedFile)) {
			blesscontextprintf(context, kBLLogLevelError,  "BootX was not updated\n");
			return 3;
		}			
	}
	
    if(labelData) {
		if(!(spec[0].foundFile || spec[1].foundFile)) {
			blesscontextprintf(context, kBLLogLevelError,  "No pre-existing OF label found in HFS+ volume\n");
			return 2;
		}
		if(!(spec[0].updatedFile || spec[1].updatedFile)) {
			blesscontextprintf(context, kBLLogLevelError,  "OF label was not updated\n");
			return 3;
		}
	}

	free(spec);
	
	return 0;
}
Exemplo n.º 17
0
void DiskArbitrationEventPublisher::DiskDisappearedCallback(DADiskRef disk,
                                                            void* context) {
  CFDictionaryRef disk_properties = DADiskCopyDescription(disk);
  fire("remove", createEventContext(), disk_properties);
  CFRelease(disk_properties);
}
Exemplo n.º 18
-1
void genIOMediaDevice(const io_service_t& device,
                      std::vector<std::string>& whole_devices,
                      QueryData& results) {
  Row r;

  // Get the device properties
  CFMutableDictionaryRef properties;
  IORegistryEntryCreateCFProperties(
      device, &properties, kCFAllocatorDefault, kNilOptions);

  r["uuid"] = getIOKitProperty(properties, "UUID");
  r["name"] = "/dev/" + getIOKitProperty(properties, "BSD Name");
  r["size"] = getIOKitProperty(properties, "Size");

  auto type = getIOKitProperty(properties, "Whole");
  if (type == "1") {
    // The "Whole" property applies to the entire disk entry, not partitions.
    whole_devices.push_back(r["name"]);
  } else {
    // Otherwise search the list of whole disks to find the node parent.
    for (const auto& parent : whole_devices) {
      if (r.at("name").find(parent) == 0) {
        r["parent"] = parent;
      }
    }
  }

  // This is the IOKit name, which is the device's label.
  io_name_t name;
  auto kr = IORegistryEntryGetName(device, name);
  if (kr == KERN_SUCCESS && (char*)name != nullptr) {
    r["label"] = std::string(name);
  }

  // Remaining details come from the Disk Arbitration service.
  DASessionRef session = DASessionCreate(kCFAllocatorDefault);
  CFDictionaryRef details;
  if (session != nullptr) {
    auto disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, session, device);
    if (disk != nullptr) {
      details = DADiskCopyDescription(disk);
      if (details != nullptr) {
        r["vendor"] =
            getIOKitProperty((CFMutableDictionaryRef)details, "DADeviceVendor");
        r["model"] =
            getIOKitProperty((CFMutableDictionaryRef)details, "DADeviceModel");
        r["type"] = getIOKitProperty((CFMutableDictionaryRef)details,
                                     "DADeviceProtocol");
        CFRelease(details);
      }
      CFRelease(disk);
    }
    CFRelease(session);
  }

  results.push_back(r);
  CFRelease(properties);
}