X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/7e4a7d3939db04e70062ae6c7bf24b8c8b2f5a7c..fe8ab488e9161c46dd9885d58fc52996dc0249ff:/iokit/Kernel/IOCatalogue.cpp diff --git a/iokit/Kernel/IOCatalogue.cpp b/iokit/Kernel/IOCatalogue.cpp index 8c51eed84..b6c335fbf 100644 --- a/iokit/Kernel/IOCatalogue.cpp +++ b/iokit/Kernel/IOCatalogue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006 Apple Inc. All rights reserved. + * Copyright (c) 1998-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -49,6 +49,7 @@ extern "C" { #include #include #include +#include #include #include @@ -63,53 +64,15 @@ extern "C" { /********************************************************************* *********************************************************************/ -#define CATALOGTEST 0 - IOCatalogue * gIOCatalogue; const OSSymbol * gIOClassKey; const OSSymbol * gIOProbeScoreKey; const OSSymbol * gIOModuleIdentifierKey; -IOLock * gIOCatalogLock; +IORWLock * gIOCatalogLock; #if PRAGMA_MARK #pragma mark Utility functions #endif -/********************************************************************* -*********************************************************************/ -static void -UniqueProperties(OSDictionary * dict) -{ - OSString * data; - - data = OSDynamicCast(OSString, dict->getObject(gIOClassKey)); - if (data) { - const OSSymbol *classSymbol = OSSymbol::withString(data); - - dict->setObject( gIOClassKey, (OSSymbol *) classSymbol); - classSymbol->release(); - } - - data = OSDynamicCast(OSString, dict->getObject(gIOMatchCategoryKey)); - if (data) { - const OSSymbol *classSymbol = OSSymbol::withString(data); - - dict->setObject(gIOMatchCategoryKey, (OSSymbol *) classSymbol); - classSymbol->release(); - } - return; -} - -/********************************************************************* -* Add a new personality to the set if it has a unique IOResourceMatchKey value. -* XXX -- svail: This should be optimized. -* esb - There doesn't seem like any reason to do this - it causes problems -* esb - when there are more than one loadable driver matching on the same provider class -*********************************************************************/ -static void -AddNewImports(OSOrderedSet * set, OSDictionary * dict) -{ - set->setObject(dict); -} #if PRAGMA_MARK #pragma mark IOCatalogue class implementation @@ -120,6 +83,10 @@ AddNewImports(OSOrderedSet * set, OSDictionary * dict) #define super OSObject OSDefineMetaClassAndStructors(IOCatalogue, OSObject) +static bool isModuleLoadedNoOSKextLock(OSDictionary *theKexts, + OSDictionary *theModuleDict); + + /********************************************************************* *********************************************************************/ void IOCatalogue::initialize(void) @@ -151,42 +118,68 @@ void IOCatalogue::initialize(void) array->release(); } +/********************************************************************* +* Initialize the IOCatalog object. +*********************************************************************/ +OSArray * IOCatalogue::arrayForPersonality(OSDictionary * dict) +{ + const OSSymbol * sym; + + sym = OSDynamicCast(OSSymbol, dict->getObject(gIOProviderClassKey)); + if (!sym) return (0); + + return ((OSArray *) personalities->getObject(sym)); +} + +void IOCatalogue::addPersonality(OSDictionary * dict) +{ + const OSSymbol * sym; + OSArray * arr; + + sym = OSDynamicCast(OSSymbol, dict->getObject(gIOProviderClassKey)); + if (!sym) return; + arr = (OSArray *) personalities->getObject(sym); + if (arr) arr->setObject(dict); + else + { + arr = OSArray::withObjects((const OSObject **)&dict, 1, 2); + personalities->setObject(sym, arr); + arr->release(); + } +} + /********************************************************************* * Initialize the IOCatalog object. *********************************************************************/ bool IOCatalogue::init(OSArray * initArray) { OSDictionary * dict; - + OSObject * obj; + if ( !super::init() ) return false; generation = 1; - array = initArray; - array->retain(); - kernelTables = OSCollectionIterator::withCollection( array ); - - gIOCatalogLock = IOLockAlloc(); - - lock = gIOCatalogLock; -#if __ppc__ || __i386__ - kld_lock = NULL; -#endif /* __ppc__ || __i386__ */ - - kernelTables->reset(); - while( (dict = (OSDictionary *) kernelTables->getNextObject())) { - UniqueProperties(dict); + personalities = OSDictionary::withCapacity(32); + personalities->setOptions(OSCollection::kSort, OSCollection::kSort); + for (unsigned int idx = 0; (obj = initArray->getObject(idx)); idx++) + { + dict = OSDynamicCast(OSDictionary, obj); + if (!dict) continue; + OSKext::uniquePersonalityProperties(dict); if( 0 == dict->getObject( gIOClassKey )) + { IOLog("Missing or bad \"%s\" key\n", gIOClassKey->getCStringNoCopy()); + continue; + } + dict->setObject("KernelConfigTable", kOSBooleanTrue); + addPersonality(dict); } -#if CATALOGTEST - AbsoluteTime deadline; - clock_interval_to_deadline( 1000, kMillisecondScale ); - thread_call_func_delayed( ping, this, deadline ); -#endif + gIOCatalogLock = IORWLockAlloc(); + lock = gIOCatalogLock; return true; } @@ -197,63 +190,8 @@ bool IOCatalogue::init(OSArray * initArray) *********************************************************************/ void IOCatalogue::free( void ) { - if ( array ) - array->release(); - - if ( kernelTables ) - kernelTables->release(); - - super::free(); -} - -/********************************************************************* -*********************************************************************/ -#if CATALOGTEST - -static int hackLimit; -enum { kDriversPerIter = 4 }; - -void -IOCatalogue::ping(thread_call_param_t arg, thread_call_param_t) -{ - IOCatalogue * self = (IOCatalogue *) arg; - OSOrderedSet * set; - OSDictionary * table; - int newLimit; - - set = OSOrderedSet::withCapacity( 1 ); - - IOLockLock( &self->lock ); - - for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) { - table = (OSDictionary *) self->array->getObject( - hackLimit + newLimit ); - if( table) { - set->setLastObject( table ); - - OSSymbol * sym = (OSSymbol *) table->getObject(gIOClassKey); - kprintf("enabling %s\n", sym->getCStringNoCopy()); - - } else { - newLimit--; - break; - } - } - - IOService::catalogNewDrivers( set ); - - hackLimit += newLimit; - self->generation++; - - IOLockUnlock( &self->lock ); - - if( kDriversPerIter == newLimit) { - AbsoluteTime deadline; - clock_interval_to_deadline(500, kMillisecondScale); - thread_call_func_delayed(ping, this, deadline); - } + panic(""); } -#endif /********************************************************************* *********************************************************************/ @@ -264,33 +202,32 @@ IOCatalogue::findDrivers( { OSDictionary * nextTable; OSOrderedSet * set; - OSString * imports; + OSArray * array; + const OSMetaClass * meta; + unsigned int idx; set = OSOrderedSet::withCapacity( 1, IOServiceOrdering, (void *)gIOProbeScoreKey ); if( !set ) return( 0 ); - IOLockLock(lock); - kernelTables->reset(); + IORWLockRead(lock); -#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 ); + 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(); - IOLockUnlock(lock); + IORWLockUnlock(lock); return( set ); } @@ -303,27 +240,42 @@ IOCatalogue::findDrivers( OSDictionary * matching, SInt32 * generationCount) { + OSCollectionIterator * iter; OSDictionary * dict; OSOrderedSet * set; + OSArray * array; + const OSSymbol * key; + unsigned int idx; - UniqueProperties(matching); + OSKext::uniquePersonalityProperties(matching); set = OSOrderedSet::withCapacity( 1, IOServiceOrdering, (void *)gIOProbeScoreKey ); + if (!set) return (0); + iter = OSCollectionIterator::withCollection(personalities); + if (!iter) + { + set->release(); + return (0); + } - 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); + 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(); - IOLockUnlock(lock); + IORWLockUnlock(lock); + iter->release(); return set; } @@ -338,6 +290,7 @@ IOCatalogue::findDrivers( * xxx - userlib used to refuse to send personalities with IOKitDebug * xxx - during safe boot. That would be better implemented here. *********************************************************************/ + bool IOCatalogue::addDrivers( OSArray * drivers, bool doNubMatching) @@ -345,9 +298,9 @@ bool IOCatalogue::addDrivers( bool result = false; OSCollectionIterator * iter = NULL; // must release OSOrderedSet * set = NULL; // must release - OSDictionary * dict = NULL; // do not release + OSObject * object = NULL; // do not release OSArray * persons = NULL; // do not release - + persons = OSDynamicCast(OSArray, drivers); if (!persons) { goto finish; @@ -364,53 +317,68 @@ bool IOCatalogue::addDrivers( goto finish; } + /* Start with success; clear it on an error. + */ result = true; - IOLockLock(lock); - while ( (dict = (OSDictionary *) iter->getNextObject()) ) { + IORWLockWrite(lock); + while ( (object = iter->getNextObject()) ) { // xxx Deleted OSBundleModuleDemand check; will handle in other ways for SL + OSDictionary * personality = OSDynamicCast(OSDictionary, object); + SInt count; - - UniqueProperties(dict); - - // Add driver personality to catalogue. - 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 (dict->isEqualTo(driver)) { - break; - } - } - if (count >= 0) { - // its a dup - continue; - } - - result = array->setObject(dict); - if (!result) { + + if (!personality) { + IOLog("IOCatalogue::addDrivers() encountered non-dictionary; bailing.\n"); + result = false; break; } - - AddNewImports(set, dict); + + 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 + * personality 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 (doNubMatching && (set->getCount() > 0)) { + if (result && doNubMatching && (set->getCount() > 0)) { IOService::catalogNewDrivers(set); generation++; } - IOLockUnlock(lock); + IORWLockUnlock(lock); finish: if (set) set->release(); @@ -428,61 +396,53 @@ IOCatalogue::removeDrivers( OSDictionary * matching, bool doNubMatching) { - OSCollectionIterator * tables; - OSDictionary * dict; OSOrderedSet * set; - OSArray * arrayCopy; + 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; - - arrayCopy = OSArray::withCapacity(100); - if ( !arrayCopy ) { - set->release(); - return false; - } - - tables = OSCollectionIterator::withCollection(arrayCopy); - arrayCopy->release(); - if ( !tables ) { - set->release(); - return false; + iter = OSCollectionIterator::withCollection(personalities); + if (!iter) + { + set->release(); + return (false); } - UniqueProperties( matching ); - - IOLockLock(lock); - kernelTables->reset(); - arrayCopy->merge(array); - array->flushCollection(); - tables->reset(); - while ( (dict = (OSDictionary *)tables->getNextObject()) ) { - - /* This comparison must be done with only the keys in the - * "matching" dict to enable general searches. - */ - if ( dict->isEqualTo(matching, matching) ) { - AddNewImports( set, dict ); - continue; + 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++; } - - array->setObject(dict); - } - // Start device matching. - if ( doNubMatching && (set->getCount() > 0) ) { - IOService::catalogNewDrivers(set); - generation++; } - IOLockUnlock(lock); - + IORWLockUnlock(lock); + set->release(); - tables->release(); + iter->release(); return true; } @@ -572,7 +532,7 @@ IOReturn IOCatalogue::unloadModule(OSString * moduleName) const return OSKext::removeKextWithIdentifier(moduleName->getCStringNoCopy()); } -static IOReturn _terminateDrivers(OSDictionary * matching) +IOReturn IOCatalogue::_terminateDrivers(OSDictionary * matching) { OSDictionary * dict; OSIterator * iter; @@ -589,7 +549,7 @@ static IOReturn _terminateDrivers(OSDictionary * matching) if ( !iter ) return kIOReturnNoMemory; - UniqueProperties( matching ); + OSKext::uniquePersonalityProperties( matching ); // terminate instances. do { @@ -617,41 +577,39 @@ static IOReturn _terminateDrivers(OSDictionary * matching) return ret; } -static IOReturn _removeDrivers( OSArray * array, OSDictionary * matching ) +IOReturn IOCatalogue::_removeDrivers(OSDictionary * matching) { - OSCollectionIterator * tables; - OSDictionary * dict; - OSArray * arrayCopy; IOReturn ret = kIOReturnSuccess; + OSCollectionIterator * iter; + OSDictionary * dict; + OSArray * array; + const OSSymbol * key; + unsigned int idx; // remove configs from catalog. - arrayCopy = OSArray::withCapacity(100); - if ( !arrayCopy ) - return kIOReturnNoMemory; - - tables = OSCollectionIterator::withCollection(arrayCopy); - arrayCopy->release(); - if ( !tables ) - return kIOReturnNoMemory; - - arrayCopy->merge(array); - array->flushCollection(); - tables->reset(); - while ( (dict = (OSDictionary *)tables->getNextObject()) ) { - - /* Remove from the catalogue's array any personalities - * that match the matching dictionary. - * This comparison must be done with only the keys in the - * "matching" dict to enable general matching. - */ - if ( dict->isEqualTo(matching, matching) ) - continue; + iter = OSCollectionIterator::withCollection(personalities); + if (!iter) return (kIOReturnNoMemory); - array->setObject(dict); + while ((key = (const OSSymbol *) iter->getNextObject())) + { + array = (OSArray *) personalities->getObject(key); + if (array) for (idx = 0; (dict = (OSDictionary *) array->getObject(idx)); idx++) + { + + /* Remove from the catalogue's array any personalities + * that match the matching dictionary. + * This comparison must be done with only the keys in the + * "matching" dict to enable general matching. + */ + if (dict->isEqualTo(matching, matching)) + { + array->removeObject(idx); + idx--; + } + } } - - tables->release(); + iter->release(); return ret; } @@ -661,11 +619,10 @@ IOReturn IOCatalogue::terminateDrivers(OSDictionary * matching) IOReturn ret; ret = _terminateDrivers(matching); - IOLockLock(lock); + IORWLockWrite(lock); if (kIOReturnSuccess == ret) - ret = _removeDrivers(array, matching); - kernelTables->reset(); - IOLockUnlock(lock); + ret = _removeDrivers(matching); + IORWLockUnlock(lock); return ret; } @@ -710,18 +667,17 @@ IOReturn IOCatalogue::terminateDriversForModule( /* No goto between IOLock calls! */ - IOLockLock(lock); + IORWLockWrite(lock); if (kIOReturnSuccess == ret) { - ret = _removeDrivers(array, dict); + ret = _removeDrivers(dict); } - kernelTables->reset(); // Unload the module itself. if (unload && isLoaded && ret == kIOReturnSuccess) { ret = unloadModule(moduleName); } - IOLockUnlock(lock); + IORWLockUnlock(lock); dict->release(); @@ -748,8 +704,12 @@ IOReturn IOCatalogue::terminateDriversForModule( bool IOCatalogue::startMatching( OSDictionary * matching ) { + OSCollectionIterator * iter; OSDictionary * dict; OSOrderedSet * set; + OSArray * array; + const OSSymbol * key; + unsigned int idx; if ( !matching ) return false; @@ -759,33 +719,174 @@ bool IOCatalogue::startMatching( OSDictionary * matching ) if ( !set ) return false; - IOLockLock(lock); - kernelTables->reset(); + iter = OSCollectionIterator::withCollection(personalities); + if (!iter) + { + set->release(); + return false; + } - while ( (dict = (OSDictionary *)kernelTables->getNextObject()) ) { + IORWLockRead(lock); - /* This comparison must be done with only the keys in the - * "matching" dict to enable general matching. - */ - if ( dict->isEqualTo(matching, matching) ) - AddNewImports(set, dict); + 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 matching. + */ + if (dict->isEqualTo(matching, matching)) { + set->setObject(dict); + } + } } + // Start device matching. if ( set->getCount() > 0 ) { IOService::catalogNewDrivers(set); generation++; } - IOLockUnlock(lock); + IORWLockUnlock(lock); set->release(); + iter->release(); return true; } void IOCatalogue::reset(void) { + IOCatalogue::resetAndAddDrivers(/* no drivers; true reset */ NULL, + /* doMatching */ false); + return; +} + +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 + OSDictionary * myKexts = NULL; // must 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; + } + + /* need copy of loaded kexts so we can check if for loaded modules without + * taking the OSKext lock. There is a potential of deadlocking if we get + * an OSKext via the normal path. See 14672140. + */ + myKexts = OSKext::copyKexts(); + + 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; + thisNewPersonality = NULL; + + 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 + * personality or the other. + */ + if (OSDynamicCast(OSDictionary, thisNewPersonality) == NULL) { + /* skip thisNewPersonality if it is not an OSDictionary */ + continue; + } + 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 ( isModuleLoadedNoOSKextLock(myKexts, thisOldPersonality) == false ) { + if (matchSet) { + matchSet->setObject(thisOldPersonality); + } + array->removeObject(idx); + idx--; + } + } + } // for... + } // while... + + // add new + if (newPersonalities) { + for (newIdx = 0; + (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx)); + newIdx++) + { + if (OSDynamicCast(OSDictionary, thisNewPersonality) == NULL) { + /* skip thisNewPersonality if it is not an OSDictionary */ + continue; + } + + 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(); + if (myKexts) myKexts->release(); + + return result; } bool IOCatalogue::serialize(OSSerialize * s) const @@ -803,8 +904,7 @@ bool IOCatalogue::serializeData(IOOptionBits kind, OSSerialize * s) const switch ( kind ) { case kIOCatalogGetContents: - if (!array->serialize(s)) - kr = kIOReturnNoMemory; + kr = KERN_NOT_SUPPORTED; break; case kIOCatalogGetModuleDemandList: @@ -827,6 +927,41 @@ bool IOCatalogue::serializeData(IOOptionBits kind, OSSerialize * s) const return kr; } +/* isModuleLoadedNoOSKextLock - used to check to see if a kext is loaded + * without taking the OSKext lock. We use this to avoid the problem + * where taking the IOCatalog lock then the OSKext lock will dealock when + * a kext load or unload is happening at the same time as IOCatalog changing. + * + * theKexts - is a dictionary of current kexts (from OSKext::copyKexts) with + * key set to the kext bundle ID and value set to an OSKext object + * theModuleDict - is an IOKit personality dictionary for a given module (kext) + */ +static bool isModuleLoadedNoOSKextLock(OSDictionary *theKexts, + OSDictionary *theModuleDict) +{ + bool myResult = false; + const OSString * myBundleID = NULL; // do not release + OSKext * myKext = NULL; // do not release + + if (theKexts == NULL || theModuleDict == NULL) { + return( myResult ); + } + + // gIOModuleIdentifierKey is "CFBundleIdentifier" + myBundleID = OSDynamicCast(OSString, + theModuleDict->getObject(gIOModuleIdentifierKey)); + if (myBundleID == NULL) { + return( myResult ); + } + + myKext = OSDynamicCast(OSKext, theKexts->getObject(myBundleID->getCStringNoCopy())); + if (myKext) { + myResult = myKext->isLoaded(); + } + + return( myResult ); +} + #if PRAGMA_MARK #pragma mark Obsolete Kext Loading Stuff @@ -837,17 +972,5 @@ bool IOCatalogue::serializeData(IOOptionBits kind, OSSerialize * s) const ********************************************************************** ********************************************************************** * These functions are no longer used are necessary for C++ binary -* compatibility on ppc/i386. +* compatibility on i386. **********************************************************************/ -#if __ppc__ || __i386__ - -bool IOCatalogue::recordStartupExtensions(void) -{ return false; } - -bool IOCatalogue::addExtensionsFromArchive(OSData * mkext) -{ return KERN_NOT_SUPPORTED; } - -kern_return_t IOCatalogue::removeKernelLinker(void) -{ return KERN_NOT_SUPPORTED; } - -#endif /* __ppc__ || __i386__ */