X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/316670eb35587141e969394ae8537d66b9211e80..a1c7dba18ef36983396c282fe85292db066e39db:/iokit/Kernel/RootDomainUserClient.cpp diff --git a/iokit/Kernel/RootDomainUserClient.cpp b/iokit/Kernel/RootDomainUserClient.cpp index 75a26e7cc..ae122f4c1 100644 --- a/iokit/Kernel/RootDomainUserClient.cpp +++ b/iokit/Kernel/RootDomainUserClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1998-2012 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -37,6 +37,7 @@ #include "RootDomainUserClient.h" #include #include +#include #define super IOUserClient @@ -46,17 +47,17 @@ OSDefineMetaClassAndStructors(RootDomainUserClient, IOUserClient) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -bool RootDomainUserClient::initWithTask(task_t owningTask, void *security_id, - UInt32 type, OSDictionary * properties) +bool RootDomainUserClient::initWithTask(task_t owningTask, void *security_id, + UInt32 type, OSDictionary * properties) { if (properties) - properties->setObject(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue); + properties->setObject(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue); if (!super::initWithTask(owningTask, security_id, type, properties)) - return false; + return false; fOwningTask = owningTask; - task_reference (fOwningTask); + task_reference (fOwningTask); return true; } @@ -77,9 +78,9 @@ IOReturn RootDomainUserClient::secureSleepSystem( uint32_t *return_code ) return secureSleepSystemOptions(NULL, 0, return_code); } -IOReturn RootDomainUserClient::secureSleepSystemOptions( - const void *inOptions, - IOByteCount inOptionsSize __unused, +IOReturn RootDomainUserClient::secureSleepSystemOptions( + const void *inOptions, + IOByteCount inOptionsSize, uint32_t *returnCode) { @@ -91,39 +92,44 @@ IOReturn RootDomainUserClient::secureSleepSystemOptions( ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser); local_priv = (kIOReturnSuccess == ret); - + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); admin_priv = (kIOReturnSuccess == ret); - - + + if (inOptions) { unserializedOptions = OSDynamicCast( OSDictionary, - OSUnserializeXML((const char *)inOptions, &unserializeErrorString)); - + OSUnserializeXML((const char *)inOptions, inOptionsSize, &unserializeErrorString)); + if (!unserializedOptions) { - IOLog("IOPMRootDomain SleepSystem unserialization failure: %s\n", + IOLog("IOPMRootDomain SleepSystem unserialization failure: %s\n", unserializeErrorString ? unserializeErrorString->getCStringNoCopy() : "Unknown"); } } - if ( (local_priv || admin_priv) - && fOwner ) + if ( (local_priv || admin_priv) && fOwner ) { - if (unserializedOptions) + proc_t p; + p = (proc_t)get_bsdtask_info(fOwningTask); + if (p) { + fOwner->setProperty("SleepRequestedByPID", proc_pid(p), 32); + } + + if (unserializedOptions) { // Publish Sleep Options in registry under root_domain - fOwner->setProperty( kRootDomainSleepOptionsKey, unserializedOptions); + fOwner->setProperty( kRootDomainSleepOptionsKey, unserializedOptions); *returnCode = fOwner->sleepSystemOptions( unserializedOptions ); - unserializedOptions->release(); + unserializedOptions->release(); } else { // No options // Clear any pre-existing options fOwner->removeProperty( kRootDomainSleepOptionsKey ); - *returnCode = fOwner->sleepSystemOptions( NULL ); + *returnCode = fOwner->sleepSystemOptions( NULL ); } } else { @@ -133,7 +139,7 @@ IOReturn RootDomainUserClient::secureSleepSystemOptions( return kIOReturnSuccess; } -IOReturn RootDomainUserClient::secureSetAggressiveness( +IOReturn RootDomainUserClient::secureSetAggressiveness( unsigned long type, unsigned long newLevel, int *return_code ) @@ -144,7 +150,7 @@ IOReturn RootDomainUserClient::secureSetAggressiveness( ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser); local_priv = (kIOReturnSuccess == ret); - + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); admin_priv = (kIOReturnSuccess == ret); @@ -162,7 +168,7 @@ IOReturn RootDomainUserClient::secureSetMaintenanceWakeCalendar( { int admin_priv = 0; IOReturn ret = kIOReturnNotPrivileged; - + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); admin_priv = (kIOReturnSuccess == ret); @@ -179,7 +185,7 @@ IOReturn RootDomainUserClient::secureSetUserAssertionLevels( { int admin_priv = 0; IOReturn ret = kIOReturnNotPrivileged; - + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); admin_priv = (kIOReturnSuccess == ret); @@ -191,50 +197,44 @@ IOReturn RootDomainUserClient::secureSetUserAssertionLevels( return kIOReturnSuccess; } +IOReturn RootDomainUserClient::secureGetSystemSleepType( + uint32_t *outSleepType) +{ + int admin_priv = 0; + IOReturn ret; + + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); + admin_priv = (kIOReturnSuccess == ret); + + if (admin_priv && fOwner) { + ret = fOwner->getSystemSleepType(outSleepType); + } else { + ret = kIOReturnNotPrivileged; + } + return ret; +} + IOReturn RootDomainUserClient::clientClose( void ) { detach(fOwner); - + if(fOwningTask) { task_deallocate(fOwningTask); fOwningTask = 0; - } - - return kIOReturnSuccess; -} - -IOReturn RootDomainUserClient::clientMemoryForType( - UInt32 type, - IOOptionBits *options, - IOMemoryDescriptor ** memory) -{ - if (!fOwner) - return kIOReturnNotReady; - - if (kPMRootDomainMapTraceBuffer == type) - { - *memory = fOwner->getPMTraceMemoryDescriptor(); - if (*memory) { - (*memory)->retain(); - *options = 0; - return kIOReturnSuccess; - } else { - return kIOReturnNotFound; - } - } - return kIOReturnUnsupported; + + return kIOReturnSuccess; } IOReturn RootDomainUserClient::externalMethod( - uint32_t selector, + uint32_t selector, IOExternalMethodArguments * arguments, - IOExternalMethodDispatch * dispatch __unused, + IOExternalMethodDispatch * dispatch __unused, OSObject * target __unused, void * reference __unused ) { - IOReturn ret = kIOReturnBadArgument; - + IOReturn ret = kIOReturnBadArgument; + switch (selector) { case kPMSetAggressiveness: @@ -247,7 +247,7 @@ IOReturn RootDomainUserClient::externalMethod( (int *)&arguments->scalarOutput[0]); } break; - + case kPMGetAggressiveness: if ((1 == arguments->scalarInputCount) && (1 == arguments->scalarOutputCount)) @@ -257,12 +257,12 @@ IOReturn RootDomainUserClient::externalMethod( (unsigned long *)&arguments->scalarOutput[0]); } break; - + case kPMSleepSystem: if (1 == arguments->scalarOutputCount) { ret = this->secureSleepSystem( - (uint32_t *)&arguments->scalarOutput[0]); + (uint32_t *)&arguments->scalarOutput[0]); } break; @@ -300,71 +300,62 @@ IOReturn RootDomainUserClient::externalMethod( break; case kPMSetMaintenanceWakeCalendar: ret = this->secureSetMaintenanceWakeCalendar( - (IOPMCalendarStruct *)arguments->structureInput, + (IOPMCalendarStruct *)arguments->structureInput, (uint32_t *)&arguments->structureOutput); arguments->structureOutputSize = sizeof(uint32_t); break; - + case kPMSetUserAssertionLevels: ret = this->secureSetUserAssertionLevels( (uint32_t)arguments->scalarInput[0]); break; - + case kPMActivityTickle: - fOwner->reportUserInput( ); - fOwner->setProperty(kIOPMRootDomainWakeTypeKey, "UserActivity Assertion"); + if ( fOwner->checkSystemCanSustainFullWake() ) + { + fOwner->reportUserInput( ); + fOwner->setProperty(kIOPMRootDomainWakeTypeKey, "UserActivity Assertion"); + } ret = kIOReturnSuccess; break; - -/* - case kPMMethodCopySystemTimeline: - // intentional fallthrough - case kPMMethodCopyDetailedTimeline: - if (!arguments->structureOutputDescriptor) + case kPMSetClamshellSleepState: + fOwner->setDisableClamShellSleep(arguments->scalarInput[0] ? true : false); + ret = kIOReturnSuccess; + break; + + case kPMGetSystemSleepType: + if (1 == arguments->scalarOutputCount) { - // TODO: Force IOKit.framework to always send this data out - // of line; so I don't have to create a MemoryDescriptor here. - mem_size = arguments->structureOutputSize; - mem = IOMemoryDescriptor::withAddressRange( - (mach_vm_address_t)arguments->structureOutput, - (mach_vm_size_t)mem_size, - kIODirectionIn, current_task()); - } else { - mem_size = arguments->structureOutputDescriptorSize; - if (( mem = arguments->structureOutputDescriptor )) - mem->retain(); + ret = this->secureGetSystemSleepType( + (uint32_t *) &arguments->scalarOutput[0]); } - - if (mem) + break; + +#if defined(__i386__) || defined(__x86_64__) + case kPMSleepWakeWatchdogEnable: + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); + if (ret == kIOReturnSuccess) + fOwner->sleepWakeDebugEnableWdog(); + break; + + + case kPMSleepWakeDebugTrig: + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); + if (ret == kIOReturnSuccess) + fOwner->sleepWakeDebugTrig(false); + break; +#endif + + case kPMSetDisplayPowerOn: + if (1 == arguments->scalarInputCount) { - mem->prepare(kIODirectionNone); - - if (kPMMethodCopySystemTimeline == selector) { - arguments->scalarOutput[0] = fOwner->copySystemTimeline( - mem, &mem_size); - } - else - if (kPMMethodCopyDetailedTimeline == selector) { - arguments->scalarOutput[0] = fOwner->copyDetailedTimeline( - mem, &mem_size); - } - - if (arguments->structureOutputDescriptor) { - arguments->structureOutputDescriptorSize = mem_size; - } else { - arguments->structureOutputSize = mem_size; - } - - mem->release(); - - ret = kIOReturnSuccess; - } else { - ret = kIOReturnCannotWire; + ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); + if (ret == kIOReturnSuccess) + fOwner->setDisplayPowerOn((uint32_t)arguments->scalarInput[0]); } - break; -*/ + default: // bad selector return kIOReturnBadArgument; @@ -378,7 +369,7 @@ IOReturn RootDomainUserClient::externalMethod( * We maintain getTargetAndExternalMethod since it's an exported symbol, * and only for that reason. */ -IOExternalMethod * RootDomainUserClient::getTargetAndMethodForIndex( +IOExternalMethod * RootDomainUserClient::getTargetAndMethodForIndex( IOService ** targetP, UInt32 index ) { // DO NOT EDIT @@ -388,6 +379,6 @@ IOExternalMethod * RootDomainUserClient::getTargetAndMethodForIndex( /* setPreventative * Does nothing. Exists only for exported symbol compatibility. */ -void +void RootDomainUserClient::setPreventative(UInt32 on_off, UInt32 types_of_sleep) { return; } // DO NOT EDIT