IOFireWireUserClientIniter.cpp [plain text]
#import "IOFireWireUserClientIniter.h"
#import <IOKit/assert.h>
#import <IOKit/IOLib.h>
#import <IOKit/IOService.h>
#import <libkern/OSAtomic.h>
#undef super
#define super IOService
IORecursiveLock * IOFireWireUserClientIniter::sIniterLock = NULL;
OSDefineMetaClassAndStructors(IOFireWireUserClientIniter, super);
OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 0);
OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 1);
OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 2);
OSMetaClassDefineReservedUnused(IOFireWireUserClientIniter, 3);
bool
IOFireWireUserClientIniter::init(OSDictionary * propTable)
{
fProvider = NULL ;
if( sIniterLock == NULL )
{
IORecursiveLock * lock = IORecursiveLockAlloc();
bool result = false;
while( sIniterLock == NULL && result == false )
{
result = OSCompareAndSwap( NULL, (UInt32)lock, (UInt32*)&sIniterLock );
}
if( result == false )
{
IORecursiveLockFree( lock );
}
}
return super::init(propTable) ;
}
bool
IOFireWireUserClientIniter::start(
IOService* provider)
{
if( provider == NULL )
{
return false;
}
fProvider = provider ;
fProvider->retain();
OSObject* dictObj = getProperty("IOProviderMergeProperties");
OSDictionary * merge_properties = OSDynamicCast(OSDictionary, dictObj);
if( merge_properties != NULL )
{
merge_properties = dictionaryDeepCopy( merge_properties );
}
if ( !merge_properties )
{
IOLog("%s %u: couldn't get merge_properties\n", __FILE__, __LINE__ ) ;
return false;
}
OSObject * userClientClassObject = merge_properties->getObject( gIOUserClientClassKey );
if( OSDynamicCast(OSString, userClientClassObject) != NULL )
{
const OSSymbol * userClientClassSymbol = OSSymbol::withString((const OSString *) userClientClassObject);
if( userClientClassSymbol != NULL )
{
merge_properties->setObject(gIOUserClientClassKey, (OSObject *) userClientClassSymbol);
userClientClassSymbol->release();
}
}
else if( OSDynamicCast(OSSymbol, userClientClassObject) == NULL )
{
merge_properties->removeObject(gIOUserClientClassKey);
}
IORecursiveLockLock( sIniterLock );
mergeProperties( fProvider, merge_properties );
IORecursiveLockUnlock( sIniterLock );
merge_properties->release();
return true ;
}
void
IOFireWireUserClientIniter::stop(IOService* provider)
{
IOService::stop(provider) ;
}
void IOFireWireUserClientIniter::free()
{
if( fProvider != NULL )
{
fProvider->release();
fProvider = NULL;
}
IOService::free();
}
void
IOFireWireUserClientIniter::mergeProperties( IORegistryEntry * dest, OSDictionary * src )
{
if( !dest || !src )
return;
OSCollectionIterator* srcIterator = OSCollectionIterator::withCollection( src );
OSSymbol* keyObject = NULL;
OSObject* destObject = NULL;
OSObject* srcObject = NULL;
while( NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())) )
{
srcObject = src->getObject(keyObject);
destObject = dest->getProperty(keyObject);
OSDictionary * destDictionary = OSDynamicCast( OSDictionary, destObject );
OSDictionary * srcDictionary = OSDynamicCast( OSDictionary, srcObject );
if( destDictionary && srcDictionary )
{
destDictionary = OSDictionary::withDictionary( destDictionary );
mergeDictionaries( destDictionary, srcDictionary );
dest->setProperty( keyObject, destDictionary );
destDictionary->release();
}
else
{
dest->setProperty( keyObject, srcObject );
}
}
srcIterator->release();
}
void
IOFireWireUserClientIniter::mergeDictionaries( OSDictionary * dest, OSDictionary * src )
{
if( !src || !dest )
return;
OSCollectionIterator* srcIterator = OSCollectionIterator::withCollection(src);
OSSymbol* keyObject = NULL;
OSObject* destObject = NULL;
OSObject* srcObject = NULL;
while( NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())) )
{
srcObject = src->getObject(keyObject);
destObject = dest->getObject(keyObject);
OSDictionary * destDictionary = OSDynamicCast( OSDictionary, destObject );
OSDictionary * srcDictionary = OSDynamicCast( OSDictionary, srcObject );
if( destDictionary && srcDictionary )
{
destDictionary = OSDictionary::withDictionary( destDictionary);
mergeDictionaries( destDictionary, srcDictionary );
dest->setObject( keyObject, destDictionary );
destDictionary->release();
}
else
{
dest->setObject( keyObject, srcObject );
}
}
srcIterator->release();
}
OSDictionary*
IOFireWireUserClientIniter::dictionaryDeepCopy(
OSDictionary* srcDictionary)
{
OSDictionary* result = NULL;
OSObject* srcObject = NULL;
OSCollectionIterator* srcIterator = NULL;
OSSymbol* keyObject = NULL;
result = OSDictionary::withCapacity(srcDictionary->getCount());
if (result)
{
srcIterator = OSCollectionIterator::withCollection(srcDictionary);
if (srcIterator)
{
while ( (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())) )
{
srcObject = srcDictionary->getObject(keyObject);
if (OSDynamicCast(OSDictionary, srcObject))
{
srcObject = dictionaryDeepCopy((OSDictionary*)srcObject);
result->setObject(keyObject, srcObject);
srcObject->release();
}
else
{
result->setObject(keyObject, srcObject);
}
}
srcIterator->release();
}
}
return result;
}