IOUSBUserClientInit.cpp [plain text]
#include <IOKit/IOService.h>
#include <IOKit/usb/IOUSBUserClient.h>
#include <IOKit/usb/IOUSBLog.h>
#define super IOService
static int gInstances = 0;
OSDefineMetaClassAndStructors(IOUSBUserClientInit, IOService);
bool
IOUSBUserClientInit::start(IOService* provider)
{
OSObject * dictObj = NULL;
OSDictionary * providerMergeProperties = NULL;
bool result = false;
OSObject * userClientClass = NULL;
USBLog(7,"+%s[%p]::start(%p) - provider = %s", getName(), this, provider, provider->getName());
gInstances++;
if ( gInstances == 1 )
retain();
providerMergeProperties = OSDynamicCast(OSDictionary, getProperty("IOProviderMergeProperties"));
if ( !providerMergeProperties )
{
return false;
}
result = MergeDictionaryIntoProvider(provider, providerMergeProperties) ;
userClientClass = provider->getProperty("IOUSBUserClientClass");
if (userClientClass)
provider->setProperty("IOUserClientClass", userClientClass);
USBLog(7,"-%s[%p]::start", getName(), this);
return false;
}
bool
IOUSBUserClientInit::MergeDictionaryIntoProvider(IOService * provider, OSDictionary * dictionaryToMerge)
{
const OSSymbol * dictionaryEntry = NULL;
OSCollectionIterator * iter = NULL;
bool result = false;
USBLog(6,"+%s[%p]::MergeDictionary(%p)IntoProvider(%p)", getName(), this, dictionaryToMerge, provider);
if (!provider || !dictionaryToMerge)
return false;
iter = OSCollectionIterator::withCollection((OSDictionary *)dictionaryToMerge);
if ( iter != NULL )
{
while ( NULL != (dictionaryEntry = (const OSSymbol *)iter->getNextObject()) )
{
const char * str = NULL;
OSDictionary * sourceDictionary = NULL;
OSDictionary * providerDictionary = NULL;
OSObject * providerProperty = NULL;
str = dictionaryEntry->getCStringNoCopy();
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider merging \"%s\"", getName(), this, str);
providerProperty = provider->getProperty(dictionaryEntry);
if ( providerProperty )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider provider already had property %s", getName(), this, str);
providerDictionary = OSDynamicCast(OSDictionary, providerProperty);
if ( providerDictionary )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider provider's %s is also a dictionary (%p)", getName(), this, str, providerDictionary);
}
}
sourceDictionary = OSDynamicCast(OSDictionary, dictionaryToMerge->getObject(dictionaryEntry));
if ( sourceDictionary )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider source dictionary had %s as a dictionary (%p)", getName(), this, str, sourceDictionary);
}
if ( providerDictionary && sourceDictionary )
{
OSDictionary * localCopyOfProvidersDictionary;
UInt32 providerSize;
UInt32 providerSizeAfterMerge;
localCopyOfProvidersDictionary = OSDictionary::withDictionary( providerDictionary, 0);
if ( localCopyOfProvidersDictionary == NULL )
{
USBError(1,"%s[%p]::MergeDictionaryIntoProvider could not copy our provider's dictionary",getName(), this);
break;
}
providerSize = providerDictionary->getCapacity();
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider Created a local copy(%p) of dictionary (%p), size %d", getName(), this, localCopyOfProvidersDictionary, providerDictionary, (uint32_t)providerSize);
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider need to merge a dictionary (%s)", getName(), this, str);
result = MergeDictionaryIntoDictionary( sourceDictionary, localCopyOfProvidersDictionary);
if ( result )
{
providerSizeAfterMerge = providerDictionary->getCapacity();
if ( providerSizeAfterMerge != providerSize )
{
USBError(1,"%s[%p]::MergeDictionaryIntoProvider our provider's dictionary size changed (%d,%d)",getName(), this, (uint32_t)providerSize, (uint32_t)providerSizeAfterMerge);
}
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider setting property %s from merged dictionary (%p)", getName(), this, str, providerDictionary);
result = provider->setProperty( dictionaryEntry, localCopyOfProvidersDictionary );
if ( !result )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider setProperty %s , returned false", getName(), this, str);
break;
}
}
else
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider MergeDictionaryIntoDictionary(%p,%p) returned false", getName(), this, sourceDictionary, providerDictionary);
break;
}
}
else
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider setting property %s", getName(), this, str);
result = provider->setProperty(dictionaryEntry, dictionaryToMerge->getObject(dictionaryEntry));
if ( !result )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoProvider setProperty %s, returned false", getName(), this, str);
break;
}
}
}
iter->release();
}
USBLog(6,"-%s[%p]::MergeDictionaryIntoProvider(%p, %p) result %d", getName(), this, provider, dictionaryToMerge, result);
return result;
}
bool
IOUSBUserClientInit::MergeDictionaryIntoDictionary(OSDictionary * parentSourceDictionary, OSDictionary * parentTargetDictionary)
{
OSCollectionIterator* srcIterator = NULL;
OSSymbol* keyObject = NULL ;
OSObject* targetObject = NULL ;
bool result = false;
USBLog(6,"+%s[%p]::MergeDictionaryIntoDictionary(%p => %p)", getName(), this, parentSourceDictionary, parentTargetDictionary);
if (!parentSourceDictionary || !parentTargetDictionary)
return false ;
srcIterator = OSCollectionIterator::withCollection(parentSourceDictionary) ;
while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())))
{
const char * str;
OSDictionary * childSourceDictionary = NULL;
OSDictionary * childTargetDictionary = NULL;
OSObject * childTargetObject = NULL;
str = keyObject->getCStringNoCopy();
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary merging \"%s\"", getName(), this, str);
childTargetObject = parentTargetDictionary->getObject(keyObject);
if ( childTargetObject )
{
childTargetDictionary = OSDynamicCast(OSDictionary, childTargetObject);
if ( childTargetDictionary )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary target object %s is a dictionary (%p)", getName(), this, str, childTargetDictionary);
}
}
childSourceDictionary = OSDynamicCast(OSDictionary, parentSourceDictionary->getObject(keyObject));
if ( childSourceDictionary )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary source dictionary had %s as a dictionary (%p)", getName(), this, str, childSourceDictionary);
}
if ( childTargetDictionary && childSourceDictionary)
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary recursing(%p,%p)", getName(), this, childSourceDictionary, childTargetDictionary);
result = MergeDictionaryIntoDictionary(childSourceDictionary, childTargetDictionary) ;
if ( !result )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary recursing (%p,%p) failed", getName(), this, childSourceDictionary, childTargetDictionary);
break;
}
}
else
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary setting object %s into dictionary %p", getName(), this, str, parentTargetDictionary);
result = parentTargetDictionary->setObject(keyObject, parentSourceDictionary->getObject(keyObject)) ;
if ( !result )
{
USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary setObject %s, returned false", getName(), this, str);
break;
}
}
}
srcIterator->release();
USBLog(6,"-%s[%p]::MergeDictionaryIntoDictionary(%p=>(%p) result %d", getName(), this, parentSourceDictionary, parentTargetDictionary, result);
return result;
}