diff -r 000000000000 -r b497e44ab2fc policymanagement/policyengine/policyengineserver/src/PolicyStorage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/policymanagement/policyengine/policyengineserver/src/PolicyStorage.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,1899 @@ +/* +* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of policymanagement components +* +*/ + + +// INCLUDE FILES + +#include "PolicyStorage.h" +#include "PolicyEngineServer.h" +#include "ElementBase.h" +#include "XACMLconstants.h" +#include "PolicyParser.h" +#include "SettingEnforcementManager.h" +#include "debug.h" +#include "ErrorCodes.h" +#include "PolicyEnginePrivateCRKeys.h" + +#include "policymnginternalpskeys.h" +#include +#include "CentRepToolClient.h" +#include +#include + + +_LIT( KCDrive, "C:\\private\\10207815\\"); +_LIT( KZDrive, "Z:\\private\\10207815\\"); +_LIT( KCDriveLetter, "C:"); +_LIT( KZDriveLetter, "Z:"); +_LIT( KFileExtensio, ".txt"); +_LIT( KBackupPath, "C:\\private\\10207815\\backup\\"); +_LIT8( KEmptyBackup, "|Empty|"); +_LIT( KServerIdFile, "C:\\private\\10207815\\serverids.dat"); +_LIT( KServerIdFileTmp, "C:\\private\\10207815\\backup\\serverids.tmp"); + +const TInt KUidLength = 10; +const TInt KFileNameLength = 14; +const TChar KElementStartMark = '<'; +const TInt KFullFileNameLength = 80; +const TInt KDriveLetterLength = 2; +// not in use anymore: KSettingSpaceLength = 100; +const TInt KCacheLimit = 100; + + + + +// ==================== LOCAL FUNCTIONS ==================== + +TInt CompareIDs( TUint32 const& aId1, TUint32 const& aId2) +{ + if ( aId1 == aId2) return 0; + return ( aId1 < aId2 ? -1 : 1 ); +} + +TInt CompareStrings( HBufC8 const& aString1, HBufC8 const& aString2) +{ + return aString1.Compare( aString2); +} + + +// ================= MEMBER FUNCTIONS ======================= + +CPolicyStorage* CPolicyStorage::iPolicyStorage = 0; + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CPolicyStorage() +// ----------------------------------------------------------------------------- +// + +CPolicyStorage::CPolicyStorage() +{ +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::~CPolicyStorage() +// ----------------------------------------------------------------------------- +// + +CPolicyStorage::~CPolicyStorage() +{ + RDEBUG("CPolicyStorage::~CPolicyStorage()"); + delete iCentRep; + delete iCentRepBackup; + delete iParser; + + //release memory used in element cache + for ( TInt i(0); i < iElementCache.Count(); i++) + { + CElementBase * element = iElementCache[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + + + delete element; + } + + //release memory used in depricated element cache + for ( TInt i(0); i < iDepricatedElements.Count(); i++) + { + CElementBase * element = iDepricatedElements[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + + + delete element; + } + + //release memory used in depricated element cache + for ( TInt i(0); i < iEditedElements.Count(); i++) + { + CElementBase * element = iEditedElements[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + + + delete element; + } + + //release resources + iElementCache.Close(); + iDepricatedElements.Close(); + iEditedElements.Close(); + iSearchedUids.Close(); + + iServerIdList.ResetAndDestroy(); + iServerIdList.Close(); + + iInvalidServerIds.ResetAndDestroy(); + iInvalidServerIds.Close(); + + + iRFs.Close(); +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::PolicyStorage() +// ----------------------------------------------------------------------------- +// +CPolicyStorage * CPolicyStorage::PolicyStorage() +{ + return iPolicyStorage; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ConstructL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::ConstructL() +{ + RDEBUG("PolicyEngineServer: CPolicyStorage::ConstructL - start"); + + iCommitted = ETrue; + //open sessions to repotories and file server + iCentRep = CRepository::NewL( KPolicyEngineRepositoryID); + RDEBUG("PolicyEngineServer: Connected to repository"); + iCentRepBackup = CRepository::NewL( KPolicyEngineBackupRepositoryID); + RDEBUG("PolicyEngineServer: Connected to backup repository"); + User::LeaveIfError( iRFs.Connect() ); + + //Create and set up parser + iParser = CPolicyParser::NewL( this); + RDEBUG("PolicyEngineServer: Policy parser created"); + iParser->SetExternalIdChecked( KNoExternalIdCheck); + + //check commit state (restore and/or delete backup if needed) + CheckCommitStateL(); + + //load server id list... + LoadServerIdListL(); + + RDEBUG("PolicyEngineServer: CPolicyStorage::ConstructL - end"); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::NewL() +// ----------------------------------------------------------------------------- +// + +CPolicyStorage * CPolicyStorage::NewL() +{ + CPolicyStorage * self = new(ELeave) CPolicyStorage(); + + CleanupStack::PushL( self); + self->ConstructL(); + CleanupStack::Pop( self); + + return self; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ReleaseElements() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::ReleaseElements() +{ + RDEBUG("PolicyEngineServer: Try to release unused elements!"); + + + //release memory used in element cache + for ( TInt i(0); i < iElementCache.Count(); i++) + { + CElementBase * element = iElementCache[i]; + if ( element->iReferenceCount == 0) + { + delete element; + iElementCache.Remove(i--); + RDEBUG_2("PolicyEngineServer: Element removed from cache (Cache count %d)", iElementCache.Count()); + } + } + + //release memory used in depricated element cache + for ( TInt i(0); i < iDepricatedElements.Count(); i++) + { + CElementBase * element = iDepricatedElements[i]; + if ( element->iReferenceCount == 0) + { + delete element; + iDepricatedElements.Remove(i--); + RDEBUG_2("PolicyEngineServer: Element removed from cache (Depricated element count %d)", iDepricatedElements.Count()); + } + } +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::SetElementL() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::SetElementL( TUint32 aId, const TDesC8& aDescription) +{ + //resolve element file name + TBuf elementFile; + elementFile.NumFixedWidth( aId, EDecimal, KUidLength); + + //buffer for file name (C-drive) + TBuf fileName; + fileName.Append( KCDrive); + fileName.Append( elementFile); + fileName.Append( KFileExtensio); + + + RDEBUG_2("PolicyEngineServer: Write element to disk (%S)", &fileName); + MakeBackupL( fileName); + + //try open existing file + RFile file; + TInt err = file.Open( iRFs, fileName, EFileWrite); + + + if ( err == KErrPathNotFound) + { + err = CreatePaths(); + + //this ensures, that also element file will be created + if ( err == KErrNone) + { + err = KErrNotFound; + } + } + + //and if file doesn't not exist create it + if ( err == KErrNotFound ) + { + err = file.Create( iRFs, fileName, EFileWrite); + } + + //write to file... + if ( err == KErrNone) + { + err = file.Write( 0, aDescription); + } + + //...and set size + if ( err == KErrNone ) + { + err = file.SetSize( aDescription.Length()); + if ( err == KErrNone ) + { + err = file.Flush(); + } + } + + file.Close(); + + RDEBUG_2("PolicyEngineServer: Write OK (%S)", &fileName); + + return err; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::MakeBackUpL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::MakeBackupL( const TDesC& aFileName) +{ + //buffer for file name (C-drive) + TBuf backupName; + backupName.Append( KBackupPath); + backupName.Append( aFileName.Right( KFileNameLength)); + + CFileMan * fileMan = CFileMan::NewL( iRFs); + + //create backup + TInt err = fileMan->Copy( aFileName, backupName, 0); + delete fileMan; + + //if file doesn't exist in workarea, create empty file which indicates that in original state file is not exist + if ( err == KErrNotFound) + { + RFile file; + CleanupClosePushL( file); + User::LeaveIfError( file.Create( iRFs, backupName, EFileWrite)); + + RDEBUG_2("PolicyEngineServer: Element backup: %S indicates new element in policy storage", &backupName); + + CleanupStack::PopAndDestroy( &file); + } + else + { + User::LeaveIfError( err); + RDEBUG_3("PolicyEngineServer: Element backup: %S -> %S", &aFileName, &backupName); + } + +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::MakeBackUpL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::MakeBackupL( const TUint32& aSettingId) +{ + //TInt settings + TInt value = 0; + TInt err = iCentRep->Get( aSettingId, value); + RDEBUG_2("PolicyEngineServer: Backup for CentRep value setting: %d", aSettingId); + + //for "empty backup" + if ( err == KErrNotFound ) + { + //Set backupvalue + TInt err = iCentRepBackup->Create( aSettingId, KEmptyBackup); + + //if value is already exist, it is a original value of setting is must be saved + if ( err == KErrAlreadyExists) + { + err = KErrNone; + } + + //Leave if backupfails + User::LeaveIfError( err); + } + else + { + //Set backupvalue + TInt err = iCentRepBackup->Create( aSettingId, value); + + if ( err == KErrAlreadyExists) + { + //if value is already exist, it is a original value of setting is must be saved + err = KErrNone; + } + + //Leave if backupfails + User::LeaveIfError( err); + } +} + +void CPolicyStorage::RestoreBackupL() +{ + //Open directory and get file list + RDir dir; + CleanupClosePushL( dir); + + TInt err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); + + //create private and backuppaths + if ( err == KErrPathNotFound) + { + CreatePaths(); + err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); + } + + User::LeaveIfError( err); + err = KErrNone; + + do + { + //read entries (files) + TEntryArray array; + err = dir.Read( array); + if ( KErrEof != err) + { + User::LeaveIfError( err); + } + + for ( TInt i = 0; i < array.Count(); i++) + { + const TEntry& entry = array[i]; + + //original file name + TBuf fileName; + fileName.Append( KCDrive); + fileName.Append( entry.iName); + + //if file size is zero, remove file from work directory + if ( entry.iSize == 0) + { + RDEBUG_2("PolicyEngineServer: Restoring backup: %S removed", &fileName); + + TInt err = iRFs.Delete( fileName); + if ( err == KErrNotFound) + { + err = KErrNone; + } + + User::LeaveIfError( err ); + } + else + { + //Create backup file name + TBuf backupName; + backupName.Append( KBackupPath); + backupName.Append( entry.iName); + + //otherwise copy file to work directory + CFileMan * fileMan = CFileMan::NewL( iRFs); + CleanupStack::PushL( fileMan); + + //Copy file to work directory + User::LeaveIfError( fileMan->Copy( backupName, fileName)); + RDEBUG_3("PolicyEngineServer: Restoring backup: %S -> %S", &backupName, &fileName); + + + CleanupStack::Pop( fileMan); //fileMan + } + } + } while ( err == KErrNone); + + //id list + RArray ids; + CleanupClosePushL( ids); + + //find all ids + iCentRepBackup->FindL( 0, 0x0, ids); + + for ( TInt i(0); i < ids.Count(); i++) + { + TUint32 id = ids[i]; + RDEBUG_2("PolicyEngineServer: Restoring centrep setting %d", id); + + //get value + TBuf8<200> buffer; + TInt err = iCentRepBackup->Get( id, buffer); + + if ( err != KErrNone) + { + TInt value = 0; + User::LeaveIfError( iCentRepBackup->Get( id, value)); + User::LeaveIfError( iCentRep->Set( id, value)); + } + else + { + if ( buffer == KEmptyBackup) + { + User::LeaveIfError( iCentRep->Delete( id)); + } + else + { + User::LeaveIfError( iCentRep->Set( id, buffer)); + } + } + } + + CleanupStack::PopAndDestroy(2, &dir); //RArray, RDir +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::RemoveBackupL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::RemoveBackupL() +{ + //Open directory and get file list + RDir dir; + CleanupClosePushL( dir); + + TInt err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); + + //create private and backuppaths + if ( err == KErrPathNotFound) + { + CreatePaths(); + err = dir.Open( iRFs, KBackupPath, KEntryAttNormal); + } + + User::LeaveIfError( err); + err = KErrNone; + + do + { + //read entries (files) + TEntryArray array; + err = dir.Read( array); + if ( KErrEof != err) + { + User::LeaveIfError( err); + } + + for ( TInt i = 0; i < array.Count(); i++) + { + const TEntry& entry = array[i]; + + TBuf backupName; + backupName.Append( KBackupPath); + backupName.Append( entry.iName); + + RDEBUG_2("Policy Engine: Remove backup file %S", &backupName); + User::LeaveIfError( iRFs.Delete( backupName)); + } + } while ( err == KErrNone); + + //id list + RArray ids; + CleanupClosePushL( ids); + + //find all ids + iCentRepBackup->FindL( 0, 0x0, ids); + + for ( TInt i(0); i < ids.Count(); i++) + { + RDEBUG_2("Policy Engine: Remove centrep backup %d", ids[i]); + User::LeaveIfError( iCentRepBackup->Delete( ids[i])); + } + + CleanupStack::PopAndDestroy(2, &dir); //RArray +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ActivateEnforcementFlagL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::ActivateEnforcementFlagL( KSettingEnforcements aSetting) +{ + TUint32 id = KEnforcementStates + aSetting; + + MakeBackupL( id); + TInt err = iCentRep->Set( id, ETrue); + + if ( KErrNotFound == err) + { + err = iCentRep->Create( id, ETrue); + } + + User::LeaveIfError( err); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::DeactivateEnforcementFlagL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::DeactivateEnforcementFlagL( KSettingEnforcements aSetting) +{ + TUint32 id = KEnforcementStates + aSetting; + + MakeBackupL( id); + TInt err = iCentRep->Set( id, EFalse); + + if ( KErrNotFound == err) + { + err = iCentRep->Create( id, EFalse); + } + + User::LeaveIfError( err); +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetElementL() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::GetElementL( TUint32 aId, HBufC8*& aDescription) +{ + //parse element file name + TBuf elementFile; + elementFile.NumFixedWidth( aId, EDecimal, KUidLength); + + //buffer for file name (C-drive) + TBuf fileName; + fileName.Append( KCDrive); + fileName.Append( elementFile); + fileName.Append( KFileExtensio); + + //try open file from C-drive + RFile file; + CleanupClosePushL( file); + TInt err = file.Open( iRFs, fileName, EFileRead); + + //and if file does not exist in C-drive try again from z-drive + if ( err == KErrNotFound || err == KErrPathNotFound) + { + fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); + err = file.Open( iRFs, fileName, EFileRead); + } + + //resolve file size + TInt size = 0; + if ( err == KErrNone) + { + err = file.Size( size); + } + + //empty file in the RAM-drive indicates that ROM-file is deleted + if ( err == KErrNone && size) + { + //create buffer for element + aDescription = HBufC8::NewLC( size); + TPtr8 ptr = aDescription->Des(); + + //read file to buffer and remove buffer from cleanupstack + file.Read( ptr); + CleanupStack::Pop( aDescription); + } + + __ASSERT_ALWAYS( aDescription, User::Panic(PolicyStoragePanic, KErrGeneral)); + + CleanupStack::PopAndDestroy( &file); + + return err; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::DeleteElement() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::DeleteElementL( TUint32 aElementId) +{ + //parse element file name + TBuf elementFile; + elementFile.NumFixedWidth( aElementId, EDecimal, KUidLength); + + //buffer for file name (C-drive) + TBuf fileName; + fileName.Append( KCDrive); + fileName.Append( elementFile); + fileName.Append( KFileExtensio); + + + //make backup + MakeBackupL( fileName); + + + //if the ROM-drive contains file, we can't delete it, create empty file (c-drive) to indicate that file is deleted + fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); + RFile file; + TInt err = file.Open( iRFs, fileName, EFileRead); + file.Close(); + + fileName.Replace( 0, KDriveLetterLength, KCDriveLetter); + + if ( err == KErrNone) + { + CleanupClosePushL( file); + User::LeaveIfError( file.Create( iRFs, fileName, EFileWrite )); + User::LeaveIfError( file.Flush()); + CleanupStack::PopAndDestroy( &file); + } + else + { + //if file is only in the ROM-drive + User::LeaveIfError( iRFs.Delete( fileName)); + } + +} + + + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::SaveElementL() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::SaveElementL( TUint32 aElementId, HBufC8 * aElementDescription) +{ + //write element + return SetElementL( aElementId, *aElementDescription); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CheckElementL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::CheckElementL( CElementBase * aElement) +{ + if ( aElement->iElementState == ENotLoaded || aElement->iElementState == ENotLoadedEditableElement) + { + TBool addEditCache = ( aElement->iElementState == ENotLoaded ? EFalse : ETrue); + LoadElementL( aElement, addEditCache); + + if ( aElement->iElementState == ENotLoaded) + { + aElement->iElementState = ECacheElement; + } + else + { + aElement->iElementState = EEditableCacheElement; + } + } +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::LoadElementL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::LoadElementL( CElementBase * aElement, TBool aAddToEditableCache) +{ + __ASSERT_ALWAYS( aElement, User::Panic(PolicyStoragePanic, KErrGeneral)); + + //load element description + HBufC8 * description = NULL; + User::LeaveIfError( GetElementL( aElement->GetId(), description)); + CleanupStack::PushL( description); + TPtr8 ptr(description->Des()); + + TNativeElementTypes elementType = aElement->ElementType(); + + //find parent element mapping for policies, policysets and rules + if ( elementType == ERule || elementType == EPolicy || elementType == EPolicySet ) + { + TInt index = ptr.Locate( KParentListStartMark); + + TPtrC8 ptrParent; + if ( index != KErrNotFound) + { + //separate description and parent id list + ptrParent.Set( ptr.Mid( index)); + ptr = ptr.Left( index); + } + + //and decode and add parant mapping + while ( index != KErrNotFound) + { + ptrParent.Set( ptrParent.Mid(1)); + index = ptrParent.Locate(KParentListStartMark); + + TPtrC8 elementId( ptrParent); + + if ( index != KErrNotFound) + { + elementId.Set( ptrParent.Left( index)); + ptrParent.Set( ptrParent.Mid( index)); + } + + TUint32 policySystemid; + TLex8 lex( elementId); + User::LeaveIfError( lex.Val( policySystemid, EDecimal)); + + aElement->AddParentIdL( policySystemid); + } + } + + //parse object + User::LeaveIfError( iParser->ParseNativeObjects( aElement, ptr, aAddToEditableCache)); + + + CleanupStack::PopAndDestroy( description); +} + + + +void CPolicyStorage::AddNewElementL( CElementBase * aElement) +{ + aElement->iElementState = ENewElement; + AddElementL( iEditedElements, aElement); + aElement->iReferenceCount = 0; + + RDEBUG_2("PolicyEngineServer: New editable element (element count %d)", iEditedElements.Count()); +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetEditableElementL() +// ----------------------------------------------------------------------------- +// +CElementBase * CPolicyStorage::GetEditableElementL( const TDesC8& aPolicyId ) +{ + TUint32 settingId = MapRealIdL( aPolicyId, EFalse); + + CElementBase * element = NULL; + + if ( settingId ) + { + element = GetEditableElementL( settingId); + } + + return element; +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetEditableElementL() +// ----------------------------------------------------------------------------- +// +CElementBase * CPolicyStorage::GetEditableElementL( const TUint32 aElementId ) +{ + //check from edit cache + CElementBase * element = FindElement( iEditedElements, aElementId); + + //if doesn't not exits + if ( element == NULL) + { + //create new element + element = ElementHelper::CreateNewElementL( aElementId); + + //Aff element to edited element cache + element->iElementState = ENotLoadedEditableElement; + AddElementL( iEditedElements, element); + element->iReferenceCount = 0; + + } + + //if element is deleted return NULL + if ( element->iElementState == EDeletedEditableElement) + { + element = NULL; + } + + return element; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetElement() +// ----------------------------------------------------------------------------- +// + + +CElementBase * CPolicyStorage::GetElementL( TUint32 aElementId) +{ + CElementBase * element = NULL; + + + if ( element == NULL) + { + element = FindElement( iElementCache, aElementId); + } + + if ( element == NULL) + { + element = ElementHelper::CreateNewElementL( aElementId); + element->iElementState = ENotLoaded; + AddElementL( iElementCache, element); + element->iReferenceCount = 0; + + RDEBUG_2("PolicyEngineServer: New cache element (element cache count %d)", iElementCache.Count()); + + //release unused eleements from cache + if ( iEditedElements.Count() > KCacheLimit) + { + RDEBUG_2("PolicyEngineServer: Cache limit exceeded (%d)", KCacheLimit); + ReleaseElements(); + } + } + + return element; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetElement() +// ----------------------------------------------------------------------------- +// + +CElementBase * CPolicyStorage::GetElementL( const TDesC8& iPolicyId ) +{ + //map external id to internal id + TUint32 settingId = MapRealIdL( iPolicyId, ETrue); + + CElementBase * element = NULL; + + //and if valid mapping exists, get element from storage + if ( settingId ) + { + element = GetElementL( settingId); + } + + return element; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::FindElement() +// ----------------------------------------------------------------------------- +// + +CElementBase * CPolicyStorage::FindElement( RArray &aElementList, const TUint32 aElementId) +{ + __UHEAP_MARK; + + TLinearOrder linearOrder(&ElementHelper::CompareElements); + CElementBase referenceElement( aElementId); + + TInt index = aElementList.FindInOrder( &referenceElement, linearOrder); + + CElementBase * element = NULL; + if ( index >= 0) + { + element = aElementList[index]; + } + + __UHEAP_MARKEND; + + return element; + +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::AddElementL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::AddElementL( RArray &aElementList, CElementBase * aElement) +{ + TLinearOrder linearOrder(&ElementHelper::CompareElements); + aElementList.InsertInOrder( aElement, linearOrder); +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::MapRealId() +// ----------------------------------------------------------------------------- +// +TUint32 CPolicyStorage::MapRealIdL( const TDesC8& aElementRealId, const TBool aOnlyCommitted) +{ + iSearchedUids.Reset(); + TUint32 retVal = 0; + + if ( !aOnlyCommitted ) + { + retVal = GetEditedMappingsL( aElementRealId); + } + + if ( !retVal) + { + retVal = GetCommittedMappingsL( aElementRealId); + } + + + if ( !retVal) + { + retVal = GetMappingsFromDriveL( aElementRealId, EDriveC, EFalse); + } + + if ( !retVal) + { + retVal = GetMappingsFromDriveL( aElementRealId, EDriveZ, EFalse); + } + + return retVal; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetEditedMappingsL() +// ----------------------------------------------------------------------------- +// + +TUint32 CPolicyStorage::GetEditedMappingsL( const TDesC8& aElementRealId) +{ + //seach matching external ids from edited elements + TLinearOrder linearOrder( &CompareIDs); + + for ( TInt i(0); i < iEditedElements.Count(); i++) + { + CElementBase * element = iEditedElements[i]; + + if ( element->iElementType == ERule || element->iElementType == EPolicy || element->iElementType == EPolicySet) + { + CheckElementL( element); + + if ( element->iElementState == EEditableCacheElement || element->iElementState == EEditedElement) + { + if ( aElementRealId.Compare( *(element->iExternalId)) == 0) + { + iSearchedUids.InsertInOrder( element->GetId(), linearOrder); + return element->iElementId; + } + } + } + } + + return 0; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetCommittedMappingsL() +// ----------------------------------------------------------------------------- +// +TUint32 CPolicyStorage::GetCommittedMappingsL( const TDesC8& aElementRealId) +{ + //seach matching external ids from edited elements + TLinearOrder linearOrder( &CompareIDs); + + for ( TInt i(0); i < iElementCache.Count(); i++) + { + CElementBase * element = iElementCache[i]; + + if ( element->iElementType == ERule || element->iElementType == EPolicy || element->iElementType == EPolicySet) + { + if ( iSearchedUids.Find( element->GetId()) >= 0) + { + CheckElementL( element); + + if ( element->iElementState == ECacheElement) + { + if ( aElementRealId.Compare( *(element->iExternalId)) == 0) + { + iSearchedUids.InsertInOrder( element->GetId(), linearOrder); + return element->iElementId; + } + } + } + } + } + + return 0; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetMappingsFromDriveL() +// ----------------------------------------------------------------------------- +// +TUint32 CPolicyStorage::GetMappingsFromDriveL( const TDesC8& aElementRealId, TDriveNumber aDrive, TBool aUpdateList) +{ + //Select correct drive + TPtrC bathPtr( KCDrive); + + if ( aDrive == EDriveZ) + { + bathPtr.Set( KZDrive); + } + + //Open directory and get file list + RDir dir; + CleanupClosePushL( dir); + + TInt err = dir.Open( iRFs, bathPtr, KEntryAttNormal); + + User::LeaveIfError( err); + err = KErrNone; + + TUint32 retVal = 0; + + do + { + //read entries (files) + TEntryArray array; + err = dir.Read( array); + if ( KErrEof != err) + { + User::LeaveIfError( err); + } + + for ( TInt i = 0; i < array.Count(); i++) + { + const TEntry& entry = array[i]; + + TPtrC ptr = entry.iName; + TInt index = ptr.Locate('.'); + User::LeaveIfError( index); + + TLex lex( ptr.Left( index)); + TUint32 id; + lex.Val( id, EDecimal); + TInt type = id & 0xff; + + if ( type == ERule || type == EPolicy || type == EPolicySet ) + { + TBuf<150> file = bathPtr; + file.Append( entry.iName); + + if ( ReadRealIdL( file, aElementRealId, aDrive)) + { + retVal = id; + + if ( aUpdateList) + { + TLinearOrder linearOrder( &CompareStrings); + iInvalidServerIds.InsertInOrder( aElementRealId.AllocL(), linearOrder); + } + + break; + } + } + } + } while ( err == KErrNone && !retVal); + + CleanupStack::PopAndDestroy( &dir); //RArray + + return retVal; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ReadRealIdL() +// ----------------------------------------------------------------------------- +// +TBool CPolicyStorage::ReadRealIdL( const TDesC& aFileName, const TDesC8& aElementRealId, TDriveNumber aDrive) +{ + TBool retVal = EFalse; + + //open file + RFile file; + + TInt err = KErrNone; + + //check first from c-drive + if ( aDrive == EDriveZ) + { + TBuf<100> buf( aFileName); + buf.Replace( 0, KDriveLetterLength, KCDriveLetter); + + err = file.Open( iRFs, buf, EFileRead); + } + else + { + err = KErrNotFound; + } + + if ( err == KErrNotFound) + { + err = file.Open( iRFs, aFileName, EFileRead); + } + + CleanupClosePushL( file); + if ( err == KErrNone) + { + TInt size; + User::LeaveIfError( file.Size( size)); + + if ( size ) + { + HBufC8* content = HBufC8::NewLC( size); + TPtr8 ptr = content->Des(); + + User::LeaveIfError( file.Read( ptr)); + + TInt index = ptr.FindF( aElementRealId); + if ( index > 0) + { + if ( ptr[ index + aElementRealId.Length()] == '"' && ptr[ index - 1] == '"') + { + TInt identifierIndex = ptr.FindF( PolicyLanguage::Rule::RuleId[ENative]); + TInt length = 0; + if ( identifierIndex < 0 ) + { + identifierIndex = ptr.FindF( PolicyLanguage::Policy::PolicyId[ENative]); + length = PolicyLanguage::Policy::PolicyId[ENative].Length(); + if ( identifierIndex < 0 ) + { + identifierIndex = ptr.FindF( PolicyLanguage::PolicySet::PolicySetId[ENative]); + length = PolicyLanguage::PolicySet::PolicySetId[ENative].Length(); + } + } + else + { + length = PolicyLanguage::Rule::RuleId[ENative].Length(); + } + + if ( (identifierIndex + length +2 ) == index) + { + retVal = ETrue; + } + } + } + + CleanupStack::PopAndDestroy( content); + } + + } + + CleanupStack::PopAndDestroy( &file); + return retVal; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ResetRealIdValidTest() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::ResetRealIdValidTest() +{ + iInvalidServerIds.ResetAndDestroy(); +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::IsRealIdValidL() +// ----------------------------------------------------------------------------- +// + +TBool CPolicyStorage::IsRealIdValidL( const TDesC8& aElementRealId) +{ + iSearchedUids.Reset(); + TLinearOrder linearOrder( &CompareStrings); + + HBufC8 * buf = aElementRealId.Alloc(); + if ( iInvalidServerIds.Find( buf) >= 0 ) + { + delete buf; + return EFalse; + } + delete buf; + + + TUint32 id = GetEditedMappingsL( aElementRealId); + + if ( !id ) + { + id = GetCommittedMappingsL( aElementRealId); + } + + if (!id) + { + id = GetMappingsFromDriveL( aElementRealId, EDriveC, ETrue); + } + + if (!id) + { + id = GetMappingsFromDriveL( aElementRealId, EDriveZ, ETrue); + } + + if ( !id) + { + iInvalidServerIds.InsertInOrder( aElementRealId.AllocL(), linearOrder); + } + + return !id; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CreateId() +// ----------------------------------------------------------------------------- +// + +TUint32 CPolicyStorage::CreateIdL( TNativeElementTypes &aType) +{ + __UHEAP_MARK; + + TUint32 nextFreeId = KNextFreeId; + TUint32 nextId(0); + TInt id(0); + TInt err( KErrNone); + + do + { + if ( id == 0) + { + //get next free id from CentRep + err = iCentRep->Get( nextFreeId, id); + } + + if ( err != KErrNone) + { + id = 1; + } + + //reset counter + if ( id > 0xFFFFFF ) + { + id = 0; + } + + //increase next free id value + nextId = id++; + + //create id (combination id next free id and element type) + nextId = nextId << 8; + nextId = nextId | aType; + + + RDEBUG_2("PolicyEngineServer: Next free id: %d", nextId); + } + while ( !IsIdValidL( nextId)); + + //backup value + MakeBackupL( KNextFreeId); + + //save new value + if ( err != KErrNone) + { + User::LeaveIfError( iCentRep->Create( KNextFreeId, id)); + } + else + { + User::LeaveIfError( iCentRep->Set( KNextFreeId, id)); + } + + + __UHEAP_MARKEND; + + return nextId; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetEditedElements() +// ----------------------------------------------------------------------------- +// +TBool CPolicyStorage::IsIdValidL( const TUint32& aId) +{ + RDEBUG("PolicyEngineServer: CPolicyStorage::IsIdValidL"); + + + //parse element file name + TBuf elementFile; + elementFile.NumFixedWidth( aId, EDecimal, KUidLength); + + //buffer for file name (C-drive) + TBuf fileName; + fileName.Append( KCDrive); + fileName.Append( elementFile); + fileName.Append( KFileExtensio); + + //try open file from C-drive + RFile file; + CleanupClosePushL( file); + TInt err = file.Open( iRFs, fileName, EFileRead); + + //and if file does not exist in C-drive try again from z-drive + if ( err == KErrNotFound || err == KErrPathNotFound) + { + fileName.Replace( 0, KDriveLetterLength, KZDriveLetter); + err = file.Open( iRFs, fileName, EFileRead); + } + + CleanupStack::PopAndDestroy( &file); + +#ifdef __DEBUG + if ( err == KErrNotFound) + { + RDEBUG("PolicyEngineServer: Id is not valid!"); + } +#endif + + return err == KErrNotFound; +} + + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::GetEditedElements() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::GetEditedElementsL( CSettingEnforcementManager* aSEManager) +{ + //Check is element changed + for ( TInt i(0); i < iEditedElements.Count(); i++) + { + CElementBase * element = iEditedElements[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + + switch ( element->iElementState) + { + //these states indicates changes + case EDeletedEditableElement: + case ENewElement: + case EEditedElement: + //add element to modified element list + aSEManager->AddModifiedElementL( element); + break; + default: + break; + } + + } +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ResetEditableMemory() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::ResetEditableMemory() +{ + //release memory used in edited element cache + for ( TInt i(0); i < iEditedElements.Count();) + { + CElementBase * element = iEditedElements[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + delete element; + iEditedElements.Remove( i); + } + + RDEBUG("PolicyEngineServer: Edited elements removed!"); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::SaveEditableMemoryL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::SaveEditableMemoryL() +{ + RDEBUG("PolicyEngineServer: Save new and modified elements"); + + + //save modified elements + for ( TInt i(0); i < iEditedElements.Count(); i++) + { + CElementBase * element = iEditedElements[i]; + __ASSERT_ALWAYS ( element->iReferenceCount == 0, User::Panic(PolicyStoragePanic, KErrGeneral)); + + TInt elementChanged = ETrue; + + switch ( element->iElementState) + { + case EDeletedEditableElement: + //delete element and remove possible id mappings... + RDEBUG_2("Element is deleted (id %d)", element->GetId()); + element->DeleteElementL(); + break; + case ENewElement: + //save element (Save new elements recursive) + element->SaveElementL( ETrue); + RDEBUG_2("New element (id %d)", element->GetId()); + break; + case EEditedElement: + //save element (not recursive) + RDEBUG_2("Element is modified (id %d)", element->GetId()); + element->SaveElementL( EFalse); + break; + default: + //no changes in elements + elementChanged = EFalse; + break; + } + + if ( elementChanged ) + { + //find elements from element cache (by id) + CElementBase referenceElement( element->GetId()); + TLinearOrder linearOrder(&ElementHelper::CompareElements); + TInt index = iElementCache.FindInOrder( &referenceElement, linearOrder); + + //if eleement is in the element cache remove it to depricated list + //Next time element is used it will be loaded from RAM + if ( index >= 0) + { + CElementBase * cacheElement = iElementCache[index]; + iElementCache.Remove( index); + + if ( element->iReferenceCount == 0 ) + { + delete cacheElement; + } + else + { + cacheElement->iElementState = EDepricated; + iDepricatedElements.AppendL( cacheElement); + RDEBUG_2("PolicyEngineServer: Depricated element list", iDepricatedElements.Count()); + } + } + } + } +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CheckCommitStateL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::CheckCommitStateL() +{ + RDEBUG( "PolicyEngineServer: CPolicyStorage::CheckCommitStateL"); + + TInt state; + iCentRep->Get( KCommitFlag, state); + + if ( state == EFalse) + { + RDEBUG( "PolicyEngineServer: Commit flag is not set, restore backup...."); + //if commit state is "not committed" restore backup files + RestoreBackupL(); + } + + //Check also commit state in centreptool + RCentRepTool centRepTool; + User::LeaveIfError( centRepTool.Connect()); + TInt err = centRepTool.CheckCommitState(); + centRepTool.Close(); + + if ( state) + { + //commit server id list + CFileMan * fileMan = CFileMan::NewL( iRFs); + + //create backup + err = fileMan->Copy( KServerIdFileTmp, KServerIdFile, CFileMan::EOverWrite); + + if ( err == KErrNone || err == KErrNotFound) + { + fileMan->Delete( KServerIdFileTmp, 0); + err = KErrNone; + } + + delete fileMan; + } + + + //if restore ok, turn commit flag to true state which indicates that storages are in valid state + if ( err == KErrNone) + { + RDEBUG( "PolicyEngineServer: Set commit flag on!"); + iCentRep->Set( KCommitFlag, ETrue); + } + + //remove back files + RDEBUG( "PolicyEngineServer: Remove backup!"); + RemoveBackupL(); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::StartCommitSessionL() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::StartCommitSessionL() +{ + //Only ONE management session can be active! + __ASSERT_ALWAYS ( iCommitted, User::Panic( Panics::PolicyStoragePanic, KErrCorrupt)); + + iCommitted = EFalse; + + //Set storage state to "Not committed", ensures rollback in error situations + iCentRep->Set( KCommitFlag, EFalse); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CreatePathsL() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::CreatePaths() +{ + //create directory + RDEBUG("PolicyEngineServer: Create private path"); + TInt err = iRFs.CreatePrivatePath( EDriveC); + + if ( err == KErrNone || err == KErrAlreadyExists ) + { + //create also backup path + RDEBUG("PolicyEngineServer: Create backup path"); + err = iRFs.MkDir( KBackupPath); + } + + return err; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::CommitChangesL() +// ----------------------------------------------------------------------------- +// + +void CPolicyStorage::CommitChangesL( TBool aAcceptCommit) +{ + RDEBUG("PolicyEngineServer: Commit changes!"); + + if ( !aAcceptCommit) + { + //if commit is not accepted, restore files! + RDEBUG("PolicyEngineServer: Commit is not accepted"); + CheckCommitStateL(); + } + + //Set storage state to "Committed" + RDEBUG("PolicyEngineServer: Set commit flag state to committed"); + iCentRep->Set( KCommitFlag, ETrue); + + if ( aAcceptCommit) + { + //This removes all backups + CheckCommitStateL(); + } + + + //Commit changes + iCommitted = ETrue; + + RDEBUG("PolicyEngineServer: Commit changes - end"); +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::AddNewServerId() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::AddNewServerId( const TDesC8& aServerId) +{ + TRAPD( err, + iServerIdList.AppendL( aServerId.AllocL()); + SaveServerIdListL()); + + if ( err != KErrNone) + { + TRAP( err, LoadServerIdListL()); + } + + return err; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::RemoveServerId() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::RemoveServerId( const TDesC8& aServerId) +{ + for ( TInt i(0); i < iServerIdList.Count(); i++) + { + if ( *(iServerIdList[i]) == aServerId) + { + delete (iServerIdList[i]); + iServerIdList.Remove( i); + break; + } + } + + TRAPD( err, SaveServerIdListL()); + + if ( err != KErrNone) + { + TRAP( err, LoadServerIdListL()); + } + + return err; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::ResetServerIdList() +// ----------------------------------------------------------------------------- +// +TInt CPolicyStorage::ResetServerIdList() +{ + iServerIdList.ResetAndDestroy(); + + TRAPD( err, SaveServerIdListL()); + + if ( err != KErrNone) + { + TRAP( err, LoadServerIdListL()); + } + + return err; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::PrintServerIdList() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::PrintServerIdList() +{ + for ( TInt i(0); i < iServerIdList.Count(); i++) + { + TPtrC8 ptr = *iServerIdList[i]; + + RDEBUG8_2("CPolicyStorage::PrintServerIdList() Server id: (%S)", &ptr); + } +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::SaveServerIdList() +// ----------------------------------------------------------------------------- +// +TBool CPolicyStorage::IsServerIdValid( const TDesC8& aServerId) +{ + for ( TInt i(0); i < iServerIdList.Count(); i++) + { + if ( *(iServerIdList[i]) == aServerId) + { + return ETrue; + } + } + + return EFalse; +} + + +// ----------------------------------------------------------------------------- +// CPolicyStorage::SaveServerIdList() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::SaveServerIdListL() +{ + __UHEAP_MARK; + + //Open file stream. RFile ownership changes for CDirectFileStore + RFile file; + CleanupClosePushL( file); + User::LeaveIfError( file.Replace( iRFs, KServerIdFileTmp, EFileWrite)); + + CDirectFileStore * directFileStore = CDirectFileStore::NewL( file); + CleanupStack::Pop( &file); + CleanupStack::PushL( directFileStore); + + //setup write stream + directFileStore->SetTypeL( TUidType(KDirectFileStoreLayoutUid, KNullUid, KPolicyEngineRepositoryID)) ; + + RStoreWriteStream rootStream ; + TStreamId rootStreamId = rootStream.CreateLC(*directFileStore) ; + + //Externalize + TInt32 count = iServerIdList.Count(); + rootStream << count; + + for ( TInt i(0); i < count; i++) + { + rootStream << *(iServerIdList[i]); + } + + rootStream.CommitL(); + + directFileStore->SetRootL(rootStreamId); + directFileStore->CommitL(); + + //destroy + CleanupStack::PopAndDestroy( 2, directFileStore); + + __UHEAP_MARKEND; +} + +// ----------------------------------------------------------------------------- +// CPolicyStorage::LoadServerIdList() +// ----------------------------------------------------------------------------- +// +void CPolicyStorage::LoadServerIdListL() +{ + RDEBUG("CPolicyStorage: LoadServerIdListL()"); + + RFile file; + iServerIdList.ResetAndDestroy(); + + //Open file + TInt err = file.Open( iRFs, KServerIdFile, EFileRead); + + if ( err == KErrNotFound) + { + RDEBUG("CPolicyStorage: ServerID file not found!"); + return; + } + + User::LeaveIfError( err); + + //Open file stream + CDirectFileStore* directFileStore = CDirectFileStore::FromLC ( file); + TStreamId rootStreamId = directFileStore->Root() ; + + //setup read stream + RStoreReadStream rootStream ; + rootStream.OpenLC( *directFileStore, rootStreamId); + + //Internalize + TInt32 count; + rootStream >> count; + + for ( TInt i(0); i < count; i++) + { + HBufC8 * buf = HBufC8::NewLC( rootStream, 200); + iServerIdList.AppendL( buf); + CleanupStack::Pop( buf); + } + + PrintServerIdList(); + + CleanupStack::PopAndDestroy( 2, directFileStore); +} + + + +// ----------------------------------------------------------------------------- +// TElementReserver::TElementReserver() +// ----------------------------------------------------------------------------- +// + +TElementReserver::TElementReserver() + : iElement( NULL), iElements( NULL), iElementList( NULL) + { + } + +// ----------------------------------------------------------------------------- +// TElementReserver::TElementReserver() +// ----------------------------------------------------------------------------- +// + +TElementReserver::TElementReserver( CElementBase * aElement) + : iElement( aElement), iElements( NULL), iElementList( NULL) + { + //reserve element + aElement->ReserveElement(); + } + +// ----------------------------------------------------------------------------- +// TElementReserver::TElementReserver() +// ----------------------------------------------------------------------------- +// + +TElementReserver::TElementReserver( RElementContainer* aElements) + : iElement( NULL), iElements( aElements), iElementList( NULL) + { + //Reserver all elements in element list + for (TInt i(0); i < iElements->Count(); i++) + { + (*iElements)[i]->iElement->ReserveElement(); + } + } + +// ----------------------------------------------------------------------------- +// TElementReserver::~TElementReserver() +// ----------------------------------------------------------------------------- +// + +TElementReserver::~TElementReserver() + { + DoRelease(); + } + +// ----------------------------------------------------------------------------- +// TElementReserver::ReserveL() +// ----------------------------------------------------------------------------- +// + +void TElementReserver::ReserveL( CElementBase* aElement) +{ + //create new element list if needed + if (!iElementList) + { + iElementList = new (ELeave) RElementList(); + } + + //add element to list and reserve it + iElementList->AppendL( aElement); + aElement->ReserveElement(); +} + +// ----------------------------------------------------------------------------- +// TElementReserver::DoRelease() +// ----------------------------------------------------------------------------- +// + + +void TElementReserver::Release() + { + } + + +void TElementReserver::DoRelease() +{ + //release eleements... + if ( iElement ) + { + iElement->ReleaseElement(); + } + else if ( iElements ) + { + for (TInt i(0); i < iElements->Count(); i++) + { + (*iElements)[i]->iElement->ReleaseElement(); + } + } + else if ( iElementList) + { + for (TInt i(0); i < iElementList->Count(); i++) + { + (*iElementList)[i]->ReleaseElement(); + } + + iElementList->Close(); + delete iElementList; + iElementList = NULL; + } +} +