__private_extern__ void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) {
    if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
        /* MF:!!! Assert that instanceCount > 0. */
        __CFBundleGetPlugInData(plugIn)->_instanceCount--;
        if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) {
            // We unload the code lazily because the code that caused this function to be called is probably code from the plugin itself.  If we unload now, we will hose things.
            //CFBundleUnloadExecutable(plugIn);
            _CFBundleScheduleForUnloading(CFPlugInGetBundle(plugIn));
        }
        /* Instances also retain the CFPlugIn */
        /* MF:!!! This will cause immediate unloading if it was the last ref on the plugin. */
        CFRelease(plugIn);
    }
}
Example #2
0
static kern_return_t
IOFindPlugIns( io_service_t service,
               CFUUIDRef pluginType,
               CFArrayRef * factories, CFArrayRef * plists )
{
    CFURLRef		url;
    CFPlugInRef		onePlugin;
    CFBundleRef		bundle;
    CFDictionaryRef	plist;
    CFDictionaryRef	matching;
    CFDictionaryRef	pluginTypes;
    CFMutableStringRef	path;
    LookUUIDContext	context;
    CFStringRef		pluginName;
    boolean_t		matches;
    kern_return_t	kr = kIOReturnSuccess;
    
    // -- loadables
    onePlugin 		= NULL;
    pluginName		= NULL;
    path 		= NULL;
    url 		= NULL;

    do {

        pluginTypes = IORegistryEntryCreateCFProperty( service, CFSTR(kIOCFPlugInTypesKey),
                                            kCFAllocatorDefault, kNilOptions );
        if( !pluginTypes )
            continue;

        // look up UUID key this way - otherwise string case matters
//        CFShow( pluginTypes );
        context.key = pluginType;
        context.result = 0;
        CFDictionaryApplyFunction( pluginTypes, &_IOGetWithUUIDKey, &context);
        pluginName = (CFStringRef) context.result;
        if( !pluginName)
            continue;

        path = CFStringCreateMutable( kCFAllocatorDefault, 0 );
        if( !path)
            continue;
        CFStringAppendCString(path,
                            "/System/Library/Extensions/",
                            kCFStringEncodingMacRoman);
        CFStringAppend(path, pluginName);
        url = CFURLCreateWithFileSystemPath(NULL, path,
                        kCFURLPOSIXPathStyle, TRUE);
        if( !url)
            continue;

        onePlugin = CFPlugInCreate(NULL, url);

    } while( false );

//    if (pluginName && (!onePlugin))
//        printf("Could not create CFPluginRef.\n");

    if( url)
        CFRelease( url );
    if( path)
        CFRelease( path );
    if( pluginTypes )
        CFRelease( pluginTypes );
    // --

    if( onePlugin
        && (bundle = CFPlugInGetBundle(onePlugin))
        && (plist = CFBundleGetInfoDictionary(bundle))
        && (matching = (CFDictionaryRef)
            CFDictionaryGetValue(plist, CFSTR("Personality")))) {

        kr = IOServiceMatchPropertyTable( service, matching, &matches);
        if( kr != kIOReturnSuccess)
            matches = FALSE;
    } else
        matches = TRUE;

    if( matches) {
        if( onePlugin)
            *factories = CFPlugInFindFactoriesForPlugInTypeInPlugIn(pluginType, onePlugin);
        else
            *factories = 0;//CFPlugInFindFactoriesForPlugInType(pluginType);
    } else
        *factories = 0;

    *plists = 0;

    return( kr );
}
__private_extern__ void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn) {
    if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
        if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) _CFBundleUnscheduleForUnloading(CFPlugInGetBundle(plugIn));     // Make sure we are not scheduled for unloading
        __CFBundleGetPlugInData(plugIn)->_instanceCount++;
        /* Instances also retain the CFBundle */
        CFRetain(plugIn);
    }
}