1368ad365SApple OSS Distributions /*
2368ad365SApple OSS Distributions  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3368ad365SApple OSS Distributions  *
4e13b1fa5SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5368ad365SApple OSS Distributions  *
6e13b1fa5SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7e13b1fa5SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8e13b1fa5SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9e13b1fa5SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10e13b1fa5SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11e13b1fa5SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12e13b1fa5SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13e13b1fa5SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14368ad365SApple OSS Distributions  *
15e13b1fa5SApple OSS Distributions  * Please obtain a copy of the License at
16e13b1fa5SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17e13b1fa5SApple OSS Distributions  *
18e13b1fa5SApple OSS Distributions  * The Original Code and all software distributed under the License are
19e13b1fa5SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20368ad365SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21368ad365SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22e13b1fa5SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23e13b1fa5SApple OSS Distributions  * Please see the License for the specific language governing rights and
24e13b1fa5SApple OSS Distributions  * limitations under the License.
25368ad365SApple OSS Distributions  *
26e13b1fa5SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27368ad365SApple OSS Distributions  */
28368ad365SApple OSS Distributions /*
29368ad365SApple OSS Distributions  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
30368ad365SApple OSS Distributions  *
31368ad365SApple OSS Distributions  */
32368ad365SApple OSS Distributions 
33368ad365SApple OSS Distributions #include <IOKit/assert.h>
34368ad365SApple OSS Distributions #include <IOKit/IOLib.h>
35e13b1fa5SApple OSS Distributions #include <IOKit/IOKitKeys.h>
36368ad365SApple OSS Distributions #include <IOKit/IOBufferMemoryDescriptor.h>
37368ad365SApple OSS Distributions #include "RootDomainUserClient.h"
38368ad365SApple OSS Distributions #include <IOKit/pwr_mgt/IOPMLibDefs.h>
39368ad365SApple OSS Distributions 
40368ad365SApple OSS Distributions #define super IOUserClient
41368ad365SApple OSS Distributions 
42368ad365SApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43368ad365SApple OSS Distributions 
44368ad365SApple OSS Distributions OSDefineMetaClassAndStructors(RootDomainUserClient, IOUserClient)
45368ad365SApple OSS Distributions 
46368ad365SApple OSS Distributions /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47368ad365SApple OSS Distributions 
48e13b1fa5SApple OSS Distributions bool RootDomainUserClient::initWithTask(task_t owningTask, void *security_id,
49e13b1fa5SApple OSS Distributions 					UInt32 type, OSDictionary * properties)
5014e3d835SApple OSS Distributions {
51e13b1fa5SApple OSS Distributions     if (properties)
52e13b1fa5SApple OSS Distributions 	properties->setObject(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue);
53e13b1fa5SApple OSS Distributions 
54e13b1fa5SApple OSS Distributions     if (!super::initWithTask(owningTask, security_id, type, properties))
5514e3d835SApple OSS Distributions 	return false;
5614e3d835SApple OSS Distributions 
5714e3d835SApple OSS Distributions     fOwningTask = owningTask;
5814e3d835SApple OSS Distributions     task_reference (fOwningTask);
5914e3d835SApple OSS Distributions     return true;
6014e3d835SApple OSS Distributions }
6114e3d835SApple OSS Distributions 
6214e3d835SApple OSS Distributions 
63368ad365SApple OSS Distributions bool RootDomainUserClient::start( IOService * provider )
64368ad365SApple OSS Distributions {
65368ad365SApple OSS Distributions     assert(OSDynamicCast(IOPMrootDomain, provider));
66368ad365SApple OSS Distributions     if(!super::start(provider))
67368ad365SApple OSS Distributions         return false;
68368ad365SApple OSS Distributions     fOwner = (IOPMrootDomain *)provider;
69368ad365SApple OSS Distributions 
70368ad365SApple OSS Distributions 
71368ad365SApple OSS Distributions     return true;
72368ad365SApple OSS Distributions }
73368ad365SApple OSS Distributions 
74e13b1fa5SApple OSS Distributions IOReturn RootDomainUserClient::secureSleepSystem( uint32_t *return_code )
7514e3d835SApple OSS Distributions {
76e13b1fa5SApple OSS Distributions     IOByteCount     return_code_size = 1;
77e13b1fa5SApple OSS Distributions 
78e13b1fa5SApple OSS Distributions     return secureSleepSystemOptions( NULL,      // inOptions
79e13b1fa5SApple OSS Distributions                                      (void *)return_code, // returnCode
80e13b1fa5SApple OSS Distributions                                      (void *)0,     // inSize
81e13b1fa5SApple OSS Distributions                                      (void *)&return_code_size, // returnSize
82e13b1fa5SApple OSS Distributions                                      NULL, NULL);
83e13b1fa5SApple OSS Distributions }
84e13b1fa5SApple OSS Distributions 
85e13b1fa5SApple OSS Distributions IOReturn RootDomainUserClient::secureSleepSystemOptions(
86e13b1fa5SApple OSS Distributions     void * p1, void * p2, void * p3,
87e13b1fa5SApple OSS Distributions     void * p4, void * p5, void * p6 )
88e13b1fa5SApple OSS Distributions {
89e13b1fa5SApple OSS Distributions     void            *inOptions = (void *)p1;
90e13b1fa5SApple OSS Distributions     uint32_t        *returnCode = (uint32_t *)p2;
91*3ca3bd55SApple OSS Distributions //  IOByteCount     inOptionsSize = (uintptr_t)p3;
92e13b1fa5SApple OSS Distributions     IOByteCount     *returnCodeSize = (IOByteCount *)p4;
93e13b1fa5SApple OSS Distributions 
9414e3d835SApple OSS Distributions     int             local_priv = 0;
9514e3d835SApple OSS Distributions     int             admin_priv = 0;
9614e3d835SApple OSS Distributions     IOReturn        ret = kIOReturnNotPrivileged;
97e13b1fa5SApple OSS Distributions     OSDictionary    *unserializedOptions =  NULL;
98e13b1fa5SApple OSS Distributions     OSString        *unserializeErrorString = NULL;
9914e3d835SApple OSS Distributions 
10014e3d835SApple OSS Distributions     ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser);
10114e3d835SApple OSS Distributions     local_priv = (kIOReturnSuccess == ret);
10214e3d835SApple OSS Distributions 
10314e3d835SApple OSS Distributions     ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator);
10414e3d835SApple OSS Distributions     admin_priv = (kIOReturnSuccess == ret);
10514e3d835SApple OSS Distributions 
106e13b1fa5SApple OSS Distributions     *returnCodeSize = sizeof(uint32_t);
107e13b1fa5SApple OSS Distributions 
108e13b1fa5SApple OSS Distributions     if (inOptions)
109e13b1fa5SApple OSS Distributions     {
110e13b1fa5SApple OSS Distributions         unserializedOptions = OSDynamicCast( OSDictionary,
111e13b1fa5SApple OSS Distributions                                              OSUnserializeXML((const char *)inOptions, &unserializeErrorString));
112e13b1fa5SApple OSS Distributions 
113e13b1fa5SApple OSS Distributions         if (!unserializedOptions) {
114e13b1fa5SApple OSS Distributions             IOLog("IOPMRootDomain SleepSystem unserialization failure: %s\n",
115e13b1fa5SApple OSS Distributions                 unserializeErrorString ? unserializeErrorString->getCStringNoCopy() : "Unknown");
116e13b1fa5SApple OSS Distributions         }
11714e3d835SApple OSS Distributions     }
11814e3d835SApple OSS Distributions 
119e13b1fa5SApple OSS Distributions     if ( (local_priv || admin_priv)
120e13b1fa5SApple OSS Distributions           && fOwner )
121e13b1fa5SApple OSS Distributions     {
122e13b1fa5SApple OSS Distributions         if (unserializedOptions)
123e13b1fa5SApple OSS Distributions         {
124e13b1fa5SApple OSS Distributions             // Publish Sleep Options in registry under root_domain
125e13b1fa5SApple OSS Distributions             fOwner->setProperty( kRootDomainSleepOptionsKey, unserializedOptions);
126e13b1fa5SApple OSS Distributions 
127e13b1fa5SApple OSS Distributions             *returnCode = fOwner->sleepSystemOptions( unserializedOptions );
128e13b1fa5SApple OSS Distributions 
129e13b1fa5SApple OSS Distributions             unserializedOptions->release();
130e13b1fa5SApple OSS Distributions         } else {
131e13b1fa5SApple OSS Distributions             // No options
132e13b1fa5SApple OSS Distributions             // Clear any pre-existing options
133e13b1fa5SApple OSS Distributions             fOwner->removeProperty( kRootDomainSleepOptionsKey );
134e13b1fa5SApple OSS Distributions 
135e13b1fa5SApple OSS Distributions             *returnCode = fOwner->sleepSystemOptions( NULL );
136e13b1fa5SApple OSS Distributions         }
137e13b1fa5SApple OSS Distributions 
138e13b1fa5SApple OSS Distributions     } else {
139e13b1fa5SApple OSS Distributions         *returnCode = kIOReturnNotPrivileged;
140e13b1fa5SApple OSS Distributions     }
141e13b1fa5SApple OSS Distributions 
142e13b1fa5SApple OSS Distributions     return kIOReturnSuccess;
14314e3d835SApple OSS Distributions }
14414e3d835SApple OSS Distributions 
14514e3d835SApple OSS Distributions IOReturn RootDomainUserClient::secureSetAggressiveness(
14614e3d835SApple OSS Distributions     unsigned long   type,
14714e3d835SApple OSS Distributions     unsigned long   newLevel,
14814e3d835SApple OSS Distributions     int             *return_code )
14914e3d835SApple OSS Distributions {
15014e3d835SApple OSS Distributions     int             local_priv = 0;
15114e3d835SApple OSS Distributions     int             admin_priv = 0;
15214e3d835SApple OSS Distributions     IOReturn        ret = kIOReturnNotPrivileged;
15314e3d835SApple OSS Distributions 
15414e3d835SApple OSS Distributions     ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser);
15514e3d835SApple OSS Distributions     local_priv = (kIOReturnSuccess == ret);
15614e3d835SApple OSS Distributions 
15714e3d835SApple OSS Distributions     ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator);
15814e3d835SApple OSS Distributions     admin_priv = (kIOReturnSuccess == ret);
15914e3d835SApple OSS Distributions 
16014e3d835SApple OSS Distributions     if((local_priv || admin_priv) && fOwner) {
16114e3d835SApple OSS Distributions         *return_code = fOwner->setAggressiveness(type, newLevel);
16214e3d835SApple OSS Distributions         return kIOReturnSuccess;
16314e3d835SApple OSS Distributions     } else {
16414e3d835SApple OSS Distributions         *return_code = kIOReturnNotPrivileged;
16514e3d835SApple OSS Distributions         return kIOReturnSuccess;
16614e3d835SApple OSS Distributions     }
16714e3d835SApple OSS Distributions }
16814e3d835SApple OSS Distributions 
169*3ca3bd55SApple OSS Distributions IOReturn RootDomainUserClient::secureSetMaintenanceWakeCalendar(
170*3ca3bd55SApple OSS Distributions     void * p1, void * p2, void * p3,
171*3ca3bd55SApple OSS Distributions     void * p4, void * p5, void * p6 )
172*3ca3bd55SApple OSS Distributions {
173*3ca3bd55SApple OSS Distributions #if ROOT_DOMAIN_RUN_STATES
174*3ca3bd55SApple OSS Distributions     IOPMCalendarStruct *    inCalendar = (IOPMCalendarStruct *) p1;
175*3ca3bd55SApple OSS Distributions     uint32_t *              returnCode = (uint32_t *) p2;
176*3ca3bd55SApple OSS Distributions     IOByteCount *           returnCodeSize = (IOByteCount *) p4;
177*3ca3bd55SApple OSS Distributions     int                     admin_priv = 0;
178*3ca3bd55SApple OSS Distributions     IOReturn                ret = kIOReturnNotPrivileged;
179*3ca3bd55SApple OSS Distributions 
180*3ca3bd55SApple OSS Distributions     ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator);
181*3ca3bd55SApple OSS Distributions     admin_priv = (kIOReturnSuccess == ret);
182*3ca3bd55SApple OSS Distributions 
183*3ca3bd55SApple OSS Distributions     *returnCodeSize = sizeof(uint32_t);
184*3ca3bd55SApple OSS Distributions 
185*3ca3bd55SApple OSS Distributions     if (admin_priv && fOwner) {
186*3ca3bd55SApple OSS Distributions         *returnCode = fOwner->setMaintenanceWakeCalendar(inCalendar);
187*3ca3bd55SApple OSS Distributions         return kIOReturnSuccess;
188*3ca3bd55SApple OSS Distributions     } else {
189*3ca3bd55SApple OSS Distributions         *returnCode = kIOReturnNotPrivileged;
190*3ca3bd55SApple OSS Distributions         return kIOReturnSuccess;
191*3ca3bd55SApple OSS Distributions     }
192*3ca3bd55SApple OSS Distributions #else
193*3ca3bd55SApple OSS Distributions     return kIOReturnUnsupported;
194*3ca3bd55SApple OSS Distributions #endif
195*3ca3bd55SApple OSS Distributions }
196368ad365SApple OSS Distributions 
197368ad365SApple OSS Distributions IOReturn RootDomainUserClient::clientClose( void )
198368ad365SApple OSS Distributions {
199368ad365SApple OSS Distributions     detach(fOwner);
20014e3d835SApple OSS Distributions 
20114e3d835SApple OSS Distributions     if(fOwningTask) {
20214e3d835SApple OSS Distributions         task_deallocate(fOwningTask);
20314e3d835SApple OSS Distributions         fOwningTask = 0;
20414e3d835SApple OSS Distributions     }
20514e3d835SApple OSS Distributions 
206368ad365SApple OSS Distributions     return kIOReturnSuccess;
207368ad365SApple OSS Distributions }
208368ad365SApple OSS Distributions 
209368ad365SApple OSS Distributions IOExternalMethod *
210368ad365SApple OSS Distributions RootDomainUserClient::getTargetAndMethodForIndex( IOService ** targetP, UInt32 index )
211368ad365SApple OSS Distributions {
212e13b1fa5SApple OSS Distributions     static const IOExternalMethod sMethods[] = {
213368ad365SApple OSS Distributions         {   // kPMSetAggressiveness, 0
214e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSetAggressiveness, kIOUCScalarIScalarO, 2, 1
215368ad365SApple OSS Distributions         },
216368ad365SApple OSS Distributions         {   // kPMGetAggressiveness, 1
217368ad365SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::getAggressiveness, kIOUCScalarIScalarO, 1, 1
218368ad365SApple OSS Distributions         },
219368ad365SApple OSS Distributions         {   // kPMSleepSystem, 2
220e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystem, kIOUCScalarIScalarO, 0, 1
221e13b1fa5SApple OSS Distributions         },
222e13b1fa5SApple OSS Distributions         {   // kPMAllowPowerChange, 3
223e13b1fa5SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::allowPowerChange, kIOUCScalarIScalarO, 1, 0
224e13b1fa5SApple OSS Distributions         },
225e13b1fa5SApple OSS Distributions         {   // kPMCancelPowerChange, 4
226e13b1fa5SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::cancelPowerChange, kIOUCScalarIScalarO, 1, 0
227e13b1fa5SApple OSS Distributions         },
228e13b1fa5SApple OSS Distributions         {   // kPMShutdownSystem, 5
229e13b1fa5SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::shutdownSystem, kIOUCScalarIScalarO, 0, 0
230e13b1fa5SApple OSS Distributions         },
231e13b1fa5SApple OSS Distributions         {   // kPMRestartSystem, 6
232e13b1fa5SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::restartSystem, kIOUCScalarIScalarO, 0, 0
233e13b1fa5SApple OSS Distributions         },
234e13b1fa5SApple OSS Distributions         {   // kPMSleepSystemOptions, 7
235e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystemOptions,
236e13b1fa5SApple OSS Distributions             kIOUCStructIStructO, kIOUCVariableStructureSize, sizeof(uint32_t)
237*3ca3bd55SApple OSS Distributions         },
238*3ca3bd55SApple OSS Distributions         {   // kPMSetMaintenanceWakeCalendar, 8
239*3ca3bd55SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSetMaintenanceWakeCalendar,
240*3ca3bd55SApple OSS Distributions             kIOUCStructIStructO, sizeof(IOPMCalendarStruct), sizeof(uint32_t)
241e13b1fa5SApple OSS Distributions         }
242e13b1fa5SApple OSS Distributions     };
243e13b1fa5SApple OSS Distributions 
244e13b1fa5SApple OSS Distributions     if(index >= kNumPMMethods)
245e13b1fa5SApple OSS Distributions     	return NULL;
246e13b1fa5SApple OSS Distributions     else {
247e13b1fa5SApple OSS Distributions         if (sMethods[index].object)
248e13b1fa5SApple OSS Distributions             *targetP = this;
249e13b1fa5SApple OSS Distributions         else
250e13b1fa5SApple OSS Distributions             *targetP = fOwner;
251e13b1fa5SApple OSS Distributions 
252e13b1fa5SApple OSS Distributions         return (IOExternalMethod *)&sMethods[index];
253e13b1fa5SApple OSS Distributions     }
254e13b1fa5SApple OSS Distributions }
255e13b1fa5SApple OSS Distributions 
256e13b1fa5SApple OSS Distributions #if 0
257e13b1fa5SApple OSS Distributions IOReturn RootDomainUserClient::externalMethod( uint32_t selector, IOExternalMethodArguments * args,
258e13b1fa5SApple OSS Distributions 						IOExternalMethodDispatch * dispatch, OSObject * target, void * reference )
259e13b1fa5SApple OSS Distributions {
260e13b1fa5SApple OSS Distributions     static const IOExternalMethodDispatch sMethods[] = {
261e13b1fa5SApple OSS Distributions         { // kPMSetAggressiveness, 0
262e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSetAggressiveness, kIOUCScalarIScalarO, 2, 1
263e13b1fa5SApple OSS Distributions         },
264e13b1fa5SApple OSS Distributions         { // kPMGetAggressiveness, 1
265e13b1fa5SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::getAggressiveness, kIOUCScalarIScalarO, 1, 1
266e13b1fa5SApple OSS Distributions         },
267e13b1fa5SApple OSS Distributions         { // kPMSleepSystem, 2
268e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystem, kIOUCScalarIScalarO, 0, 1
269368ad365SApple OSS Distributions         },
270368ad365SApple OSS Distributions         { // kPMAllowPowerChange, 3
271368ad365SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::allowPowerChange, kIOUCScalarIScalarO, 1, 0
272368ad365SApple OSS Distributions         },
273368ad365SApple OSS Distributions         { // kPMCancelPowerChange, 4
274368ad365SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::cancelPowerChange, kIOUCScalarIScalarO, 1, 0
275368ad365SApple OSS Distributions         },
276368ad365SApple OSS Distributions         { // kPMShutdownSystem, 5
277368ad365SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::shutdownSystem, kIOUCScalarIScalarO, 0, 0
278368ad365SApple OSS Distributions         },
279368ad365SApple OSS Distributions         { // kPMRestartSystem, 6
280368ad365SApple OSS Distributions             0, (IOMethod)&IOPMrootDomain::restartSystem, kIOUCScalarIScalarO, 0, 0
281368ad365SApple OSS Distributions         },
282368ad365SApple OSS Distributions         { // kPMSetPreventative, 7
283e13b1fa5SApple OSS Distributions             (IOService *)1, (IOMethod)&RootDomainUserClient::setPreventative, kIOUCScalarIScalarO, 2, 0
284368ad365SApple OSS Distributions         },
285368ad365SApple OSS Distributions     };
286368ad365SApple OSS Distributions 
287e13b1fa5SApple OSS Distributions     if (selector > (sizeof(sMethods) / sizeof(sMethods[0])))
288e13b1fa5SApple OSS Distributions 	return (kIOReturnBadArgument);
289368ad365SApple OSS Distributions 
290e13b1fa5SApple OSS Distributions     if ((1 << selector) & ((1 << 0) | (1 << 7))
291e13b1fa5SApple OSS Distributions 	target = this;
292e13b1fa5SApple OSS Distributions     else
293e13b1fa5SApple OSS Distributions 	target = fOwner;
294e13b1fa5SApple OSS Distributions 
295e13b1fa5SApple OSS Distributions     return (super::externalMethod(selector, args, &sMethods[selector], target, 0));
296368ad365SApple OSS Distributions }
297e13b1fa5SApple OSS Distributions #endif
298368ad365SApple OSS Distributions 
299368ad365SApple OSS Distributions void
300368ad365SApple OSS Distributions RootDomainUserClient::setPreventative(UInt32 on_off, UInt32 types_of_sleep)
301368ad365SApple OSS Distributions {
302368ad365SApple OSS Distributions     return;
303368ad365SApple OSS Distributions }
304368ad365SApple OSS Distributions 
305