Beispiel #1
0
/*********************************************************************
* Is personality already in the catalog?
*********************************************************************/
OSOrderedSet *
IOCatalogue::findDrivers(
    OSDictionary * matching,
    SInt32 * generationCount)
{
    OSDictionary         * dict;
    OSOrderedSet         * set;

    UniqueProperties(matching);

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );

    IOLockLock(lock);
    kernelTables->reset();
    while ( (dict = (OSDictionary *) kernelTables->getNextObject()) ) {

        /* This comparison must be done with only the keys in the
         * "matching" dict to enable general searches.
         */
        if ( dict->isEqualTo(matching, matching) )
            set->setObject(dict);
    }
    *generationCount = getGenerationCount();
    IOLockUnlock(lock);

    return set;
}
Beispiel #2
0
/*********************************************************************
* Remove drivers from the catalog which match the
* properties in the matching dictionary.
*********************************************************************/
bool
IOCatalogue::removeDrivers(
    OSDictionary * matching,
    bool doNubMatching)
{
    OSOrderedSet         * set;
    OSCollectionIterator * iter;
    OSDictionary         * dict;
    OSArray              * array;
    const OSSymbol       * key;
    unsigned int           idx;

    if ( !matching )
        return false;
    
    set = OSOrderedSet::withCapacity(10,
                                     IOServiceOrdering,
                                     (void *)gIOProbeScoreKey);
    if ( !set )
        return false;
    iter = OSCollectionIterator::withCollection(personalities);
    if (!iter) 
    {
    	set->release();
    	return (false);
    }

    IORWLockWrite(lock);
    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++)
        {
           /* This comparison must be done with only the keys in the
            * "matching" dict to enable general searches.
            */
            if ( dict->isEqualTo(matching, matching) ) {
                set->setObject(dict);        
                array->removeObject(idx);
                idx--;
            }
        }
        // Start device matching.
        if ( doNubMatching && (set->getCount() > 0) ) {
            IOService::catalogNewDrivers(set);
            generation++;
        }
    }
    IORWLockUnlock(lock);
   
    set->release();
    iter->release();
    
    return true;
}
Beispiel #3
0
/*********************************************************************
* Is personality already in the catalog?
*********************************************************************/
OSOrderedSet *
IOCatalogue::findDrivers(
    OSDictionary * matching,
    SInt32 * generationCount)
{
    OSCollectionIterator * iter;
    OSDictionary         * dict;
    OSOrderedSet         * set;
    OSArray              * array;
    const OSSymbol       * key;
    unsigned int           idx;

    OSKext::uniquePersonalityProperties(matching);

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );
    if (!set) return (0);
    iter = OSCollectionIterator::withCollection(personalities);
    if (!iter) 
    {
    	set->release();
    	return (0);
    }

    IORWLockRead(lock);
    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++)
        {
	   /* This comparison must be done with only the keys in the
	    * "matching" dict to enable general searches.
	    */
	    if ( dict->isEqualTo(matching, matching) )
		set->setObject(dict);
	}
    }
    *generationCount = getGenerationCount();
    IORWLockUnlock(lock);

    iter->release();
    return set;
}
Beispiel #4
0
OSOrderedSet *
IOCatalogue::findDrivers(
    IOService * service,
    SInt32 * generationCount)
{
    OSDictionary         * nextTable;
    OSOrderedSet         * set;
    OSString             * imports;

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );
    if( !set )
        return( 0 );

    IOLockLock(lock);
    kernelTables->reset();

#if CATALOGTEST
    int hackIndex = 0;
#endif
    while( (nextTable = (OSDictionary *) kernelTables->getNextObject())) {
#if CATALOGTEST
        if( hackIndex++ > hackLimit)
            break;
#endif
        imports = OSDynamicCast( OSString,
                                 nextTable->getObject( gIOProviderClassKey ));
        if( imports && service->metaCast( imports ))
            set->setObject( nextTable );
    }

    *generationCount = getGenerationCount();

    IOLockUnlock(lock);

    return( set );
}
Beispiel #5
0
OSOrderedSet *
IOCatalogue::findDrivers(
    IOService * service,
    SInt32 * generationCount)
{
    OSDictionary         * nextTable;
    OSOrderedSet         * set;
    OSArray              * array;
    const OSMetaClass    * meta;
    unsigned int           idx;

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );
    if( !set )
	return( 0 );

    IORWLockRead(lock);

    meta = service->getMetaClass();
    while (meta)
    {
    	array = (OSArray *) personalities->getObject(meta->getClassNameSymbol());
	if (array) for (idx = 0; (nextTable = (OSDictionary *) array->getObject(idx)); idx++)
	{
            set->setObject(nextTable);
	}
	if (meta == &IOService::gMetaClass) break;
	meta = meta->getSuperClass();
    }

    *generationCount = getGenerationCount();

    IORWLockUnlock(lock);

    return( set );
}
Beispiel #6
0
bool IOCatalogue::resetAndAddDrivers(OSArray * drivers, bool doNubMatching)
{
    bool                   result              = false;
    OSArray              * newPersonalities    = NULL;  // do not release
    OSCollectionIterator * iter                = NULL;  // must release
    OSOrderedSet         * matchSet            = NULL;  // must release
    const OSSymbol       * key;
    OSArray              * array;
    OSDictionary         * thisNewPersonality  = NULL;  // do not release
    OSDictionary         * thisOldPersonality  = NULL;  // do not release
    signed int             idx, newIdx;

    if (drivers) {
        newPersonalities = OSDynamicCast(OSArray, drivers);
        if (!newPersonalities) {
            goto finish;
        }
        
        matchSet = OSOrderedSet::withCapacity(10, IOServiceOrdering,
            (void *)gIOProbeScoreKey);
        if (!matchSet) {
            goto finish;
        }
        iter = OSCollectionIterator::withCollection(personalities);
        if (!iter) {
            goto finish;
        }
    }

    result = true;

    IOLog("Resetting IOCatalogue.\n");

   /* No goto finish from here to unlock.
    */
    IORWLockWrite(lock);
    
    while ((key = (const OSSymbol *) iter->getNextObject()))
    {
        array = (OSArray *) personalities->getObject(key);
        if (!array) continue;
        for (idx = 0; (thisOldPersonality = (OSDictionary *) array->getObject(idx)); idx++)
        {
            if (thisOldPersonality->getObject("KernelConfigTable")) continue;
            if (newPersonalities) for (newIdx = 0; 
                (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx)); 
                newIdx++)
            {
	       /* Unlike in other functions, this comparison must be exact!
            * The catalogue must be able to contain personalities that
            * are proper supersets of others.
            * Do not compare just the properties present in one driver
            * pesonality or the other.
            */
                if (thisNewPersonality->isEqualTo(thisOldPersonality))  
                    break;
            }
            if (thisNewPersonality)
            {
                // dup, ignore
                newPersonalities->removeObject(newIdx);
            }
            else
            {
                // not in new set - remove
                // only remove dictionary if this module in not loaded - 9953845
                if ( isModuleLoaded(thisOldPersonality) == false ) 
                {
                    if (matchSet)  matchSet->setObject(thisOldPersonality);
                    array->removeObject(idx);
                    idx--;
                }
            }
        }
    }
    
     // add new
     for (newIdx = 0;
          (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx)); 
          newIdx++)
     {
         OSKext::uniquePersonalityProperties(thisNewPersonality);
         addPersonality(thisNewPersonality);
         matchSet->setObject(thisNewPersonality);
     }

   /* Finally, start device matching on all new & removed personalities.
    */
    if (result && doNubMatching && (matchSet->getCount() > 0)) {
        IOService::catalogNewDrivers(matchSet);
        generation++;
    }

    IORWLockUnlock(lock);

finish:
    if (matchSet) matchSet->release();
    if (iter)     iter->release();

    return result;
}
Beispiel #7
0
bool IOCatalogue::addDrivers(
    OSArray * drivers,
    bool doNubMatching)
{
    bool                   result = false;
    OSCollectionIterator * iter = NULL;       // must release
    OSOrderedSet         * set = NULL;        // must release
    OSObject             * object = NULL;       // do not release
    OSArray              * persons = NULL;    // do not release
    
    persons = OSDynamicCast(OSArray, drivers);
    if (!persons) {
        goto finish;
    }
    
    set = OSOrderedSet::withCapacity( 10, IOServiceOrdering,
        (void *)gIOProbeScoreKey );
    if (!set) {
        goto finish;
    }

    iter = OSCollectionIterator::withCollection(persons);
    if (!iter) {
        goto finish;
    }

   /* Start with success; clear it on an error.
    */
    result = true;

    IORWLockWrite(lock);
    while ( (object = iter->getNextObject()) ) {
    
        // xxx Deleted OSBundleModuleDemand check; will handle in other ways for SL

        OSDictionary * personality = OSDynamicCast(OSDictionary, object);

        SInt count;

        if (!personality) {
            IOLog("IOCatalogue::addDrivers() encountered non-dictionary; bailing.\n");
            result = false;
            break;
        }

        OSKext::uniquePersonalityProperties(personality);

        // Add driver personality to catalogue.

	OSArray * array = arrayForPersonality(personality);
	if (!array) addPersonality(personality);
	else
	{       
	    count = array->getCount();
	    while (count--) {
		OSDictionary * driver;
		
		// Be sure not to double up on personalities.
		driver = (OSDictionary *)array->getObject(count);
		
	       /* Unlike in other functions, this comparison must be exact!
		* The catalogue must be able to contain personalities that
		* are proper supersets of others.
		* Do not compare just the properties present in one driver
		* pesonality or the other.
		*/
		if (personality->isEqualTo(driver)) {
		    break;
		}
	    }
	    if (count >= 0) {
		// its a dup
		continue;
	    }
	    result = array->setObject(personality);
	    if (!result) {
		break;
	    }
        }

	set->setObject(personality);        
    }
    // Start device matching.
    if (result && doNubMatching && (set->getCount() > 0)) {
        IOService::catalogNewDrivers(set);
        generation++;
    }
    IORWLockUnlock(lock);

finish:
    if (set)  set->release();
    if (iter) iter->release();

    return result;
}