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 = (uintptr_t)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
;
169 IOReturn
RootDomainUserClient::secureSetMaintenanceWakeCalendar(
170 void * p1
, void * p2
, void * p3
,
171 void * p4
, void * p5
, void * p6
)
173 #if ROOT_DOMAIN_RUN_STATES
174 IOPMCalendarStruct
* inCalendar
= (IOPMCalendarStruct
*) p1
;
175 uint32_t * returnCode
= (uint32_t *) p2
;
176 IOByteCount
* returnCodeSize
= (IOByteCount
*) p4
;
178 IOReturn ret
= kIOReturnNotPrivileged
;
180 ret
= clientHasPrivilege(fOwningTask
, kIOClientPrivilegeAdministrator
);
181 admin_priv
= (kIOReturnSuccess
== ret
);
183 *returnCodeSize
= sizeof(uint32_t);
185 if (admin_priv
&& fOwner
) {
186 *returnCode
= fOwner
->setMaintenanceWakeCalendar(inCalendar
);
187 return kIOReturnSuccess
;
189 *returnCode
= kIOReturnNotPrivileged
;
190 return kIOReturnSuccess
;
193 return kIOReturnUnsupported
;
197 IOReturn
RootDomainUserClient::clientClose( void )
202 task_deallocate(fOwningTask
);
206 return kIOReturnSuccess
;
210 RootDomainUserClient::getTargetAndMethodForIndex( IOService
** targetP
, UInt32 index
)
212 static const IOExternalMethod sMethods
[] = {
213 { // kPMSetAggressiveness, 0
214 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSetAggressiveness
, kIOUCScalarIScalarO
, 2, 1
216 { // kPMGetAggressiveness, 1
217 0, (IOMethod
)&IOPMrootDomain::getAggressiveness
, kIOUCScalarIScalarO
, 1, 1
219 { // kPMSleepSystem, 2
220 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystem
, kIOUCScalarIScalarO
, 0, 1
222 { // kPMAllowPowerChange, 3
223 0, (IOMethod
)&IOPMrootDomain::allowPowerChange
, kIOUCScalarIScalarO
, 1, 0
225 { // kPMCancelPowerChange, 4
226 0, (IOMethod
)&IOPMrootDomain::cancelPowerChange
, kIOUCScalarIScalarO
, 1, 0
228 { // kPMShutdownSystem, 5
229 0, (IOMethod
)&IOPMrootDomain::shutdownSystem
, kIOUCScalarIScalarO
, 0, 0
231 { // kPMRestartSystem, 6
232 0, (IOMethod
)&IOPMrootDomain::restartSystem
, kIOUCScalarIScalarO
, 0, 0
234 { // kPMSleepSystemOptions, 7
235 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystemOptions
,
236 kIOUCStructIStructO
, kIOUCVariableStructureSize
, sizeof(uint32_t)
238 { // kPMSetMaintenanceWakeCalendar, 8
239 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSetMaintenanceWakeCalendar
,
240 kIOUCStructIStructO
, sizeof(IOPMCalendarStruct
), sizeof(uint32_t)
244 if(index
>= kNumPMMethods
)
247 if (sMethods
[index
].object
)
252 return (IOExternalMethod
*)&sMethods
[index
];
257 IOReturn
RootDomainUserClient::externalMethod( uint32_t selector
, IOExternalMethodArguments
* args
,
258 IOExternalMethodDispatch
* dispatch
, OSObject
* target
, void * reference
)
260 static const IOExternalMethodDispatch sMethods
[] = {
261 { // kPMSetAggressiveness, 0
262 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSetAggressiveness
, kIOUCScalarIScalarO
, 2, 1
264 { // kPMGetAggressiveness, 1
265 0, (IOMethod
)&IOPMrootDomain::getAggressiveness
, kIOUCScalarIScalarO
, 1, 1
267 { // kPMSleepSystem, 2
268 (IOService
*)1, (IOMethod
)&RootDomainUserClient::secureSleepSystem
, kIOUCScalarIScalarO
, 0, 1
270 { // kPMAllowPowerChange, 3
271 0, (IOMethod
)&IOPMrootDomain::allowPowerChange
, kIOUCScalarIScalarO
, 1, 0
273 { // kPMCancelPowerChange, 4
274 0, (IOMethod
)&IOPMrootDomain::cancelPowerChange
, kIOUCScalarIScalarO
, 1, 0
276 { // kPMShutdownSystem, 5
277 0, (IOMethod
)&IOPMrootDomain::shutdownSystem
, kIOUCScalarIScalarO
, 0, 0
279 { // kPMRestartSystem, 6
280 0, (IOMethod
)&IOPMrootDomain::restartSystem
, kIOUCScalarIScalarO
, 0, 0
282 { // kPMSetPreventative, 7
283 (IOService
*)1, (IOMethod
)&RootDomainUserClient::setPreventative
, kIOUCScalarIScalarO
, 2, 0
287 if (selector
> (sizeof(sMethods
) / sizeof(sMethods
[0])))
288 return (kIOReturnBadArgument
);
290 if ((1 << selector
) & ((1 << 0) | (1 << 7))
295 return (super::externalMethod(selector
, args
, &sMethods
[selector
], target
, 0));
300 RootDomainUserClient::setPreventative(UInt32 on_off
, UInt32 types_of_sleep
)