-static bool verifyCompatibleVersions(OSArray * dependencyList) {
- bool result = true;
-
- OSString * requestedModuleName = NULL;
-
- OSDictionary * extensionsDict = NULL;
- int count, i;
- OSString * curName = NULL;
- OSDictionary * curExt = NULL;
- OSDictionary * curExtPlist = NULL;
-
- OSBoolean * isKernelResource = NULL;
-
- OSDictionary * dependencies = NULL;
- OSCollectionIterator * dependencyIterator = NULL; // must release
- OSString * dependencyName = NULL;
- OSString * curExtDependencyVersion = NULL;
- UInt32 cur_ext_required_dependency_vers;
-
- OSDictionary * dependency = NULL;
- OSDictionary * dependencyPlist = NULL;
-
- OSString * dependencyVersion = NULL;
- OSString * dependencyCompatibleVersion = NULL;
- UInt32 dependency_vers;
- UInt32 dependency_compat_vers;
-
-
- /* Get the dictionary of startup extensions.
- * This is keyed by module name.
- */
- extensionsDict = getStartupExtensions();
- if (!extensionsDict) {
- IOLog("verifyCompatibleVersions(): No extensions dictionary.\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
-
- count = dependencyList->getCount();
- if (!count) {
- IOLog("verifyCompatibleVersions(): "
- "Invoked with no dependency list.\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- requestedModuleName = OSDynamicCast(OSString,
- dependencyList->getObject(count - 1));
-
- for (i = count - 1; i >= 0; i--) {
-
- if (dependencyIterator) {
- dependencyIterator->release();
- dependencyIterator = NULL;
- }
-
- curName = OSDynamicCast(OSString, dependencyList->getObject(i));
- if (!curName) {
- IOLog("verifyCompatibleVersions(): Internal error (1).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- curExt = OSDynamicCast(OSDictionary,
- extensionsDict->getObject(curName));
- if (!curExt) {
- IOLog("verifyCompatibleVersions(): Internal error (2).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- curExtPlist = OSDynamicCast(OSDictionary,
- curExt->getObject("plist"));
- if (!curExtPlist) {
- IOLog("verifyCompatibleVersions(): Internal error (3).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
-
- /* In-kernel extensions don't need to check dependencies.
- */
- isKernelResource = OSDynamicCast(OSBoolean,
- curExtPlist->getObject("OSKernelResource"));
- if (isKernelResource && isKernelResource->isTrue()) {
- continue;
- }
-
- dependencies = OSDynamicCast(OSDictionary,
- curExtPlist->getObject("OSBundleLibraries"));
- if (!dependencies || dependencies->getCount() < 1) {
- IOLog(VTYELLOW "verifyCompatibleVersions(): Extension \"%s\" "
- "declares no dependencies.\n" VTRESET,
- curName->getCStringNoCopy());
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- dependencyIterator =
- OSCollectionIterator::withCollection(dependencies);
- if (!curExtPlist) {
- IOLog("verifyCompatibleVersions(): Internal error (4).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- while ((dependencyName = OSDynamicCast(OSString,
- dependencyIterator->getNextObject()))) {
-
- curExtDependencyVersion = OSDynamicCast(OSString,
- dependencies->getObject(dependencyName));
- if (!curExtDependencyVersion) {
- IOLog("verifyCompatibleVersions(): Internal error (5).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- dependency = OSDynamicCast(OSDictionary,
- extensionsDict->getObject(dependencyName));
- if (!dependency) {
- IOLog("verifyCompatibleVersions(): Internal error (6).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- dependencyPlist = OSDynamicCast(OSDictionary,
- dependency->getObject("plist"));
- if (!dependencyPlist) {
- IOLog("verifyCompatibleVersions(): Internal error (7).\n");
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- dependencyVersion = OSDynamicCast(OSString,
- dependencyPlist->getObject("CFBundleVersion"));
- if (!curExtDependencyVersion) {
- IOLog(VTYELLOW "Dependency extension \"%s\" doesn't declare a "
- "version.\n" VTRESET,
- dependencyName->getCStringNoCopy());
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
- dependencyCompatibleVersion = OSDynamicCast(OSString,
- dependencyPlist->getObject("OSBundleCompatibleVersion"));
- if (!dependencyCompatibleVersion) {
- IOLog(VTYELLOW "Dependency extension \"%s\" doesn't declare a "
- "compatible version.\n" VTRESET,
- dependencyName->getCStringNoCopy());
- LOG_DELAY();
- result = false;
- goto finish;
- }
-
-IOLog("\033[33m %s (needs %s, compat-current is %s-%s).\n" VTRESET,
- dependencyName->getCStringNoCopy(),
- curExtDependencyVersion->getCStringNoCopy(),
- dependencyCompatibleVersion->getCStringNoCopy(),
- dependencyVersion->getCStringNoCopy());
-LOG_DELAY();
-
- if (!VERS_parse_string(curExtDependencyVersion->getCStringNoCopy(),
- &cur_ext_required_dependency_vers)) {
- }
- if (!VERS_parse_string(dependencyVersion->getCStringNoCopy(),
- &dependency_vers)) {
- }
- if (!VERS_parse_string(dependencyCompatibleVersion->getCStringNoCopy(),
- &dependency_compat_vers)) {
- }
-
- if (cur_ext_required_dependency_vers > dependency_vers ||
- cur_ext_required_dependency_vers < dependency_compat_vers) {
-
- IOLog(VTYELLOW "Cannot load extension \"%s\": dependencies "
- "\"%s\" and \"%s\" are not of compatible versions.\n" VTRESET,
- requestedModuleName->getCStringNoCopy(),
- curName->getCStringNoCopy(),
- dependencyName->getCStringNoCopy());
- LOG_DELAY();
- result = false;
- goto finish;
- }
- }
- }
-
-finish:
- return result;
-}
-
-