/** * 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"); }
IOService * IOPlatformExpert::createNub( OSDictionary * from ) { IOService * nub; nub = new IOPlatformDevice; if(nub) { if( !nub->init( from )) { nub->release(); nub = 0; } } return( nub); }
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); }
bool IOHIDInterface::matchPropertyTable( OSDictionary * table, SInt32 * score) { IOService * provider; bool ret; RETAIN_ON_STACK(this); if ( !super::matchPropertyTable(table, score) || !(provider = OSDynamicCast(IOService, copyParentEntry(gIOServicePlane))) ) return false; // We should retain a reference to our provider while calling matchPropertyTable. // This is necessary in a situation where a user space process could be searching // the registry during termination. ret = provider->matchPropertyTable(table, score); provider->release(); return ret; }
bool IOATABlockStorageDriver::createNub ( IOService * provider ) { IOService * nub = NULL; STATUS_LOG ( ( "IOATABlockStorageDriver::createNub entering.\n" ) ); // Instantiate a generic hard disk nub so a generic driver // can match above us. nub = instantiateNub ( ); if ( nub == NULL ) { ERROR_LOG ( ( "IOATABlockStorageDriver::createNub instantiateNub() failed, returning false\n" ) ); return false; } nub->init ( ); if ( !nub->attach ( this ) ) { // panic since the nub can't attach PANIC_NOW ( ( "IOATABlockStorageDriver::createNub() unable to attach nub" ) ); return false; } nub->registerService ( ); // The IORegistry retains the nub, so we can release our refcount // because we don't need it any more. nub->release ( ); STATUS_LOG ( ( "IOATABlockStorageDriver::createNub exiting true.\n" ) ); return true; }
BrcmFirmwareStore* BrcmPatchRAM::getFirmwareStore() { if (!mFirmwareStore) { // check to see if it already loaded mFirmwareStore = OSDynamicCast(BrcmFirmwareStore, waitForMatchingService(serviceMatching(kBrcmFirmwareStoreService), 0)); if (!mFirmwareStore) { // not loaded, so publish personality... publishResourcePersonality(kBrcmFirmwareStoreService); // and wait... mFirmwareStore = OSDynamicCast(BrcmFirmwareStore, waitForMatchingService(serviceMatching(kBrcmFirmwareStoreService), 2000UL*1000UL*1000UL)); } #ifdef NON_RESIDENT // also need BrcmPatchRAMResidency IOService* residency = OSDynamicCast(BrcmPatchRAMResidency, waitForMatchingService(serviceMatching(kBrcmPatchRAMResidency), 0)); if (!residency) { // not loaded, so publish personality... publishResourcePersonality(kBrcmPatchRAMResidency); // and wait... residency = OSDynamicCast(BrcmPatchRAMResidency, waitForMatchingService(serviceMatching(kBrcmPatchRAMResidency), 2000UL*1000UL*1000UL)); if (residency) residency->release(); else AlwaysLog("[%04x:%04x]: BrcmPatchRAMResidency does not appear to be available.\n", mVendorId, mProductId); } #endif } if (!mFirmwareStore) AlwaysLog("[%04x:%04x]: BrcmFirmwareStore does not appear to be available.\n", mVendorId, mProductId); return mFirmwareStore; }
/** * Start this service. */ bool org_virtualbox_VBoxVFS::start(IOService *pProvider) { int rc; if (!IOService::start(pProvider)) return false; /* Low level initialization should be performed only once */ if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false)) { IOService::stop(pProvider); return false; } /* Wait for VBoxGuest to be started */ coreService = waitForCoreService(); if (coreService) { rc = vboxInit(); if (RT_SUCCESS(rc)) { /* Connect to the host service. */ rc = vboxConnect(&g_vboxSFClient); if (RT_SUCCESS(rc)) { PINFO("VBox client connected"); rc = vboxCallSetUtf8(&g_vboxSFClient); if (RT_SUCCESS(rc)) { rc = VBoxVFSRegisterFilesystem(); if (RT_SUCCESS(rc)) { registerService(); PINFO("Successfully started I/O kit class instance"); return true; } PERROR("Unable to register VBoxVFS filesystem"); } else { PERROR("vboxCallSetUtf8 failed: rc=%d", rc); } vboxDisconnect(&g_vboxSFClient); } else { PERROR("Failed to get connection to host: rc=%d", rc); } vboxUninit(); } else { PERROR("Failed to initialize low level library"); } coreService->release(); } else { PERROR("VBoxGuest KEXT not started"); } ASMAtomicXchgBool(&g_fInstantiated, false); IOService::stop(pProvider); return false; }
IOReturn IOPolledFileOpen(const char * filename, uint64_t setFileSize, uint64_t fsFreeSize, void * write_file_addr, size_t write_file_len, IOPolledFileIOVars ** fileVars, OSData ** imagePath, uint8_t * volumeCryptKey, size_t keySize) { IOReturn err = kIOReturnSuccess; IOPolledFileIOVars * vars; _OpenFileContext ctx; OSData * extentsData; OSNumber * num; IOService * part = 0; dev_t block_dev; dev_t image_dev; AbsoluteTime startTime, endTime; uint64_t nsec; vars = IONew(IOPolledFileIOVars, 1); if (!vars) return (kIOReturnNoMemory); bzero(vars, sizeof(*vars)); vars->allocated = true; do { extentsData = OSData::withCapacity(32); ctx.extents = extentsData; ctx.size = 0; clock_get_uptime(&startTime); vars->fileRef = kern_open_file_for_direct_io(filename, (write_file_addr != NULL) || (0 != setFileSize), &file_extent_callback, &ctx, setFileSize, fsFreeSize, // write file: 0, write_file_addr, write_file_len, // results &block_dev, &image_dev, &vars->block0, &vars->maxiobytes, &vars->flags); #if 0 uint32_t msDelay = (131071 & random()); HIBLOG("sleep %d\n", msDelay); IOSleep(msDelay); #endif clock_get_uptime(&endTime); SUB_ABSOLUTETIME(&endTime, &startTime); absolutetime_to_nanoseconds(endTime, &nsec); if (!vars->fileRef) err = kIOReturnNoSpace; HIBLOG("kern_open_file_for_direct_io took %qd ms\n", nsec / 1000000ULL); if (kIOReturnSuccess != err) break; HIBLOG("Opened file %s, size %qd, extents %ld, maxio %qx ssd %d\n", filename, ctx.size, (extentsData->getLength() / sizeof(IOPolledFileExtent)) - 1, vars->maxiobytes, kIOPolledFileSSD & vars->flags); assert(!vars->block0); if (extentsData->getLength() < sizeof(IOPolledFileExtent)) { err = kIOReturnNoSpace; break; } vars->fileSize = ctx.size; vars->extentMap = (IOPolledFileExtent *) extentsData->getBytesNoCopy(); part = IOCopyMediaForDev(image_dev); if (!part) { err = kIOReturnNotFound; break; } if (!(vars->pollers = IOPolledFilePollers::copyPollers(part))) break; if ((num = OSDynamicCast(OSNumber, part->getProperty(kIOMediaPreferredBlockSizeKey)))) vars->blockSize = num->unsigned32BitValue(); if (vars->blockSize < 4096) vars->blockSize = 4096; HIBLOG("polled file major %d, minor %d, blocksize %ld, pollers %d\n", major(image_dev), minor(image_dev), (long)vars->blockSize, vars->pollers->pollers->getCount()); OSString * keyUUID = NULL; if (volumeCryptKey) { err = IOGetVolumeCryptKey(block_dev, &keyUUID, volumeCryptKey, keySize); } *fileVars = vars; vars->fileExtents = extentsData; // make imagePath OSData * data; if (imagePath) { #if defined(__i386__) || defined(__x86_64__) char str2[24 + sizeof(uuid_string_t) + 2]; if (keyUUID) snprintf(str2, sizeof(str2), "%qx:%s", vars->extentMap[0].start, keyUUID->getCStringNoCopy()); else snprintf(str2, sizeof(str2), "%qx", vars->extentMap[0].start); err = IOService::getPlatform()->callPlatformFunction( gIOCreateEFIDevicePathSymbol, false, (void *) part, (void *) str2, (void *) (uintptr_t) true, (void *) &data); #else data = 0; err = kIOReturnSuccess; #endif if (kIOReturnSuccess != err) { HIBLOG("error 0x%x getting path\n", err); break; } *imagePath = data; } } while (false); if (kIOReturnSuccess != err) { HIBLOG("error 0x%x opening polled file\n", err); IOPolledFileClose(&vars, 0, 0, 0, 0, 0); } if (part) part->release(); return (err); }