Пример #1
0
// ======================================================================
void ListHookedDevice::Item::setDeviceIdentifier(void) {
  if (!device_) return;

  IORegistryEntry* dev = device_;

  while (dev) {
    const OSNumber* vid = nullptr;
    vid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDVendorIDKey));

    const OSNumber* pid = nullptr;
    pid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDProductIDKey));

    if (vid && pid) {
      deviceIdentifier_.setVendor(DeviceVendor(vid->unsigned32BitValue()));
      deviceIdentifier_.setProduct(DeviceProduct(pid->unsigned32BitValue()));

      goto finish;

    } else {
      // ApplePS2Keyboard does not have ProductID,
      // so we check for Manufacturer and Product strings
      const char* name = dev->getName();

      if (name && strcmp(name, "ApplePS2Keyboard") == 0) {
        // kIOHIDManufacturerKey == "Manufacturer"
        // kIOHIDProductKey == "Product"
        const OSString* manufacturer = OSDynamicCast(OSString, dev->getProperty(kIOHIDManufacturerKey));
        const OSString* product = OSDynamicCast(OSString, dev->getProperty(kIOHIDProductKey));

        if (manufacturer && product) {
          if (manufacturer->isEqualTo("Apple") &&
              product->isEqualTo("Keyboard")) {
            deviceIdentifier_.setVendor(DeviceVendor::APPLE_COMPUTER);
            deviceIdentifier_.setProduct(DeviceProduct::APPLE_INTERNAL_KEYBOARD_TRACKPAD_0x0218);
            goto finish;
          }
        }
      }
    }

    // check parent property.
    dev = dev->getParentEntry(IORegistryEntry::getPlane(kIOServicePlane));
  }

finish:
  // Set LocationID
  if (dev) {
    const OSNumber* locationid = nullptr;
    locationid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDLocationIDKey));
    if (locationid) {
      deviceIdentifier_.setLocation(DeviceLocation(locationid->unsigned32BitValue()));
    }
  }

  IOLOG_DEBUG("HookedDevice::setVendorProductLocation device_:%p, vendor:0x%04x, product:0x%04x location:0x%04x\n",
              device_,
              deviceIdentifier_.getVendor().get(),
              deviceIdentifier_.getProduct().get(),
              deviceIdentifier_.getLocation().get());
}
Пример #2
0
  void
  ListHookedDevice::Item::setVendorProduct(void)
  {
    if (! device_) return;

    IORegistryEntry* dev = device_;

    while (dev) {
      const OSNumber* vid = NULL;
      vid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDVendorIDKey));

      const OSNumber* pid = NULL;
      pid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDProductIDKey));

      if (vid && pid) {
        vendor_ = vid->unsigned32BitValue();
        product_ = pid->unsigned32BitValue();

        goto finish;
      }

      // check parent property.
      dev = dev->getParentEntry(IORegistryEntry::getPlane(kIOServicePlane));
    }

  finish:
    IOLOG_DEBUG("HookedDevice::setVendorProduct device_:%p, vendor_:0x%04x, product_:0x%04x\n", device_, vendor_.get(), product_.get());
  }
/*
 * Copyright (c) 1998-2013 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

#include <IOKit/IODeviceTreeSupport.h>
#include <IOKit/IOMessage.h>
#include <IOKit/storage/IOPartitionScheme.h>

#define super IOStorage
OSDefineMetaClassAndStructors(IOPartitionScheme, IOStorage)

#ifndef __LP64__
extern IOStorageAttributes gIOStorageAttributesUnsupported;
#endif /* !__LP64__ */

static SInt32 partitionComparison( const OSMetaClassBase * object1,
                                   const OSMetaClassBase * object2,
                                   void *                  context )
{
    //
    // Internal comparison routine for sorting partitions in an ordered set.
    //

    UInt64 base1 = ( ( IOMedia * ) object1 )->getBase( );
    UInt64 base2 = ( ( IOMedia * ) object2 )->getBase( );

#if TARGET_OS_EMBEDDED
    OSString * uuid1 = OSDynamicCast( OSString, ( ( IOMedia * ) object1 )->getProperty( kIOMediaUUIDKey ) );
    OSString * uuid2 = OSDynamicCast( OSString, ( ( IOMedia * ) object2 )->getProperty( kIOMediaUUIDKey ) );

    if ( uuid1 || uuid2 )
    {
        if ( uuid1 == 0 ) return -1;
        if ( uuid2 == 0 ) return  1;

        return strcmp( uuid2->getCStringNoCopy( ), uuid1->getCStringNoCopy( ) );
    }
#endif /* TARGET_OS_EMBEDDED */

    if ( base1 < base2 ) return  1;
    if ( base1 > base2 ) return -1;

    return 0;
}

IOMedia * IOPartitionScheme::getProvider() const
{
    //
    // Obtain this object's provider.  We override the superclass's method
    // to return a more specific subclass of OSObject -- an IOMedia.  This
    // method serves simply as a convenience to subclass developers.
    //

    return (IOMedia *) IOService::getProvider();
}

bool IOPartitionScheme::init(OSDictionary * properties)
{
    //
    // Initialize this object's minimal state.
    //

    if (super::init(properties) == false)  return false;

    _openLevel         = kIOStorageAccessNone;
    _openReaders       = OSSet::withCapacity(16);
    _openReaderWriters = OSSet::withCapacity(16);

    if (_openReaders == 0 || _openReaderWriters == 0) return false;

    return true;
}

void IOPartitionScheme::free()
{
    //
    // Free all of this object's outstanding resources.
    //

    if (_openReaders)        _openReaders->release();
    if (_openReaderWriters)  _openReaderWriters->release();

    super::free();
}

bool IOPartitionScheme::handleOpen(IOService *  client,
                                   IOOptionBits options,
                                   void *       argument)
{
    //
    // The handleOpen method grants or denies permission to access this object
    // to an interested client.  The argument is an IOStorageAccess value that
    // specifies the level of access desired -- reader or reader-writer.
    //
    // This method can be invoked to upgrade or downgrade the access level for
    // an existing client as well.  The previous access level will prevail for
    // upgrades that fail, of course.   A downgrade should never fail.  If the
    // new access level should be the same as the old for a given client, this
    // method will do nothing and return success.  In all cases, one, singular
    // close-per-client is expected for all opens-per-client received.
    //
    // This implementation replaces the IOService definition of handleOpen().
    //
    // We are guaranteed that no other opens or closes will be processed until
    // we make our decision, change our state, and return from this method.
    //

    IOStorageAccess access  = (uintptr_t) argument;
    IOStorageAccess level;

    assert(client);
    assert( access == kIOStorageAccessReader       ||
            access == kIOStorageAccessReaderWriter );

    //
    // A partition scheme multiplexes the opens it receives from several clients
    // and sends one open to the level below that satisfies the highest level of
    // access.
    //

    unsigned writers = _openReaderWriters->getCount();

    if (_openReaderWriters->containsObject(client))  writers--;
    if (access == kIOStorageAccessReaderWriter)  writers++;

    level = (writers) ? kIOStorageAccessReaderWriter : kIOStorageAccessReader;

    //
    // Determine whether the levels below us accept this open or not (we avoid
    // the open if the required access is the access we already hold).
    //

    if ( _openLevel != level )
    {
        IOStorage * provider;

        provider = OSDynamicCast( IOStorage, getProvider( ) );

        if ( provider )
        {
            bool success;

            level = ( level | kIOStorageAccessSharedLock );

            success = provider->open( this, options, level );

            level = ( level & kIOStorageAccessReaderWriter );

            if ( success == false )
            {
                return false;
            }
        }
    }

    //
    // Process the open.
    //

    if (access == kIOStorageAccessReader)
    {
        _openReaders->setObject(client);

        _openReaderWriters->removeObject(client);           // (for a downgrade)
    }
    else // (access == kIOStorageAccessReaderWriter)
    {
        _openReaderWriters->setObject(client);

        _openReaders->removeObject(client);                  // (for an upgrade)
    }

    _openLevel = level;

    return true;
}

bool IOPartitionScheme::handleIsOpen(const IOService * client) const
{
    //
    // The handleIsOpen method determines whether the specified client, or any
    // client if none is specificed, presently has an open on this object.
    //
    // This implementation replaces the IOService definition of handleIsOpen().
    //
    // We are guaranteed that no other opens or closes will be processed until
    // we return from this method.
    //

    if (client == 0)  return (_openLevel != kIOStorageAccessNone);

    return ( _openReaderWriters->containsObject(client) ||
             _openReaders->containsObject(client)       );
}

void IOPartitionScheme::handleClose(IOService * client, IOOptionBits options)
{
    //
    // The handleClose method closes the client's access to this object.
    //
    // This implementation replaces the IOService definition of handleClose().
    //
    // We are guaranteed that no other opens or closes will be processed until
    // we change our state and return from this method.
    //

    assert(client);

    //
    // Process the close.
    //

    if (_openReaderWriters->containsObject(client))  // (is it a reader-writer?)
    {
        _openReaderWriters->removeObject(client);
    }
    else if (_openReaders->containsObject(client))  // (is the client a reader?)
    {
        _openReaders->removeObject(client);
    }
    else                                      // (is the client is an imposter?)
    {
        assert(0);
        return;
    }

    //
    // Reevaluate the open we have on the level below us.  If no opens remain,
    // we close, or if no reader-writer remains, but readers do, we downgrade.
    //

    IOStorageAccess level;

    if (_openReaderWriters->getCount())  level = kIOStorageAccessReaderWriter;
    else if (_openReaders->getCount())   level = kIOStorageAccessReader;
    else                                 level = kIOStorageAccessNone;

    if ( _openLevel != level )
    {
        IOStorage * provider;

        provider = OSDynamicCast( IOStorage, getProvider( ) );

        if ( provider )
        {
            if ( level == kIOStorageAccessNone )
            {
                provider->close( this, options );
            }
            else
            {
                bool success;

                level = ( level | kIOStorageAccessSharedLock );

                success = provider->open( this, 0, level );

                level = ( level & kIOStorageAccessReaderWriter );

                assert( success );
            }
         }

         _openLevel = level;
    }
}

void IOPartitionScheme::read(IOService *           client,
                             UInt64                byteStart,
                             IOMemoryDescriptor *  buffer,
                             IOStorageAttributes * attributes,
                             IOStorageCompletion * completion)
{
    //
    // Read data from the storage object at the specified byte offset into the
    // specified buffer, asynchronously.   When the read completes, the caller
    // will be notified via the specified completion action.
    //
    // The buffer will be retained for the duration of the read.
    //
    // For simple partition schemes, the default behavior is to simply pass the
    // read through to the provider media.  More complex partition schemes such
    // as RAID will need to do extra processing here.
    //

#ifndef __LP64__
    if ( IOStorage::_expansionData )
    {
        if ( attributes == &gIOStorageAttributesUnsupported )
        {
            attributes = NULL;
        }
        else
        {
            IOStorage::read( client, byteStart, buffer, attributes, completion );

            return;
        }
    }
#endif /* !__LP64__ */

    getProvider( )->read( this, byteStart, buffer, attributes, completion );
}

void IOPartitionScheme::write(IOService *           client,
                              UInt64                byteStart,
                              IOMemoryDescriptor *  buffer,
                              IOStorageAttributes * attributes,
                              IOStorageCompletion * completion)
{
    //
    // Write data into the storage object at the specified byte offset from the
    // specified buffer, asynchronously.   When the write completes, the caller
    // will be notified via the specified completion action.
    //
    // The buffer will be retained for the duration of the write.
    //
    // For simple partition schemes, the default behavior is to simply pass the
    // write through to the provider media. More complex partition schemes such
    // as RAID will need to do extra processing here.
    //

#ifndef __LP64__
    if ( IOStorage::_expansionData )
    {
        if ( attributes == &gIOStorageAttributesUnsupported )
        {
            attributes = NULL;
        }
        else
        {
            IOStorage::write( client, byteStart, buffer, attributes, completion );

            return;
        }
    }
#endif /* !__LP64__ */

    getProvider( )->write( this, byteStart, buffer, attributes, completion );
}

IOReturn IOPartitionScheme::synchronizeCache(IOService * client)
{
    //
    // Flush the cached data in the storage object, if any, synchronously.
    //

    return getProvider()->synchronizeCache(this);
}

IOReturn IOPartitionScheme::unmap(IOService *       client,
                                  IOStorageExtent * extents,
                                  UInt32            extentsCount,
                                  UInt32            options)
{
    //
    // Delete unused data from the storage object at the specified byte offsets,
    // synchronously.
    //

    return getProvider( )->unmap( this, extents, extentsCount, options );
}

bool IOPartitionScheme::lockPhysicalExtents(IOService * client)
{
    //
    // Lock the contents of the storage object against relocation temporarily,
    // for the purpose of getting physical extents.
    //

    return getProvider( )->lockPhysicalExtents( this );
}

IOStorage * IOPartitionScheme::copyPhysicalExtent(IOService * client,
                                                  UInt64 *    byteStart,
                                                  UInt64 *    byteCount)
{
    //
    // Convert the specified byte offset into a physical byte offset, relative
    // to a physical storage object.  This call should only be made within the
    // context of lockPhysicalExtents().
    //

    return getProvider( )->copyPhysicalExtent( this, byteStart, byteCount );
}

void IOPartitionScheme::unlockPhysicalExtents(IOService * client)
{
    //
    // Unlock the contents of the storage object for relocation again.  This
    // call must balance a successful call to lockPhysicalExtents().
    //

    getProvider( )->unlockPhysicalExtents( this );
}

#ifdef __LP64__
bool IOPartitionScheme::attachMediaObjectToDeviceTree(IOMedia * media)
#else /* !__LP64__ */
bool IOPartitionScheme::attachMediaObjectToDeviceTree(IOMedia *    media,
                                                      IOOptionBits options)
#endif /* !__LP64__ */
{
    //
    // Attach the given media object to the device tree plane.
    //

    IORegistryEntry * parent = this;

    while ( (parent = parent->getParentEntry(gIOServicePlane)) )
    {
        if ( parent->inPlane(gIODTPlane) )
        {
            char         location[ 32 ];
            const char * locationOfParent = parent->getLocation(gIODTPlane);
            const char * nameOfParent     = parent->getName(gIODTPlane);

            if ( locationOfParent == 0 )  break;

            if ( OSDynamicCast(IOMedia, parent) == 0 )  break;

            parent = parent->getParentEntry(gIODTPlane);

            if ( parent == 0 )  break;

            if ( media->attachToParent(parent, gIODTPlane) == false )  break;

            strlcpy(location, locationOfParent, sizeof(location));
            if ( strchr(location, ':') )  *(strchr(location, ':') + 1) = 0;
            strlcat(location, media->getLocation(), sizeof(location) - strlen(location));
            media->setLocation(location, gIODTPlane);
            media->setName(nameOfParent, gIODTPlane);

            return true;
        }
    }

    return false;
}
Пример #4
0
IOService * IOPMPagingPlexus::findProvider ( IOService * mediaObject )
{
    IORegistryEntry * node = mediaObject;
    
    if ( mediaObject == NULL ) {
        return NULL;
    }
    
    while ( node ) {
        if ( node->inPlane(gIOPowerPlane) ) {
            return (IOService *)node;
        }
        node = node->getParentEntry(gIOServicePlane);
    }
    return NULL;
}
Пример #5
0
IOReturn
IOPolledFilePollersClose(IOPolledFileIOVars * filevars, uint32_t state)
{
    IOPolledFilePollers * vars = filevars->pollers;
    IOPolledInterface * poller;
    IORegistryEntry *   next;
    IOReturn            err;
    int32_t		idx;

    (void) IOPolledFilePollersIODone(vars, false);

    if (kIOPolledPostflightState == state)
    {
        vars->openCount--;
        if (vars->openCount)
        {
            // 21207427
            IOPolledFilePollersOpen(filevars, vars->openState, vars->abortable);
            return (kIOReturnSuccess);
        }
    }

    for (idx = 0, err = kIOReturnSuccess;
            (poller = (IOPolledInterface *) vars->pollers->getObject(idx));
            idx++)
    {
        err = poller->close(state);
        if (err) HIBLOG("IOPolledInterface::close[%d] 0x%x\n", idx, err);
    }

    if (kIOPolledPostflightState == state)
    {
        next = vars->media;
        while (next)
        {
            next->removeProperty(kIOPolledInterfaceActiveKey);
            next = next->getParentEntry(gIOServicePlane);
        }

        if (vars->ioBuffer)
        {
            vars->ioBuffer->release();
            vars->ioBuffer = 0;
        }
    }
    return (err);
}
Пример #6
0
void IOPMPagingPlexus::processSiblings ( IOService * aNode )
{
    OSIterator *	parentIterator;
    IORegistryEntry *	nextNub;
    IORegistryEntry *	nextParent;
    OSIterator *	siblingIterator;
    IORegistryEntry *	nextSibling;

    parentIterator = aNode->getParentIterator(gIOPowerPlane);		// iterate parents of this node

    if ( parentIterator ) {
        while ( true ) {
            if ( ! (nextNub = (IORegistryEntry *)(parentIterator->getNextObject())) ) {
                parentIterator->release();
                break;
            }
            if ( OSDynamicCast(IOPowerConnection,nextNub) ) {
                nextParent = nextNub->getParentEntry(gIOPowerPlane);
                if ( nextParent == getPMRootDomain() ) {
                    continue;				// plexus already has root's children
                }
                if ( nextParent == this ) {
                    parentIterator->release();
                    removePowerChild((IOPowerConnection *)nextNub);
                    break;
                }
                siblingIterator = nextParent->getChildIterator(gIOPowerPlane);
                                                                                // iterate children of this parent
                if ( siblingIterator ) {
                    while ( (nextSibling = (IORegistryEntry *)(siblingIterator->getNextObject())) ) {
                        if ( OSDynamicCast(IOPowerConnection,nextSibling) ) {
                            nextSibling = nextSibling->getChildEntry(gIOPowerPlane);
                            if ( nextSibling != aNode ) {			// non-ancestor of driver gets
                                addPowerChild((IOService *)nextSibling);	// plexus as parent
                            }
                        }
                    }
                    siblingIterator->release();
                }
                processSiblings((IOService *)nextParent);			// do the same thing to this parent
            }
   	}
    }
}
Пример #7
0
// ----------------------------------------------------------------------
bool org_pqrs_driver_Seil::isTargetDevice(IOHIKeyboard* kbd) {
    if (!kbd) return false;

    // ------------------------------------------------------------
    uint32_t vendorID = 0;
    uint32_t productID = 0;

    IORegistryEntry* dev = kbd;

    while (dev) {
        const OSNumber* vid = nullptr;
        vid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDVendorIDKey));

        const OSNumber* pid = nullptr;
        pid = OSDynamicCast(OSNumber, dev->getProperty(kIOHIDProductIDKey));

        if (vid && pid) {
            vendorID = vid->unsigned32BitValue();
            productID = pid->unsigned32BitValue();

            goto finish;
        }

        // check parent property.
        dev = dev->getParentEntry(IORegistryEntry::getPlane(kIOServicePlane));
    }

finish:
    enum {
        VENDOR_LOGITECH = 0x046d,
        PRODUCT_LOGITECH_G700_LASER_MOUSE = 0xc06b,
    };

    if (vendorID == VENDOR_LOGITECH && productID == PRODUCT_LOGITECH_G700_LASER_MOUSE) {
        IOLOG_INFO("vendorID:0x%04x, productID:0x%04x (skipped)\n", vendorID, productID);
        return false;
    }

    return true;
}
static void createNubs(IOService *provider) {
	const char nameID[2][8] = {"@0,name", "@1,name"};
	const char name[11] = "Aty,Radeon";
	const char typeID[2][15] = {"@0,device_type", "@1,device_type"};
	const char type[] = "display";
	OSObject *tempObj;
	
	int i;
	
	if (provider->getProperty(kIONDRVIgnoreKey)) return;
	provider->setProperty(kIONDRVIgnoreKey, kOSBooleanTrue);	//prevent IONDRVFramebuffer from match
	
	LOG("createNubs\n");
	
	if (!provider->getProperty("@0,name") && !provider->getProperty("@1,name")) {
		for (i = 0;i < 2;i++) {	// Debug
			tempObj = OSData::withBytes(name, 11);
			provider->setProperty(nameID[i], tempObj);
			tempObj->release();
			tempObj = OSData::withBytes(type, 8);
			provider->setProperty(typeID[i], tempObj);
			tempObj->release();
		}
	}
	// have to move below part from IONDRVFramebuffer to make it work
	IORegistryIterator * iter;
	IORegistryEntry *    next;
	IOService *          newNub;
	OSArray *            toDo = 0;
	bool                 firstLevel;
    OSData *            data;
	
	if (provider->getProperty("@0,name"))
	{
		OSDictionary *         dict;
		OSCollectionIterator * keys;
		const OSSymbol *       key;
		char                   buffer[80];
		const char *           keyChrs;
		size_t                 len;
		char                   c;
		
		dict = provider->dictionaryWithProperties();
		keys = OSCollectionIterator::withCollection(dict);
		if (dict)
			dict->release();
		if (keys)
		{
			while ((key = OSDynamicCast(OSSymbol, keys->getNextObject())))
			{
				keyChrs = key->getCStringNoCopy();
				if ('@' != keyChrs[0])
					continue;
				
				len = 0;
				do
				{
					c = keyChrs[len];
					if (!c || (c == ','))
						break;
					buffer[len] = c;
					len++;
				}
				while (len < (sizeof(buffer) - 1));
				if (!c)
					continue;
				
				buffer[len] = 0;
				keyChrs += len + 1;
				
				next = provider->childFromPath(buffer, gIODTPlane);
				if (!next)
				{
					next = new IOService;
					if (next && !next->init())
					{
						next->release();
						next = 0;
					}
					if (!next)
						continue;
					next->setLocation(&buffer[1]);
					if (!next->attachToParent(provider, gIODTPlane))
						continue;
				}
				
				OSObject * obj = dict->getObject(key);
				next->setProperty(keyChrs, dict->getObject(key));
				if (!strcmp(keyChrs, "name"))
				{
					OSData * data = OSDynamicCast(OSData, obj);
					if (data)
						next->setName((const char *) data->getBytesNoCopy());
				}
				next->release();
				provider->removeProperty(key);
			}
			keys->release();
		}
	}
	
	iter = IORegistryIterator::iterateOver( provider, gIODTPlane, 0 );
	toDo = OSArray::withCapacity(2);
	
	if (iter && toDo)
	{
		bool haveDoneLibInit = false;
		UInt32 index = 0;
		do
		{
			while ((next = (IORegistryEntry *) iter->getNextObject()))
			{
				firstLevel = (provider == next->getParentEntry(gIODTPlane));
				if (firstLevel)
				{
					data = OSDynamicCast( OSData, next->getProperty("device_type"));
					if (!data || (0 != strcmp("display", (char *) data->getBytesNoCopy())))
						continue;
					
					if (!haveDoneLibInit)
					{
						haveDoneLibInit = (kIOReturnSuccess == _IONDRVLibrariesInitialize(provider));
						if (!haveDoneLibInit)
							continue;
					}
					next->setProperty( kIOFBDependentIDKey, (uintptr_t) provider, 64 );
					next->setProperty( kIOFBDependentIndexKey, index, 32 );
					next->setProperty( kIONDRVIgnoreKey, kOSBooleanTrue );
					index++;
				}
				
				toDo->setObject( next );
				iter->enterEntry();
			}
		}
		while (iter->exitEntry());
	}
	if (iter)
		iter->release();
	
	if (toDo)
	{
		OSObject * obj;
		OSArray  * deviceMemory;
		obj = provider->copyProperty(gIODeviceMemoryKey);
		deviceMemory = OSDynamicCast(OSArray, obj);
		
		for (unsigned int i = 0;
			 (next = (IORegistryEntry *) toDo->getObject(i));
			 i++)
		{
			newNub = new IONDRVDevice;
			if (!newNub)
				continue;
			if (!newNub->init(next, gIODTPlane))
			{
				newNub->free();
				newNub = 0;
				continue;
			}
			if (deviceMemory)
				newNub->setDeviceMemory(deviceMemory);
			newNub->attach(provider);
			newNub->registerService(kIOServiceSynchronous);
		}
		if (obj)
			obj->release();
		toDo->release();
	}
}
Пример #9
0
IOPolledFilePollers *
IOPolledFilePollers::copyPollers(IOService * media)
{
    IOPolledFilePollers * vars;
    IOReturn              err;
    IOService       * service;
    OSObject        * obj;
    IORegistryEntry * next;
    IORegistryEntry * child;

    if ((obj = media->copyProperty(kIOPolledInterfaceStackKey)))
    {
        return (OSDynamicCast(IOPolledFilePollers, obj));
    }

    do
    {
        vars = OSTypeAlloc(IOPolledFilePollers);
        vars->init();

        vars->pollers = OSArray::withCapacity(4);
        if (!vars->pollers)
        {
            err = kIOReturnNoMemory;
            break;
        }

        next = vars->media = media;
        do
        {
            IOPolledInterface * poller;
            OSObject *          obj;

            obj = next->getProperty(kIOPolledInterfaceSupportKey);
            if (kOSBooleanFalse == obj)
            {
                vars->pollers->flushCollection();
                break;
            }
            else if ((poller = OSDynamicCast(IOPolledInterface, obj)))
                vars->pollers->setObject(poller);

            if ((service = OSDynamicCast(IOService, next))
                    && service->getDeviceMemory()
                    && !vars->pollers->getCount())	break;

            child = next;
        }
        while ((next = child->getParentEntry(gIOServicePlane))
                && child->isParent(next, gIOServicePlane, true));

        if (!vars->pollers->getCount())
        {
            err = kIOReturnUnsupported;
            break;
        }
    }
    while (false);

    media->setProperty(kIOPolledInterfaceStackKey, vars);

    return (vars);
}