]>
Commit | Line | Data |
---|---|---|
55e303ae A |
1 | /* |
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
55e303ae | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
55e303ae A |
27 | */ |
28 | /* | |
29 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
30 | * | |
31 | */ | |
32 | ||
33 | #include <IOKit/assert.h> | |
34 | #include <IOKit/IOLib.h> | |
0c530ab8 | 35 | #include <IOKit/IOKitKeys.h> |
55e303ae A |
36 | #include <IOKit/IOBufferMemoryDescriptor.h> |
37 | #include "RootDomainUserClient.h" | |
38 | #include <IOKit/pwr_mgt/IOPMLibDefs.h> | |
39 | ||
40 | #define super IOUserClient | |
41 | ||
42 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
43 | ||
44 | OSDefineMetaClassAndStructors(RootDomainUserClient, IOUserClient) | |
45 | ||
46 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
47 | ||
0c530ab8 A |
48 | bool RootDomainUserClient::initWithTask(task_t owningTask, void *security_id, |
49 | UInt32 type, OSDictionary * properties) | |
91447636 | 50 | { |
0c530ab8 A |
51 | if (properties) |
52 | properties->setObject(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue); | |
53 | ||
54 | if (!super::initWithTask(owningTask, security_id, type, properties)) | |
91447636 A |
55 | return false; |
56 | ||
57 | fOwningTask = owningTask; | |
58 | task_reference (fOwningTask); | |
59 | return true; | |
60 | } | |
61 | ||
62 | ||
55e303ae A |
63 | bool RootDomainUserClient::start( IOService * provider ) |
64 | { | |
65 | assert(OSDynamicCast(IOPMrootDomain, provider)); | |
66 | if(!super::start(provider)) | |
67 | return false; | |
68 | fOwner = (IOPMrootDomain *)provider; | |
69 | ||
70 | ||
71 | return true; | |
72 | } | |
73 | ||
2d21ac55 | 74 | IOReturn RootDomainUserClient::secureSleepSystem( uint32_t *return_code ) |
91447636 | 75 | { |
2d21ac55 A |
76 | IOByteCount return_code_size = 1; |
77 | ||
78 | return secureSleepSystemOptions( NULL, // inOptions | |
79 | (void *)return_code, // returnCode | |
80 | (void *)0, // inSize | |
81 | (void *)&return_code_size, // returnSize | |
82 | NULL, NULL); | |
83 | } | |
84 | ||
85 | IOReturn RootDomainUserClient::secureSleepSystemOptions( | |
86 | void * p1, void * p2, void * p3, | |
87 | void * p4, void * p5, void * p6 ) | |
88 | { | |
89 | void *inOptions = (void *)p1; | |
90 | uint32_t *returnCode = (uint32_t *)p2; | |
91 | IOByteCount inOptionsSize = (IOByteCount)p3; | |
92 | IOByteCount *returnCodeSize = (IOByteCount *)p4; | |
93 | ||
91447636 A |
94 | int local_priv = 0; |
95 | int admin_priv = 0; | |
96 | IOReturn ret = kIOReturnNotPrivileged; | |
2d21ac55 A |
97 | OSDictionary *unserializedOptions = NULL; |
98 | OSString *unserializeErrorString = NULL; | |
91447636 A |
99 | |
100 | ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser); | |
101 | local_priv = (kIOReturnSuccess == ret); | |
102 | ||
103 | ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); | |
104 | admin_priv = (kIOReturnSuccess == ret); | |
2d21ac55 A |
105 | |
106 | *returnCodeSize = sizeof(uint32_t); | |
107 | ||
108 | if (inOptions) | |
109 | { | |
110 | unserializedOptions = OSDynamicCast( OSDictionary, | |
111 | OSUnserializeXML((const char *)inOptions, &unserializeErrorString)); | |
112 | ||
113 | if (!unserializedOptions) { | |
114 | IOLog("IOPMRootDomain SleepSystem unserialization failure: %s\n", | |
115 | unserializeErrorString ? unserializeErrorString->getCStringNoCopy() : "Unknown"); | |
116 | } | |
117 | } | |
118 | ||
119 | if ( (local_priv || admin_priv) | |
120 | && fOwner ) | |
121 | { | |
122 | if (unserializedOptions) | |
123 | { | |
124 | // Publish Sleep Options in registry under root_domain | |
125 | fOwner->setProperty( kRootDomainSleepOptionsKey, unserializedOptions); | |
126 | ||
127 | *returnCode = fOwner->sleepSystemOptions( unserializedOptions ); | |
128 | ||
129 | unserializedOptions->release(); | |
130 | } else { | |
131 | // No options | |
132 | // Clear any pre-existing options | |
133 | fOwner->removeProperty( kRootDomainSleepOptionsKey ); | |
134 | ||
135 | *returnCode = fOwner->sleepSystemOptions( NULL ); | |
136 | } | |
91447636 | 137 | |
91447636 | 138 | } else { |
2d21ac55 | 139 | *returnCode = kIOReturnNotPrivileged; |
91447636 A |
140 | } |
141 | ||
2d21ac55 | 142 | return kIOReturnSuccess; |
91447636 A |
143 | } |
144 | ||
145 | IOReturn RootDomainUserClient::secureSetAggressiveness( | |
146 | unsigned long type, | |
147 | unsigned long newLevel, | |
148 | int *return_code ) | |
149 | { | |
150 | int local_priv = 0; | |
151 | int admin_priv = 0; | |
152 | IOReturn ret = kIOReturnNotPrivileged; | |
153 | ||
154 | ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeLocalUser); | |
155 | local_priv = (kIOReturnSuccess == ret); | |
156 | ||
157 | ret = clientHasPrivilege(fOwningTask, kIOClientPrivilegeAdministrator); | |
158 | admin_priv = (kIOReturnSuccess == ret); | |
159 | ||
160 | if((local_priv || admin_priv) && fOwner) { | |
161 | *return_code = fOwner->setAggressiveness(type, newLevel); | |
162 | return kIOReturnSuccess; | |
163 | } else { | |
164 | *return_code = kIOReturnNotPrivileged; | |
165 | return kIOReturnSuccess; | |
166 | } | |
167 | ||
168 | } | |
169 | ||
55e303ae A |
170 | |
171 | IOReturn RootDomainUserClient::clientClose( void ) | |
172 | { | |
173 | detach(fOwner); | |
91447636 A |
174 | |
175 | if(fOwningTask) { | |
176 | task_deallocate(fOwningTask); | |
177 | fOwningTask = 0; | |
178 | } | |
179 | ||
55e303ae A |
180 | return kIOReturnSuccess; |
181 | } | |
182 | ||
183 | IOExternalMethod * | |
184 | RootDomainUserClient::getTargetAndMethodForIndex( IOService ** targetP, UInt32 index ) | |
185 | { | |
2d21ac55 | 186 | static const IOExternalMethod sMethods[] = { |
55e303ae | 187 | { // kPMSetAggressiveness, 0 |
0c530ab8 | 188 | (IOService *)1, (IOMethod)&RootDomainUserClient::secureSetAggressiveness, kIOUCScalarIScalarO, 2, 1 |
55e303ae A |
189 | }, |
190 | { // kPMGetAggressiveness, 1 | |
191 | 0, (IOMethod)&IOPMrootDomain::getAggressiveness, kIOUCScalarIScalarO, 1, 1 | |
192 | }, | |
193 | { // kPMSleepSystem, 2 | |
0c530ab8 | 194 | (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystem, kIOUCScalarIScalarO, 0, 1 |
55e303ae A |
195 | }, |
196 | { // kPMAllowPowerChange, 3 | |
197 | 0, (IOMethod)&IOPMrootDomain::allowPowerChange, kIOUCScalarIScalarO, 1, 0 | |
198 | }, | |
199 | { // kPMCancelPowerChange, 4 | |
200 | 0, (IOMethod)&IOPMrootDomain::cancelPowerChange, kIOUCScalarIScalarO, 1, 0 | |
201 | }, | |
202 | { // kPMShutdownSystem, 5 | |
203 | 0, (IOMethod)&IOPMrootDomain::shutdownSystem, kIOUCScalarIScalarO, 0, 0 | |
204 | }, | |
205 | { // kPMRestartSystem, 6 | |
206 | 0, (IOMethod)&IOPMrootDomain::restartSystem, kIOUCScalarIScalarO, 0, 0 | |
207 | }, | |
2d21ac55 A |
208 | { // kPMSleepSystemOptions, 7 |
209 | (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystemOptions, | |
210 | kIOUCStructIStructO, kIOUCVariableStructureSize, sizeof(uint32_t) | |
211 | } | |
55e303ae | 212 | }; |
91447636 | 213 | |
55e303ae A |
214 | if(index >= kNumPMMethods) |
215 | return NULL; | |
216 | else { | |
217 | if (sMethods[index].object) | |
218 | *targetP = this; | |
219 | else | |
220 | *targetP = fOwner; | |
221 | ||
2d21ac55 | 222 | return (IOExternalMethod *)&sMethods[index]; |
55e303ae A |
223 | } |
224 | } | |
225 | ||
2d21ac55 A |
226 | #if 0 |
227 | IOReturn RootDomainUserClient::externalMethod( uint32_t selector, IOExternalMethodArguments * args, | |
228 | IOExternalMethodDispatch * dispatch, OSObject * target, void * reference ) | |
229 | { | |
230 | static const IOExternalMethodDispatch sMethods[] = { | |
231 | { // kPMSetAggressiveness, 0 | |
232 | (IOService *)1, (IOMethod)&RootDomainUserClient::secureSetAggressiveness, kIOUCScalarIScalarO, 2, 1 | |
233 | }, | |
234 | { // kPMGetAggressiveness, 1 | |
235 | 0, (IOMethod)&IOPMrootDomain::getAggressiveness, kIOUCScalarIScalarO, 1, 1 | |
236 | }, | |
237 | { // kPMSleepSystem, 2 | |
238 | (IOService *)1, (IOMethod)&RootDomainUserClient::secureSleepSystem, kIOUCScalarIScalarO, 0, 1 | |
239 | }, | |
240 | { // kPMAllowPowerChange, 3 | |
241 | 0, (IOMethod)&IOPMrootDomain::allowPowerChange, kIOUCScalarIScalarO, 1, 0 | |
242 | }, | |
243 | { // kPMCancelPowerChange, 4 | |
244 | 0, (IOMethod)&IOPMrootDomain::cancelPowerChange, kIOUCScalarIScalarO, 1, 0 | |
245 | }, | |
246 | { // kPMShutdownSystem, 5 | |
247 | 0, (IOMethod)&IOPMrootDomain::shutdownSystem, kIOUCScalarIScalarO, 0, 0 | |
248 | }, | |
249 | { // kPMRestartSystem, 6 | |
250 | 0, (IOMethod)&IOPMrootDomain::restartSystem, kIOUCScalarIScalarO, 0, 0 | |
251 | }, | |
252 | { // kPMSetPreventative, 7 | |
253 | (IOService *)1, (IOMethod)&RootDomainUserClient::setPreventative, kIOUCScalarIScalarO, 2, 0 | |
254 | }, | |
255 | }; | |
256 | ||
257 | if (selector > (sizeof(sMethods) / sizeof(sMethods[0]))) | |
258 | return (kIOReturnBadArgument); | |
259 | ||
260 | if ((1 << selector) & ((1 << 0) | (1 << 7)) | |
261 | target = this; | |
262 | else | |
263 | target = fOwner; | |
264 | ||
265 | return (super::externalMethod(selector, args, &sMethods[selector], target, 0)); | |
266 | } | |
267 | #endif | |
268 | ||
55e303ae A |
269 | void |
270 | RootDomainUserClient::setPreventative(UInt32 on_off, UInt32 types_of_sleep) | |
271 | { | |
272 | return; | |
273 | } | |
274 |