Exemple #1
0
void db_dumpiojunk( const IORegistryPlane * plane )
{
    IORegistryEntry *		next;
    IORegistryIterator * 	iter;
    OSOrderedSet *		all;
    char			format[] = "%xxxs";
    IOService *			service;

    iter = IORegistryIterator::iterateOver( plane );

    all = iter->iterateAll();
    if( all) {
        dbugprintf("Count %d\n", all->getCount() );
        all->release();
    } else dbugprintf("Empty\n");

    iter->reset();
    while( (next = iter->getNextObjectRecursive())) {
		snprintf(format + 1, sizeof(format) - 1, "%ds", 2 * next->getDepth( plane ));
		dbugprintf( format, "");
		dbugprintf( "%s", next->getName( plane ));
		if( (next->getLocation( plane )))
				dbugprintf("@%s", next->getLocation( plane ));
		dbugprintf(" <class %s", next->getMetaClass()->getClassName());
			if( (service = OSDynamicCast(IOService, next)))
				dbugprintf(", busy %ld", service->getBusyState());
		dbugprintf( ">\n");
    }
    iter->release();
}
Exemple #2
0
void IOPrintPlane( const IORegistryPlane * plane )
{
    IORegistryEntry *		next;
    IORegistryIterator * 	iter;
    OSOrderedSet *		all;
    char			format[] = "%xxxs";
    IOService *			service;

    iter = IORegistryIterator::iterateOver( plane );
    assert( iter );
    all = iter->iterateAll();
    if( all) {
        DEBG("Count %d\n", all->getCount() );
        all->release();
    } else
	DEBG("Empty\n");

    iter->reset();
    while( (next = iter->getNextObjectRecursive())) {
	snprintf(format + 1, sizeof(format) - 1, "%ds", 2 * next->getDepth( plane ));
	DEBG( format, "");
	DEBG( "\033[33m%s", next->getName( plane ));
	if( (next->getLocation( plane )))
            DEBG("@%s", next->getLocation( plane ));
	DEBG("\033[0m <class %s", next->getMetaClass()->getClassName());
        if( (service = OSDynamicCast(IOService, next)))
            DEBG(", busy %ld", (long) service->getBusyState());
	DEBG( ">\n");
//	IOSleep(250);
    }
    iter->release();
}
Exemple #3
0
IOReturn IOI2CMaxim1631::publishChildren(IOService *nub)
{
    OSIterator			*childIterator = NULL;
    IORegistryEntry		*childEntry = NULL;
    IOService			*childNub = NULL;

	childIterator = nub->getChildIterator(gIODTPlane);
	if( childIterator != NULL )
	{
		// Iterate through children and create nubs
		while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL )
		{
			// Publish child as IOService
			childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService"));
		
			childNub->init(childEntry, gIODTPlane);
			childNub->attach(this);
			childNub->registerService();
                           			
			DLOG("IOI2CMaxim1631::publishChildren(0x%x) published child %s\n", getI2CAddress(), childEntry->getName());
		}
	
		childIterator->release();
	}

	return kIOReturnSuccess;
}
Exemple #4
0
void ARMIO::publishBelow( IORegistryEntry * root )
{
    OSCollectionIterator *	kids;
    IORegistryEntry *		next;
    IOService *			nub;
    
    // infanticide
    kids = IODTFindMatchingEntries( root, kIODTRecursive, deleteList() );
    if( kids) {
        while( (next = (IORegistryEntry *)kids->getNextObject())) {
            next->detachAll( gIODTPlane);
        }
        kids->release();
    }
    
    // publish everything below, minus excludeList
    kids = IODTFindMatchingEntries( root, kIODTRecursive | kIODTExclusive,
                                   excludeList());
    if( kids) {
        while( (next = (IORegistryEntry *)kids->getNextObject())) {
            
            if( 0 == (nub = createNub( next )))
                continue;
            
            nub->attach( this );
            
            processNub(nub);
            
            nub->registerService();
        }
        kids->release();
    }
}
Exemple #5
0
TEST_F(RPCTest, test_30_client_shutdown_halfway) {
    IOService service;
    printf("%d\n", test_port);
    test_count = 10000;
    min_success = std::numeric_limits<int>::max();
    max_success = -1;
    EchoServer::Ptr server = EchoServer::create<EchoServer>(&service, "127.0.0.1", test_port);
    server->bind_and_listen();
    Thread* run_thrs[12];
    for (int i = 0; i < 12; i++) {
        run_thrs[i] = new Thread([&service](){service.run(); LOG_DEBUG("run thread exiting");});
    }

    Thread* client_thrs[30];
    for (int i = 0; i < 30; i++) {
        client_thrs[i] = new Thread(std::bind(client_thread));
    }
    sleep(1);
    server->shutdown();
    server.reset();
    for (int i = 0; i < 30; i++) {
        client_thrs[i]->join();
        delete client_thrs[i];
    }
    for (int i = 0; i < 12; i++) {
        run_thrs[i]->join();
        delete run_thrs[i];
    }
    LOG_INFO("min %d max %d", min_success, max_success);
}
IOService * ACPIBacklightPanel::getBatteryDevice()
{
	DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
    OSDictionary * matching = IOService::serviceMatching("IOPMPowerSource");
	OSIterator *   iter = NULL;
	IOService * bat = NULL;
	
	if (matching)
	{
		DbgLog("%s: getBatteryDevice() serviceMatching OK\n", this->getName());
		iter = IOService::getMatchingServices(matching);
		matching->release();
	}
	
	if (iter)
	{
		DbgLog("%s: getBatteryDevice() iter OK\n", this->getName());
		
		bat = OSDynamicCast(IOService, iter->getNextObject());
		if (bat)
		{
			DbgLog("%s: getBatteryDevice() bat is of class %s\n", this->getName(), bat->getMetaClass()->getClassName());	
		}
		
		iter->release();
	}
	
	return bat;
}
Exemple #7
0
IOReturn IOI2CDriveBayGPIO::publishChildren(IOService *provider)
{
    IOReturn 			status = kIOReturnSuccess;
	OSIterator			*iter;
	IORegistryEntry		*next;
    IOService			*nub;

	if (iter = provider->getChildIterator(gIODTPlane))
	{
		// Iterate through children and create nubs
		while (next = (IORegistryEntry *)(iter->getNextObject()))
		{
			nub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOI2CService"));
			if (nub)
			{
				nub->init(next, gIODTPlane);
				nub->attach(this);
				nub->registerService();
			
//				DLOG("IOI2CDriveBayGPIO@%lx::publishChildren published child %s\n", getI2CAddress(), next->getName());
			}
		}

		iter->release();
	}

	return status;
}
IOReturn AudioProj7PowerObject::setHardwarePowerOn(){
    debugIOLog (3, "+ AudioProj7PowerObject::setHardwarePowerOn");
    IOReturn result = kIOReturnSuccess;
    UInt32 progOut;
    IOService *keyLargo = 0;

    keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo"));
    
    if(keyLargo){
        long gpioOffset = kPowerObjectOffset;
        UInt8  value = kPowerOn;
        keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0);
    }
    
    if(audioPluginRef) {
        IOSleep(300);   		// we need to wait to be sure that the antipop has the time to do his stuff
        progOut = audioPluginRef->sndHWGetProgOutput();
        progOut |= kSndHWProgOutput0;
        audioPluginRef->sndHWSetProgOutput(progOut);
    }
    
    if(audioPluginRef) {
        audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive);
        audioPluginRef->setDeviceDetectionActive();
    }
    debugIOLog (3, "- AudioProj7PowerObject::setHardwarePowerOn");
    return result;
}
IOHIDKeyboardDevice * 
IOHIDKeyboardDevice::newKeyboardDeviceAndStart(IOService * owner, UInt32 location)
{
    IOService * provider = owner;
    
    while ( NULL != (provider = provider->getProvider()) )
    {
	if(OSDynamicCast(IOHIDDevice, provider) || OSDynamicCast(IOHIDevice, provider))
            return  0;
    }


    IOHIDKeyboardDevice * device = new IOHIDKeyboardDevice;
    
    if (device)
    {
        if ( device->initWithLocation(location) && device->attach(owner) )
        {
            if (!device->start(owner))
            {
                device->detach(owner);
                device->release();
                device = 0;
            }
        }
        else 
        {
            device->release();
            device = 0;
        }
    }
    
    return device;
}
IOReturn AudioProj7PowerObject::setHardwarePowerOff(){
    IOReturn result = kIOReturnSuccess;
    UInt32 progOut;
    IOService *keyLargo = 0;
    debugIOLog (3, "+ AudioProj7PowerObject::setHardwarePowerOff");
    
    progOut = audioPluginRef->sndHWGetProgOutput();
    progOut &= ~kSndHWProgOutput0;
    audioPluginRef->sndHWSetProgOutput(progOut);
    IOSleep(200);

    audioPluginRef->sndHWSetPowerState(kIOAudioDeviceSleep);
    audioPluginRef->setDeviceDetectionInActive();

    keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo")); 
                
    if(keyLargo){
        long gpioOffset = kPowerObjectOffset;
        UInt8  value = kPowerOff;
        keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0);
    }
    
    debugIOLog (3, "- AudioProj7PowerObject::setHardwarePowerOff");
    return result;
}
IOReturn AudioProj6PowerObject::setHardwarePowerOn(){
    IOReturn result = kIOReturnSuccess;
    IOService *HeathRow = 0;
    UInt32 mask, data;
    UInt32 powerRegAdrr;

    debugIOLog (3, "+ AudioProj6PowerObject::setHardwarePowerOn");
        
    HeathRow = IOService::waitForService(IOService::serviceMatching("Heathrow"));

    powerRegAdrr = kPowerObjectOffset;
    if(HeathRow) {
        mask = kPowerObjectMask;
        data = kPowerOn;        
        HeathRow->callPlatformFunction(OSSymbol::withCString("heathrow_safeWriteRegUInt32"), false, 
                                                                (void *)powerRegAdrr, (void *)mask, (void *) data, 0);
        IOSleep(10);
    }
    
    if(audioPluginRef) {
        audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive);
        audioPluginRef->setDeviceDetectionActive();
    }

    debugIOLog (3, "- AudioProj6PowerObject::setHardwarePowerOn, %d", kIOReturnSuccess == result);
    return result;

}
void IOInterruptController::timeStampInterruptHandlerInternal(bool isStart, IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector)
{
  uint64_t providerID = 0;
  vm_offset_t unslidHandler = 0;
  vm_offset_t unslidTarget = 0;

  IOService * provider = getProvider();

  if (provider) {
    providerID = provider->getRegistryEntryID();
  }

  if (vector) {
    unslidHandler = VM_KERNEL_UNSLIDE((vm_offset_t)vector->handler);
    unslidTarget = VM_KERNEL_UNSLIDE_OR_PERM((vm_offset_t)vector->target);
  }


  if (isStart) {
    IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler,
                           (uintptr_t)unslidTarget, (uintptr_t)providerID);
  } else {
    IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler,
                           (uintptr_t)unslidTarget, (uintptr_t)providerID);
  }
}
Exemple #13
0
IOReturn
IOI2CLM6x::createChildNubs	(
								IOService*			nub
							)
{
	OSIterator*							childIterator;
	IORegistryEntry*					childEntry;
	IOService*							childNub;

	require( ( childIterator = nub->getChildIterator( gIODTPlane ) ) != NULL, IOI2CLM6x_createChildNubs_getChildIteratorNull );

	while ( ( childEntry = ( IORegistryEntry * ) childIterator->getNextObject() ) != NULL )
	{
		childNub = OSDynamicCast( IOService, OSMetaClass::allocClassWithName( "IOService" ) );

		if ( childNub )
		{
			childNub->init( childEntry, gIODTPlane );
			childNub->attach( this );
			childNub->registerService();
		}
	}

IOI2CLM6x_createChildNubs_getChildIteratorNull:
	return( kIOReturnSuccess );
}
Exemple #14
0
IOReturn AppleLM8x::publishChildren(IOService *nub)
{
	OSIterator			*childIterator = NULL;
	IORegistryEntry		*childEntry = NULL;
    IOService			*childNub = NULL;
    IOReturn 			status;

	childIterator = nub->getChildIterator(gIODTPlane);
	if( childIterator != NULL )
	{
		// Iterate through children and create nubs
		while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL )
		{
			// Build Table
			status = buildEntryTable(childEntry);
			LUNtableElement++;
			
			// Publish child as IOService
			childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService"));
		
			childNub->init(childEntry, gIODTPlane);
			childNub->attach(this);
			childNub->registerService();
			
//			DLOG("AppleLM8x::publishChildren(0x%x) published child %s\n", kLM8xAddr<<1, childEntry->getName());
		}
	
		childIterator->release();
	}

	return kIOReturnSuccess;
}
Exemple #15
0
void IOService::StopCurrentIOService(int signal) {
  MI_LOG_INFO(logger, "IOService::StopCurrentIOService signal:" << signal);

  if (current_) {
    IOService* current = (IOService*)current_;
    current->Stop();
  }
}
IOReturn
IOPolledFilePollersOpen(IOPolledFileIOVars * filevars, uint32_t state, bool abortable)
{

    IOPolledFilePollers      * vars = filevars->pollers;
    IOBufferMemoryDescriptor * ioBuffer;
    IOPolledInterface        * poller;
    IOService                * next;
    IOReturn                   err = kIOReturnError;
    int32_t		       idx;

    vars->abortable = abortable;
    ioBuffer = 0;

    if (kIOPolledAfterSleepState == state)
    {
        vars->ioStatus = 0;
        vars->io = false;
    }
    (void) IOPolledFilePollersIODone(vars, false);

    if ((kIOPolledPreflightState == state) || (kIOPolledPreflightCoreDumpState == state))
    {
        ioBuffer = vars->ioBuffer;
        if (!ioBuffer)
        {
            vars->ioBuffer = ioBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionInOut,
                                        2 * kDefaultIOSize, page_size);
            if (!ioBuffer) return (kIOReturnNoMemory);
        }
    }

    for (idx = vars->pollers->getCount() - 1; idx >= 0; idx--)
    {
        poller = (IOPolledInterface *) vars->pollers->getObject(idx);
        err = poller->open(state, ioBuffer);
        if ((kIOReturnSuccess != err) && (kIOPolledPreflightCoreDumpState == state))
        {
            err = poller->open(kIOPolledPreflightState, ioBuffer);
        }
        if (kIOReturnSuccess != err)
        {
            HIBLOG("IOPolledInterface::open[%d] 0x%x\n", idx, err);
            break;
        }
    }
    if (kIOReturnSuccess == err)
    {
        next = vars->media;
        while (next)
        {
            next->setProperty(kIOPolledInterfaceActiveKey, kOSBooleanTrue);
            next = next->getProvider();
        }
    }

    return (err);
}
Exemple #17
0
bool com_prebeg_kext_KeyLog::notificationHandler(void *target, void *ref, IOService *newServ, IONotifier *notifier)
{
    com_prebeg_kext_KeyLog* self = OSDynamicCast( com_prebeg_kext_KeyLog, (OSMetaClassBase*)target );
    if (!self)
        return false;
    
#ifdef DEBUG
    IOLog( "%s::Notification handler called\n", self->getName() );
#endif
    
    IOHIKeyboard*   keyboard = OSDynamicCast( IOHIKeyboard, newServ );
    if (!keyboard)
        return false;
    
    if (!keyboard->_keyboardEventTarget)
    {
#ifdef DEBUG
        IOLog( "%s::No Keyboard event target\n", self->getName());
#endif
        
        return false;
    }
    // event target must be IOHIDSystem
    
    IOService*      targetServ = OSDynamicCast( IOService, keyboard->_keyboardEventTarget );
    if (targetServ)
    {
#ifdef DEBUG
        IOLog( "%s::Keyboard event target is %s\n", self->getName(), targetServ->getName());
#endif
    }
    
    if (!keyboard->_keyboardEventTarget->metaCast("IOHIDSystem"))
        return false;

    // we have a valid keyboard to be logged
#ifdef DEBUG
    IOLog( "%s::Adding keyboard %p\n", self->getName(),keyboard );
#endif
    
    
    int index = self->loggedKeyboards->getNextIndexOfObject(keyboard,0);
    if (index<0)
    {       
        self->loggedKeyboards->setObject(keyboard);
        self->kextKeys++;
    }
    
    origAction = keyboard->_keyboardEventAction;            // save the original action
    keyboard->_keyboardEventAction = (KeyboardEventAction) logAction;       // apply the new action
    
    origSpecialAction = keyboard->_keyboardSpecialEventAction;              // save the original action
    keyboard->_keyboardSpecialEventAction = (KeyboardSpecialEventAction) specialAction;     // apply the new action
    
    return true;
}
void IOInterruptController::timeStampSpuriousInterrupt(void)
{
  uint64_t providerID = 0;
  IOService * provider = getProvider();

  if (provider) {
    providerID = provider->getRegistryEntryID();
  }

  IOTimeStampConstant(IODBG_INTC(IOINTC_SPURIOUS), providerID);
}
static IOUSBDevice* GetOwnerProvider(const IOService *us)
{
	IOService *prov = us->getProvider(), *provprov;

	if (prov == NULL)
		return NULL;
	provprov = prov->getProvider();
	if (provprov == NULL)
		return NULL;
	return OSDynamicCast(IOUSBDevice, provprov);
}
IOFireWireUnit * IOFireWireSBP2LUN::getFireWireUnit( void )
{
	IOService * unit = NULL;
	
	IOService * provider = getProvider();
	if( provider )
	{
		unit = provider->getProvider();
	}
	
    return (IOFireWireUnit*)unit;
}
bool getACStatus()
{
	IOService * batteryDevice = getBatteryDevice();
	
	if (NULL != batteryDevice)
	{
		OSObject * obj = batteryDevice->getProperty("ExternalConnected");
		OSBoolean * status = OSDynamicCast(OSBoolean, obj);
        if (status)
            return status->getValue();
	}
    return true;
}
Exemple #22
0
IOService * ARMIO::createNub( IORegistryEntry * from )
{
    IOService *	nub;
    
    nub = new ARMIODevice;
    
    if( nub && !nub->init( from, gIODTPlane )) {
        nub->free();
        nub = 0;
    }
    
    return( nub);
}
IOService * IOPlatformExpert::createNub( OSDictionary * from )
{
    IOService *		nub;

    nub = new IOPlatformDevice;
    if(nub) {
	if( !nub->init( from )) {
	    nub->release();
	    nub = 0;
	}
    }
    return( nub);
}
IOService * IODTPlatformExpert::createNub( IORegistryEntry * from )
{
    IOService *		nub;

    nub = new IOPlatformDevice;
    if( nub) {
	if( !nub->init( from, gIODTPlane )) {
	    nub->free();
	    nub = 0;
	}
    }
    return( nub);
}
Exemple #25
0
IOReturn ARMIODevice::getResources( void )
{
    IOService *macIO = this;

    if (getDeviceMemory() != 0) return kIOReturnSuccess;
    
    while (macIO && ((macIO = macIO->getProvider()) != 0))
        if (strcmp("arm-io", macIO->getName()) == 0) break;
    
    if (macIO == 0) return kIOReturnError;
    
    IODTResolveAddressing(this, "reg", macIO->getDeviceMemoryWithIndex(0));
    
    return kIOReturnSuccess;
}
Exemple #26
0
// Access to Keylargo registers:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	[3110829] register accesses need to translate endian format.
void AudioI2SControl::KLSetRegister(UInt32 klRegisterOffset, UInt32 value)
{
    IOService *				keyLargoService = NULL;
	UInt32					mask = kAudioFCR1Mask;
	const OSSymbol *		theSymbol;
	
	theSymbol = OSSymbol::withCString ("keyLargo_safeWriteRegUInt32");
	
    keyLargoService = IOService::waitForService (IOService::serviceMatching ("KeyLargo"));

    if (keyLargoService && theSymbol) {
        keyLargoService->callPlatformFunction (theSymbol, false, (void *)klRegisterOffset, (void *)mask, (void *) value, 0);
		theSymbol->release ();
    } 
}
/**
 * Stop this service.
 */
void org_virtualbox_VBoxVFS::stop(IOService *pProvider)
{
    int rc;

    AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));

    rc = VBoxVFSUnRegisterFilesystem();
    if (RT_FAILURE(rc))
    {
        PERROR("VBoxVFS filesystem is busy. Make sure all "
               "shares are unmounted (%d)", rc);
    }

    vboxDisconnect(&g_vboxSFClient);
    PINFO("VBox client disconnected");

    vboxUninit();
    PINFO("Low level uninit done");

    coreService->release();
    PINFO("VBoxGuest service released");

    IOService::stop(pProvider);

    ASMAtomicWriteBool(&g_fInstantiated, false);

    PINFO("Successfully stopped I/O kit class instance");
}
Exemple #28
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//	[3110829] register accesses need to translate endian format.
UInt32 AudioI2SControl::KLGetRegister(UInt32 klRegisterOffset)
{
	UInt32					value = 0;
    IOService *				keyLargoService = NULL;
	const OSSymbol *		theSymbol;
	
	theSymbol = OSSymbol::withCString ("keyLargo_safeReadRegUInt32");

    keyLargoService = IOService::waitForService (IOService::serviceMatching ("KeyLargo"));

    if (keyLargoService && theSymbol) {
        keyLargoService->callPlatformFunction (theSymbol, false, (void *)klRegisterOffset, &value, 0, 0);
		theSymbol->release ();
    } 

	return value;
}
bool IOPlatformExpert::RegisterServiceInTree (IOService * theService, OSDictionary * theTreeNode, OSDictionary * theTreeParentNode, IOService * theProvider)
{
  IOService *    aService;
  bool           registered = false;
  OSArray *      children;
  unsigned int   numChildren;
  OSDictionary * child;

  // make sure someone is not already registered here

  if ( NULL == theTreeNode->getObject ("service") ) {

    if ( theTreeNode->setObject ("service", OSDynamicCast ( OSObject, theService)) ) {

      // 1. CHILDREN ------------------

      // we registered the node in the tree...now if the node has children
      // registered we must tell this service to add them.

      if ( NULL != (children = (OSArray *) theTreeNode->getObject ("children")) ) {
        numChildren = children->getCount ();
        for ( unsigned int i = 0; i < numChildren; i++ ) {
          if ( NULL != (child = (OSDictionary *) children->getObject (i)) ) {
            if ( NULL != (aService = (IOService *) child->getObject ("service")) )
              theService->addPowerChild (aService);
          }
        }
      }

      // 2. PARENT --------------------

      // also we must notify the parent of this node (if a registered service
      // exists there) of a new child.

      if ( theTreeParentNode ) {
        if ( NULL != (aService = (IOService *) theTreeParentNode->getObject ("service")) )
          if (aService != theProvider)
            aService->addPowerChild (theService);
      }

      registered = true;
    }
  }

  return registered;
}
static IOReturn
IOGetVolumeCryptKey(dev_t block_dev,  OSString ** pKeyUUID,
                    uint8_t * volumeCryptKey, size_t keySize)
{
    IOReturn         err;
    IOService *      part;
    OSString *       keyUUID = 0;
    OSString *       keyStoreUUID = 0;
    uuid_t           volumeKeyUUID;
    aks_volume_key_t vek;

    static IOService * sKeyStore;

    part = IOCopyMediaForDev(block_dev);
    if (!part) return (kIOReturnNotFound);

    err = part->callPlatformFunction(PLATFORM_FUNCTION_GET_MEDIA_ENCRYPTION_KEY_UUID, false,
                                     (void *) &keyUUID, (void *) &keyStoreUUID, NULL, NULL);
    if ((kIOReturnSuccess == err) && keyUUID && keyStoreUUID)
    {
//            IOLog("got volume key %s\n", keyStoreUUID->getCStringNoCopy());

        if (!sKeyStore)
            sKeyStore = (IOService *) IORegistryEntry::fromPath(AKS_SERVICE_PATH, gIOServicePlane);
        if (sKeyStore)
            err = uuid_parse(keyStoreUUID->getCStringNoCopy(), volumeKeyUUID);
        else
            err = kIOReturnNoResources;
        if (kIOReturnSuccess == err)
            err = sKeyStore->callPlatformFunction(gAKSGetKey, true, volumeKeyUUID, &vek, NULL, NULL);
        if (kIOReturnSuccess != err)
            IOLog("volume key err 0x%x\n", err);
        else
        {
            if (vek.key.keybytecount < keySize) keySize = vek.key.keybytecount;
            bcopy(&vek.key.keybytes[0], volumeCryptKey, keySize);
        }
        bzero(&vek, sizeof(vek));

    }
    part->release();
    if (pKeyUUID) *pKeyUUID = keyUUID;

    return (err);
}