void DldIOShadowFile::UnLockShared() { assert( this->rwLock ); assert( preemption_enabled() ); IORWLockUnlock( this->rwLock ); };
IOReturn IOCatalogue::terminateDriversForModule( OSString * moduleName, bool unload) { IOReturn ret; OSDictionary * dict; bool isLoaded = false; /* Check first if the kext currently has any linkage dependents; * in such a case the unload would fail so let's not terminate any * IOServices (since doing so typically results in a panic when there * are loaded dependencies). Note that we aren't locking the kext here * so it might lose or gain dependents by the time we call unloadModule(); * I think that's ok, our unload can fail if a kext comes in on top of * this one even after we've torn down IOService objects. Conversely, * if we fail the unload here and then lose a library, the autounload * thread will get us in short order. */ if (OSKext::isKextWithIdentifierLoaded(moduleName->getCStringNoCopy())) { isLoaded = true; if (!OSKext::canUnloadKextWithIdentifier(moduleName, /* checkClasses */ false)) { ret = kOSKextReturnInUse; goto finish; } } dict = OSDictionary::withCapacity(1); if (!dict) { ret = kIOReturnNoMemory; goto finish; } dict->setObject(gIOModuleIdentifierKey, moduleName); ret = _terminateDrivers(dict); /* No goto between IOLock calls! */ IORWLockWrite(lock); if (kIOReturnSuccess == ret) { ret = _removeDrivers(dict); } // Unload the module itself. if (unload && isLoaded && ret == kIOReturnSuccess) { ret = unloadModule(moduleName); } IORWLockUnlock(lock); dict->release(); finish: return ret; }
/********************************************************************* * 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; }
IOReturn IOCatalogue::terminateDrivers(OSDictionary * matching) { IOReturn ret; ret = _terminateDrivers(matching); IORWLockWrite(lock); if (kIOReturnSuccess == ret) ret = _removeDrivers(matching); IORWLockUnlock(lock); return ret; }
void DldIOShadowFile::UnLockExclusive() { assert( this->rwLock ); assert( preemption_enabled() ); #if defined(DBG) assert( current_thread() == this->exclusiveThread ); this->exclusiveThread = NULL; #endif//DBG IORWLockUnlock( this->rwLock ); };
/********************************************************************* * 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; }
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 ); }
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; }
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; }