|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * RUpsSession implementation. See class and function definitions |
|
16 * for more detail. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 /** |
|
22 @file |
|
23 */ |
|
24 |
|
25 |
|
26 #include <ups/upsclient.h> |
|
27 #include <e32property.h> |
|
28 #include <e32debug.h> |
|
29 #include "upscommon.h" |
|
30 #include "upsclientconfig.h" |
|
31 |
|
32 namespace UserPromptService |
|
33 { |
|
34 |
|
35 NONSHARABLE_CLASS(CPolicyChangeWatcher) : public CActive |
|
36 { |
|
37 public: |
|
38 static CPolicyChangeWatcher *NewL(RUpsSession &aUpsSession); |
|
39 ~CPolicyChangeWatcher(); |
|
40 private: |
|
41 CPolicyChangeWatcher(RUpsSession &aUpsSession); |
|
42 void ConstructL(); |
|
43 virtual void DoCancel(); |
|
44 virtual void RunL(); |
|
45 virtual TInt RunError(TInt aError); |
|
46 |
|
47 private: |
|
48 RProperty iUpsPolicyChangeProperty; |
|
49 RUpsSession &iUpsSession; |
|
50 }; |
|
51 |
|
52 EXPORT_C RUpsSession::RUpsSession() |
|
53 /** |
|
54 This constructor provides a single point of definition from |
|
55 which the superclass constructor is called. |
|
56 */ |
|
57 : RScsClientBase(), |
|
58 iPolicyChangeWatcher(0), |
|
59 iClientConfig(0) |
|
60 { |
|
61 // empty. |
|
62 } |
|
63 |
|
64 EXPORT_C TInt RUpsSession::Connect() |
|
65 /** |
|
66 Connect to the UPS server. |
|
67 |
|
68 The thread which calls this function must be the same one which later calls Close(). |
|
69 |
|
70 Once connected, this session can be shared by multiple RUpsSubsession objects. |
|
71 |
|
72 The RUpsSubsession objects are allowed to be in different threads, in which case ShareAuto() must be called before they are created. |
|
73 |
|
74 @return Symbian OS error code where KErrNone indicates |
|
75 success and any other value indicates failure. |
|
76 */ |
|
77 { |
|
78 TVersion v = UserPromptService::Version(); |
|
79 TUidType serverFullUid = UserPromptService::ServerImageFullUid(); |
|
80 |
|
81 TInt r = RScsClientBase::Connect( |
|
82 UserPromptService::KUpsServerName, v, UserPromptService::KServerImageName, serverFullUid); |
|
83 |
|
84 if (r == KErrNone) |
|
85 { |
|
86 // preload the configuration |
|
87 TRAP(r, RetrieveClientConfigL()); |
|
88 } |
|
89 |
|
90 if((r == KErrNone) && (CActiveScheduler::Current() != 0)) |
|
91 { |
|
92 delete iPolicyChangeWatcher; |
|
93 iPolicyChangeWatcher = 0; |
|
94 TRAP(r, iPolicyChangeWatcher = CPolicyChangeWatcher::NewL(*this)); |
|
95 } |
|
96 |
|
97 if(r != KErrNone) |
|
98 { |
|
99 Close(); |
|
100 } |
|
101 |
|
102 return r; |
|
103 } |
|
104 |
|
105 |
|
106 static void deleteArrayOfTServiceConfig(TAny *aPtr) |
|
107 { |
|
108 TServiceConfig *array = reinterpret_cast<TServiceConfig *>(aPtr); |
|
109 delete [] array; |
|
110 } |
|
111 |
|
112 void RUpsSession::RetrieveClientConfigL() |
|
113 { |
|
114 // Query how many TServiceConfig entries there are. |
|
115 TPckgBuf<TInt> countBuf; |
|
116 User::LeaveIfError(CallSessionFunction(EGetClientConfigLength, TIpcArgs(&countBuf))); |
|
117 // Retrieve count from buffer |
|
118 TInt count = countBuf(); |
|
119 |
|
120 // Create buffer to hold entries |
|
121 TServiceConfig *rawServiceConfig = new(ELeave) TServiceConfig[count]; |
|
122 CleanupStack::PushL(TCleanupItem(deleteArrayOfTServiceConfig, rawServiceConfig)); |
|
123 |
|
124 // Wrap array in a TPtr8 and use it to read array from server |
|
125 TInt size = count * sizeof(TServiceConfig); |
|
126 TPtr8 ptr((TUint8*)rawServiceConfig, size, size); |
|
127 User::LeaveIfError(CallSessionFunction(EGetClientConfigData, TIpcArgs(&ptr))); |
|
128 |
|
129 CUpsClientConfig *tmp = CUpsClientConfig::NewL(count, rawServiceConfig); |
|
130 delete iClientConfig; |
|
131 iClientConfig = tmp; |
|
132 |
|
133 CleanupStack::PopAndDestroy(); // get rid of rawServiceConfig array |
|
134 } |
|
135 |
|
136 |
|
137 EXPORT_C void RUpsSession::Close() |
|
138 /** |
|
139 Frees the configuration object and calls RScsClientBase::Close |
|
140 |
|
141 This function MUST be called by the same thread which Connect(). |
|
142 */ |
|
143 { |
|
144 delete iClientConfig; |
|
145 iClientConfig = 0; |
|
146 |
|
147 if(iPolicyChangeWatcher) |
|
148 { |
|
149 iPolicyChangeWatcher->Cancel(); |
|
150 } |
|
151 delete iPolicyChangeWatcher; |
|
152 iPolicyChangeWatcher = 0; |
|
153 |
|
154 RScsClientBase::Close(); |
|
155 } |
|
156 |
|
157 void RUpsSession::NotifyPolicyFileChangedL() |
|
158 /** |
|
159 @internalComponent |
|
160 @released |
|
161 |
|
162 Policy files have changed so update serviceconfig cache. |
|
163 */ |
|
164 { |
|
165 RetrieveClientConfigL(); |
|
166 } |
|
167 |
|
168 CUpsClientConfig::CUpsClientConfig() |
|
169 : iServiceConfig(1 /* granularity */, 0 /* key offset */) |
|
170 { |
|
171 } |
|
172 |
|
173 CUpsClientConfig::~CUpsClientConfig() |
|
174 { |
|
175 iServiceConfig.Close(); |
|
176 } |
|
177 |
|
178 CUpsClientConfig* CUpsClientConfig::NewL(TInt aCount, TServiceConfig *aRawServiceConfig) |
|
179 /** |
|
180 @param serviceConfig |
|
181 |
|
182 Takes ownership of the serviceConfig array via swap. Callers array will be cleared. |
|
183 */ |
|
184 { |
|
185 CUpsClientConfig *self = new(ELeave) CUpsClientConfig(); |
|
186 CleanupStack::PushL(self); |
|
187 self->ConstructL(aCount, aRawServiceConfig); |
|
188 CleanupStack::Pop(self); |
|
189 return self; |
|
190 } |
|
191 |
|
192 |
|
193 void CUpsClientConfig::ConstructL(TInt aCount, TServiceConfig *aRawServiceConfig) |
|
194 { |
|
195 iServiceConfig.ReserveL(aCount); |
|
196 for(TInt i=0; i < aCount; ++i) |
|
197 { |
|
198 iServiceConfig.InsertInUnsignedKeyOrderL(aRawServiceConfig[i]); |
|
199 } |
|
200 } |
|
201 |
|
202 CUpsClientConfig::TQueryUpsResult |
|
203 CUpsClientConfig::QueryUps(TBool aServerChecksPassed, |
|
204 const TServiceId &aServiceId, |
|
205 const TSecureId &aClientSid, |
|
206 const TProcessId &aClientProcessId) const |
|
207 { |
|
208 TServiceConfig sc = {0}; |
|
209 sc.iServiceId = aServiceId.iUid; /* Only service id is used in lookup */ |
|
210 TInt i = iServiceConfig.FindInUnsignedKeyOrder(sc); |
|
211 if(i == KErrNotFound) |
|
212 { |
|
213 // Must be no policy file for this service so no point in querying UPS |
|
214 return aServerChecksPassed ? EAllow: EReject; |
|
215 } |
|
216 |
|
217 |
|
218 // Read entry |
|
219 sc = iServiceConfig[i]; |
|
220 |
|
221 switch(sc.iPolicy) |
|
222 { |
|
223 case EAlwaysCheck: |
|
224 return EQueryUps; |
|
225 |
|
226 case ECheckPostManufacture: |
|
227 { |
|
228 TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0; |
|
229 if(! isProtected) |
|
230 { |
|
231 return EQueryUps; |
|
232 } |
|
233 |
|
234 // Need to obtain the drive letter for the exe |
|
235 // |
|
236 // This requires opening the RProcess and two copies of a full filename (one 8 bit the other unicode)...... |
|
237 // We could optimse this by doing it when Initialise() is called, but that then slows down all Initialise calls even ones |
|
238 // not doing the ECheckPostManufacture check. |
|
239 RProcess clientProcess; |
|
240 if(clientProcess.Open(aClientProcessId) != KErrNone) |
|
241 { |
|
242 return EReject; // Presumably it exited... |
|
243 } |
|
244 |
|
245 TFileName clientExeName = clientProcess.FileName(); |
|
246 clientProcess.Close(); |
|
247 TChar driveChar= clientExeName[0]; |
|
248 |
|
249 if(aServerChecksPassed && |
|
250 (driveChar == 'z' || driveChar == 'Z')) |
|
251 { |
|
252 return EAllow; |
|
253 } |
|
254 |
|
255 return EQueryUps; |
|
256 } |
|
257 |
|
258 case ECheckUnprotectedSids: |
|
259 { |
|
260 TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0; |
|
261 |
|
262 if(aServerChecksPassed && isProtected) |
|
263 { |
|
264 return EAllow; |
|
265 } |
|
266 |
|
267 return EQueryUps; |
|
268 } |
|
269 |
|
270 case ECheckIfFailed: |
|
271 return aServerChecksPassed ? EAllow : EQueryUps; |
|
272 |
|
273 BULLSEYE_OFF |
|
274 default: |
|
275 BULLSEYE_RESTORE |
|
276 case ENeverCheck: |
|
277 return aServerChecksPassed ? EAllow: EReject; |
|
278 } |
|
279 // Never gets here |
|
280 } |
|
281 |
|
282 // |
|
283 // CPolicyChangeWatcher member functions |
|
284 // |
|
285 CPolicyChangeWatcher *CPolicyChangeWatcher::NewL(RUpsSession &aUpsSession) |
|
286 { |
|
287 CPolicyChangeWatcher *self = new(ELeave) CPolicyChangeWatcher(aUpsSession); |
|
288 CleanupStack::PushL(self); |
|
289 self->ConstructL(); |
|
290 CleanupStack::Pop(self); |
|
291 return self; |
|
292 } |
|
293 |
|
294 CPolicyChangeWatcher::CPolicyChangeWatcher(RUpsSession &aUpsSession) |
|
295 : CActive(CActive::EPriorityStandard+1), |
|
296 iUpsSession(aUpsSession) |
|
297 { |
|
298 CActiveScheduler::Add(this); |
|
299 } |
|
300 |
|
301 void CPolicyChangeWatcher::ConstructL() |
|
302 { |
|
303 User::LeaveIfError(iUpsPolicyChangeProperty.Attach(KUpsServerUid, KUpsServiceConfigProperty, EOwnerThread)); |
|
304 iUpsPolicyChangeProperty.Subscribe(iStatus); |
|
305 SetActive(); |
|
306 } |
|
307 |
|
308 CPolicyChangeWatcher::~CPolicyChangeWatcher() |
|
309 { |
|
310 Cancel(); |
|
311 } |
|
312 |
|
313 void CPolicyChangeWatcher::DoCancel() |
|
314 { |
|
315 iUpsPolicyChangeProperty.Cancel(); |
|
316 } |
|
317 |
|
318 void CPolicyChangeWatcher::RunL() |
|
319 { |
|
320 // Re-subscribe for policy file change notifications |
|
321 iUpsPolicyChangeProperty.Subscribe(iStatus); |
|
322 SetActive(); |
|
323 |
|
324 // Tell session to update its cache. |
|
325 iUpsSession.NotifyPolicyFileChangedL(); |
|
326 } |
|
327 |
|
328 TInt CPolicyChangeWatcher::RunError(TInt /* aError */) |
|
329 { |
|
330 // Ignore all errors |
|
331 //RDebug::Printf("CPolicyChangeWatcher::RunError(%d)\n", aError); |
|
332 return KErrNone; |
|
333 } |
|
334 |
|
335 |
|
336 } // End of namespace UserPromptService |
|
337 |
|
338 // End of file |
|
339 |