Update contrib.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "policycache.h"
20 #include "policylist.h"
21 #include "policyreader.h"
22 #include "promptrequest.h"
23 #include "serviceconfig.h"
25 #include <ups/upserr.h>
28 using namespace UserPromptService;
30 EXPORT_C CPolicyCache* CPolicyCache::NewL(RFs& aFs, const TDesC& aPolicyPath)
32 Creates a new policy cache.
33 @param aFs The file server session used to load policy files.\n
34 Ownership is not transferred.
35 @param aPolicyPath The path of the policy files (minus the drive). It must be
36 in the following form "\private\sid\policies\"
37 @return A pointer to the new policy cache object.
40 CPolicyCache* self = new(ELeave) CPolicyCache(aFs);
41 CleanupStack::PushL(self);
42 self->ConstructL(aPolicyPath);
43 CleanupStack::Pop(self);
47 CPolicyCache::CPolicyCache(RFs& aFs)
50 @param aFs The file server session used to load policy files.
56 CPolicyCache::~CPolicyCache()
61 iPolicyLists.ResetAndDestroy();
65 void CPolicyCache::ConstructL(const TDesC& aPolicyPath)
67 Second phase constructor, resolves the system drive.
68 @param aPolicyPath The directory where the policy files are stored.
71 iPolicyPath = aPolicyPath.AllocL();
72 iSystemDriveChar = iFs.GetSystemDriveChar();
75 EXPORT_C const CPolicy* CPolicyCache::MatchL(const CPromptRequest& aRequest)
77 Finds the first policy that matches the request.
79 @param aRequest The request data from the system server.
80 @return A copy of the policy object to apply to the request. If a policy
81 file exists but no policy is defined then a default policy object
82 is returned that current request to be accepted or denied.
84 @leave KErrUpsMissingPolicyFile If no policy file is found for the requested server sid and service id.
85 @leave KErrUpsBadPolicyFile If an error occured whilst parsing a policy file.
88 CPolicyList::TId id(aRequest.ServerSid(), aRequest.ServiceId());
89 const CPolicyList* list = PolicyList(id);
93 // Policy list not found so try and load it. This
94 // leaves if a UPS policy file is not found.
95 list = LoadPolicyListL(id);
99 return list->Match(aRequest);
102 const CPolicyList* CPolicyCache::PolicyList(const CPolicyList::TId& aId) const
104 Gets the specified policy list if it is loaded.
105 @param The ID of the policy list.
106 @return A pointer to the policy list if it is loaded; otherwise, is returned.
109 TInt count = iPolicyLists.Count();
110 for (TInt i = 0; i < count; ++i) // Check if policy list is in the cache
112 if (iPolicyLists[i]->Id() == aId)
114 return iPolicyLists[i];
120 CPolicyList* CPolicyCache::LoadPolicyListL(const CPolicyList::TId& aId)
122 Loads a list of policies from the policy file for the specified system server and service.
123 @param aId A tuple of the system server SID and service UID that identifies a policy file.
125 @return The list of policies, or N
126 @leave KErrUpsBadPolicyFile if an error occured whilst parsing a policy file.
127 KErrUpsMissingPolicyFile if the policy file was not found on the Z or the system drive.
131 fn.CreateL(KMaxFileName);
132 CleanupClosePushL(fn);
134 LocatePolicyFileL(fn, aId);
137 TRAPD(err, l = ParseListL(aId, fn));
138 if (err != KErrNone && err != KErrNoMemory)
140 DEBUG_PRINTF2(_L("Unable to parse %S"), &fn);
141 err = KErrUpsBadPolicyFile;
145 DEBUG_PRINTF2(_L("Unable to parse %S"), &fn);
146 User::Panic(KUpsPoliciesPanicCat, EUpsPoliciesCorruptRomPolicy);
149 // If we failed to read the policy file from the system
150 // drive then try the Z drive.
152 TRAP(err, l = ParseListL(aId, fn));
155 DEBUG_PRINTF2(_L("Ignoring corrupt policy file on system drive. Loading %S"), &fn);
157 else if (err != KErrNotFound && err != KErrNoMemory)
159 DEBUG_PRINTF2(_L("Unable to parse %S"), &fn);
160 User::Panic(KUpsPoliciesPanicCat, EUpsPoliciesCorruptRomPolicy);
164 User::LeaveIfError(err);
166 CleanupStack::PushL(l);
167 iPolicyLists.AppendL(l);
168 CleanupStack::Pop(l);
169 CleanupStack::PopAndDestroy(&fn);
173 void CPolicyCache::LocatePolicyFileL(TDes& aPolicyFileName, const CPolicyList::TId& aId)
175 Determines whether the policy file should be loaded from the Z drive
176 or the system drive and returns the filename.
178 @param aPolicyFileName Descriptor to populate with the filename.
179 @param aId The id of the policy file to load.
181 @leave KErrUpsMissingPolicyFile The policy file was not found on either the Z drive
185 _LIT(KDriveSpec, "!:");
187 aPolicyFileName.Zero();
188 aPolicyFileName.Append(KDriveSpec);
189 aPolicyFileName.Append(*iPolicyPath);
190 aId.AppendNameToPath(aPolicyFileName);
192 // System drive eclipses Z drive
193 aPolicyFileName[0] = iSystemDriveChar;
194 if (! FileExistsL(aPolicyFileName))
196 aPolicyFileName[0] = 'Z';
197 if (! FileExistsL(aPolicyFileName))
199 DEBUG_PRINTF3(_L8("No policy file for system server sid = 0x%08x, service id = 0x%08x"),
200 aId.iServerSid.iId, aId.iServiceId.iUid);
201 User::Leave(KErrUpsMissingPolicyFile);
206 CPolicyList* CPolicyCache::ParseListL(const CPolicyList::TId& aId, const TDesC& aPolicyFileName)
208 Parses a policy file and constructs a policy list object.
210 @param aId The policy file id that will be used to locate the policy list within
212 @param aPolicyFileName The absolute path of the policy file to parse.
213 @return The new policy list object.
216 CPolicyReader* r = CPolicyReader::NewLC(iFs, aPolicyFileName);
217 CPolicyList* l = CPolicyList::NewL(aId, *r);
218 CleanupStack::PopAndDestroy(r);
222 EXPORT_C void CPolicyCache::ServiceConfigL(const TSecureId& aServerSid, RArray<TServiceConfig>& aConfigs)
224 Loads the service configuration data from the policy files for every service provided
225 by a given system server.
226 @param aServerSid The secure id of the system server.
227 @param aConfigs The RArray to populate with the configuration data.
230 RArray<TUint> services;
231 CleanupClosePushL(services);
233 DEBUG_PRINTF2(_L8("Loading service configuration for system server 0x%08x"), aServerSid.iId);
235 FindServicesL(aServerSid, services);
236 TInt numServices = services.Count();
239 for (TInt i = 0; i < numServices; ++i)
241 CPolicyList::TId id(aServerSid, TUid::Uid(services[i]));
242 const CPolicyList* list = PolicyList(id);
245 // Use in-memory service configuration
246 aConfigs.AppendL(list->ServiceConfig());
250 // Load policy file into cache
251 CPolicyList* loadedList = LoadPolicyListL(id);
252 aConfigs.AppendL(loadedList->ServiceConfig());
255 CleanupStack::PopAndDestroy(&services);
258 void CPolicyCache::FindServicesL(const TSecureId& aServerSid, RArray<TUint>& aServices)
260 Finds all of the policy files on Z drive and C drive for this system server
261 A wildcard string is used to filter out policy files for other system servers.
263 @param aServerSid The secure id of the system server.
264 @param aServices The array of service ids to populate.
267 _LIT(KFilenameTemplate, "ups_%08x_????????.rsc");
269 pattern.AppendFormat(KFilenameTemplate, aServerSid.iId);
271 RBuf fn; // Store current file/directory name.
272 fn.CreateL(KMaxFileName);
273 CleanupClosePushL(fn);
274 for (TInt i = 0; i < 2; ++i)
276 TUint driveChar = (i == 0) ? TChar('Z') : iSystemDriveChar;
279 _LIT(KDirFormat, "%c:%S");
280 fn.AppendFormat(KDirFormat, driveChar, &*iPolicyPath);
283 TInt err = iFs.GetDir(fn, KEntryAttNormal, ESortNone, dir);
284 if (err == KErrPathNotFound)
288 User::LeaveIfError(err);
289 CleanupStack::PushL(dir);
292 TInt count = dir->Count();
293 for (TInt j = 0; j < count; ++j)
295 const TEntry& e((*dir)[j]);
296 if (e.iName.MatchF(pattern) >= 0)
299 _LIT(KFileFormat, "%C:%S%S");
300 fn.AppendFormat(KFileFormat, driveChar, iPolicyPath, &e.iName);
302 CPolicyList::TId policyListId;
303 TRAP(err, CPolicyList::TId::IdL(fn, policyListId))
304 if (err == KErrNoMemory)
306 // Do not let OOM cause us to ignore policy files
311 // Ensure there are no duplicate service configs due to eclisped policy files.
312 err = aServices.InsertInOrder(static_cast<TUint>(policyListId.iServiceId.iUid));
313 if (err != KErrAlreadyExists)
315 User::LeaveIfError(err);
320 DEBUG_PRINTF2(_L("%S does not match UPS policy filename rules"), &fn);
323 // Policy file is for a different system server
325 CleanupStack::PopAndDestroy(dir);
327 CleanupStack::PopAndDestroy(&fn);
330 TBool CPolicyCache::FileExistsL(const TDesC& aFileName)
332 Checks whether a file exists.
333 - If the FileName corresponds to a directory then EFalse is returned.
335 @param aFileName The absolute path of the file to check.
336 @return ETrue, if aFileName exists; otherwise, EFalse is returned.
339 TBool exists = EFalse;
340 TEntry* e = new(ELeave) TEntry();
341 TInt err = iFs.Entry(aFileName, *e);
342 if (err == KErrNone && ! e->IsDir())