2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
33 #include <IOKit/assert.h>
34 #include <IOKit/IOLib.h>
35 #include <IOKit/IOKitKeys.h>
36 #include <IOKit/IOBufferMemoryDescriptor.h>
37 #include "RootDomainUserClient.h"
38 #include <IOKit/pwr_mgt/IOPMLibDefs.h>
40 #define super IOUserClient
42 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
44 OSDefineMetaClassAndStructors(RootDomainUserClient
, IOUserClient
)
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48 bool RootDomainUserClient::initWithTask(task_t owningTask
, void *security_id
,
49 UInt32 type
, OSDictionary
* properties
)
52 properties
->setObject(kIOUserClientCrossEndianCompatibleKey
, kOSBooleanTrue
);
54 if (!super::initWithTask(owningTask
, security_id
, type
, properties
))
57 fOwningTask
= owningTask
;
58 task_reference (fOwningTask
);
63 bool RootDomainUserClient::start( IOService
* provider
)
65 assert(OSDynamicCast(IOPMrootDomain
, provider
));
66 if(!super::start(provider
))
68 fOwner
= (IOPMrootDomain
*)provider
;
74 IOReturn
RootDomainUserClient::secureSleepSystem( uint32_t *return_code
)
76 IOByteCount return_code_size
= 1;
78 return secureSleepSystemOptions( NULL
, // inOptions
79 (void *)return_code
, // returnCode
81 (void *)&return_code_size
, // returnSize
85 IOReturn
RootDomainUserClient::secureSleepSystemOptions(
86 void * p1
, void * p2
, void * p3
,
87 void * p4
, void * p5
, void * p6
)
89 void *inOptions
= (void *)p1
;
90 uint32_t *returnCode
= (uint32_t *)p2
;
91 IOByteCount inOptionsSize
= (IOByteCount
)p3
;
92 IOByteCount
*returnCodeSize
= (IOByteCount
*)p4
;
96 IOReturn ret
= kIOReturnNotPrivileged
;
97 OSDictionary
*unserializedOptions
= NULL
;
98 OSString
*unserializeErrorString
= NULL
;
100 ret
= clientHasPrivilege(fOwningTask
, kIOClientPrivilegeLocalUser
);
101 local_priv
= (kIOReturnSuccess
== ret
);
103 ret
= clientHasPrivilege(fOwningTask
, kIOClientPrivilegeAdministrator
);
104 admin_priv
= (kIOReturnSuccess
== ret
);
106 *returnCodeSize
= sizeof(uint32_t);
110 unserializedOptions
= OSDynamicCast( OSDictionary
,
111 OSUnserializeXML((const char *)inOptions
, &unserializeErrorString
));
113 if (!unserializedOptions
) {
114 IOLog("IOPMRootDomain SleepSystem unserialization failure: %s\n",
115 unserializeErrorString
? unserializeErrorString
->getCStringNoCopy() : "Unknown");
119 if ( (local_priv
|| admin_priv
)
122 if (unserializedOptions
)
124 // Publish Sleep Options in registry under root_domain
125 fOwner
->setProperty( kRootDomainSleepOptionsKey
, unserializedOptions
);
127 *returnCode
= fOwner
->sleepSystemOptions( unserializedOptions
);
129 unserializedOptions
->release();
132 // Clear any pre-existing options
133 fOwner
->removeProperty( kRootDomainSleepOptionsKey
);
135 *returnCode
= fOwner
->sleepSystemOptions( NULL
);
139 *returnCode
= kIOReturnNotPrivileged
;
142 return kIOReturnSuccess
;
145 IOReturn
RootDomainUserClient::secureSetAggressiveness(
147 unsigned long newLevel
,
152 IOReturn ret
= kIOReturnNotPrivileged
;
154 ret
= clientHasPrivilege(fOwningTask
, kIOClientPrivilegeLocalUser
);
155 local_priv
= (kIOReturnSuccess
== ret
);
157 ret
= clientHasPrivilege(fOwningTask
, kIOClientPrivilegeAdministrator
);
158 admin_priv
= (kIOReturnSuccess
== ret
);
160 if((local_priv
|| admin_priv
) && fOwner
) {
161 *return_code
= fOwner
->setAggressiveness(type
, newLevel
);
162 return kIOReturnSuccess
;
164 *return_code
= kIOReturnNotPrivileged
;
165 return kIOReturnSuccess
;
171 IOReturn
RootDomainUserClient::clientClose( void )
176 task_deallocate(fOwningTask
);
180 return kIOReturnSuccess
;
184 RootDomainUserClient::getTargetAndMethodForIndex( IOService
** targetP
, UInt32 index
)
186 static const IOExternalMethod sMethods
[] = {
187 { // kPMSetAggressiveness, 0
188 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSetAggressiveness
, kIOUCScalarIScalarO
, 2, 1
190 { // kPMGetAggressiveness, 1
191 0, (IOMethod
)&IOPMrootDomain::getAggressiveness
, kIOUCScalarIScalarO
, 1, 1
193 { // kPMSleepSystem, 2
194 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystem
, kIOUCScalarIScalarO
, 0, 1
196 { // kPMAllowPowerChange, 3
197 0, (IOMethod
)&IOPMrootDomain::allowPowerChange
, kIOUCScalarIScalarO
, 1, 0
199 { // kPMCancelPowerChange, 4
200 0, (IOMethod
)&IOPMrootDomain::cancelPowerChange
, kIOUCScalarIScalarO
, 1, 0
202 { // kPMShutdownSystem, 5
203 0, (IOMethod
)&IOPMrootDomain::shutdownSystem
, kIOUCScalarIScalarO
, 0, 0
205 { // kPMRestartSystem, 6
206 0, (IOMethod
)&IOPMrootDomain::restartSystem
, kIOUCScalarIScalarO
, 0, 0
208 { // kPMSleepSystemOptions, 7
209 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystemOptions
,
210 kIOUCStructIStructO
, kIOUCVariableStructureSize
, sizeof(uint32_t)
214 if(index
>= kNumPMMethods
)
217 if (sMethods
[index
].object
)
222 return (IOExternalMethod
*)&sMethods
[index
];
227 IOReturn
RootDomainUserClient::externalMethod( uint32_t selector
, IOExternalMethodArguments
* args
,
228 IOExternalMethodDispatch
* dispatch
, OSObject
* target
, void * reference
)
230 static const IOExternalMethodDispatch sMethods
[] = {
231 { // kPMSetAggressiveness, 0
232 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSetAggressiveness
, kIOUCScalarIScalarO
, 2, 1
234 { // kPMGetAggressiveness, 1
235 0, (IOMethod
)&IOPMrootDomain::getAggressiveness
, kIOUCScalarIScalarO
, 1, 1
237 { // kPMSleepSystem, 2
238 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystem
, kIOUCScalarIScalarO
, 0, 1
240 { // kPMAllowPowerChange, 3
241 0, (IOMethod
)&IOPMrootDomain::allowPowerChange
, kIOUCScalarIScalarO
, 1, 0
243 { // kPMCancelPowerChange, 4
244 0, (IOMethod
)&IOPMrootDomain::cancelPowerChange
, kIOUCScalarIScalarO
, 1, 0
246 { // kPMShutdownSystem, 5
247 0, (IOMethod
)&IOPMrootDomain::shutdownSystem
, kIOUCScalarIScalarO
, 0, 0
249 { // kPMRestartSystem, 6
250 0, (IOMethod
)&IOPMrootDomain::restartSystem
, kIOUCScalarIScalarO
, 0, 0
252 { // kPMSetPreventative, 7
253 (IOService
*)1, (IOMethod
)&RootDomainUserClient::setPreventative
, kIOUCScalarIScalarO
, 2, 0
257 if (selector
> (sizeof(sMethods
) / sizeof(sMethods
[0])))
258 return (kIOReturnBadArgument
);
260 if ((1 << selector
) & ((1 << 0) | (1 << 7))
265 return (super::externalMethod(selector
, args
, &sMethods
[selector
], target
, 0));
270 RootDomainUserClient::setPreventative(UInt32 on_off
, UInt32 types_of_sleep
)