예제 #1
0
kern_return_t
IOCreatePlugInInterfaceForService(io_service_t service,
                CFUUIDRef pluginType, CFUUIDRef interfaceType,
                IOCFPlugInInterface *** theInterface, SInt32 * theScore)
{
    CFDictionaryRef	plist = 0;
    CFArrayRef		plists;
    CFArrayRef		factories;
    CFMutableArrayRef	candidates;
    CFMutableArrayRef	scores;
    CFIndex		index;
    CFIndex		insert;
    CFUUIDRef		factoryID;
    kern_return_t	kr;
    SInt32		score;
    IOCFPlugInInterface **	interface;
    Boolean		haveOne;


    kr = IOFindPlugIns( service, pluginType,
                        &factories, &plists );
    if( KERN_SUCCESS != kr) {
        if (factories) CFRelease(factories);
        if (plists) CFRelease(plists);
        return( kr );
    }
    if ((KERN_SUCCESS != kr)
        || (factories == NULL)
        || (0 == CFArrayGetCount(factories))) {
//        printf("No factories for type\n");
        if (factories) CFRelease(factories);
        if (plists) CFRelease(plists);
        return( kIOReturnUnsupported );
    }
    candidates = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
    scores = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);

    // allocate and Probe all
    if (candidates && scores) {
        CFIndex numfactories = CFArrayGetCount(factories);
        for ( index = 0; index < numfactories; index++ ) {
            IUnknownVTbl **				iunknown;
    
            factoryID = (CFUUIDRef) CFArrayGetValueAtIndex(factories, index);
            iunknown = (IUnknownVTbl **)
                CFPlugInInstanceCreate(NULL, factoryID, pluginType);
            if (!iunknown) {
    //            printf("Failed to create instance (link error?)\n");
                continue;
            }
            (*iunknown)->QueryInterface(iunknown, CFUUIDGetUUIDBytes(interfaceType),
                                (LPVOID *)&interface);
    
            // Now we are done with IUnknown interface
            (*iunknown)->Release(iunknown);
    
            if (!interface) {
    //            printf("Failed to get interface.\n");
                continue;
            }
            if (plists)
                plist = (CFDictionaryRef) CFArrayGetValueAtIndex( plists, index );
            score = 0;   // from property table
            kr = (*interface)->Probe(interface, plist, service, &score);
    
            if (kIOReturnSuccess == kr) {
                CFIndex numscores = CFArrayGetCount(scores);
                for (insert = 0; insert < numscores; insert++) {
                    if (score > (SInt32) ((intptr_t) CFArrayGetValueAtIndex(scores, insert)))
                        break;
                }
                CFArrayInsertValueAtIndex(candidates, insert, (void *) interface);
                CFArrayInsertValueAtIndex(scores, insert, (void *) (intptr_t) score);
            } else
                (*interface)->Release(interface);
        }
    }


    // Start in score order
    CFIndex candidatecount = CFArrayGetCount(candidates);
    for (haveOne = false, index = 0;
         index < candidatecount;
         index++) {

        Boolean freeIt;

        if (plists)
            plist = (CFDictionaryRef) CFArrayGetValueAtIndex(plists, index );
        interface = (IOCFPlugInInterface **)
            CFArrayGetValueAtIndex(candidates, index );
        if (!haveOne) {
            haveOne = (kIOReturnSuccess == (*interface)->Start(interface, plist, service));
            freeIt = !haveOne;
            if (haveOne) {
                *theInterface = interface;
                *theScore = (SInt32) (intptr_t)
		    CFArrayGetValueAtIndex(scores, index );
            }
        } else
            freeIt = true;
        if (freeIt)
            (*interface)->Release(interface);
    }

    if (factories)
        CFRelease(factories);
    if (plists)
        CFRelease(plists);
    if (candidates)
        CFRelease(candidates);
    if (scores)
        CFRelease(scores);
    //    CFRelease(plugin);

    return (haveOne ? kIOReturnSuccess : kIOReturnNoResources);
}
예제 #2
0
static CFPlugInRef MyLoadPlugIn( void )
{
	CFPlugInRef		newPlugIn;
	CFURLRef		bundleURL;
	CFURLRef		plugInURL;
	Boolean			foundInterface	= false;

	//  Obtain a URL to the PlugIns directory inside our application.
	bundleURL	= CFBundleCopyBuiltInPlugInsURL( CFBundleGetMainBundle() );

	//  We just want to load our test plug-in, so append its name to the URL.
	plugInURL	= CFURLCreateCopyAppendingPathComponent( NULL, bundleURL, CFSTR( kPlugInName ), FALSE );

	//  Create a CFPlugin using the URL. This step causes the plug-in's types and factories to
	//  be registered with the system. Note that the plug-in's code is not actually loaded at
	//  this stage unless the plug-in is using dynamic registration.

	newPlugIn	= CFPlugInCreate( NULL, plugInURL );

	CFRelease( bundleURL );
	CFRelease( plugInURL );

	//  The plug-in was located. Now locate the interface.
	if( newPlugIn )
	{
		CFArrayRef	factories;
		
		//  See if this plug-in implements the Test type.
		factories	= CFPlugInFindFactoriesForPlugInTypeInPlugIn( kTestTypeID, newPlugIn );

		//  If there are factories for the Test type, attempt to get the IUnknown interface.
		if ( factories != NULL )
		{
			CFIndex	factoryCount;
			CFIndex	index;

	    	factoryCount	= CFArrayGetCount( factories );
	    	if ( factoryCount > 0 )
	    	{
	    		for ( index = 0 ; (index < factoryCount) && (foundInterface == false) ; index++ )
	    		{
	    			CFUUIDRef	factoryID;

	        		//  Get the factory ID for the first location in the array of IDs.
	       			factoryID = (CFUUIDRef) CFArrayGetValueAtIndex( factories, index );
	       			if ( factoryID )
	       			{
						IUnknownVTbl **iunknown;
						
						//  Use the factory ID to get an IUnknown interface. Here the plug-in code is loaded.
						iunknown	= (IUnknownVTbl **) CFPlugInInstanceCreate( NULL, factoryID, kTestTypeID );
						
						if ( iunknown )
						{
	        				//  If this is an IUnknown interface, query for the test interface.
							(*iunknown)->QueryInterface( iunknown, CFUUIDGetUUIDBytes( kTestInterfaceID ), (LPVOID *)( &gDrawBallInterface ) );

			                // Now we are done with IUnknown
			                (*iunknown)->Release( iunknown );
			                
			                if ( gDrawBallInterface )
			                {
			                	//	We found the interface we need
			                	foundInterface	= true;
			                }
						}
	       			}
	       		}
			}
		}
		
		CFRelease( factories );
	}

	if ( foundInterface == false )
	{
	    CFRelease( newPlugIn );
	    newPlugIn	= NULL;
	}

	return( newPlugIn );
}