/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-class IOUserNotification : public OSIterator
+class IOUserIterator : public OSIterator
+{
+ OSDeclareDefaultStructors(IOUserIterator)
+public:
+ OSObject * userIteratorObject;
+ IOLock * lock;
+
+ static IOUserIterator * withIterator(OSIterator * iter);
+ virtual bool init( void ) APPLE_KEXT_OVERRIDE;
+ virtual void free() APPLE_KEXT_OVERRIDE;
+
+ virtual void reset() APPLE_KEXT_OVERRIDE;
+ virtual bool isValid() APPLE_KEXT_OVERRIDE;
+ virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE;
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+class IOUserNotification : public IOUserIterator
{
OSDeclareDefaultStructors(IOUserNotification)
- IONotifier * holdNotify;
- IOLock * lock;
+#define holdNotify userIteratorObject
public:
- virtual bool init( void ) APPLE_KEXT_OVERRIDE;
virtual void free() APPLE_KEXT_OVERRIDE;
virtual void setNotification( IONotifier * obj );
virtual bool isValid() APPLE_KEXT_OVERRIDE;
};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+OSDefineMetaClassAndStructors( IOUserIterator, OSIterator )
+
+IOUserIterator *
+IOUserIterator::withIterator(OSIterator * iter)
+{
+ IOUserIterator * me;
+
+ if (!iter) return (0);
+
+ me = new IOUserIterator;
+ if (me && !me->init())
+ {
+ me->release();
+ me = 0;
+ }
+ if (!me) return me;
+ me->userIteratorObject = iter;
+
+ return (me);
+}
+
+bool
+IOUserIterator::init( void )
+{
+ if (!OSObject::init()) return (false);
+
+ lock = IOLockAlloc();
+ if( !lock)
+ return( false );
+
+ return (true);
+}
+
+void
+IOUserIterator::free()
+{
+ if (userIteratorObject) userIteratorObject->release();
+ if (lock) IOLockFree(lock);
+ OSObject::free();
+}
+
+void
+IOUserIterator::reset()
+{
+ IOLockLock(lock);
+ assert(OSDynamicCast(OSIterator, userIteratorObject));
+ ((OSIterator *)userIteratorObject)->reset();
+ IOLockUnlock(lock);
+}
+
+bool
+IOUserIterator::isValid()
+{
+ bool ret;
+
+ IOLockLock(lock);
+ assert(OSDynamicCast(OSIterator, userIteratorObject));
+ ret = ((OSIterator *)userIteratorObject)->isValid();
+ IOLockUnlock(lock);
+
+ return (ret);
+}
+
+OSObject *
+IOUserIterator::getNextObject()
+{
+ OSObject * ret;
+
+ IOLockLock(lock);
+ assert(OSDynamicCast(OSIterator, userIteratorObject));
+ ret = ((OSIterator *)userIteratorObject)->getNextObject();
+ IOLockUnlock(lock);
+
+ return (ret);
+}
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
extern "C" {
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#undef super
-#define super OSIterator
-OSDefineMetaClass( IOUserNotification, OSIterator )
-OSDefineAbstractStructors( IOUserNotification, OSIterator )
+#define super IOUserIterator
+OSDefineMetaClass( IOUserNotification, IOUserIterator )
+OSDefineAbstractStructors( IOUserNotification, IOUserIterator )
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-bool IOUserNotification::init( void )
-{
- if( !super::init())
- return( false );
-
- lock = IOLockAlloc();
- if( !lock)
- return( false );
-
- return( true );
-}
-
void IOUserNotification::free( void )
{
- if( holdNotify)
- holdNotify->remove();
+ if (holdNotify)
+ {
+ assert(OSDynamicCast(IONotifier, holdNotify));
+ ((IONotifier *)holdNotify)->remove();
+ holdNotify = 0;
+ }
// can't be in handler now
- if( lock)
- IOLockFree( lock );
-
super::free();
}
void IOUserNotification::setNotification( IONotifier * notify )
{
- IONotifier * previousNotify;
+ OSObject * previousNotify;
IOLockLock( gIOObjectPortLock);
IOLockUnlock( gIOObjectPortLock);
if( previousNotify)
- previousNotify->remove();
+ {
+ assert(OSDynamicCast(IONotifier, previousNotify));
+ ((IONotifier *)previousNotify)->remove();
+ }
}
void IOUserNotification::reset()
if( !(out = OSDynamicCast( cls, obj))) \
return( kIOReturnBadArgument )
+#define CHECKLOCKED(cls,obj,out) \
+ IOUserIterator * oIter; \
+ cls * out; \
+ if( !(oIter = OSDynamicCast(IOUserIterator, obj))) \
+ return (kIOReturnBadArgument); \
+ if( !(out = OSDynamicCast(cls, oIter->userIteratorObject))) \
+ return (kIOReturnBadArgument)
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Create a vm_map_copy_t or kalloc'ed data for memory
io_object_t iterator,
io_object_t *object )
{
+ IOReturn ret;
OSObject * obj;
CHECK( OSIterator, iterator, iter );
if( obj) {
obj->retain();
*object = obj;
- return( kIOReturnSuccess );
+ ret = kIOReturnSuccess;
} else
- return( kIOReturnNoDevice );
+ ret = kIOReturnNoDevice;
+
+ return (ret);
}
/* Routine io_iterator_reset */
obj = matching_size ? OSUnserializeXML(matching, matching_size)
: OSUnserializeXML(matching);
if( (dict = OSDynamicCast( OSDictionary, obj))) {
+
*matches = service->passiveMatch( dict );
kr = kIOReturnSuccess;
} else
obj = matching_size ? OSUnserializeXML(matching, matching_size)
: OSUnserializeXML(matching);
if( (dict = OSDynamicCast( OSDictionary, obj))) {
- *existing = IOService::getMatchingServices( dict );
+ *existing = IOUserIterator::withIterator(IOService::getMatchingServices( dict ));
kr = kIOReturnSuccess;
} else
kr = kIOReturnBadArgument;
if( master_port != master_device_port)
return( kIOReturnNotPrivileged);
- *iterator = IORegistryIterator::iterateOver(
- IORegistryEntry::getPlane( plane ), options );
+ *iterator = IOUserIterator::withIterator(
+ IORegistryIterator::iterateOver(
+ IORegistryEntry::getPlane( plane ), options ));
return( *iterator ? kIOReturnSuccess : kIOReturnBadArgument );
}
{
CHECK( IORegistryEntry, registry_entry, entry );
- *iterator = IORegistryIterator::iterateOver( entry,
- IORegistryEntry::getPlane( plane ), options );
+ *iterator = IOUserIterator::withIterator(
+ IORegistryIterator::iterateOver( entry,
+ IORegistryEntry::getPlane( plane ), options ));
return( *iterator ? kIOReturnSuccess : kIOReturnBadArgument );
}
kern_return_t is_io_registry_iterator_enter_entry(
io_object_t iterator )
{
- CHECK( IORegistryIterator, iterator, iter );
+ CHECKLOCKED( IORegistryIterator, iterator, iter );
+ IOLockLock(oIter->lock);
iter->enterEntry();
+ IOLockUnlock(oIter->lock);
return( kIOReturnSuccess );
}
{
bool didIt;
- CHECK( IORegistryIterator, iterator, iter );
+ CHECKLOCKED( IORegistryIterator, iterator, iter );
+ IOLockLock(oIter->lock);
didIt = iter->exitEntry();
+ IOLockUnlock(oIter->lock);
return( didIt ? kIOReturnSuccess : kIOReturnNoDevice );
}