IOHIDUserClientIniter.cpp [plain text]
#include <libkern/OSAtomic.h>
#include <libkern/c++/OSDictionary.h>
#include <IOKit/IOLib.h>
#include "IOHIDUserClientIniter.h"
#define super IOService
OSDefineMetaClassAndStructors(IOHIDUserClientIniter, IOService);
bool IOHIDUserClientIniter::start(IOService* provider)
{
OSObject * providerMergeProperties = NULL;
bool result = false;
providerMergeProperties = copyProperty("IOProviderMergeProperties");
result = mergeDictionaryIntoProvider(provider, OSDynamicCast(OSDictionary, providerMergeProperties));
OSSafeReleaseNULL(providerMergeProperties);
return result;
}
bool IOHIDUserClientIniter::mergeDictionaryIntoProvider(IOService * provider, OSDictionary * dictionaryToMerge)
{
const OSSymbol * dictionaryEntry = NULL;
OSCollectionIterator * iter = NULL;
bool result = false;
if (!provider || !dictionaryToMerge)
return false;
iter = OSCollectionIterator::withCollection((OSDictionary *)dictionaryToMerge);
if ( iter != NULL ) {
OSObject * providerObject = NULL;
while ( NULL != (dictionaryEntry = (const OSSymbol *)iter->getNextObject()) ) {
OSDictionary * sourceDictionary = NULL;
OSDictionary * providerDictionary = NULL;
OSSafeReleaseNULL(providerObject); providerObject = provider->copyProperty(dictionaryEntry);
sourceDictionary = OSDynamicCast(OSDictionary, dictionaryToMerge->getObject(dictionaryEntry));
providerDictionary = OSDynamicCast(OSDictionary, providerDictionary);
if ( providerDictionary && sourceDictionary ) {
OSDictionary *localCopyOfProvidersDictionary;
UInt32 providerSize;
UInt32 providerSizeAfterMerge;
localCopyOfProvidersDictionary = OSDictionary::withDictionary( providerDictionary, 0);
if ( localCopyOfProvidersDictionary == NULL )
break;
providerSize = providerDictionary->getCapacity();
result = mergeDictionaryIntoDictionary( sourceDictionary, localCopyOfProvidersDictionary);
if ( result ) {
providerSizeAfterMerge = providerDictionary->getCapacity();
result = provider->setProperty( dictionaryEntry, localCopyOfProvidersDictionary );
if ( !result )
break;
}
else
break;
} else {
result = provider->setProperty(dictionaryEntry, dictionaryToMerge->getObject(dictionaryEntry));
if ( !result )
break;
}
}
OSSafeReleaseNULL(providerObject); iter->release();
}
return result;
}
bool IOHIDUserClientIniter::mergeDictionaryIntoDictionary(OSDictionary * parentSourceDictionary, OSDictionary * parentTargetDictionary)
{
OSCollectionIterator* srcIterator = NULL;
OSSymbol* keyObject = NULL;
bool result = false;
if (!parentSourceDictionary || !parentTargetDictionary)
return false ;
srcIterator = OSCollectionIterator::withCollection(parentSourceDictionary);
while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject()))) {
OSDictionary * childSourceDictionary = NULL;
OSDictionary * childTargetDictionary = NULL;
OSObject * childTargetObject = NULL;
childTargetObject = parentTargetDictionary->getObject(keyObject);
if ( childTargetObject )
childTargetDictionary = OSDynamicCast(OSDictionary, childTargetObject);
childSourceDictionary = OSDynamicCast(OSDictionary, parentSourceDictionary->getObject(keyObject));
if ( childTargetDictionary && childSourceDictionary) {
result = mergeDictionaryIntoDictionary(childSourceDictionary, childTargetDictionary) ;
if ( !result )
break;
} else {
result = parentTargetDictionary->setObject(keyObject, parentSourceDictionary->getObject(keyObject)) ;
if ( !result )
break;
}
}
srcIterator->release();
return result;
}