|
1 /* |
|
2 * Copyright (c) 2002-2004 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 "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: Implementation of policymanagement components |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include "PolicyStorage.h" |
|
22 #include "PolicyEngineServer.h" |
|
23 #include "ElementBase.h" |
|
24 #include "XACMLconstants.h" |
|
25 #include "PolicyParser.h" |
|
26 #include "SettingEnforcementManager.h" |
|
27 #include "debug.h" |
|
28 #include "ErrorCodes.h" |
|
29 #include "PolicyEnginePrivateCRKeys.h" |
|
30 |
|
31 #include "policymnginternalpskeys.h" |
|
32 #include <centralrepository.h> |
|
33 #include "CentRepToolClient.h" |
|
34 #include <e32property.h> |
|
35 #include <s32file.h> |
|
36 |
|
37 |
|
38 _LIT( KCDrive, "C:\\private\\10207815\\"); |
|
39 _LIT( KZDrive, "Z:\\private\\10207815\\"); |
|
40 _LIT( KCDriveLetter, "C:"); |
|
41 _LIT( KZDriveLetter, "Z:"); |
|
42 _LIT( KFileExtensio, ".txt"); |
|
43 _LIT( KBackupPath, "C:\\private\\10207815\\backup\\"); |
|
44 _LIT8( KEmptyBackup, "|Empty|"); |
|
45 _LIT( KServerIdFile, "C:\\private\\10207815\\serverids.dat"); |
|
46 _LIT( KServerIdFileTmp, "C:\\private\\10207815\\backup\\serverids.tmp"); |
|
47 |
|
48 const TInt KUidLength = 10; |
|
49 const TInt KFileNameLength = 14; |
|
50 const TChar KElementStartMark = '<'; |
|
51 const TInt KFullFileNameLength = 80; |
|
52 const TInt KDriveLetterLength = 2; |
|
53 // not in use anymore: KSettingSpaceLength = 100; |
|
54 const TInt KCacheLimit = 100; |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 // ==================== LOCAL FUNCTIONS ==================== |
|
60 |
|
61 TInt CompareIDs( TUint32 const& aId1, TUint32 const& aId2) |
|
62 { |
|
63 if ( aId1 == aId2) return 0; |
|
64 return ( aId1 < aId2 ? -1 : 1 ); |
|
65 } |
|
66 |
|
67 TInt CompareStrings( HBufC8 const& aString1, HBufC8 const& aString2) |
|
68 { |
|
69 return aString1.Compare( aString2); |
|
70 } |
|
71 |
|
72 |
|
73 // ================= MEMBER FUNCTIONS ======================= |
|
74 |
|
75 CPolicyStorage* CPolicyStorage::iPolicyStorage = 0; |
|
76 |
|
77 // ----------------------------------------------------------------------------- |
|
78 // CPolicyStorage::CPolicyStorage() |
|
79 // ----------------------------------------------------------------------------- |
|
80 // |
|
81 |
|
82 CPolicyStorage::CPolicyStorage() |
|
83 { |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CPolicyStorage::~CPolicyStorage() |
|
88 // ----------------------------------------------------------------------------- |
|
89 // |
|
90 |
|
91 CPolicyStorage::~CPolicyStorage() |
|
92 { |
|
93 RDEBUG("CPolicyStorage::~CPolicyStorage()"); |
|
94 delete iCentRep; |
|
95 delete iCentRepBackup; |
|
96 delete iParser; |
|
97 |
|
98 //release memory used in element cache |
|
99 for ( TInt i(0); i < iElementCache.Count(); i++) |
|
100 { |
|
101 CElementBase * element = iElementCache[i]; |
|
102 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
103 |
|
104 |
|
105 delete element; |
|
106 } |
|
107 |
|
108 //release memory used in depricated element cache |
|
109 for ( TInt i(0); i < iDepricatedElements.Count(); i++) |
|
110 { |
|
111 CElementBase * element = iDepricatedElements[i]; |
|
112 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
113 |
|
114 |
|
115 delete element; |
|
116 } |
|
117 |
|
118 //release memory used in depricated element cache |
|
119 for ( TInt i(0); i < iEditedElements.Count(); i++) |
|
120 { |
|
121 CElementBase * element = iEditedElements[i]; |
|
122 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
123 |
|
124 |
|
125 delete element; |
|
126 } |
|
127 |
|
128 //release resources |
|
129 iElementCache.Close(); |
|
130 iDepricatedElements.Close(); |
|
131 iEditedElements.Close(); |
|
132 iSearchedUids.Close(); |
|
133 |
|
134 iServerIdList.ResetAndDestroy(); |
|
135 iServerIdList.Close(); |
|
136 |
|
137 iInvalidServerIds.ResetAndDestroy(); |
|
138 iInvalidServerIds.Close(); |
|
139 |
|
140 |
|
141 iRFs.Close(); |
|
142 } |
|
143 |
|
144 |
|
145 // ----------------------------------------------------------------------------- |
|
146 // CPolicyStorage::PolicyStorage() |
|
147 // ----------------------------------------------------------------------------- |
|
148 // |
|
149 CPolicyStorage * CPolicyStorage::PolicyStorage() |
|
150 { |
|
151 return iPolicyStorage; |
|
152 } |
|
153 |
|
154 |
|
155 // ----------------------------------------------------------------------------- |
|
156 // CPolicyStorage::ConstructL() |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 |
|
160 void CPolicyStorage::ConstructL() |
|
161 { |
|
162 RDEBUG("PolicyEngineServer: CPolicyStorage::ConstructL - start"); |
|
163 |
|
164 iCommitted = ETrue; |
|
165 //open sessions to repotories and file server |
|
166 iCentRep = CRepository::NewL( KPolicyEngineRepositoryID); |
|
167 RDEBUG("PolicyEngineServer: Connected to repository"); |
|
168 iCentRepBackup = CRepository::NewL( KPolicyEngineBackupRepositoryID); |
|
169 RDEBUG("PolicyEngineServer: Connected to backup repository"); |
|
170 User::LeaveIfError( iRFs.Connect() ); |
|
171 |
|
172 //Create and set up parser |
|
173 iParser = CPolicyParser::NewL( this); |
|
174 RDEBUG("PolicyEngineServer: Policy parser created"); |
|
175 iParser->SetExternalIdChecked( KNoExternalIdCheck); |
|
176 |
|
177 //check commit state (restore and/or delete backup if needed) |
|
178 CheckCommitStateL(); |
|
179 |
|
180 //load server id list... |
|
181 LoadServerIdListL(); |
|
182 |
|
183 RDEBUG("PolicyEngineServer: CPolicyStorage::ConstructL - end"); |
|
184 } |
|
185 |
|
186 // ----------------------------------------------------------------------------- |
|
187 // CPolicyStorage::NewL() |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 |
|
191 CPolicyStorage * CPolicyStorage::NewL() |
|
192 { |
|
193 CPolicyStorage * self = new(ELeave) CPolicyStorage(); |
|
194 |
|
195 CleanupStack::PushL( self); |
|
196 self->ConstructL(); |
|
197 CleanupStack::Pop( self); |
|
198 |
|
199 return self; |
|
200 } |
|
201 |
|
202 // ----------------------------------------------------------------------------- |
|
203 // CPolicyStorage::ReleaseElements() |
|
204 // ----------------------------------------------------------------------------- |
|
205 // |
|
206 void CPolicyStorage::ReleaseElements() |
|
207 { |
|
208 RDEBUG("PolicyEngineServer: Try to release unused elements!"); |
|
209 |
|
210 |
|
211 //release memory used in element cache |
|
212 for ( TInt i(0); i < iElementCache.Count(); i++) |
|
213 { |
|
214 CElementBase * element = iElementCache[i]; |
|
215 if ( element->iReferenceCount == 0) |
|
216 { |
|
217 delete element; |
|
218 iElementCache.Remove(i--); |
|
219 RDEBUG_2("PolicyEngineServer: Element removed from cache (Cache count %d)", iElementCache.Count()); |
|
220 } |
|
221 } |
|
222 |
|
223 //release memory used in depricated element cache |
|
224 for ( TInt i(0); i < iDepricatedElements.Count(); i++) |
|
225 { |
|
226 CElementBase * element = iDepricatedElements[i]; |
|
227 if ( element->iReferenceCount == 0) |
|
228 { |
|
229 delete element; |
|
230 iDepricatedElements.Remove(i--); |
|
231 RDEBUG_2("PolicyEngineServer: Element removed from cache (Depricated element count %d)", iDepricatedElements.Count()); |
|
232 } |
|
233 } |
|
234 } |
|
235 |
|
236 |
|
237 // ----------------------------------------------------------------------------- |
|
238 // CPolicyStorage::SetElementL() |
|
239 // ----------------------------------------------------------------------------- |
|
240 // |
|
241 TInt CPolicyStorage::SetElementL( TUint32 aId, const TDesC8& aDescription) |
|
242 { |
|
243 //resolve element file name |
|
244 TBuf<KUidLength> elementFile; |
|
245 elementFile.NumFixedWidth( aId, EDecimal, KUidLength); |
|
246 |
|
247 //buffer for file name (C-drive) |
|
248 TBuf<KFullFileNameLength> fileName; |
|
249 fileName.Append( KCDrive); |
|
250 fileName.Append( elementFile); |
|
251 fileName.Append( KFileExtensio); |
|
252 |
|
253 |
|
254 RDEBUG_2("PolicyEngineServer: Write element to disk (%S)", &fileName); |
|
255 MakeBackupL( fileName); |
|
256 |
|
257 //try open existing file |
|
258 RFile file; |
|
259 TInt err = file.Open( iRFs, fileName, EFileWrite); |
|
260 |
|
261 |
|
262 if ( err == KErrPathNotFound) |
|
263 { |
|
264 err = CreatePaths(); |
|
265 |
|
266 //this ensures, that also element file will be created |
|
267 if ( err == KErrNone) |
|
268 { |
|
269 err = KErrNotFound; |
|
270 } |
|
271 } |
|
272 |
|
273 //and if file doesn't not exist create it |
|
274 if ( err == KErrNotFound ) |
|
275 { |
|
276 err = file.Create( iRFs, fileName, EFileWrite); |
|
277 } |
|
278 |
|
279 //write to file... |
|
280 if ( err == KErrNone) |
|
281 { |
|
282 err = file.Write( 0, aDescription); |
|
283 } |
|
284 |
|
285 //...and set size |
|
286 if ( err == KErrNone ) |
|
287 { |
|
288 err = file.SetSize( aDescription.Length()); |
|
289 if ( err == KErrNone ) |
|
290 { |
|
291 err = file.Flush(); |
|
292 } |
|
293 } |
|
294 |
|
295 file.Close(); |
|
296 |
|
297 RDEBUG_2("PolicyEngineServer: Write OK (%S)", &fileName); |
|
298 |
|
299 return err; |
|
300 } |
|
301 |
|
302 |
|
303 // ----------------------------------------------------------------------------- |
|
304 // CPolicyStorage::MakeBackUpL() |
|
305 // ----------------------------------------------------------------------------- |
|
306 // |
|
307 void CPolicyStorage::MakeBackupL( const TDesC& aFileName) |
|
308 { |
|
309 //buffer for file name (C-drive) |
|
310 TBuf<KFullFileNameLength> backupName; |
|
311 backupName.Append( KBackupPath); |
|
312 backupName.Append( aFileName.Right( KFileNameLength)); |
|
313 |
|
314 CFileMan * fileMan = CFileMan::NewL( iRFs); |
|
315 |
|
316 //create backup |
|
317 TInt err = fileMan->Copy( aFileName, backupName, 0); |
|
318 delete fileMan; |
|
319 |
|
320 //if file doesn't exist in workarea, create empty file which indicates that in original state file is not exist |
|
321 if ( err == KErrNotFound) |
|
322 { |
|
323 RFile file; |
|
324 CleanupClosePushL( file); |
|
325 User::LeaveIfError( file.Create( iRFs, backupName, EFileWrite)); |
|
326 |
|
327 RDEBUG_2("PolicyEngineServer: Element backup: %S indicates new element in policy storage", &backupName); |
|
328 |
|
329 CleanupStack::PopAndDestroy( &file); |
|
330 } |
|
331 else |
|
332 { |
|
333 User::LeaveIfError( err); |
|
334 RDEBUG_3("PolicyEngineServer: Element backup: %S -> %S", &aFileName, &backupName); |
|
335 } |
|
336 |
|
337 } |
|
338 |
|
339 // ----------------------------------------------------------------------------- |
|
340 // CPolicyStorage::MakeBackUpL() |
|
341 // ----------------------------------------------------------------------------- |
|
342 // |
|
343 void CPolicyStorage::MakeBackupL( const TUint32& aSettingId) |
|
344 { |
|
345 //TInt settings |
|
346 TInt value = 0; |
|
347 TInt err = iCentRep->Get( aSettingId, value); |
|
348 RDEBUG_2("PolicyEngineServer: Backup for CentRep value setting: %d", aSettingId); |
|
349 |
|
350 //for "empty backup" |
|
351 if ( err == KErrNotFound ) |
|
352 { |
|
353 //Set backupvalue |
|
354 TInt err = iCentRepBackup->Create( aSettingId, KEmptyBackup); |
|
355 |
|
356 //if value is already exist, it is a original value of setting is must be saved |
|
357 if ( err == KErrAlreadyExists) |
|
358 { |
|
359 err = KErrNone; |
|
360 } |
|
361 |
|
362 //Leave if backupfails |
|
363 User::LeaveIfError( err); |
|
364 } |
|
365 else |
|
366 { |
|
367 //Set backupvalue |
|
368 TInt err = iCentRepBackup->Create( aSettingId, value); |
|
369 |
|
370 if ( err == KErrAlreadyExists) |
|
371 { |
|
372 //if value is already exist, it is a original value of setting is must be saved |
|
373 err = KErrNone; |
|
374 } |
|
375 |
|
376 //Leave if backupfails |
|
377 User::LeaveIfError( err); |
|
378 } |
|
379 } |
|
380 |
|
381 void CPolicyStorage::RestoreBackupL() |
|
382 { |
|
383 //Open directory and get file list |
|
384 RDir dir; |
|
385 CleanupClosePushL( dir); |
|
386 |
|
387 TInt err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); |
|
388 |
|
389 //create private and backuppaths |
|
390 if ( err == KErrPathNotFound) |
|
391 { |
|
392 CreatePaths(); |
|
393 err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); |
|
394 } |
|
395 |
|
396 User::LeaveIfError( err); |
|
397 err = KErrNone; |
|
398 |
|
399 do |
|
400 { |
|
401 //read entries (files) |
|
402 TEntryArray array; |
|
403 err = dir.Read( array); |
|
404 if ( KErrEof != err) |
|
405 { |
|
406 User::LeaveIfError( err); |
|
407 } |
|
408 |
|
409 for ( TInt i = 0; i < array.Count(); i++) |
|
410 { |
|
411 const TEntry& entry = array[i]; |
|
412 |
|
413 //original file name |
|
414 TBuf<KFullFileNameLength> fileName; |
|
415 fileName.Append( KCDrive); |
|
416 fileName.Append( entry.iName); |
|
417 |
|
418 //if file size is zero, remove file from work directory |
|
419 if ( entry.iSize == 0) |
|
420 { |
|
421 RDEBUG_2("PolicyEngineServer: Restoring backup: %S removed", &fileName); |
|
422 |
|
423 TInt err = iRFs.Delete( fileName); |
|
424 if ( err == KErrNotFound) |
|
425 { |
|
426 err = KErrNone; |
|
427 } |
|
428 |
|
429 User::LeaveIfError( err ); |
|
430 } |
|
431 else |
|
432 { |
|
433 //Create backup file name |
|
434 TBuf<KFullFileNameLength> backupName; |
|
435 backupName.Append( KBackupPath); |
|
436 backupName.Append( entry.iName); |
|
437 |
|
438 //otherwise copy file to work directory |
|
439 CFileMan * fileMan = CFileMan::NewL( iRFs); |
|
440 CleanupStack::PushL( fileMan); |
|
441 |
|
442 //Copy file to work directory |
|
443 User::LeaveIfError( fileMan->Copy( backupName, fileName)); |
|
444 RDEBUG_3("PolicyEngineServer: Restoring backup: %S -> %S", &backupName, &fileName); |
|
445 |
|
446 |
|
447 CleanupStack::Pop( fileMan); //fileMan |
|
448 } |
|
449 } |
|
450 } while ( err == KErrNone); |
|
451 |
|
452 //id list |
|
453 RArray<TUint32> ids; |
|
454 CleanupClosePushL( ids); |
|
455 |
|
456 //find all ids |
|
457 iCentRepBackup->FindL( 0, 0x0, ids); |
|
458 |
|
459 for ( TInt i(0); i < ids.Count(); i++) |
|
460 { |
|
461 TUint32 id = ids[i]; |
|
462 RDEBUG_2("PolicyEngineServer: Restoring centrep setting %d", id); |
|
463 |
|
464 //get value |
|
465 TBuf8<200> buffer; |
|
466 TInt err = iCentRepBackup->Get( id, buffer); |
|
467 |
|
468 if ( err != KErrNone) |
|
469 { |
|
470 TInt value = 0; |
|
471 User::LeaveIfError( iCentRepBackup->Get( id, value)); |
|
472 User::LeaveIfError( iCentRep->Set( id, value)); |
|
473 } |
|
474 else |
|
475 { |
|
476 if ( buffer == KEmptyBackup) |
|
477 { |
|
478 User::LeaveIfError( iCentRep->Delete( id)); |
|
479 } |
|
480 else |
|
481 { |
|
482 User::LeaveIfError( iCentRep->Set( id, buffer)); |
|
483 } |
|
484 } |
|
485 } |
|
486 |
|
487 CleanupStack::PopAndDestroy(2, &dir); //RArray<TUint32>, RDir |
|
488 } |
|
489 |
|
490 // ----------------------------------------------------------------------------- |
|
491 // CPolicyStorage::RemoveBackupL() |
|
492 // ----------------------------------------------------------------------------- |
|
493 // |
|
494 void CPolicyStorage::RemoveBackupL() |
|
495 { |
|
496 //Open directory and get file list |
|
497 RDir dir; |
|
498 CleanupClosePushL( dir); |
|
499 |
|
500 TInt err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); |
|
501 |
|
502 //create private and backuppaths |
|
503 if ( err == KErrPathNotFound) |
|
504 { |
|
505 CreatePaths(); |
|
506 err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); |
|
507 } |
|
508 |
|
509 User::LeaveIfError( err); |
|
510 err = KErrNone; |
|
511 |
|
512 do |
|
513 { |
|
514 //read entries (files) |
|
515 TEntryArray array; |
|
516 err = dir.Read( array); |
|
517 if ( KErrEof != err) |
|
518 { |
|
519 User::LeaveIfError( err); |
|
520 } |
|
521 |
|
522 for ( TInt i = 0; i < array.Count(); i++) |
|
523 { |
|
524 const TEntry& entry = array[i]; |
|
525 |
|
526 TBuf<KFullFileNameLength> backupName; |
|
527 backupName.Append( KBackupPath); |
|
528 backupName.Append( entry.iName); |
|
529 |
|
530 RDEBUG_2("Policy Engine: Remove backup file %S", &backupName); |
|
531 User::LeaveIfError( iRFs.Delete( backupName)); |
|
532 } |
|
533 } while ( err == KErrNone); |
|
534 |
|
535 //id list |
|
536 RArray<TUint32> ids; |
|
537 CleanupClosePushL( ids); |
|
538 |
|
539 //find all ids |
|
540 iCentRepBackup->FindL( 0, 0x0, ids); |
|
541 |
|
542 for ( TInt i(0); i < ids.Count(); i++) |
|
543 { |
|
544 RDEBUG_2("Policy Engine: Remove centrep backup %d", ids[i]); |
|
545 User::LeaveIfError( iCentRepBackup->Delete( ids[i])); |
|
546 } |
|
547 |
|
548 CleanupStack::PopAndDestroy(2, &dir); //RArray<TUint32> |
|
549 } |
|
550 |
|
551 |
|
552 // ----------------------------------------------------------------------------- |
|
553 // CPolicyStorage::ActivateEnforcementFlagL() |
|
554 // ----------------------------------------------------------------------------- |
|
555 // |
|
556 void CPolicyStorage::ActivateEnforcementFlagL( KSettingEnforcements aSetting) |
|
557 { |
|
558 TUint32 id = KEnforcementStates + aSetting; |
|
559 |
|
560 MakeBackupL( id); |
|
561 TInt err = iCentRep->Set( id, ETrue); |
|
562 |
|
563 if ( KErrNotFound == err) |
|
564 { |
|
565 err = iCentRep->Create( id, ETrue); |
|
566 } |
|
567 |
|
568 User::LeaveIfError( err); |
|
569 } |
|
570 |
|
571 // ----------------------------------------------------------------------------- |
|
572 // CPolicyStorage::DeactivateEnforcementFlagL() |
|
573 // ----------------------------------------------------------------------------- |
|
574 // |
|
575 void CPolicyStorage::DeactivateEnforcementFlagL( KSettingEnforcements aSetting) |
|
576 { |
|
577 TUint32 id = KEnforcementStates + aSetting; |
|
578 |
|
579 MakeBackupL( id); |
|
580 TInt err = iCentRep->Set( id, EFalse); |
|
581 |
|
582 if ( KErrNotFound == err) |
|
583 { |
|
584 err = iCentRep->Create( id, EFalse); |
|
585 } |
|
586 |
|
587 User::LeaveIfError( err); |
|
588 } |
|
589 |
|
590 |
|
591 |
|
592 // ----------------------------------------------------------------------------- |
|
593 // CPolicyStorage::GetElementL() |
|
594 // ----------------------------------------------------------------------------- |
|
595 // |
|
596 TInt CPolicyStorage::GetElementL( TUint32 aId, HBufC8*& aDescription) |
|
597 { |
|
598 //parse element file name |
|
599 TBuf<KUidLength> elementFile; |
|
600 elementFile.NumFixedWidth( aId, EDecimal, KUidLength); |
|
601 |
|
602 //buffer for file name (C-drive) |
|
603 TBuf<KFullFileNameLength> fileName; |
|
604 fileName.Append( KCDrive); |
|
605 fileName.Append( elementFile); |
|
606 fileName.Append( KFileExtensio); |
|
607 |
|
608 //try open file from C-drive |
|
609 RFile file; |
|
610 CleanupClosePushL( file); |
|
611 TInt err = file.Open( iRFs, fileName, EFileRead); |
|
612 |
|
613 //and if file does not exist in C-drive try again from z-drive |
|
614 if ( err == KErrNotFound || err == KErrPathNotFound) |
|
615 { |
|
616 fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); |
|
617 err = file.Open( iRFs, fileName, EFileRead); |
|
618 } |
|
619 |
|
620 //resolve file size |
|
621 TInt size = 0; |
|
622 if ( err == KErrNone) |
|
623 { |
|
624 err = file.Size( size); |
|
625 } |
|
626 |
|
627 //empty file in the RAM-drive indicates that ROM-file is deleted |
|
628 if ( err == KErrNone && size) |
|
629 { |
|
630 //create buffer for element |
|
631 aDescription = HBufC8::NewLC( size); |
|
632 TPtr8 ptr = aDescription->Des(); |
|
633 |
|
634 //read file to buffer and remove buffer from cleanupstack |
|
635 file.Read( ptr); |
|
636 CleanupStack::Pop( aDescription); |
|
637 } |
|
638 |
|
639 __ASSERT_ALWAYS( aDescription, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
640 |
|
641 CleanupStack::PopAndDestroy( &file); |
|
642 |
|
643 return err; |
|
644 } |
|
645 |
|
646 // ----------------------------------------------------------------------------- |
|
647 // CPolicyStorage::DeleteElement() |
|
648 // ----------------------------------------------------------------------------- |
|
649 // |
|
650 void CPolicyStorage::DeleteElementL( TUint32 aElementId) |
|
651 { |
|
652 //parse element file name |
|
653 TBuf<KUidLength> elementFile; |
|
654 elementFile.NumFixedWidth( aElementId, EDecimal, KUidLength); |
|
655 |
|
656 //buffer for file name (C-drive) |
|
657 TBuf<KFullFileNameLength> fileName; |
|
658 fileName.Append( KCDrive); |
|
659 fileName.Append( elementFile); |
|
660 fileName.Append( KFileExtensio); |
|
661 |
|
662 |
|
663 //make backup |
|
664 MakeBackupL( fileName); |
|
665 |
|
666 |
|
667 //if the ROM-drive contains file, we can't delete it, create empty file (c-drive) to indicate that file is deleted |
|
668 fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); |
|
669 RFile file; |
|
670 TInt err = file.Open( iRFs, fileName, EFileRead); |
|
671 file.Close(); |
|
672 |
|
673 fileName.Replace( 0, KDriveLetterLength, KCDriveLetter); |
|
674 |
|
675 if ( err == KErrNone) |
|
676 { |
|
677 CleanupClosePushL( file); |
|
678 User::LeaveIfError( file.Create( iRFs, fileName, EFileWrite )); |
|
679 User::LeaveIfError( file.Flush()); |
|
680 CleanupStack::PopAndDestroy( &file); |
|
681 } |
|
682 else |
|
683 { |
|
684 //if file is only in the ROM-drive |
|
685 User::LeaveIfError( iRFs.Delete( fileName)); |
|
686 } |
|
687 |
|
688 } |
|
689 |
|
690 |
|
691 |
|
692 |
|
693 |
|
694 // ----------------------------------------------------------------------------- |
|
695 // CPolicyStorage::SaveElementL() |
|
696 // ----------------------------------------------------------------------------- |
|
697 // |
|
698 TInt CPolicyStorage::SaveElementL( TUint32 aElementId, HBufC8 * aElementDescription) |
|
699 { |
|
700 //write element |
|
701 return SetElementL( aElementId, *aElementDescription); |
|
702 } |
|
703 |
|
704 // ----------------------------------------------------------------------------- |
|
705 // CPolicyStorage::CheckElementL() |
|
706 // ----------------------------------------------------------------------------- |
|
707 // |
|
708 |
|
709 void CPolicyStorage::CheckElementL( CElementBase * aElement) |
|
710 { |
|
711 if ( aElement->iElementState == ENotLoaded || aElement->iElementState == ENotLoadedEditableElement) |
|
712 { |
|
713 TBool addEditCache = ( aElement->iElementState == ENotLoaded ? EFalse : ETrue); |
|
714 LoadElementL( aElement, addEditCache); |
|
715 |
|
716 if ( aElement->iElementState == ENotLoaded) |
|
717 { |
|
718 aElement->iElementState = ECacheElement; |
|
719 } |
|
720 else |
|
721 { |
|
722 aElement->iElementState = EEditableCacheElement; |
|
723 } |
|
724 } |
|
725 } |
|
726 |
|
727 // ----------------------------------------------------------------------------- |
|
728 // CPolicyStorage::LoadElementL() |
|
729 // ----------------------------------------------------------------------------- |
|
730 // |
|
731 |
|
732 void CPolicyStorage::LoadElementL( CElementBase * aElement, TBool aAddToEditableCache) |
|
733 { |
|
734 __ASSERT_ALWAYS( aElement, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
735 |
|
736 //load element description |
|
737 HBufC8 * description = NULL; |
|
738 User::LeaveIfError( GetElementL( aElement->GetId(), description)); |
|
739 CleanupStack::PushL( description); |
|
740 TPtr8 ptr(description->Des()); |
|
741 |
|
742 TNativeElementTypes elementType = aElement->ElementType(); |
|
743 |
|
744 //find parent element mapping for policies, policysets and rules |
|
745 if ( elementType == ERule || elementType == EPolicy || elementType == EPolicySet ) |
|
746 { |
|
747 TInt index = ptr.Locate( KParentListStartMark); |
|
748 |
|
749 TPtrC8 ptrParent; |
|
750 if ( index != KErrNotFound) |
|
751 { |
|
752 //separate description and parent id list |
|
753 ptrParent.Set( ptr.Mid( index)); |
|
754 ptr = ptr.Left( index); |
|
755 } |
|
756 |
|
757 //and decode and add parant mapping |
|
758 while ( index != KErrNotFound) |
|
759 { |
|
760 ptrParent.Set( ptrParent.Mid(1)); |
|
761 index = ptrParent.Locate(KParentListStartMark); |
|
762 |
|
763 TPtrC8 elementId( ptrParent); |
|
764 |
|
765 if ( index != KErrNotFound) |
|
766 { |
|
767 elementId.Set( ptrParent.Left( index)); |
|
768 ptrParent.Set( ptrParent.Mid( index)); |
|
769 } |
|
770 |
|
771 TUint32 policySystemid; |
|
772 TLex8 lex( elementId); |
|
773 User::LeaveIfError( lex.Val( policySystemid, EDecimal)); |
|
774 |
|
775 aElement->AddParentIdL( policySystemid); |
|
776 } |
|
777 } |
|
778 |
|
779 //parse object |
|
780 User::LeaveIfError( iParser->ParseNativeObjects( aElement, ptr, aAddToEditableCache)); |
|
781 |
|
782 |
|
783 CleanupStack::PopAndDestroy( description); |
|
784 } |
|
785 |
|
786 |
|
787 |
|
788 void CPolicyStorage::AddNewElementL( CElementBase * aElement) |
|
789 { |
|
790 aElement->iElementState = ENewElement; |
|
791 AddElementL( iEditedElements, aElement); |
|
792 aElement->iReferenceCount = 0; |
|
793 |
|
794 RDEBUG_2("PolicyEngineServer: New editable element (element count %d)", iEditedElements.Count()); |
|
795 } |
|
796 |
|
797 |
|
798 // ----------------------------------------------------------------------------- |
|
799 // CPolicyStorage::GetEditableElementL() |
|
800 // ----------------------------------------------------------------------------- |
|
801 // |
|
802 CElementBase * CPolicyStorage::GetEditableElementL( const TDesC8& aPolicyId ) |
|
803 { |
|
804 TUint32 settingId = MapRealIdL( aPolicyId, EFalse); |
|
805 |
|
806 CElementBase * element = NULL; |
|
807 |
|
808 if ( settingId ) |
|
809 { |
|
810 element = GetEditableElementL( settingId); |
|
811 } |
|
812 |
|
813 return element; |
|
814 } |
|
815 |
|
816 |
|
817 |
|
818 // ----------------------------------------------------------------------------- |
|
819 // CPolicyStorage::GetEditableElementL() |
|
820 // ----------------------------------------------------------------------------- |
|
821 // |
|
822 CElementBase * CPolicyStorage::GetEditableElementL( const TUint32 aElementId ) |
|
823 { |
|
824 //check from edit cache |
|
825 CElementBase * element = FindElement( iEditedElements, aElementId); |
|
826 |
|
827 //if doesn't not exits |
|
828 if ( element == NULL) |
|
829 { |
|
830 //create new element |
|
831 element = ElementHelper::CreateNewElementL( aElementId); |
|
832 |
|
833 //Aff element to edited element cache |
|
834 element->iElementState = ENotLoadedEditableElement; |
|
835 AddElementL( iEditedElements, element); |
|
836 element->iReferenceCount = 0; |
|
837 |
|
838 } |
|
839 |
|
840 //if element is deleted return NULL |
|
841 if ( element->iElementState == EDeletedEditableElement) |
|
842 { |
|
843 element = NULL; |
|
844 } |
|
845 |
|
846 return element; |
|
847 } |
|
848 |
|
849 // ----------------------------------------------------------------------------- |
|
850 // CPolicyStorage::GetElement() |
|
851 // ----------------------------------------------------------------------------- |
|
852 // |
|
853 |
|
854 |
|
855 CElementBase * CPolicyStorage::GetElementL( TUint32 aElementId) |
|
856 { |
|
857 CElementBase * element = NULL; |
|
858 |
|
859 |
|
860 if ( element == NULL) |
|
861 { |
|
862 element = FindElement( iElementCache, aElementId); |
|
863 } |
|
864 |
|
865 if ( element == NULL) |
|
866 { |
|
867 element = ElementHelper::CreateNewElementL( aElementId); |
|
868 element->iElementState = ENotLoaded; |
|
869 AddElementL( iElementCache, element); |
|
870 element->iReferenceCount = 0; |
|
871 |
|
872 RDEBUG_2("PolicyEngineServer: New cache element (element cache count %d)", iElementCache.Count()); |
|
873 |
|
874 //release unused eleements from cache |
|
875 if ( iEditedElements.Count() > KCacheLimit) |
|
876 { |
|
877 RDEBUG_2("PolicyEngineServer: Cache limit exceeded (%d)", KCacheLimit); |
|
878 ReleaseElements(); |
|
879 } |
|
880 } |
|
881 |
|
882 return element; |
|
883 } |
|
884 |
|
885 // ----------------------------------------------------------------------------- |
|
886 // CPolicyStorage::GetElement() |
|
887 // ----------------------------------------------------------------------------- |
|
888 // |
|
889 |
|
890 CElementBase * CPolicyStorage::GetElementL( const TDesC8& iPolicyId ) |
|
891 { |
|
892 //map external id to internal id |
|
893 TUint32 settingId = MapRealIdL( iPolicyId, ETrue); |
|
894 |
|
895 CElementBase * element = NULL; |
|
896 |
|
897 //and if valid mapping exists, get element from storage |
|
898 if ( settingId ) |
|
899 { |
|
900 element = GetElementL( settingId); |
|
901 } |
|
902 |
|
903 return element; |
|
904 } |
|
905 |
|
906 |
|
907 // ----------------------------------------------------------------------------- |
|
908 // CPolicyStorage::FindElement() |
|
909 // ----------------------------------------------------------------------------- |
|
910 // |
|
911 |
|
912 CElementBase * CPolicyStorage::FindElement( RArray<CElementBase*> &aElementList, const TUint32 aElementId) |
|
913 { |
|
914 __UHEAP_MARK; |
|
915 |
|
916 TLinearOrder<CElementBase*> linearOrder(&ElementHelper::CompareElements); |
|
917 CElementBase referenceElement( aElementId); |
|
918 |
|
919 TInt index = aElementList.FindInOrder( &referenceElement, linearOrder); |
|
920 |
|
921 CElementBase * element = NULL; |
|
922 if ( index >= 0) |
|
923 { |
|
924 element = aElementList[index]; |
|
925 } |
|
926 |
|
927 __UHEAP_MARKEND; |
|
928 |
|
929 return element; |
|
930 |
|
931 } |
|
932 |
|
933 |
|
934 |
|
935 // ----------------------------------------------------------------------------- |
|
936 // CPolicyStorage::AddElementL() |
|
937 // ----------------------------------------------------------------------------- |
|
938 // |
|
939 void CPolicyStorage::AddElementL( RArray<CElementBase*> &aElementList, CElementBase * aElement) |
|
940 { |
|
941 TLinearOrder<CElementBase*> linearOrder(&ElementHelper::CompareElements); |
|
942 aElementList.InsertInOrder( aElement, linearOrder); |
|
943 } |
|
944 |
|
945 |
|
946 |
|
947 // ----------------------------------------------------------------------------- |
|
948 // CPolicyStorage::MapRealId() |
|
949 // ----------------------------------------------------------------------------- |
|
950 // |
|
951 TUint32 CPolicyStorage::MapRealIdL( const TDesC8& aElementRealId, const TBool aOnlyCommitted) |
|
952 { |
|
953 iSearchedUids.Reset(); |
|
954 TUint32 retVal = 0; |
|
955 |
|
956 if ( !aOnlyCommitted ) |
|
957 { |
|
958 retVal = GetEditedMappingsL( aElementRealId); |
|
959 } |
|
960 |
|
961 if ( !retVal) |
|
962 { |
|
963 retVal = GetCommittedMappingsL( aElementRealId); |
|
964 } |
|
965 |
|
966 |
|
967 if ( !retVal) |
|
968 { |
|
969 retVal = GetMappingsFromDriveL( aElementRealId, EDriveC, EFalse); |
|
970 } |
|
971 |
|
972 if ( !retVal) |
|
973 { |
|
974 retVal = GetMappingsFromDriveL( aElementRealId, EDriveZ, EFalse); |
|
975 } |
|
976 |
|
977 return retVal; |
|
978 } |
|
979 |
|
980 // ----------------------------------------------------------------------------- |
|
981 // CPolicyStorage::GetEditedMappingsL() |
|
982 // ----------------------------------------------------------------------------- |
|
983 // |
|
984 |
|
985 TUint32 CPolicyStorage::GetEditedMappingsL( const TDesC8& aElementRealId) |
|
986 { |
|
987 //seach matching external ids from edited elements |
|
988 TLinearOrder<TUint32> linearOrder( &CompareIDs); |
|
989 |
|
990 for ( TInt i(0); i < iEditedElements.Count(); i++) |
|
991 { |
|
992 CElementBase * element = iEditedElements[i]; |
|
993 |
|
994 if ( element->iElementType == ERule || element->iElementType == EPolicy || element->iElementType == EPolicySet) |
|
995 { |
|
996 CheckElementL( element); |
|
997 |
|
998 if ( element->iElementState == EEditableCacheElement || element->iElementState == EEditedElement) |
|
999 { |
|
1000 if ( aElementRealId.Compare( *(element->iExternalId)) == 0) |
|
1001 { |
|
1002 iSearchedUids.InsertInOrder( element->GetId(), linearOrder); |
|
1003 return element->iElementId; |
|
1004 } |
|
1005 } |
|
1006 } |
|
1007 } |
|
1008 |
|
1009 return 0; |
|
1010 } |
|
1011 |
|
1012 // ----------------------------------------------------------------------------- |
|
1013 // CPolicyStorage::GetCommittedMappingsL() |
|
1014 // ----------------------------------------------------------------------------- |
|
1015 // |
|
1016 TUint32 CPolicyStorage::GetCommittedMappingsL( const TDesC8& aElementRealId) |
|
1017 { |
|
1018 //seach matching external ids from edited elements |
|
1019 TLinearOrder<TUint32> linearOrder( &CompareIDs); |
|
1020 |
|
1021 for ( TInt i(0); i < iElementCache.Count(); i++) |
|
1022 { |
|
1023 CElementBase * element = iElementCache[i]; |
|
1024 |
|
1025 if ( element->iElementType == ERule || element->iElementType == EPolicy || element->iElementType == EPolicySet) |
|
1026 { |
|
1027 if ( iSearchedUids.Find( element->GetId()) >= 0) |
|
1028 { |
|
1029 CheckElementL( element); |
|
1030 |
|
1031 if ( element->iElementState == ECacheElement) |
|
1032 { |
|
1033 if ( aElementRealId.Compare( *(element->iExternalId)) == 0) |
|
1034 { |
|
1035 iSearchedUids.InsertInOrder( element->GetId(), linearOrder); |
|
1036 return element->iElementId; |
|
1037 } |
|
1038 } |
|
1039 } |
|
1040 } |
|
1041 } |
|
1042 |
|
1043 return 0; |
|
1044 } |
|
1045 |
|
1046 // ----------------------------------------------------------------------------- |
|
1047 // CPolicyStorage::GetMappingsFromDriveL() |
|
1048 // ----------------------------------------------------------------------------- |
|
1049 // |
|
1050 TUint32 CPolicyStorage::GetMappingsFromDriveL( const TDesC8& aElementRealId, TDriveNumber aDrive, TBool aUpdateList) |
|
1051 { |
|
1052 //Select correct drive |
|
1053 TPtrC bathPtr( KCDrive); |
|
1054 |
|
1055 if ( aDrive == EDriveZ) |
|
1056 { |
|
1057 bathPtr.Set( KZDrive); |
|
1058 } |
|
1059 |
|
1060 //Open directory and get file list |
|
1061 RDir dir; |
|
1062 CleanupClosePushL( dir); |
|
1063 |
|
1064 TInt err = dir.Open( iRFs, bathPtr, KEntryAttNormal); |
|
1065 |
|
1066 User::LeaveIfError( err); |
|
1067 err = KErrNone; |
|
1068 |
|
1069 TUint32 retVal = 0; |
|
1070 |
|
1071 do |
|
1072 { |
|
1073 //read entries (files) |
|
1074 TEntryArray array; |
|
1075 err = dir.Read( array); |
|
1076 if ( KErrEof != err) |
|
1077 { |
|
1078 User::LeaveIfError( err); |
|
1079 } |
|
1080 |
|
1081 for ( TInt i = 0; i < array.Count(); i++) |
|
1082 { |
|
1083 const TEntry& entry = array[i]; |
|
1084 |
|
1085 TPtrC ptr = entry.iName; |
|
1086 TInt index = ptr.Locate('.'); |
|
1087 User::LeaveIfError( index); |
|
1088 |
|
1089 TLex lex( ptr.Left( index)); |
|
1090 TUint32 id; |
|
1091 lex.Val( id, EDecimal); |
|
1092 TInt type = id & 0xff; |
|
1093 |
|
1094 if ( type == ERule || type == EPolicy || type == EPolicySet ) |
|
1095 { |
|
1096 TBuf<150> file = bathPtr; |
|
1097 file.Append( entry.iName); |
|
1098 |
|
1099 if ( ReadRealIdL( file, aElementRealId, aDrive)) |
|
1100 { |
|
1101 retVal = id; |
|
1102 |
|
1103 if ( aUpdateList) |
|
1104 { |
|
1105 TLinearOrder<HBufC8> linearOrder( &CompareStrings); |
|
1106 iInvalidServerIds.InsertInOrder( aElementRealId.AllocL(), linearOrder); |
|
1107 } |
|
1108 |
|
1109 break; |
|
1110 } |
|
1111 } |
|
1112 } |
|
1113 } while ( err == KErrNone && !retVal); |
|
1114 |
|
1115 CleanupStack::PopAndDestroy( &dir); //RArray<TUint32> |
|
1116 |
|
1117 return retVal; |
|
1118 } |
|
1119 |
|
1120 |
|
1121 // ----------------------------------------------------------------------------- |
|
1122 // CPolicyStorage::ReadRealIdL() |
|
1123 // ----------------------------------------------------------------------------- |
|
1124 // |
|
1125 TBool CPolicyStorage::ReadRealIdL( const TDesC& aFileName, const TDesC8& aElementRealId, TDriveNumber aDrive) |
|
1126 { |
|
1127 TBool retVal = EFalse; |
|
1128 |
|
1129 //open file |
|
1130 RFile file; |
|
1131 |
|
1132 TInt err = KErrNone; |
|
1133 |
|
1134 //check first from c-drive |
|
1135 if ( aDrive == EDriveZ) |
|
1136 { |
|
1137 TBuf<100> buf( aFileName); |
|
1138 buf.Replace( 0, KDriveLetterLength, KCDriveLetter); |
|
1139 |
|
1140 err = file.Open( iRFs, buf, EFileRead); |
|
1141 } |
|
1142 else |
|
1143 { |
|
1144 err = KErrNotFound; |
|
1145 } |
|
1146 |
|
1147 if ( err == KErrNotFound) |
|
1148 { |
|
1149 err = file.Open( iRFs, aFileName, EFileRead); |
|
1150 } |
|
1151 |
|
1152 CleanupClosePushL( file); |
|
1153 if ( err == KErrNone) |
|
1154 { |
|
1155 TInt size; |
|
1156 User::LeaveIfError( file.Size( size)); |
|
1157 |
|
1158 if ( size ) |
|
1159 { |
|
1160 HBufC8* content = HBufC8::NewLC( size); |
|
1161 TPtr8 ptr = content->Des(); |
|
1162 |
|
1163 User::LeaveIfError( file.Read( ptr)); |
|
1164 |
|
1165 TInt index = ptr.FindF( aElementRealId); |
|
1166 if ( index > 0) |
|
1167 { |
|
1168 if ( ptr[ index + aElementRealId.Length()] == '"' && ptr[ index - 1] == '"') |
|
1169 { |
|
1170 TInt identifierIndex = ptr.FindF( PolicyLanguage::Rule::RuleId[ENative]); |
|
1171 TInt length = 0; |
|
1172 if ( identifierIndex < 0 ) |
|
1173 { |
|
1174 identifierIndex = ptr.FindF( PolicyLanguage::Policy::PolicyId[ENative]); |
|
1175 length = PolicyLanguage::Policy::PolicyId[ENative].Length(); |
|
1176 if ( identifierIndex < 0 ) |
|
1177 { |
|
1178 identifierIndex = ptr.FindF( PolicyLanguage::PolicySet::PolicySetId[ENative]); |
|
1179 length = PolicyLanguage::PolicySet::PolicySetId[ENative].Length(); |
|
1180 } |
|
1181 } |
|
1182 else |
|
1183 { |
|
1184 length = PolicyLanguage::Rule::RuleId[ENative].Length(); |
|
1185 } |
|
1186 |
|
1187 if ( (identifierIndex + length +2 ) == index) |
|
1188 { |
|
1189 retVal = ETrue; |
|
1190 } |
|
1191 } |
|
1192 } |
|
1193 |
|
1194 CleanupStack::PopAndDestroy( content); |
|
1195 } |
|
1196 |
|
1197 } |
|
1198 |
|
1199 CleanupStack::PopAndDestroy( &file); |
|
1200 return retVal; |
|
1201 } |
|
1202 |
|
1203 |
|
1204 // ----------------------------------------------------------------------------- |
|
1205 // CPolicyStorage::ResetRealIdValidTest() |
|
1206 // ----------------------------------------------------------------------------- |
|
1207 // |
|
1208 void CPolicyStorage::ResetRealIdValidTest() |
|
1209 { |
|
1210 iInvalidServerIds.ResetAndDestroy(); |
|
1211 } |
|
1212 |
|
1213 |
|
1214 |
|
1215 // ----------------------------------------------------------------------------- |
|
1216 // CPolicyStorage::IsRealIdValidL() |
|
1217 // ----------------------------------------------------------------------------- |
|
1218 // |
|
1219 |
|
1220 TBool CPolicyStorage::IsRealIdValidL( const TDesC8& aElementRealId) |
|
1221 { |
|
1222 iSearchedUids.Reset(); |
|
1223 TLinearOrder<HBufC8> linearOrder( &CompareStrings); |
|
1224 |
|
1225 HBufC8 * buf = aElementRealId.Alloc(); |
|
1226 if ( iInvalidServerIds.Find( buf) >= 0 ) |
|
1227 { |
|
1228 delete buf; |
|
1229 return EFalse; |
|
1230 } |
|
1231 delete buf; |
|
1232 |
|
1233 |
|
1234 TUint32 id = GetEditedMappingsL( aElementRealId); |
|
1235 |
|
1236 if ( !id ) |
|
1237 { |
|
1238 id = GetCommittedMappingsL( aElementRealId); |
|
1239 } |
|
1240 |
|
1241 if (!id) |
|
1242 { |
|
1243 id = GetMappingsFromDriveL( aElementRealId, EDriveC, ETrue); |
|
1244 } |
|
1245 |
|
1246 if (!id) |
|
1247 { |
|
1248 id = GetMappingsFromDriveL( aElementRealId, EDriveZ, ETrue); |
|
1249 } |
|
1250 |
|
1251 if ( !id) |
|
1252 { |
|
1253 iInvalidServerIds.InsertInOrder( aElementRealId.AllocL(), linearOrder); |
|
1254 } |
|
1255 |
|
1256 return !id; |
|
1257 } |
|
1258 |
|
1259 // ----------------------------------------------------------------------------- |
|
1260 // CPolicyStorage::CreateId() |
|
1261 // ----------------------------------------------------------------------------- |
|
1262 // |
|
1263 |
|
1264 TUint32 CPolicyStorage::CreateIdL( TNativeElementTypes &aType) |
|
1265 { |
|
1266 __UHEAP_MARK; |
|
1267 |
|
1268 TUint32 nextFreeId = KNextFreeId; |
|
1269 TUint32 nextId(0); |
|
1270 TInt id(0); |
|
1271 TInt err( KErrNone); |
|
1272 |
|
1273 do |
|
1274 { |
|
1275 if ( id == 0) |
|
1276 { |
|
1277 //get next free id from CentRep |
|
1278 err = iCentRep->Get( nextFreeId, id); |
|
1279 } |
|
1280 |
|
1281 if ( err != KErrNone) |
|
1282 { |
|
1283 id = 1; |
|
1284 } |
|
1285 |
|
1286 //reset counter |
|
1287 if ( id > 0xFFFFFF ) |
|
1288 { |
|
1289 id = 0; |
|
1290 } |
|
1291 |
|
1292 //increase next free id value |
|
1293 nextId = id++; |
|
1294 |
|
1295 //create id (combination id next free id and element type) |
|
1296 nextId = nextId << 8; |
|
1297 nextId = nextId | aType; |
|
1298 |
|
1299 |
|
1300 RDEBUG_2("PolicyEngineServer: Next free id: %d", nextId); |
|
1301 } |
|
1302 while ( !IsIdValidL( nextId)); |
|
1303 |
|
1304 //backup value |
|
1305 MakeBackupL( KNextFreeId); |
|
1306 |
|
1307 //save new value |
|
1308 if ( err != KErrNone) |
|
1309 { |
|
1310 User::LeaveIfError( iCentRep->Create( KNextFreeId, id)); |
|
1311 } |
|
1312 else |
|
1313 { |
|
1314 User::LeaveIfError( iCentRep->Set( KNextFreeId, id)); |
|
1315 } |
|
1316 |
|
1317 |
|
1318 __UHEAP_MARKEND; |
|
1319 |
|
1320 return nextId; |
|
1321 } |
|
1322 |
|
1323 |
|
1324 // ----------------------------------------------------------------------------- |
|
1325 // CPolicyStorage::GetEditedElements() |
|
1326 // ----------------------------------------------------------------------------- |
|
1327 // |
|
1328 TBool CPolicyStorage::IsIdValidL( const TUint32& aId) |
|
1329 { |
|
1330 RDEBUG("PolicyEngineServer: CPolicyStorage::IsIdValidL"); |
|
1331 |
|
1332 |
|
1333 //parse element file name |
|
1334 TBuf<KUidLength> elementFile; |
|
1335 elementFile.NumFixedWidth( aId, EDecimal, KUidLength); |
|
1336 |
|
1337 //buffer for file name (C-drive) |
|
1338 TBuf<KFullFileNameLength> fileName; |
|
1339 fileName.Append( KCDrive); |
|
1340 fileName.Append( elementFile); |
|
1341 fileName.Append( KFileExtensio); |
|
1342 |
|
1343 //try open file from C-drive |
|
1344 RFile file; |
|
1345 CleanupClosePushL( file); |
|
1346 TInt err = file.Open( iRFs, fileName, EFileRead); |
|
1347 |
|
1348 //and if file does not exist in C-drive try again from z-drive |
|
1349 if ( err == KErrNotFound || err == KErrPathNotFound) |
|
1350 { |
|
1351 fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); |
|
1352 err = file.Open( iRFs, fileName, EFileRead); |
|
1353 } |
|
1354 |
|
1355 CleanupStack::PopAndDestroy( &file); |
|
1356 |
|
1357 #ifdef __DEBUG |
|
1358 if ( err == KErrNotFound) |
|
1359 { |
|
1360 RDEBUG("PolicyEngineServer: Id is not valid!"); |
|
1361 } |
|
1362 #endif |
|
1363 |
|
1364 return err == KErrNotFound; |
|
1365 } |
|
1366 |
|
1367 |
|
1368 |
|
1369 // ----------------------------------------------------------------------------- |
|
1370 // CPolicyStorage::GetEditedElements() |
|
1371 // ----------------------------------------------------------------------------- |
|
1372 // |
|
1373 void CPolicyStorage::GetEditedElementsL( CSettingEnforcementManager* aSEManager) |
|
1374 { |
|
1375 //Check is element changed |
|
1376 for ( TInt i(0); i < iEditedElements.Count(); i++) |
|
1377 { |
|
1378 CElementBase * element = iEditedElements[i]; |
|
1379 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
1380 |
|
1381 switch ( element->iElementState) |
|
1382 { |
|
1383 //these states indicates changes |
|
1384 case EDeletedEditableElement: |
|
1385 case ENewElement: |
|
1386 case EEditedElement: |
|
1387 //add element to modified element list |
|
1388 aSEManager->AddModifiedElementL( element); |
|
1389 break; |
|
1390 default: |
|
1391 break; |
|
1392 } |
|
1393 |
|
1394 } |
|
1395 } |
|
1396 |
|
1397 // ----------------------------------------------------------------------------- |
|
1398 // CPolicyStorage::ResetEditableMemory() |
|
1399 // ----------------------------------------------------------------------------- |
|
1400 // |
|
1401 |
|
1402 void CPolicyStorage::ResetEditableMemory() |
|
1403 { |
|
1404 //release memory used in edited element cache |
|
1405 for ( TInt i(0); i < iEditedElements.Count();) |
|
1406 { |
|
1407 CElementBase * element = iEditedElements[i]; |
|
1408 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
1409 delete element; |
|
1410 iEditedElements.Remove( i); |
|
1411 } |
|
1412 |
|
1413 RDEBUG("PolicyEngineServer: Edited elements removed!"); |
|
1414 } |
|
1415 |
|
1416 // ----------------------------------------------------------------------------- |
|
1417 // CPolicyStorage::SaveEditableMemoryL() |
|
1418 // ----------------------------------------------------------------------------- |
|
1419 // |
|
1420 |
|
1421 void CPolicyStorage::SaveEditableMemoryL() |
|
1422 { |
|
1423 RDEBUG("PolicyEngineServer: Save new and modified elements"); |
|
1424 |
|
1425 |
|
1426 //save modified elements |
|
1427 for ( TInt i(0); i < iEditedElements.Count(); i++) |
|
1428 { |
|
1429 CElementBase * element = iEditedElements[i]; |
|
1430 __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); |
|
1431 |
|
1432 TInt elementChanged = ETrue; |
|
1433 |
|
1434 switch ( element->iElementState) |
|
1435 { |
|
1436 case EDeletedEditableElement: |
|
1437 //delete element and remove possible id mappings... |
|
1438 RDEBUG_2("Element is deleted (id %d)", element->GetId()); |
|
1439 element->DeleteElementL(); |
|
1440 break; |
|
1441 case ENewElement: |
|
1442 //save element (Save new elements recursive) |
|
1443 element->SaveElementL( ETrue); |
|
1444 RDEBUG_2("New element (id %d)", element->GetId()); |
|
1445 break; |
|
1446 case EEditedElement: |
|
1447 //save element (not recursive) |
|
1448 RDEBUG_2("Element is modified (id %d)", element->GetId()); |
|
1449 element->SaveElementL( EFalse); |
|
1450 break; |
|
1451 default: |
|
1452 //no changes in elements |
|
1453 elementChanged = EFalse; |
|
1454 break; |
|
1455 } |
|
1456 |
|
1457 if ( elementChanged ) |
|
1458 { |
|
1459 //find elements from element cache (by id) |
|
1460 CElementBase referenceElement( element->GetId()); |
|
1461 TLinearOrder<CElementBase*> linearOrder(&ElementHelper::CompareElements); |
|
1462 TInt index = iElementCache.FindInOrder( &referenceElement, linearOrder); |
|
1463 |
|
1464 //if eleement is in the element cache remove it to depricated list |
|
1465 //Next time element is used it will be loaded from RAM |
|
1466 if ( index >= 0) |
|
1467 { |
|
1468 CElementBase * cacheElement = iElementCache[index]; |
|
1469 iElementCache.Remove( index); |
|
1470 |
|
1471 if ( element->iReferenceCount == 0 ) |
|
1472 { |
|
1473 delete cacheElement; |
|
1474 } |
|
1475 else |
|
1476 { |
|
1477 cacheElement->iElementState = EDepricated; |
|
1478 iDepricatedElements.AppendL( cacheElement); |
|
1479 RDEBUG_2("PolicyEngineServer: Depricated element list", iDepricatedElements.Count()); |
|
1480 } |
|
1481 } |
|
1482 } |
|
1483 } |
|
1484 } |
|
1485 |
|
1486 // ----------------------------------------------------------------------------- |
|
1487 // CPolicyStorage::CheckCommitStateL() |
|
1488 // ----------------------------------------------------------------------------- |
|
1489 // |
|
1490 |
|
1491 void CPolicyStorage::CheckCommitStateL() |
|
1492 { |
|
1493 RDEBUG( "PolicyEngineServer: CPolicyStorage::CheckCommitStateL"); |
|
1494 |
|
1495 TInt state; |
|
1496 iCentRep->Get( KCommitFlag, state); |
|
1497 |
|
1498 if ( state == EFalse) |
|
1499 { |
|
1500 RDEBUG( "PolicyEngineServer: Commit flag is not set, restore backup...."); |
|
1501 //if commit state is "not committed" restore backup files |
|
1502 RestoreBackupL(); |
|
1503 } |
|
1504 |
|
1505 //Check also commit state in centreptool |
|
1506 RCentRepTool centRepTool; |
|
1507 User::LeaveIfError( centRepTool.Connect()); |
|
1508 TInt err = centRepTool.CheckCommitState(); |
|
1509 centRepTool.Close(); |
|
1510 |
|
1511 if ( state) |
|
1512 { |
|
1513 //commit server id list |
|
1514 CFileMan * fileMan = CFileMan::NewL( iRFs); |
|
1515 |
|
1516 //create backup |
|
1517 err = fileMan->Copy( KServerIdFileTmp, KServerIdFile, CFileMan::EOverWrite); |
|
1518 |
|
1519 if ( err == KErrNone || err == KErrNotFound) |
|
1520 { |
|
1521 fileMan->Delete( KServerIdFileTmp, 0); |
|
1522 err = KErrNone; |
|
1523 } |
|
1524 |
|
1525 delete fileMan; |
|
1526 } |
|
1527 |
|
1528 |
|
1529 //if restore ok, turn commit flag to true state which indicates that storages are in valid state |
|
1530 if ( err == KErrNone) |
|
1531 { |
|
1532 RDEBUG( "PolicyEngineServer: Set commit flag on!"); |
|
1533 iCentRep->Set( KCommitFlag, ETrue); |
|
1534 } |
|
1535 |
|
1536 //remove back files |
|
1537 RDEBUG( "PolicyEngineServer: Remove backup!"); |
|
1538 RemoveBackupL(); |
|
1539 } |
|
1540 |
|
1541 // ----------------------------------------------------------------------------- |
|
1542 // CPolicyStorage::StartCommitSessionL() |
|
1543 // ----------------------------------------------------------------------------- |
|
1544 // |
|
1545 void CPolicyStorage::StartCommitSessionL() |
|
1546 { |
|
1547 //Only ONE management session can be active! |
|
1548 __ASSERT_ALWAYS ( iCommitted, User::Panic( Panics::PolicyStoragePanic, KErrCorrupt)); |
|
1549 |
|
1550 iCommitted = EFalse; |
|
1551 |
|
1552 //Set storage state to "Not committed", ensures rollback in error situations |
|
1553 iCentRep->Set( KCommitFlag, EFalse); |
|
1554 } |
|
1555 |
|
1556 // ----------------------------------------------------------------------------- |
|
1557 // CPolicyStorage::CreatePathsL() |
|
1558 // ----------------------------------------------------------------------------- |
|
1559 // |
|
1560 TInt CPolicyStorage::CreatePaths() |
|
1561 { |
|
1562 //create directory |
|
1563 RDEBUG("PolicyEngineServer: Create private path"); |
|
1564 TInt err = iRFs.CreatePrivatePath( EDriveC); |
|
1565 |
|
1566 if ( err == KErrNone || err == KErrAlreadyExists ) |
|
1567 { |
|
1568 //create also backup path |
|
1569 RDEBUG("PolicyEngineServer: Create backup path"); |
|
1570 err = iRFs.MkDir( KBackupPath); |
|
1571 } |
|
1572 |
|
1573 return err; |
|
1574 } |
|
1575 |
|
1576 |
|
1577 // ----------------------------------------------------------------------------- |
|
1578 // CPolicyStorage::CommitChangesL() |
|
1579 // ----------------------------------------------------------------------------- |
|
1580 // |
|
1581 |
|
1582 void CPolicyStorage::CommitChangesL( TBool aAcceptCommit) |
|
1583 { |
|
1584 RDEBUG("PolicyEngineServer: Commit changes!"); |
|
1585 |
|
1586 if ( !aAcceptCommit) |
|
1587 { |
|
1588 //if commit is not accepted, restore files! |
|
1589 RDEBUG("PolicyEngineServer: Commit is not accepted"); |
|
1590 CheckCommitStateL(); |
|
1591 } |
|
1592 |
|
1593 //Set storage state to "Committed" |
|
1594 RDEBUG("PolicyEngineServer: Set commit flag state to committed"); |
|
1595 iCentRep->Set( KCommitFlag, ETrue); |
|
1596 |
|
1597 if ( aAcceptCommit) |
|
1598 { |
|
1599 //This removes all backups |
|
1600 CheckCommitStateL(); |
|
1601 } |
|
1602 |
|
1603 |
|
1604 //Commit changes |
|
1605 iCommitted = ETrue; |
|
1606 |
|
1607 RDEBUG("PolicyEngineServer: Commit changes - end"); |
|
1608 } |
|
1609 |
|
1610 // ----------------------------------------------------------------------------- |
|
1611 // CPolicyStorage::AddNewServerId() |
|
1612 // ----------------------------------------------------------------------------- |
|
1613 // |
|
1614 TInt CPolicyStorage::AddNewServerId( const TDesC8& aServerId) |
|
1615 { |
|
1616 TRAPD( err, |
|
1617 iServerIdList.AppendL( aServerId.AllocL()); |
|
1618 SaveServerIdListL()); |
|
1619 |
|
1620 if ( err != KErrNone) |
|
1621 { |
|
1622 TRAP( err, LoadServerIdListL()); |
|
1623 } |
|
1624 |
|
1625 return err; |
|
1626 } |
|
1627 |
|
1628 // ----------------------------------------------------------------------------- |
|
1629 // CPolicyStorage::RemoveServerId() |
|
1630 // ----------------------------------------------------------------------------- |
|
1631 // |
|
1632 TInt CPolicyStorage::RemoveServerId( const TDesC8& aServerId) |
|
1633 { |
|
1634 for ( TInt i(0); i < iServerIdList.Count(); i++) |
|
1635 { |
|
1636 if ( *(iServerIdList[i]) == aServerId) |
|
1637 { |
|
1638 delete (iServerIdList[i]); |
|
1639 iServerIdList.Remove( i); |
|
1640 break; |
|
1641 } |
|
1642 } |
|
1643 |
|
1644 TRAPD( err, SaveServerIdListL()); |
|
1645 |
|
1646 if ( err != KErrNone) |
|
1647 { |
|
1648 TRAP( err, LoadServerIdListL()); |
|
1649 } |
|
1650 |
|
1651 return err; |
|
1652 } |
|
1653 |
|
1654 // ----------------------------------------------------------------------------- |
|
1655 // CPolicyStorage::ResetServerIdList() |
|
1656 // ----------------------------------------------------------------------------- |
|
1657 // |
|
1658 TInt CPolicyStorage::ResetServerIdList() |
|
1659 { |
|
1660 iServerIdList.ResetAndDestroy(); |
|
1661 |
|
1662 TRAPD( err, SaveServerIdListL()); |
|
1663 |
|
1664 if ( err != KErrNone) |
|
1665 { |
|
1666 TRAP( err, LoadServerIdListL()); |
|
1667 } |
|
1668 |
|
1669 return err; |
|
1670 } |
|
1671 |
|
1672 |
|
1673 // ----------------------------------------------------------------------------- |
|
1674 // CPolicyStorage::PrintServerIdList() |
|
1675 // ----------------------------------------------------------------------------- |
|
1676 // |
|
1677 void CPolicyStorage::PrintServerIdList() |
|
1678 { |
|
1679 for ( TInt i(0); i < iServerIdList.Count(); i++) |
|
1680 { |
|
1681 TPtrC8 ptr = *iServerIdList[i]; |
|
1682 |
|
1683 RDEBUG8_2("CPolicyStorage::PrintServerIdList() Server id: (%S)", &ptr); |
|
1684 } |
|
1685 } |
|
1686 |
|
1687 |
|
1688 // ----------------------------------------------------------------------------- |
|
1689 // CPolicyStorage::SaveServerIdList() |
|
1690 // ----------------------------------------------------------------------------- |
|
1691 // |
|
1692 TBool CPolicyStorage::IsServerIdValid( const TDesC8& aServerId) |
|
1693 { |
|
1694 for ( TInt i(0); i < iServerIdList.Count(); i++) |
|
1695 { |
|
1696 if ( *(iServerIdList[i]) == aServerId) |
|
1697 { |
|
1698 return ETrue; |
|
1699 } |
|
1700 } |
|
1701 |
|
1702 return EFalse; |
|
1703 } |
|
1704 |
|
1705 |
|
1706 // ----------------------------------------------------------------------------- |
|
1707 // CPolicyStorage::SaveServerIdList() |
|
1708 // ----------------------------------------------------------------------------- |
|
1709 // |
|
1710 void CPolicyStorage::SaveServerIdListL() |
|
1711 { |
|
1712 __UHEAP_MARK; |
|
1713 |
|
1714 //Open file stream. RFile ownership changes for CDirectFileStore |
|
1715 RFile file; |
|
1716 CleanupClosePushL( file); |
|
1717 User::LeaveIfError( file.Replace( iRFs, KServerIdFileTmp, EFileWrite)); |
|
1718 |
|
1719 CDirectFileStore * directFileStore = CDirectFileStore::NewL( file); |
|
1720 CleanupStack::Pop( &file); |
|
1721 CleanupStack::PushL( directFileStore); |
|
1722 |
|
1723 //setup write stream |
|
1724 directFileStore->SetTypeL( TUidType(KDirectFileStoreLayoutUid, KNullUid, KPolicyEngineRepositoryID)) ; |
|
1725 |
|
1726 RStoreWriteStream rootStream ; |
|
1727 TStreamId rootStreamId = rootStream.CreateLC(*directFileStore) ; |
|
1728 |
|
1729 //Externalize |
|
1730 TInt32 count = iServerIdList.Count(); |
|
1731 rootStream << count; |
|
1732 |
|
1733 for ( TInt i(0); i < count; i++) |
|
1734 { |
|
1735 rootStream << *(iServerIdList[i]); |
|
1736 } |
|
1737 |
|
1738 rootStream.CommitL(); |
|
1739 |
|
1740 directFileStore->SetRootL(rootStreamId); |
|
1741 directFileStore->CommitL(); |
|
1742 |
|
1743 //destroy |
|
1744 CleanupStack::PopAndDestroy( 2, directFileStore); |
|
1745 |
|
1746 __UHEAP_MARKEND; |
|
1747 } |
|
1748 |
|
1749 // ----------------------------------------------------------------------------- |
|
1750 // CPolicyStorage::LoadServerIdList() |
|
1751 // ----------------------------------------------------------------------------- |
|
1752 // |
|
1753 void CPolicyStorage::LoadServerIdListL() |
|
1754 { |
|
1755 RDEBUG("CPolicyStorage: LoadServerIdListL()"); |
|
1756 |
|
1757 RFile file; |
|
1758 iServerIdList.ResetAndDestroy(); |
|
1759 |
|
1760 //Open file |
|
1761 TInt err = file.Open( iRFs, KServerIdFile, EFileRead); |
|
1762 |
|
1763 if ( err == KErrNotFound) |
|
1764 { |
|
1765 RDEBUG("CPolicyStorage: ServerID file not found!"); |
|
1766 return; |
|
1767 } |
|
1768 |
|
1769 User::LeaveIfError( err); |
|
1770 |
|
1771 //Open file stream |
|
1772 CDirectFileStore* directFileStore = CDirectFileStore::FromLC ( file); |
|
1773 TStreamId rootStreamId = directFileStore->Root() ; |
|
1774 |
|
1775 //setup read stream |
|
1776 RStoreReadStream rootStream ; |
|
1777 rootStream.OpenLC( *directFileStore, rootStreamId); |
|
1778 |
|
1779 //Internalize |
|
1780 TInt32 count; |
|
1781 rootStream >> count; |
|
1782 |
|
1783 for ( TInt i(0); i < count; i++) |
|
1784 { |
|
1785 HBufC8 * buf = HBufC8::NewLC( rootStream, 200); |
|
1786 iServerIdList.AppendL( buf); |
|
1787 CleanupStack::Pop( buf); |
|
1788 } |
|
1789 |
|
1790 PrintServerIdList(); |
|
1791 |
|
1792 CleanupStack::PopAndDestroy( 2, directFileStore); |
|
1793 } |
|
1794 |
|
1795 |
|
1796 |
|
1797 // ----------------------------------------------------------------------------- |
|
1798 // TElementReserver::TElementReserver() |
|
1799 // ----------------------------------------------------------------------------- |
|
1800 // |
|
1801 |
|
1802 TElementReserver::TElementReserver() |
|
1803 : iElement( NULL), iElements( NULL), iElementList( NULL) |
|
1804 { |
|
1805 } |
|
1806 |
|
1807 // ----------------------------------------------------------------------------- |
|
1808 // TElementReserver::TElementReserver() |
|
1809 // ----------------------------------------------------------------------------- |
|
1810 // |
|
1811 |
|
1812 TElementReserver::TElementReserver( CElementBase * aElement) |
|
1813 : iElement( aElement), iElements( NULL), iElementList( NULL) |
|
1814 { |
|
1815 //reserve element |
|
1816 aElement->ReserveElement(); |
|
1817 } |
|
1818 |
|
1819 // ----------------------------------------------------------------------------- |
|
1820 // TElementReserver::TElementReserver() |
|
1821 // ----------------------------------------------------------------------------- |
|
1822 // |
|
1823 |
|
1824 TElementReserver::TElementReserver( RElementContainer* aElements) |
|
1825 : iElement( NULL), iElements( aElements), iElementList( NULL) |
|
1826 { |
|
1827 //Reserver all elements in element list |
|
1828 for (TInt i(0); i < iElements->Count(); i++) |
|
1829 { |
|
1830 (*iElements)[i]->iElement->ReserveElement(); |
|
1831 } |
|
1832 } |
|
1833 |
|
1834 // ----------------------------------------------------------------------------- |
|
1835 // TElementReserver::~TElementReserver() |
|
1836 // ----------------------------------------------------------------------------- |
|
1837 // |
|
1838 |
|
1839 TElementReserver::~TElementReserver() |
|
1840 { |
|
1841 DoRelease(); |
|
1842 } |
|
1843 |
|
1844 // ----------------------------------------------------------------------------- |
|
1845 // TElementReserver::ReserveL() |
|
1846 // ----------------------------------------------------------------------------- |
|
1847 // |
|
1848 |
|
1849 void TElementReserver::ReserveL( CElementBase* aElement) |
|
1850 { |
|
1851 //create new element list if needed |
|
1852 if (!iElementList) |
|
1853 { |
|
1854 iElementList = new (ELeave) RElementList(); |
|
1855 } |
|
1856 |
|
1857 //add element to list and reserve it |
|
1858 iElementList->AppendL( aElement); |
|
1859 aElement->ReserveElement(); |
|
1860 } |
|
1861 |
|
1862 // ----------------------------------------------------------------------------- |
|
1863 // TElementReserver::DoRelease() |
|
1864 // ----------------------------------------------------------------------------- |
|
1865 // |
|
1866 |
|
1867 |
|
1868 void TElementReserver::Release() |
|
1869 { |
|
1870 } |
|
1871 |
|
1872 |
|
1873 void TElementReserver::DoRelease() |
|
1874 { |
|
1875 //release eleements... |
|
1876 if ( iElement ) |
|
1877 { |
|
1878 iElement->ReleaseElement(); |
|
1879 } |
|
1880 else if ( iElements ) |
|
1881 { |
|
1882 for (TInt i(0); i < iElements->Count(); i++) |
|
1883 { |
|
1884 (*iElements)[i]->iElement->ReleaseElement(); |
|
1885 } |
|
1886 } |
|
1887 else if ( iElementList) |
|
1888 { |
|
1889 for (TInt i(0); i < iElementList->Count(); i++) |
|
1890 { |
|
1891 (*iElementList)[i]->ReleaseElement(); |
|
1892 } |
|
1893 |
|
1894 iElementList->Close(); |
|
1895 delete iElementList; |
|
1896 iElementList = NULL; |
|
1897 } |
|
1898 } |
|
1899 |