--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/centralrepository/cenrepsrv/srvsubsess.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1374 @@
+// Copyright (c) 2006-2009 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:
+//
+
+#include "srvreqs.h"
+#include "backup.h"
+#include "srvsubsess.h"
+#include "log.h"
+#include "centralrepositoryinternal.h"
+#include <e32def_private.h>
+
+using namespace NCentralRepositoryConstants;
+
+CServerSubSession::CServerSubSession(CServerSession* aSession)
+ : iSession(aSession), iInitialised(EFalse)
+ {
+ }
+
+CServerSubSession::~CServerSubSession()
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("~CServerSubSession() UID: 0x%x\n",uid.iUid);
+#endif
+
+ iRepository.Close();
+ iFindResult.Close();
+ iInitialised = EFalse;
+ }
+
+// if session ServiceL Leaves, execution resumes in this method.
+// this allows us to panic clients using bad descriptors, to deal with OOM conditions
+// and to fail transactions with the correct reason: OOM etc.
+void CServerSubSession::ServiceError(TInt aError)
+ {
+ // ensure any transaction is failed for the reason aError
+ iRepository.FailTransaction(aError, KUnspecifiedKey);
+ }
+
+TInt CServerSubSession::ServiceL(const RMessage2& aMessage)
+ {
+ const TClientRequest msg(aMessage);
+
+ struct SAction
+ {
+ TServerRequest req;
+ TInt (CServerSubSession::*groupFuncL)(const TClientRequest&, TServerFunc);
+ TServerFunc funcL;
+ };
+
+ static const SAction actionTable[] =
+ {
+ {EInitialise, &CServerSubSession::GeneralOperationsL, &CServerSubSession::InitialiseL},
+ {ECreateInt, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateIntL},
+ {ECreateReal, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateRealL},
+ {ECreateString, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateStringL},
+ {EDelete, &CServerSubSession::WriteOperationsL, &CServerSubSession::DeleteL},
+ {EGetInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetIntL},
+ {ESetInt, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetIntL},
+ {EGetReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetRealL},
+ {ESetReal, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetRealL},
+ {EGetString, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetStringL},
+ {ESetString, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetStringL},
+ {EFind, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindL},
+ {EFindEqInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqIntL},
+ {EFindEqReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqRealL},
+ {EFindEqString, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqStringL},
+ {EFindNeqInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqIntL},
+ {EFindNeqReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqRealL},
+ {EFindNeqString, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqStringL},
+ {EGetFindResult, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetFindResultL},
+ {ENotifyRequestCheck, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyRequestCheck},
+ {ENotifyRequest, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyRequest},
+ {ENotifyCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyCancel},
+ {ENotifyCancelAll, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyCancelAll},
+ {EGroupNotifyRequest, &CServerSubSession::GeneralOperationsL, &CServerSubSession::GroupNotifyRequest},
+ {EGroupNotifyCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::GroupNotifyCancel},
+ {EReset, &CServerSubSession::ResetOperationsL, &CServerSubSession::ResetL},
+ {EResetAll, &CServerSubSession::ResetOperationsL, &CServerSubSession::ResetAllL},
+ {ETransactionStart, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionStart},
+ {ETransactionCommit, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionCommitL},
+ {ETransactionCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionCancel},
+ {EMove, &CServerSubSession::WriteOperationsL, &CServerSubSession::MoveL},
+ {ETransactionState, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionStateL},
+ {ETransactionFail, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionFail},
+ {EDeleteRange, &CServerSubSession::WriteOperationsL, &CServerSubSession::DeleteRangeL},
+ {EGetMeta, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetMeta}
+ };
+
+#ifdef SRVSUBSESS_TRACE
+ const TPtrC actionTableNames[] =
+ {
+ _L("EInitialize"),
+ _L("ECreateInt"),
+ _L("ECreateReal"),
+ _L("ECreateString"),
+ _L("EDelete"),
+ _L("EGetInt"),
+ _L("ESetInt"),
+ _L("EGetReal"),
+ _L("ESetReal"),
+ _L("EGetString"),
+ _L("ESetString"),
+ _L("EFind"),
+ _L("EFindEqInt"),
+ _L("EFindEqReal"),
+ _L("EFindEqString"),
+ _L("EFindNeqInt"),
+ _L("EFindNeqReal"),
+ _L("EFindNeqString"),
+ _L("EGetFindResult"),
+ _L("ENotifyRequestCheck"),
+ _L("ENotifyRequest"),
+ _L("ENotifyCancel"),
+ _L("ENotifyCancelAll"),
+ _L("EGroupNotifyRequest"),
+ _L("EGroupNotifyCancel"),
+ _L("EReset"),
+ _L("EResetAll"),
+ _L("ETransactionStart"),
+ _L("ETransactionCommit"),
+ _L("ETransactionCancel"),
+ _L("EMove"),
+ _L("ETransactionState"),
+ _L("ETransactionFail"),
+ _L("EDeleteRange"),
+ _L("EGetMeta")
+ };
+#endif
+
+ TInt r;
+ TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
+
+ __ASSERT_ALWAYS(iInitialised || fn==EInitialise, PanicClient(ESessionNotInitialised, msg));
+ // In this assert we use (ELastInTable - 1) rather than ELastInTable because EClose is handled in the session
+ // rather than the subsession, consiquently the actionTable array is one element shorter than ELastInTable
+ __ASSERT_ALWAYS((fn < (ELastInTable)) && (fn >= EInitialise), PanicClient(EBadMessageNumber, msg));
+
+ if (EInitialise != fn)
+ {
+ iRepository.AccessRepositoryL();
+ }
+#ifdef SRVSUBSESS_TRACE
+
+ if (EInitialise != fn)
+ {
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::ServiceL - UID: 0x%x %S\n",uid.iUid,&actionTableNames[fn]);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::ServiceL - UID: 0x?? %S\n",&actionTableNames[fn]);
+ }
+
+#endif
+ // plus need to check we are initialised
+ // this comment removes a false positive from the coverity output. if fn >= ELastInTable then this code
+ // will assert (see above). but coverity doesn't consider this and therefore complains that there is a
+ // posibility that actionTable could be indexed beyond it's length
+ //coverity[overrun-local]
+ r = (this->*actionTable[fn].groupFuncL)(aMessage, actionTable[fn].funcL);
+
+ return r;
+ }
+
+//method allows transactions and notify requests to get through during backup/restore
+//process to prevent them from being blocked.
+//Transactions being blocked would lead clients to be panicked
+//if they were trying to open a second transaction in the same session.
+// Notify cancels must be allowed through because they must always succeed.
+TInt CServerSubSession::GeneralOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
+ {
+ ASSERT(aFuncL != NULL);
+ return (this->*aFuncL)(aMessage);
+ }
+
+// method allows read operations to share transaction-related tasks.
+// Read operations are allowed only during backup process.
+// During restore it fails transactions with KErrLocked and returns KErrAbort
+// and if it is a standalone read oparation it rejects it with KErrServerBusy.
+TInt CServerSubSession::ReadOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
+ {
+ TInt backupStatus = CRepositoryBackupClient::GetBackupStatus();
+
+ if (iRepository.IsInFailedTransaction())
+ {
+ return KErrAbort;
+ }
+ else if (iRepository.IsInTransaction() && (backupStatus == ERestoreInProgress) )
+ {
+ iRepository.FailTransaction(KErrLocked,KUnspecifiedKey);
+ return KErrAbort;
+ }
+ else if (backupStatus == ERestoreInProgress)
+ {
+ return KErrServerBusy;
+ }
+
+ ASSERT(aFuncL != NULL);
+ return (this->*aFuncL)(aMessage);
+ }
+
+// method allows write operations to share transaction-related tasks
+// All write operations are not allowed either during backup or restore process.
+// If backup or restore is in progress it fails transaction with KErrLocked,
+// returns KErrAbort or if it is a standalone operation it returns KErrServerBusy.
+TInt CServerSubSession::WriteOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
+ {
+ TInt backupStatus = CRepositoryBackupClient::GetBackupStatus();
+
+ if (iRepository.IsInFailedTransaction())
+ {
+ return KErrAbort;
+ }
+ else if (iRepository.IsInTransaction() && (backupStatus != ENoBackupActivty) )
+ {
+ iRepository.FailTransaction(KErrLocked,KUnspecifiedKey);
+ return KErrAbort;
+ }
+ else if (backupStatus != ENoBackupActivty)
+ {
+ return KErrServerBusy;
+ }
+
+ // if not already in a transaction, create a temporary concurrent read/write transaction
+ const TBool tempTransaction = !iRepository.IsInTransaction();
+ if (tempTransaction)
+ {
+ // concurrent read/write transaction is guaranteed to start
+ iRepository.StartTransaction(EConcurrentReadWriteTransaction);
+ // to protect against Leaves:
+ iRepository.CleanupCancelTransactionPushL();
+ }
+ else
+ {
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ // must be a read/write transaction to continue
+ iRepository.AttemptPromoteTransactionToReadWrite();
+ // Note we don't check the return value of the above and return it here.
+ // Instead we call the next level write function and expect it to have the
+ // following code:
+ // if (iRepository.IsInActiveReadTransaction())
+ // {
+ // return iRepository.FailTransaction(KErrLocked, key);
+ // }
+ // this ensures CommitTransaction reports the failing key.
+ }
+ // Note ServiceError will fail the transaction if write operation leaves
+ }
+
+ // call the server function
+ ASSERT(aFuncL != NULL);
+ TInt result = (this->*aFuncL)(aMessage);
+
+ // commit the temporary transaction
+ if (tempTransaction)
+ {
+ CleanupStack::Pop(); // remove cleanup item from earlier
+ // absorb result and keyInfo from commit of temporary transaction
+ TUint32 tempKeyInfo;
+ User::LeaveIfError(iRepository.CommitTransaction(tempKeyInfo));
+ }
+ return result;
+ }
+
+TInt CServerSubSession::ResetOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
+ {
+ // reset operations are not currently supported in transactions
+ if (iRepository.IsInTransaction())
+ {
+ // fail transaction otherwise client may be misled to believe operation worked
+ return iRepository.FailTransaction(KErrNotSupported, KUnspecifiedKey);
+ }
+ //can't reset when backup or restore is in progress
+ else if (CRepositoryBackupClient::GetBackupStatus() != ENoBackupActivty)
+ {
+ return KErrServerBusy;
+ }
+ ASSERT(aFuncL != NULL);
+ return (this->*aFuncL)(aMessage);
+ }
+
+TInt CServerSubSession::InitialiseL(const TClientRequest& aMessage)
+ {
+ __ASSERT_ALWAYS(!iInitialised,
+ PanicClient(ESessionAlreadyInitialised, aMessage));
+ // We let anyone to open a repository...
+ // it's not considered a breach of security to let people know
+ // that a repository is there...
+ TUid uid = TUid::Uid(aMessage.Int0());
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::InitialiseL UID: 0x%x\n",uid.iUid);
+
+ // Calls iObserver->AccessL internally
+ iRepository.OpenL(uid, iNotifier);
+
+ iInitialised = ETrue;
+
+ return KErrNone;
+ }
+
+TInt CServerSubSession::CreateIntL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSubSession::CreateIntL - Attempt made to create a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TInt val = aMessage.Int1();
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::CreateIntL UID: 0x%x Key=0x%x\n",uid.iUid,key);
+#endif
+
+ TInt r = iRepository.TransactionCreateL(key, val, NULL);
+
+ return r;
+ }
+
+TInt CServerSubSession::CreateRealL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::CreateRealL - Attempt made to create a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TReal val;
+ TPckg<TReal> p(val);
+ aMessage.ReadL(1, p);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::CreateRealL UID: 0x%x Key=0x%x\n",uid.iUid,key);
+#endif
+ TInt r = iRepository.TransactionCreateL(key, val, NULL);
+
+ return r;
+ }
+
+TInt CServerSubSession::CreateStringL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ // sometime: must ensure bad descriptor results in client being panic'd
+
+ // check for descriptor-too-long was previously on the client side,
+ // hence test code expects KErrArgument response before KErrPermissionDenied
+ TInt length = aMessage.GetDesLengthL(1);
+ if (length > KMaxBinaryLength)
+ {
+ return iRepository.FailTransaction(KErrArgument, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::CreateStringL - Attempt made to create a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TBuf8<KMaxBinaryLength> val;
+ aMessage.ReadL(1, val);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::CreateStringL UID: 0x%x Key=0x%x\n",uid.iUid,key);
+#endif
+
+ TInt error = iRepository.TransactionCreateL(key, val, NULL);
+
+ return error;
+ }
+
+TInt CServerSubSession::DeleteL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::DeleteL - Attempt made to delete a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::DeleteL UID: 0x%x Key=0x%x\n",uid.iUid,key);
+#endif
+
+ TInt r = iRepository.TransactionDeleteL(key);
+
+ return r;
+ }
+
+TInt CServerSubSession::GetIntL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetIntL - Attempt made to read a setting")))
+ return KErrPermissionDenied;
+
+ TInt val;
+ TInt error = iRepository.Get(key, val);
+
+ if (error == KErrNone)
+ {
+ TPckg<TInt> p(val);
+ aMessage.WriteL(1, p);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GetIntL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::GetIntL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::SetIntL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetIntL - Attempt made to write a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TInt val = aMessage.Int1();
+ TInt error = iRepository.TransactionSetL(key, val);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::SetIntL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::SetIntL **Failure** UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+#endif
+ return error;
+ }
+
+TInt CServerSubSession::GetRealL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetRealL - Attempt made to read a setting")))
+ return KErrPermissionDenied;
+
+ TReal val;
+ TInt error = iRepository.Get(key, val);
+
+ if(error==KErrNone)
+ {
+ TPckg<TReal> p(val);
+ aMessage.WriteL(1, p);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GetRealL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::GetRealL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+ return error;
+ }
+
+TInt CServerSubSession::SetRealL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetRealL - Attempt made to write a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TReal val;
+ TPckg<TReal> p(val);
+ aMessage.ReadL(1, p);
+
+ TInt error = iRepository.TransactionSetL(key, val);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::SetRealL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::SetRealL **Failure** UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::GetStringL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetStringL - Attempt made to read a setting")))
+ return KErrPermissionDenied;
+
+ TBuf8<KMaxBinaryLength> val;
+
+ TInt error = iRepository.Get(key, val);
+
+ if(error==KErrNone)
+ {
+ TInt clientMaxDescriptorLength;
+ TPckg<TInt> pInt (clientMaxDescriptorLength);
+ aMessage.Read(2, pInt);
+
+ TInt descriptorLength = val.Length();
+
+ // write the descriptor length to aMessage
+ TPckg<TInt> p(descriptorLength);
+ error = aMessage.Write(2, p);
+
+ if(error==KErrNone)
+ {
+ if(descriptorLength > clientMaxDescriptorLength)
+ {
+ // if it is, fill the descriptor up to its max length
+ error = aMessage.Write(1, val.Left(clientMaxDescriptorLength));
+
+ // if client-side descriptor is too small to take the value, which it is, returns KErrOverflow
+ if(error == KErrNone)
+ {
+ error = KErrOverflow;
+ }
+ }
+ else
+ {
+ error = aMessage.Write(1, val);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GetStringL UID: 0x%x Key=0x%x Value=%S\n",uid.iUid,key,&val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::GetStringL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+ }
+
+ // if error is KErrOverflow should not failing transaction
+ if ((error != KErrNone) && (error != KErrOverflow))
+ {
+ // ServiceError will fail transaction
+ User::Leave(error);
+ }
+ }
+ return error;
+ }
+
+TInt CServerSubSession::SetStringL(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ return iRepository.FailTransaction(KErrLocked, key);
+ }
+
+ // check for descriptor-too-long was previously on the client side,
+ // hence test code expects KErrArgument response before KErrPermissionDenied
+ TInt length = aMessage.GetDesLengthL(1);
+ if (length > KMaxBinaryLength)
+ {
+ return iRepository.FailTransaction(KErrArgument, key);
+ }
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetStringL - Attempt made to write a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TBuf8<KMaxBinaryLength> val;
+ aMessage.ReadL(1, val); // no error if too long, truncated instead
+
+ TInt error = iRepository.TransactionSetL(key, val);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::SetStringL UID: 0x%x Key=0x%x Value=%S\n",uid.iUid,key,&val);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::SetStringL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::GetMeta(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetMeta - Attempt made to read a setting")))
+ return KErrPermissionDenied;
+
+ TUint32 meta;
+ TInt error = iRepository.GetMeta(key, meta);
+
+ if (error == KErrNone)
+ {
+ TPckg<TUint32> p(meta);
+ error = aMessage.Write(1, p);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GetMeta UID: 0x%x Key=0x%x Meta=0x%x\n",uid.iUid,key,meta);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::GetMeta **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::FindL(const TClientRequest& aMessage)
+ {
+ // PLATSEC NOTE:
+ // There are no read policy checks on FindL.
+ // Client is returned the full list of keys whether they have read permission or not.
+ // They were able to find this out by brute force using FindL on single setting ranges
+ // anyway (because it would return KErrPermissionDenied if it existed, KErrNotFound otherwise).
+ // Revealing the existence of settings is not considered a breach of security.
+ TKeyFilter keyIdentifier;
+ TPckg<TKeyFilter> p(keyIdentifier);
+ aMessage.Read(0, p);
+ // we reset results first since we do not police GetResult
+ // and this way we can guarantee no results are available if access not granted
+ iFindResult.Reset();
+
+ RArray<TUint32> settingsToSend;
+ CleanupClosePushL(settingsToSend);
+
+ TInt error=KErrNone;
+ TRAP(error,iRepository.FindL(keyIdentifier.iPartialId, keyIdentifier.iIdMask,settingsToSend,KCentRepFindBufSize,iFindResult));
+ if (error==KErrNone)
+ {
+ //write back the total number of settingsFound;
+ TInt numSettings=settingsToSend.Count()+iFindResult.Count();
+ TPtrC8 count(reinterpret_cast<TUint8*>(&numSettings),sizeof(TUint32));
+ error=aMessage.Write(2,count);
+ if (error==KErrNone)
+ {
+ TPtrC8 p(reinterpret_cast<TUint8*>(&(settingsToSend[0])), (settingsToSend.Count())*sizeof(TUint32));
+ error=aMessage.Write(2,p,4);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE4("CServerSubSession::FindL UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
+ keyIdentifier.iIdMask,&p);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE4("CServerSubSession::FindL (failed write) UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
+ keyIdentifier.iIdMask,&p);
+ }
+#endif
+ }
+ CleanupStack::PopAndDestroy(); //settingsToSend
+
+ if (error != KErrNone)
+ {
+ iFindResult.Reset();
+ if ((error != KErrNone) && (error != KErrNotFound))
+ {
+ // ServiceError will fail transaction
+ User::Leave(error);
+ }
+ }
+ return error;
+ }
+
+TInt CServerSubSession::FindEqIntL(const TClientRequest& aMessage)
+ {
+ TInt val = aMessage.Int1();
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val);
+ }
+
+TInt CServerSubSession::FindEqRealL(const TClientRequest& aMessage)
+ {
+ TReal val;
+ TPckg<TReal> p(val);
+ aMessage.Read(1, p);
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val);
+ }
+
+TInt CServerSubSession::FindEqStringL(const TClientRequest& aMessage)
+ {
+ TBuf8<KMaxBinaryLength> val;
+ aMessage.ReadL(1, val); // no error if too long, truncated instead
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val);
+ }
+
+TInt CServerSubSession::FindNeqIntL(const TClientRequest& aMessage)
+ {
+ TInt val = aMessage.Int1();
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val, ENotEqual);
+ }
+
+TInt CServerSubSession::FindNeqRealL(const TClientRequest& aMessage)
+ {
+ TReal val;
+ TPckg<TReal> p(val);
+ aMessage.Read(1, p);
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val, ENotEqual);
+ }
+
+TInt CServerSubSession::FindNeqStringL(const TClientRequest& aMessage)
+ {
+ TBuf8<KMaxBinaryLength> val;
+ aMessage.ReadL(1, val); // no error if too long, truncated instead
+ // PlatSec check done in FindValueL
+ return FindValueL(aMessage, val, ENotEqual);
+ }
+
+template <class T>
+TInt CServerSubSession::FindValueL(const TClientRequest& aMessage, const T& aVal,TComparison aComparison)
+ {
+ // IMPORTANT PLATSEC NOTE:
+ // MUST return KErrPermissionDenied if read policy of ANY setting in the search range not passed.
+ // MUST NOT merely check read policy of matching entries, otherwise it is possible to determine
+ // secret values by brute force: Using single-value ranges, cycling through the possible values and
+ // confirming a match when it returns KErrPermissionDenied rather than KErrNotFound.
+ TKeyFilter keyIdentifier;
+ TPckg<TKeyFilter> p(keyIdentifier);
+ aMessage.Read(0, p);
+ // we reset results first since we do not police GetResult
+ // and this way we can guarantee no results are available if access not granted
+ iFindResult.Reset();
+ RSettingPointerArray settings;
+ CleanupClosePushL(settings);
+ TInt error = iRepository.FindSettings(keyIdentifier.iPartialId, keyIdentifier.iIdMask, settings);
+ if (error == KErrNone)
+ {
+ //perform the read checking policies first
+ TUint32 dummyErrId;
+ error=iRepository.CheckPermissions(settings,aMessage,
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::FindValueL - Attempt made to search settings"),ETrue,dummyErrId);
+ if (error==KErrPermissionDenied)
+ iFindResult.Reset();
+
+ //now if everything passes, do perform the FindValue
+ if (error==KErrNone)
+ {
+ TRAP(error,iRepository.FindCompareL(settings,aVal,aComparison,iFindResult));
+ if (error==KErrNone)
+ {
+ const TInt numSettings = iFindResult.Count();
+ const TInt numInitial = numSettings > KCentRepFindBufSize ? KCentRepFindBufSize : numSettings;
+ RArray<TUint32> settingsToSend;
+ CleanupClosePushL(settingsToSend);
+
+ //reserve memory for everything that needs to be added to the array
+ settingsToSend.Reserve(numInitial);
+
+ //first append the number of found settings
+ settingsToSend.AppendL(numSettings);
+
+ //now append up to KCentRepFindBufSize settings
+ for(TInt i = 0; i < numInitial; i++)
+ {
+ settingsToSend.AppendL(iFindResult[0]);
+ iFindResult.Remove(0);
+ }
+
+ if(iFindResult.Count() == 0)
+ {
+ iFindResult.Reset();
+ }
+
+ //send:
+ //1 - the count of total settings found
+ //2 - the settings that fit in the buffer allocated for the first IPC
+ TPtrC8 p(reinterpret_cast<TUint8*>(&(settingsToSend[0])), (numInitial+1)*sizeof(TUint32));
+ error = aMessage.Write(2, p);
+
+ #ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE4("CServerSubSession::FindValueL UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
+ keyIdentifier.iIdMask,&p);
+ #endif
+ CleanupStack::PopAndDestroy(); //settingsToSend
+ }
+ }
+ }
+ if ((error != KErrNone) && (error != KErrNotFound) && (error != KErrPermissionDenied))
+ {
+ iFindResult.Reset();
+ CleanupStack::PopAndDestroy(); //settings
+
+ // ServiceError will fail transaction
+ User::Leave(error);
+ }
+#ifdef SRVSUBSESS_TRACE
+ else
+ {
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE3("CServerSubSession::FindValueL **Failure** UID: 0x%x Key=0x%x Mask=0x%x\n",uid.iUid,keyIdentifier.iPartialId,
+ keyIdentifier.iIdMask);
+ }
+#endif
+
+ CleanupStack::PopAndDestroy(); //settings
+ return error;
+ }
+
+TInt CServerSubSession::GetFindResultL(const TClientRequest& aMessage)
+ {
+ TInt n = iFindResult.Count();
+ if (n==0)
+ {
+ return KErrNotFound;
+ }
+
+ TPtrC8 p(reinterpret_cast<TUint8*>(&(iFindResult[0])), n*sizeof(TUint32));
+ TInt error = aMessage.Write(0, p);
+ // Free up iFindResult - it's no longer needed
+ iFindResult.Reset();
+ // ServiceError will fail transaction
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::GetFindResultL UID: 0x%x Value=%S\n",uid.iUid,&p);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::GetFindResultL **Failure** UID: 0x%x\n",uid.iUid);
+ }
+#endif
+ return User::LeaveIfError(error);
+ }
+
+TInt CServerSubSession::NotifyRequestCheck(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::NotifyRequestCheck - Attempt made to check Notify request")))
+ return KErrPermissionDenied;
+
+ TInt error = iRepository.GetPersistentSetting(key) ? KErrNone : KErrNotFound;
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::NotifyRequestCheck UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::NotifyRequestCheck **Failure** UID: 0x%x\n",uid.iUid);
+ }
+#endif
+ return error;
+ }
+
+TInt CServerSubSession::NotifyRequest(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::NotifyRequest - Attempt made to register for Notify")))
+ return KErrPermissionDenied;
+ TInt error = iNotifier.AddRequest(key, aMessage);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::NotifyRequest UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::NotifyRequest **Failure** UID: 0x%x\n",uid.iUid);
+ }
+#endif
+
+ return (error == KErrNone) ? KDontCompleteMessage : error;
+ }
+
+TInt CServerSubSession::NotifyCancel(const TClientRequest& aMessage)
+ {
+ TUint32 key = aMessage.Int0();
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::NotifyCancel UID: 0x%x Key=0x%x\n",uid.iUid,key);
+#endif
+
+ return iNotifier.CancelRequest(key);
+ }
+
+TInt CServerSubSession::NotifyCancelAll(const TClientRequest& /*aMessage*/)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::NotifyCancelAll UID: 0x%x\n",uid.iUid);
+#endif
+ return iNotifier.CancelAllRequests();
+ }
+
+TInt CServerSubSession::GroupNotifyRequest(const TClientRequest& aMessage)
+ {
+ TUint32 partialId = aMessage.Int0();
+ TUint32 idMask = aMessage.Int1();
+ RSettingPointerArray settings;
+ TInt error = iRepository.FindPersistentSettings(partialId, idMask, settings);
+ if (error == KErrNone)
+ {
+ TUint32 dummyErrId;
+ error = iRepository.CheckPermissions(settings, aMessage,
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GroupNotifyRequest - Attempt made to register for group Notify"),ETrue,dummyErrId);
+ }
+ settings.Reset();
+ if (error != KErrNone)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest **Failure** UID: 0x%x\n PartialId=0x%x Mask=0x%x\n",
+ uid.iUid,partialId,idMask);
+#endif
+
+ return KErrPermissionDenied;
+ }
+
+ error = iNotifier.AddRequest(partialId, idMask, aMessage);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest UID: 0x%x PartialId=0x%x Mask=0x%x\n",
+ uid.iUid,partialId,idMask);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest **Failure** UID: 0x%x PartialId=0x%x Mask=0x%x\n",uid.iUid,
+ partialId,idMask);
+ }
+#endif
+
+ return error==KErrNone ? KDontCompleteMessage : error;
+ }
+
+TInt CServerSubSession::GroupNotifyCancel(const TClientRequest& aMessage)
+ {
+ TKeyFilter keyIdentifier;
+ TPckg<TKeyFilter> p(keyIdentifier);
+ aMessage.Read(0, p);
+
+ RSettingPointerArray settings;
+ TInt error = iRepository.FindPersistentSettings(keyIdentifier.iPartialId, keyIdentifier.iIdMask, settings);
+ settings.Reset();
+ if (error != KErrNone)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel **Failure** UID: 0x%x\n PartialId=0x%x Mask=0x%x\n",
+ uid.iUid,keyIdentifier.iPartialId, keyIdentifier.iIdMask);
+#endif
+ return error;
+ }
+
+ error = iNotifier.CancelRequest(keyIdentifier.iPartialId, keyIdentifier.iIdMask);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel UID: 0x%x PartialId=0x%x Mask=0x%x\n",
+ uid.iUid,keyIdentifier.iPartialId, keyIdentifier.iIdMask);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel **Failure** UID: 0x%x PartialId=0x%x Mask=0x%x\n",uid.iUid,
+ keyIdentifier.iPartialId, keyIdentifier.iIdMask);
+ }
+#endif
+
+
+ return error;
+ }
+
+TInt CServerSubSession::ResetL(const TClientRequest& aMessage)
+ {
+ // individual setting reset is not yet supported in transactions
+ ASSERT(!iRepository.IsInTransaction());
+ TUint32 key = aMessage.Int0();
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::ResetL - Attempt made to reset a setting")))
+ return iRepository.FailTransaction(KErrPermissionDenied, key);
+
+ TInt error = iRepository.ResetL(key);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::ResetL UID: 0x%x Key=0x%x\n",
+ uid.iUid,key);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::ResetL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::ResetAllL(const TClientRequest& aMessage)
+ {
+ // factory reset operation is not yet supported in transactions
+ ASSERT(!iRepository.IsInTransaction());
+ if(KErrNone != CheckPolicy(aMessage,iRepository.GetDefaultWriteAccessPolicy(),
+ __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::ResetAllL - Attempt made to reset repository")))
+ return KErrPermissionDenied;
+
+ iNotifier.IdReportingOff();
+ TInt error = iRepository.ResetAllL();
+ iNotifier.IdReportingOn();
+
+ if (error == KErrNone)
+ {
+ iRepository.CommitChangesL(); // temporary measure
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::ResetAllL UID: 0x%x\n",uid.iUid);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::ResetAllL **Failure** UID: 0x%x\n",uid.iUid);
+ }
+#endif
+
+ return error;
+ }
+
+TInt CServerSubSession::MoveL(const TClientRequest& aMessage)
+ {
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ TKeyFilter keyIdentifier;
+ TPckg<TKeyFilter> p(keyIdentifier);
+ aMessage.Read(0, p);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE3("CServerSubSession::MoveL **Failure** In Transaction UID: 0x%x PartialId=0x%x Mask=0x%x\n",
+ uid.iUid,keyIdentifier.iPartialId,keyIdentifier.iIdMask);
+#endif
+
+ // could not promote to read/write: fail & give the source partialKey as the error key
+ return iRepository.FailTransaction(KErrLocked, keyIdentifier.iPartialId);
+ }
+
+ TUint32 errorKey = KUnspecifiedKey;
+ TInt result = iRepository.TransactionMoveL(aMessage, errorKey);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (result == KErrNone)
+ {
+ __SRVSUBSESS_TRACE1("CServerSubSession::MoveL UID: 0x%x\n",uid.iUid);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::MoveL **Failure** UID: 0x%x Error=%d\n",uid.iUid,errorKey);
+ }
+#endif
+
+ if (result != KErrNone && result!=KErrNotFound)
+ {
+ iRepository.FailTransaction(result, errorKey);
+ TPckg<TUint32> p(errorKey);
+ aMessage.WriteL(2, p);
+ }
+ return result;
+ }
+
+TInt CServerSubSession::TransactionStart(const TClientRequest& aMessage)
+ {
+ // check if we are already in a transaction
+ TBool inTransactionAlready = iRepository.IsInTransaction();
+
+ // panic client if attempting to start a transaction when already in one
+ __ASSERT_ALWAYS(!inTransactionAlready, PanicClient(EStartAlreadyInTransaction, aMessage));
+
+ // if the client has been panicked then we don't want to continue.
+ // client session will already have been taken down so don't want to complete the message
+ if (inTransactionAlready)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::TransactionStart **Failure** already in transaction UID=0x%x\n",uid.iUid);
+#endif
+
+ return KDontCompleteMessage;
+ }
+
+ const TInt mode = aMessage.Int0();
+
+ TInt error = iRepository.StartTransaction(mode);
+
+#ifdef SRVSUBSESS_TRACE
+
+ TUid uid = RepositoryUid();
+
+ // mode strings match transstate.h - if that is updated, this should be as well.
+ const TPtrC modeStrings[] =
+ {
+ _L("ENoTransaction"), // 0
+ _L("EReadTransaction"), // EReadBit 1
+ _L("EConcurrentReadWriteTransaction"), // EWriteBit 2
+ _L("EReadWriteTransaction|EAllTransactionBits"), //EReadBit | EWriteBit 3
+ _L("EFailedBit") // 4
+ };
+
+ if (error == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::TransactionStart UID: 0x%x Mode=%d (%S)\n",uid.iUid,mode,&modeStrings[mode]);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::TransactionStart **Failure** UID: 0x%x Mode=%d (%S)\n",uid.iUid,mode,&modeStrings[mode]);
+ }
+#endif
+
+ return error;
+ }
+
+// serves as both rollback and async cancel
+TInt CServerSubSession::TransactionCancel(const TClientRequest& /*aMessage*/)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::TransactionCancel UID: 0x%x",uid.iUid);
+#endif
+ iRepository.CancelTransaction();
+ return KErrNone;
+ }
+
+TInt CServerSubSession::TransactionCommitL(const TClientRequest& aMessage)
+ {
+ // check if we are in a transaction
+ TBool inTransaction = iRepository.IsInTransaction();
+
+ // panic client if attempting to commit a transaction when we are not in one
+ __ASSERT_ALWAYS(inTransaction, PanicClient(ECommitNotInTransaction, aMessage));
+
+ // if the client has been panicked then we don't want to continue.
+ // client session will already have been taken down so don't want to complete the message
+ if (!inTransaction)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::TransactionCommitL **Failure** In Transaction UID: 0x%x TransactionKey=%d\n",uid.iUid);
+#endif
+ return KDontCompleteMessage;
+ }
+
+ TUint32 keyInfo = KUnspecifiedKey;
+ TInt result = iRepository.CommitTransaction(keyInfo);
+
+ TPckg<TUint32> p(keyInfo);
+ aMessage.WriteL(0, p);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ if (result == KErrNone)
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::TransactionCommitL UID: 0x%x TransactionKey=%d\n",uid.iUid,keyInfo);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::TransactionCommitL **Failure** UID: 0x%x TransactionKey=%d\n",uid.iUid,keyInfo);
+ }
+#endif
+ return result;
+ }
+
+TInt CServerSubSession::DeleteRangeL(const TClientRequest& aMessage)
+ {
+ if (iRepository.IsInActiveReadTransaction())
+ {
+ // could not promote to read/write: fail & give the partialKey as the error key
+ TUint32 partialKey = aMessage.Int0();
+ return iRepository.FailTransaction(KErrLocked, partialKey);
+ }
+ TUint32 errorKey = KUnspecifiedKey;
+ TInt result = iRepository.TransactionDeleteRangeL(aMessage, errorKey);
+ if (result != KErrNone)
+ {
+ TPckg<TUint32> p(errorKey);
+ aMessage.WriteL(2, p);
+ }
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+ TUint32 partialKey = aMessage.Int0();
+ TUint32 keyMask = aMessage.Int1();
+
+ if (result == KErrNone)
+ {
+ __SRVSUBSESS_TRACE3("CServerSubSession::DeleteRangeL UID: 0x%x Key=0x%x Mask=0x%x\n",uid.iUid,partialKey,keyMask);
+ }
+ else
+ {
+ __SRVSUBSESS_TRACE2("CServerSubSession::DeleteRangeL **Failure** UID: 0x%x ErrorKey=%d\n",uid.iUid,errorKey);
+ }
+#endif
+
+ return result;
+ }
+
+TInt CServerSubSession::TransactionStateL(const TClientRequest& aMessage)
+ {
+ TInt iState = iRepository.TransactionState();
+
+ TPckg<TInt> p(iState);
+ aMessage.WriteL(0, p);
+
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE2("CServerSubSession::TransactionStateL UID: 0x%x State=%d\n",uid.iUid,iState);
+#endif
+
+ return KErrNone;
+ }
+
+TInt CServerSubSession::TransactionFail(const TClientRequest& aMessage)
+ {
+#ifdef SRVSUBSESS_TRACE
+ TUid uid = RepositoryUid();
+
+ __SRVSUBSESS_TRACE1("CServerSubSession::TransactionFail UID: 0x%x",uid.iUid);
+#endif
+
+ iRepository.FailTransaction(aMessage.Int0(), KUnspecifiedKey);
+ return KErrNone;
+ }
+
+//Check the security policy against a RMessage.
+TInt CServerSubSession::CheckPolicy(const TClientRequest& msg,
+ const TSecurityPolicy& aPolicy,
+ const char *aDiagnostic)
+ {
+ return msg.CheckPolicy(aPolicy,aDiagnostic) ? KErrNone : KErrPermissionDenied;
+ }