ExitStatus checkKextForProblems( KcgenArgs * toolArgs, OSKextRef theKext, const NXArchInfo * arch) { ExitStatus result = EX_SOFTWARE; char kextPath[PATH_MAX]; if (!CFURLGetFileSystemRepresentation(OSKextGetURL(theKext), /* resolveToBase */ false, (UInt8 *)kextPath, sizeof(kextPath))) { strlcpy(kextPath, "(unknown)", sizeof(kextPath)); } /* Skip kexts we have no interest in for the current arch. */ if (!OSKextSupportsArchitecture(theKext, arch)) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag, "%s doesn't support architecture '%s'; ommiting.", kextPath, arch->name); goto finish; } if (!OSKextIsValid(theKext)) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag | kOSKextLogValidationFlag | kOSKextLogGeneralFlag, "%s is not valid; omitting.", kextPath); if (toolArgs->printTestResults) { OSKextLogDiagnostics(theKext, kOSKextDiagnosticsFlagAll); } goto finish; } if (!OSKextResolveDependencies(theKext)) { OSKextLog(/* kext */ NULL, kOSKextLogWarningLevel | kOSKextLogArchiveFlag | kOSKextLogDependenciesFlag | kOSKextLogGeneralFlag, "%s is missing dependencies (including anyway; " "dependencies may be available from elsewhere)", kextPath); if (toolArgs->printTestResults) { OSKextLogDiagnostics(theKext, kOSKextDiagnosticsFlagAll); } } result = EX_OK; finish: return result; }
/******************************************************************************* * XXX: I'm really not sure this is completely reliable for getting a relative * XXX: path. *******************************************************************************/ CFStringRef copyKextInfoDictionaryPath( OSKextRef theKext, PathSpec pathSpec) { CFStringRef result = NULL; CFURLRef kextURL = NULL; // do not release CFURLRef kextAbsURL = NULL; // must release CFBundleRef kextBundle = NULL; // must release CFURLRef infoDictURL = NULL; // must release kextURL = OSKextGetURL(theKext); if (!kextURL) { OSKextLog(theKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Kext has no URL!"); goto finish; } kextAbsURL = CFURLCopyAbsoluteURL(kextURL); if (!kextAbsURL) { OSKextLogMemError(); goto finish; } kextBundle = CFBundleCreate(kCFAllocatorDefault, kextAbsURL); if (!kextBundle) { OSKextLogMemError(); goto finish; } infoDictURL = _CFBundleCopyInfoPlistURL(kextBundle); if (!infoDictURL) { // not able to determine error here, bundle might have no plist // (well, we should never have gotten here if that were the case) result = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8); goto finish; } result = copyAdjustedPathForURL(theKext, infoDictURL, pathSpec); finish: SAFE_RELEASE(infoDictURL); SAFE_RELEASE(kextBundle); SAFE_RELEASE(kextAbsURL); return result; }
/******************************************************************************* * XXX: I'm really not sure this is completely reliable for getting a relative * XXX: path. *******************************************************************************/ CFStringRef copyKextExecutablePath( OSKextRef theKext, PathSpec pathSpec) { CFStringRef result = NULL; CFURLRef kextURL = NULL; // do not release CFURLRef kextAbsURL = NULL; // must release CFURLRef executableURL = NULL; // must release kextURL = OSKextGetURL(theKext); if (!kextURL) { OSKextLog(theKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Kext has no URL!"); goto finish; } kextAbsURL = CFURLCopyAbsoluteURL(kextURL); if (!kextAbsURL) { OSKextLogMemError(); goto finish; } executableURL = _CFBundleCopyExecutableURLInDirectory(kextAbsURL); if (!executableURL) { // not able to determine error here, bundle might have no executable result = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8); goto finish; } result = copyAdjustedPathForURL(theKext, executableURL, pathSpec); finish: SAFE_RELEASE(executableURL); SAFE_RELEASE(kextAbsURL); return result; }
CFStringRef copyPathForKext( OSKextRef theKext, PathSpec pathSpec) { CFStringRef result = CFSTR("(can't determine kext path)"); CFURLRef kextURL = OSKextGetURL(theKext); // do not release CFURLRef absURL = NULL; // must release OSKextRef containerKext = NULL; // must release CFURLRef containerURL = NULL; // do not release CFURLRef containerAbsURL = NULL; // must release CFURLRef repositoryURL = NULL; // must release CFStringRef repositoryPath = NULL; // must release CFStringRef kextPath = NULL; // must release if (!kextURL) { OSKextLog(theKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Kext has no URL!"); goto finish; } if (pathSpec == kPathsNone) { result = CFURLCopyLastPathComponent(kextURL); } else if (pathSpec == kPathsFull) { absURL = CFURLCopyAbsoluteURL(kextURL); if (!absURL) { OSKextLogMemError(); goto finish; } result = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); } else if (pathSpec == kPathsRelative) { CFRange relativeRange; absURL = CFURLCopyAbsoluteURL(kextURL); if (!absURL) { OSKextLogMemError(); goto finish; } containerKext = OSKextCopyContainerForPluginKext(theKext); if (containerKext) { containerURL = OSKextGetURL(containerKext); if (!containerURL) { OSKextLog(containerKext, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Container kext has no URL!"); goto finish; } containerAbsURL = CFURLCopyAbsoluteURL(containerURL); if (!containerAbsURL) { OSKextLogMemError(); goto finish; } repositoryURL = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault, containerAbsURL); if (!repositoryURL) { OSKextLogMemError(); goto finish; } } else { repositoryURL = CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault, absURL); if (!repositoryURL) { OSKextLogMemError(); goto finish; } } repositoryPath = CFURLCopyFileSystemPath(repositoryURL, kCFURLPOSIXPathStyle); kextPath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); if (!repositoryPath || !kextPath) { OSKextLogMemError(); goto finish; } /* We add 1 to the length of the repositoryPath to handle the * intermediate '/' character. */ relativeRange = CFRangeMake(1+CFStringGetLength(repositoryPath), CFStringGetLength(kextPath) - (1+CFStringGetLength(repositoryPath))); result = CFStringCreateWithSubstring(kCFAllocatorDefault, kextPath, relativeRange); } else { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag, "Internal error."); goto finish; } finish: SAFE_RELEASE(absURL); SAFE_RELEASE(containerKext); SAFE_RELEASE(containerAbsURL); SAFE_RELEASE(repositoryURL); SAFE_RELEASE(repositoryPath); SAFE_RELEASE(kextPath); return result; }