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! */ IOLockLock(lock); if (kIOReturnSuccess == ret) { ret = _removeDrivers(array, dict); } kernelTables->reset(); // Unload the module itself. if (unload && isLoaded && ret == kIOReturnSuccess) { ret = unloadModule(moduleName); } IOLockUnlock(lock); dict->release(); finish: return ret; }
IOReturn IOCatalogue::terminateDrivers(OSDictionary * matching) { IOReturn ret; ret = _terminateDrivers(matching); IORWLockWrite(lock); if (kIOReturnSuccess == ret) ret = _removeDrivers(matching); IORWLockUnlock(lock); return ret; }
IOReturn IOCatalogue::terminateDrivers(OSDictionary * matching) { IOReturn ret; ret = _terminateDrivers(matching); IOLockLock(lock); if (kIOReturnSuccess == ret) ret = _removeDrivers(array, matching); kernelTables->reset(); IOLockUnlock(lock); return ret; }