1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/centralrepository/cenrepsrv/srvsubsess.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1374 @@
1.4 +// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "srvreqs.h"
1.20 +#include "backup.h"
1.21 +#include "srvsubsess.h"
1.22 +#include "log.h"
1.23 +#include "centralrepositoryinternal.h"
1.24 +#include <e32def_private.h>
1.25 +
1.26 +using namespace NCentralRepositoryConstants;
1.27 +
1.28 +CServerSubSession::CServerSubSession(CServerSession* aSession)
1.29 + : iSession(aSession), iInitialised(EFalse)
1.30 + {
1.31 + }
1.32 +
1.33 +CServerSubSession::~CServerSubSession()
1.34 + {
1.35 +#ifdef SRVSUBSESS_TRACE
1.36 + TUid uid = RepositoryUid();
1.37 +
1.38 + __SRVSUBSESS_TRACE1("~CServerSubSession() UID: 0x%x\n",uid.iUid);
1.39 +#endif
1.40 +
1.41 + iRepository.Close();
1.42 + iFindResult.Close();
1.43 + iInitialised = EFalse;
1.44 + }
1.45 +
1.46 +// if session ServiceL Leaves, execution resumes in this method.
1.47 +// this allows us to panic clients using bad descriptors, to deal with OOM conditions
1.48 +// and to fail transactions with the correct reason: OOM etc.
1.49 +void CServerSubSession::ServiceError(TInt aError)
1.50 + {
1.51 + // ensure any transaction is failed for the reason aError
1.52 + iRepository.FailTransaction(aError, KUnspecifiedKey);
1.53 + }
1.54 +
1.55 +TInt CServerSubSession::ServiceL(const RMessage2& aMessage)
1.56 + {
1.57 + const TClientRequest msg(aMessage);
1.58 +
1.59 + struct SAction
1.60 + {
1.61 + TServerRequest req;
1.62 + TInt (CServerSubSession::*groupFuncL)(const TClientRequest&, TServerFunc);
1.63 + TServerFunc funcL;
1.64 + };
1.65 +
1.66 + static const SAction actionTable[] =
1.67 + {
1.68 + {EInitialise, &CServerSubSession::GeneralOperationsL, &CServerSubSession::InitialiseL},
1.69 + {ECreateInt, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateIntL},
1.70 + {ECreateReal, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateRealL},
1.71 + {ECreateString, &CServerSubSession::WriteOperationsL, &CServerSubSession::CreateStringL},
1.72 + {EDelete, &CServerSubSession::WriteOperationsL, &CServerSubSession::DeleteL},
1.73 + {EGetInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetIntL},
1.74 + {ESetInt, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetIntL},
1.75 + {EGetReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetRealL},
1.76 + {ESetReal, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetRealL},
1.77 + {EGetString, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetStringL},
1.78 + {ESetString, &CServerSubSession::WriteOperationsL, &CServerSubSession::SetStringL},
1.79 + {EFind, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindL},
1.80 + {EFindEqInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqIntL},
1.81 + {EFindEqReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqRealL},
1.82 + {EFindEqString, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindEqStringL},
1.83 + {EFindNeqInt, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqIntL},
1.84 + {EFindNeqReal, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqRealL},
1.85 + {EFindNeqString, &CServerSubSession::ReadOperationsL, &CServerSubSession::FindNeqStringL},
1.86 + {EGetFindResult, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetFindResultL},
1.87 + {ENotifyRequestCheck, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyRequestCheck},
1.88 + {ENotifyRequest, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyRequest},
1.89 + {ENotifyCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyCancel},
1.90 + {ENotifyCancelAll, &CServerSubSession::GeneralOperationsL, &CServerSubSession::NotifyCancelAll},
1.91 + {EGroupNotifyRequest, &CServerSubSession::GeneralOperationsL, &CServerSubSession::GroupNotifyRequest},
1.92 + {EGroupNotifyCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::GroupNotifyCancel},
1.93 + {EReset, &CServerSubSession::ResetOperationsL, &CServerSubSession::ResetL},
1.94 + {EResetAll, &CServerSubSession::ResetOperationsL, &CServerSubSession::ResetAllL},
1.95 + {ETransactionStart, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionStart},
1.96 + {ETransactionCommit, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionCommitL},
1.97 + {ETransactionCancel, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionCancel},
1.98 + {EMove, &CServerSubSession::WriteOperationsL, &CServerSubSession::MoveL},
1.99 + {ETransactionState, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionStateL},
1.100 + {ETransactionFail, &CServerSubSession::GeneralOperationsL, &CServerSubSession::TransactionFail},
1.101 + {EDeleteRange, &CServerSubSession::WriteOperationsL, &CServerSubSession::DeleteRangeL},
1.102 + {EGetMeta, &CServerSubSession::ReadOperationsL, &CServerSubSession::GetMeta}
1.103 + };
1.104 +
1.105 +#ifdef SRVSUBSESS_TRACE
1.106 + const TPtrC actionTableNames[] =
1.107 + {
1.108 + _L("EInitialize"),
1.109 + _L("ECreateInt"),
1.110 + _L("ECreateReal"),
1.111 + _L("ECreateString"),
1.112 + _L("EDelete"),
1.113 + _L("EGetInt"),
1.114 + _L("ESetInt"),
1.115 + _L("EGetReal"),
1.116 + _L("ESetReal"),
1.117 + _L("EGetString"),
1.118 + _L("ESetString"),
1.119 + _L("EFind"),
1.120 + _L("EFindEqInt"),
1.121 + _L("EFindEqReal"),
1.122 + _L("EFindEqString"),
1.123 + _L("EFindNeqInt"),
1.124 + _L("EFindNeqReal"),
1.125 + _L("EFindNeqString"),
1.126 + _L("EGetFindResult"),
1.127 + _L("ENotifyRequestCheck"),
1.128 + _L("ENotifyRequest"),
1.129 + _L("ENotifyCancel"),
1.130 + _L("ENotifyCancelAll"),
1.131 + _L("EGroupNotifyRequest"),
1.132 + _L("EGroupNotifyCancel"),
1.133 + _L("EReset"),
1.134 + _L("EResetAll"),
1.135 + _L("ETransactionStart"),
1.136 + _L("ETransactionCommit"),
1.137 + _L("ETransactionCancel"),
1.138 + _L("EMove"),
1.139 + _L("ETransactionState"),
1.140 + _L("ETransactionFail"),
1.141 + _L("EDeleteRange"),
1.142 + _L("EGetMeta")
1.143 + };
1.144 +#endif
1.145 +
1.146 + TInt r;
1.147 + TServerRequest fn = static_cast<TServerRequest>(aMessage.Function());
1.148 +
1.149 + __ASSERT_ALWAYS(iInitialised || fn==EInitialise, PanicClient(ESessionNotInitialised, msg));
1.150 + // In this assert we use (ELastInTable - 1) rather than ELastInTable because EClose is handled in the session
1.151 + // rather than the subsession, consiquently the actionTable array is one element shorter than ELastInTable
1.152 + __ASSERT_ALWAYS((fn < (ELastInTable)) && (fn >= EInitialise), PanicClient(EBadMessageNumber, msg));
1.153 +
1.154 + if (EInitialise != fn)
1.155 + {
1.156 + iRepository.AccessRepositoryL();
1.157 + }
1.158 +#ifdef SRVSUBSESS_TRACE
1.159 +
1.160 + if (EInitialise != fn)
1.161 + {
1.162 + TUid uid = RepositoryUid();
1.163 +
1.164 + __SRVSUBSESS_TRACE2("CServerSubSession::ServiceL - UID: 0x%x %S\n",uid.iUid,&actionTableNames[fn]);
1.165 + }
1.166 + else
1.167 + {
1.168 + __SRVSUBSESS_TRACE1("CServerSubSession::ServiceL - UID: 0x?? %S\n",&actionTableNames[fn]);
1.169 + }
1.170 +
1.171 +#endif
1.172 + // plus need to check we are initialised
1.173 + // this comment removes a false positive from the coverity output. if fn >= ELastInTable then this code
1.174 + // will assert (see above). but coverity doesn't consider this and therefore complains that there is a
1.175 + // posibility that actionTable could be indexed beyond it's length
1.176 + //coverity[overrun-local]
1.177 + r = (this->*actionTable[fn].groupFuncL)(aMessage, actionTable[fn].funcL);
1.178 +
1.179 + return r;
1.180 + }
1.181 +
1.182 +//method allows transactions and notify requests to get through during backup/restore
1.183 +//process to prevent them from being blocked.
1.184 +//Transactions being blocked would lead clients to be panicked
1.185 +//if they were trying to open a second transaction in the same session.
1.186 +// Notify cancels must be allowed through because they must always succeed.
1.187 +TInt CServerSubSession::GeneralOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
1.188 + {
1.189 + ASSERT(aFuncL != NULL);
1.190 + return (this->*aFuncL)(aMessage);
1.191 + }
1.192 +
1.193 +// method allows read operations to share transaction-related tasks.
1.194 +// Read operations are allowed only during backup process.
1.195 +// During restore it fails transactions with KErrLocked and returns KErrAbort
1.196 +// and if it is a standalone read oparation it rejects it with KErrServerBusy.
1.197 +TInt CServerSubSession::ReadOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
1.198 + {
1.199 + TInt backupStatus = CRepositoryBackupClient::GetBackupStatus();
1.200 +
1.201 + if (iRepository.IsInFailedTransaction())
1.202 + {
1.203 + return KErrAbort;
1.204 + }
1.205 + else if (iRepository.IsInTransaction() && (backupStatus == ERestoreInProgress) )
1.206 + {
1.207 + iRepository.FailTransaction(KErrLocked,KUnspecifiedKey);
1.208 + return KErrAbort;
1.209 + }
1.210 + else if (backupStatus == ERestoreInProgress)
1.211 + {
1.212 + return KErrServerBusy;
1.213 + }
1.214 +
1.215 + ASSERT(aFuncL != NULL);
1.216 + return (this->*aFuncL)(aMessage);
1.217 + }
1.218 +
1.219 +// method allows write operations to share transaction-related tasks
1.220 +// All write operations are not allowed either during backup or restore process.
1.221 +// If backup or restore is in progress it fails transaction with KErrLocked,
1.222 +// returns KErrAbort or if it is a standalone operation it returns KErrServerBusy.
1.223 +TInt CServerSubSession::WriteOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
1.224 + {
1.225 + TInt backupStatus = CRepositoryBackupClient::GetBackupStatus();
1.226 +
1.227 + if (iRepository.IsInFailedTransaction())
1.228 + {
1.229 + return KErrAbort;
1.230 + }
1.231 + else if (iRepository.IsInTransaction() && (backupStatus != ENoBackupActivty) )
1.232 + {
1.233 + iRepository.FailTransaction(KErrLocked,KUnspecifiedKey);
1.234 + return KErrAbort;
1.235 + }
1.236 + else if (backupStatus != ENoBackupActivty)
1.237 + {
1.238 + return KErrServerBusy;
1.239 + }
1.240 +
1.241 + // if not already in a transaction, create a temporary concurrent read/write transaction
1.242 + const TBool tempTransaction = !iRepository.IsInTransaction();
1.243 + if (tempTransaction)
1.244 + {
1.245 + // concurrent read/write transaction is guaranteed to start
1.246 + iRepository.StartTransaction(EConcurrentReadWriteTransaction);
1.247 + // to protect against Leaves:
1.248 + iRepository.CleanupCancelTransactionPushL();
1.249 + }
1.250 + else
1.251 + {
1.252 + if (iRepository.IsInActiveReadTransaction())
1.253 + {
1.254 + // must be a read/write transaction to continue
1.255 + iRepository.AttemptPromoteTransactionToReadWrite();
1.256 + // Note we don't check the return value of the above and return it here.
1.257 + // Instead we call the next level write function and expect it to have the
1.258 + // following code:
1.259 + // if (iRepository.IsInActiveReadTransaction())
1.260 + // {
1.261 + // return iRepository.FailTransaction(KErrLocked, key);
1.262 + // }
1.263 + // this ensures CommitTransaction reports the failing key.
1.264 + }
1.265 + // Note ServiceError will fail the transaction if write operation leaves
1.266 + }
1.267 +
1.268 + // call the server function
1.269 + ASSERT(aFuncL != NULL);
1.270 + TInt result = (this->*aFuncL)(aMessage);
1.271 +
1.272 + // commit the temporary transaction
1.273 + if (tempTransaction)
1.274 + {
1.275 + CleanupStack::Pop(); // remove cleanup item from earlier
1.276 + // absorb result and keyInfo from commit of temporary transaction
1.277 + TUint32 tempKeyInfo;
1.278 + User::LeaveIfError(iRepository.CommitTransaction(tempKeyInfo));
1.279 + }
1.280 + return result;
1.281 + }
1.282 +
1.283 +TInt CServerSubSession::ResetOperationsL(const TClientRequest& aMessage, TServerFunc aFuncL)
1.284 + {
1.285 + // reset operations are not currently supported in transactions
1.286 + if (iRepository.IsInTransaction())
1.287 + {
1.288 + // fail transaction otherwise client may be misled to believe operation worked
1.289 + return iRepository.FailTransaction(KErrNotSupported, KUnspecifiedKey);
1.290 + }
1.291 + //can't reset when backup or restore is in progress
1.292 + else if (CRepositoryBackupClient::GetBackupStatus() != ENoBackupActivty)
1.293 + {
1.294 + return KErrServerBusy;
1.295 + }
1.296 + ASSERT(aFuncL != NULL);
1.297 + return (this->*aFuncL)(aMessage);
1.298 + }
1.299 +
1.300 +TInt CServerSubSession::InitialiseL(const TClientRequest& aMessage)
1.301 + {
1.302 + __ASSERT_ALWAYS(!iInitialised,
1.303 + PanicClient(ESessionAlreadyInitialised, aMessage));
1.304 + // We let anyone to open a repository...
1.305 + // it's not considered a breach of security to let people know
1.306 + // that a repository is there...
1.307 + TUid uid = TUid::Uid(aMessage.Int0());
1.308 +
1.309 + __SRVSUBSESS_TRACE1("CServerSubSession::InitialiseL UID: 0x%x\n",uid.iUid);
1.310 +
1.311 + // Calls iObserver->AccessL internally
1.312 + iRepository.OpenL(uid, iNotifier);
1.313 +
1.314 + iInitialised = ETrue;
1.315 +
1.316 + return KErrNone;
1.317 + }
1.318 +
1.319 +TInt CServerSubSession::CreateIntL(const TClientRequest& aMessage)
1.320 + {
1.321 + TUint32 key = aMessage.Int0();
1.322 +
1.323 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.324 + if (iRepository.IsInActiveReadTransaction())
1.325 + {
1.326 + return iRepository.FailTransaction(KErrLocked, key);
1.327 + }
1.328 +
1.329 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.330 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSubSession::CreateIntL - Attempt made to create a setting")))
1.331 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.332 +
1.333 + TInt val = aMessage.Int1();
1.334 +
1.335 +#ifdef SRVSUBSESS_TRACE
1.336 + TUid uid = RepositoryUid();
1.337 +
1.338 + __SRVSUBSESS_TRACE2("CServerSubSession::CreateIntL UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.339 +#endif
1.340 +
1.341 + TInt r = iRepository.TransactionCreateL(key, val, NULL);
1.342 +
1.343 + return r;
1.344 + }
1.345 +
1.346 +TInt CServerSubSession::CreateRealL(const TClientRequest& aMessage)
1.347 + {
1.348 + TUint32 key = aMessage.Int0();
1.349 +
1.350 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.351 + if (iRepository.IsInActiveReadTransaction())
1.352 + {
1.353 + return iRepository.FailTransaction(KErrLocked, key);
1.354 + }
1.355 +
1.356 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.357 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::CreateRealL - Attempt made to create a setting")))
1.358 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.359 +
1.360 + TReal val;
1.361 + TPckg<TReal> p(val);
1.362 + aMessage.ReadL(1, p);
1.363 +
1.364 +#ifdef SRVSUBSESS_TRACE
1.365 + TUid uid = RepositoryUid();
1.366 +
1.367 + __SRVSUBSESS_TRACE2("CServerSubSession::CreateRealL UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.368 +#endif
1.369 + TInt r = iRepository.TransactionCreateL(key, val, NULL);
1.370 +
1.371 + return r;
1.372 + }
1.373 +
1.374 +TInt CServerSubSession::CreateStringL(const TClientRequest& aMessage)
1.375 + {
1.376 + TUint32 key = aMessage.Int0();
1.377 +
1.378 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.379 + if (iRepository.IsInActiveReadTransaction())
1.380 + {
1.381 + return iRepository.FailTransaction(KErrLocked, key);
1.382 + }
1.383 +
1.384 + // sometime: must ensure bad descriptor results in client being panic'd
1.385 +
1.386 + // check for descriptor-too-long was previously on the client side,
1.387 + // hence test code expects KErrArgument response before KErrPermissionDenied
1.388 + TInt length = aMessage.GetDesLengthL(1);
1.389 + if (length > KMaxBinaryLength)
1.390 + {
1.391 + return iRepository.FailTransaction(KErrArgument, key);
1.392 + }
1.393 +
1.394 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.395 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::CreateStringL - Attempt made to create a setting")))
1.396 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.397 +
1.398 + TBuf8<KMaxBinaryLength> val;
1.399 + aMessage.ReadL(1, val);
1.400 +
1.401 +#ifdef SRVSUBSESS_TRACE
1.402 + TUid uid = RepositoryUid();
1.403 +
1.404 + __SRVSUBSESS_TRACE2("CServerSubSession::CreateStringL UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.405 +#endif
1.406 +
1.407 + TInt error = iRepository.TransactionCreateL(key, val, NULL);
1.408 +
1.409 + return error;
1.410 + }
1.411 +
1.412 +TInt CServerSubSession::DeleteL(const TClientRequest& aMessage)
1.413 + {
1.414 + TUint32 key = aMessage.Int0();
1.415 +
1.416 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.417 + if (iRepository.IsInActiveReadTransaction())
1.418 + {
1.419 + return iRepository.FailTransaction(KErrLocked, key);
1.420 + }
1.421 +
1.422 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.423 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::DeleteL - Attempt made to delete a setting")))
1.424 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.425 +
1.426 +#ifdef SRVSUBSESS_TRACE
1.427 + TUid uid = RepositoryUid();
1.428 +
1.429 + __SRVSUBSESS_TRACE2("CServerSubSession::DeleteL UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.430 +#endif
1.431 +
1.432 + TInt r = iRepository.TransactionDeleteL(key);
1.433 +
1.434 + return r;
1.435 + }
1.436 +
1.437 +TInt CServerSubSession::GetIntL(const TClientRequest& aMessage)
1.438 + {
1.439 + TUint32 key = aMessage.Int0();
1.440 +
1.441 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.442 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetIntL - Attempt made to read a setting")))
1.443 + return KErrPermissionDenied;
1.444 +
1.445 + TInt val;
1.446 + TInt error = iRepository.Get(key, val);
1.447 +
1.448 + if (error == KErrNone)
1.449 + {
1.450 + TPckg<TInt> p(val);
1.451 + aMessage.WriteL(1, p);
1.452 + }
1.453 +
1.454 +#ifdef SRVSUBSESS_TRACE
1.455 + TUid uid = RepositoryUid();
1.456 +
1.457 + if (error == KErrNone)
1.458 + {
1.459 + __SRVSUBSESS_TRACE3("CServerSubSession::GetIntL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.460 + }
1.461 + else
1.462 + {
1.463 + __SRVSUBSESS_TRACE2("CServerSubSession::GetIntL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.464 + }
1.465 +#endif
1.466 +
1.467 + return error;
1.468 + }
1.469 +
1.470 +TInt CServerSubSession::SetIntL(const TClientRequest& aMessage)
1.471 + {
1.472 + TUint32 key = aMessage.Int0();
1.473 +
1.474 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.475 + if (iRepository.IsInActiveReadTransaction())
1.476 + {
1.477 + return iRepository.FailTransaction(KErrLocked, key);
1.478 + }
1.479 +
1.480 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.481 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetIntL - Attempt made to write a setting")))
1.482 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.483 +
1.484 + TInt val = aMessage.Int1();
1.485 + TInt error = iRepository.TransactionSetL(key, val);
1.486 +
1.487 +#ifdef SRVSUBSESS_TRACE
1.488 + TUid uid = RepositoryUid();
1.489 +
1.490 + if (error == KErrNone)
1.491 + {
1.492 + __SRVSUBSESS_TRACE3("CServerSubSession::SetIntL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.493 + }
1.494 + else
1.495 + {
1.496 + __SRVSUBSESS_TRACE3("CServerSubSession::SetIntL **Failure** UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.497 + }
1.498 +#endif
1.499 + return error;
1.500 + }
1.501 +
1.502 +TInt CServerSubSession::GetRealL(const TClientRequest& aMessage)
1.503 + {
1.504 + TUint32 key = aMessage.Int0();
1.505 +
1.506 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.507 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetRealL - Attempt made to read a setting")))
1.508 + return KErrPermissionDenied;
1.509 +
1.510 + TReal val;
1.511 + TInt error = iRepository.Get(key, val);
1.512 +
1.513 + if(error==KErrNone)
1.514 + {
1.515 + TPckg<TReal> p(val);
1.516 + aMessage.WriteL(1, p);
1.517 + }
1.518 +
1.519 +#ifdef SRVSUBSESS_TRACE
1.520 + TUid uid = RepositoryUid();
1.521 +
1.522 + if (error == KErrNone)
1.523 + {
1.524 + __SRVSUBSESS_TRACE3("CServerSubSession::GetRealL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.525 + }
1.526 + else
1.527 + {
1.528 + __SRVSUBSESS_TRACE2("CServerSubSession::GetRealL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.529 + }
1.530 +#endif
1.531 + return error;
1.532 + }
1.533 +
1.534 +TInt CServerSubSession::SetRealL(const TClientRequest& aMessage)
1.535 + {
1.536 + TUint32 key = aMessage.Int0();
1.537 +
1.538 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.539 + if (iRepository.IsInActiveReadTransaction())
1.540 + {
1.541 + return iRepository.FailTransaction(KErrLocked, key);
1.542 + }
1.543 +
1.544 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.545 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetRealL - Attempt made to write a setting")))
1.546 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.547 +
1.548 + TReal val;
1.549 + TPckg<TReal> p(val);
1.550 + aMessage.ReadL(1, p);
1.551 +
1.552 + TInt error = iRepository.TransactionSetL(key, val);
1.553 +
1.554 +#ifdef SRVSUBSESS_TRACE
1.555 + TUid uid = RepositoryUid();
1.556 +
1.557 + if (error == KErrNone)
1.558 + {
1.559 + __SRVSUBSESS_TRACE3("CServerSubSession::SetRealL UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.560 + }
1.561 + else
1.562 + {
1.563 + __SRVSUBSESS_TRACE3("CServerSubSession::SetRealL **Failure** UID: 0x%x Key=0x%x Value=%d\n",uid.iUid,key,val);
1.564 + }
1.565 +#endif
1.566 +
1.567 + return error;
1.568 + }
1.569 +
1.570 +TInt CServerSubSession::GetStringL(const TClientRequest& aMessage)
1.571 + {
1.572 + TUint32 key = aMessage.Int0();
1.573 +
1.574 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.575 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetStringL - Attempt made to read a setting")))
1.576 + return KErrPermissionDenied;
1.577 +
1.578 + TBuf8<KMaxBinaryLength> val;
1.579 +
1.580 + TInt error = iRepository.Get(key, val);
1.581 +
1.582 + if(error==KErrNone)
1.583 + {
1.584 + TInt clientMaxDescriptorLength;
1.585 + TPckg<TInt> pInt (clientMaxDescriptorLength);
1.586 + aMessage.Read(2, pInt);
1.587 +
1.588 + TInt descriptorLength = val.Length();
1.589 +
1.590 + // write the descriptor length to aMessage
1.591 + TPckg<TInt> p(descriptorLength);
1.592 + error = aMessage.Write(2, p);
1.593 +
1.594 + if(error==KErrNone)
1.595 + {
1.596 + if(descriptorLength > clientMaxDescriptorLength)
1.597 + {
1.598 + // if it is, fill the descriptor up to its max length
1.599 + error = aMessage.Write(1, val.Left(clientMaxDescriptorLength));
1.600 +
1.601 + // if client-side descriptor is too small to take the value, which it is, returns KErrOverflow
1.602 + if(error == KErrNone)
1.603 + {
1.604 + error = KErrOverflow;
1.605 + }
1.606 + }
1.607 + else
1.608 + {
1.609 + error = aMessage.Write(1, val);
1.610 + }
1.611 +
1.612 +#ifdef SRVSUBSESS_TRACE
1.613 + TUid uid = RepositoryUid();
1.614 +
1.615 + if (error == KErrNone)
1.616 + {
1.617 + __SRVSUBSESS_TRACE3("CServerSubSession::GetStringL UID: 0x%x Key=0x%x Value=%S\n",uid.iUid,key,&val);
1.618 + }
1.619 + else
1.620 + {
1.621 + __SRVSUBSESS_TRACE2("CServerSubSession::GetStringL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.622 + }
1.623 +#endif
1.624 + }
1.625 +
1.626 + // if error is KErrOverflow should not failing transaction
1.627 + if ((error != KErrNone) && (error != KErrOverflow))
1.628 + {
1.629 + // ServiceError will fail transaction
1.630 + User::Leave(error);
1.631 + }
1.632 + }
1.633 + return error;
1.634 + }
1.635 +
1.636 +TInt CServerSubSession::SetStringL(const TClientRequest& aMessage)
1.637 + {
1.638 + TUint32 key = aMessage.Int0();
1.639 +
1.640 + // cannot make changes in a read transaction - upgrade must have failed due to write lock being used
1.641 + if (iRepository.IsInActiveReadTransaction())
1.642 + {
1.643 + return iRepository.FailTransaction(KErrLocked, key);
1.644 + }
1.645 +
1.646 + // check for descriptor-too-long was previously on the client side,
1.647 + // hence test code expects KErrArgument response before KErrPermissionDenied
1.648 + TInt length = aMessage.GetDesLengthL(1);
1.649 + if (length > KMaxBinaryLength)
1.650 + {
1.651 + return iRepository.FailTransaction(KErrArgument, key);
1.652 + }
1.653 +
1.654 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.655 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::SetStringL - Attempt made to write a setting")))
1.656 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.657 +
1.658 + TBuf8<KMaxBinaryLength> val;
1.659 + aMessage.ReadL(1, val); // no error if too long, truncated instead
1.660 +
1.661 + TInt error = iRepository.TransactionSetL(key, val);
1.662 +
1.663 +#ifdef SRVSUBSESS_TRACE
1.664 + TUid uid = RepositoryUid();
1.665 +
1.666 + if (error == KErrNone)
1.667 + {
1.668 + __SRVSUBSESS_TRACE3("CServerSubSession::SetStringL UID: 0x%x Key=0x%x Value=%S\n",uid.iUid,key,&val);
1.669 + }
1.670 + else
1.671 + {
1.672 + __SRVSUBSESS_TRACE2("CServerSubSession::SetStringL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.673 + }
1.674 +#endif
1.675 +
1.676 + return error;
1.677 + }
1.678 +
1.679 +TInt CServerSubSession::GetMeta(const TClientRequest& aMessage)
1.680 + {
1.681 + TUint32 key = aMessage.Int0();
1.682 +
1.683 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.684 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GetMeta - Attempt made to read a setting")))
1.685 + return KErrPermissionDenied;
1.686 +
1.687 + TUint32 meta;
1.688 + TInt error = iRepository.GetMeta(key, meta);
1.689 +
1.690 + if (error == KErrNone)
1.691 + {
1.692 + TPckg<TUint32> p(meta);
1.693 + error = aMessage.Write(1, p);
1.694 + }
1.695 +
1.696 +#ifdef SRVSUBSESS_TRACE
1.697 + TUid uid = RepositoryUid();
1.698 +
1.699 + if (error == KErrNone)
1.700 + {
1.701 + __SRVSUBSESS_TRACE3("CServerSubSession::GetMeta UID: 0x%x Key=0x%x Meta=0x%x\n",uid.iUid,key,meta);
1.702 + }
1.703 + else
1.704 + {
1.705 + __SRVSUBSESS_TRACE2("CServerSubSession::GetMeta **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.706 + }
1.707 +#endif
1.708 +
1.709 + return error;
1.710 + }
1.711 +
1.712 +TInt CServerSubSession::FindL(const TClientRequest& aMessage)
1.713 + {
1.714 + // PLATSEC NOTE:
1.715 + // There are no read policy checks on FindL.
1.716 + // Client is returned the full list of keys whether they have read permission or not.
1.717 + // They were able to find this out by brute force using FindL on single setting ranges
1.718 + // anyway (because it would return KErrPermissionDenied if it existed, KErrNotFound otherwise).
1.719 + // Revealing the existence of settings is not considered a breach of security.
1.720 + TKeyFilter keyIdentifier;
1.721 + TPckg<TKeyFilter> p(keyIdentifier);
1.722 + aMessage.Read(0, p);
1.723 + // we reset results first since we do not police GetResult
1.724 + // and this way we can guarantee no results are available if access not granted
1.725 + iFindResult.Reset();
1.726 +
1.727 + RArray<TUint32> settingsToSend;
1.728 + CleanupClosePushL(settingsToSend);
1.729 +
1.730 + TInt error=KErrNone;
1.731 + TRAP(error,iRepository.FindL(keyIdentifier.iPartialId, keyIdentifier.iIdMask,settingsToSend,KCentRepFindBufSize,iFindResult));
1.732 + if (error==KErrNone)
1.733 + {
1.734 + //write back the total number of settingsFound;
1.735 + TInt numSettings=settingsToSend.Count()+iFindResult.Count();
1.736 + TPtrC8 count(reinterpret_cast<TUint8*>(&numSettings),sizeof(TUint32));
1.737 + error=aMessage.Write(2,count);
1.738 + if (error==KErrNone)
1.739 + {
1.740 + TPtrC8 p(reinterpret_cast<TUint8*>(&(settingsToSend[0])), (settingsToSend.Count())*sizeof(TUint32));
1.741 + error=aMessage.Write(2,p,4);
1.742 + }
1.743 +
1.744 +#ifdef SRVSUBSESS_TRACE
1.745 + TUid uid = RepositoryUid();
1.746 + if (error == KErrNone)
1.747 + {
1.748 + __SRVSUBSESS_TRACE4("CServerSubSession::FindL UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
1.749 + keyIdentifier.iIdMask,&p);
1.750 + }
1.751 + else
1.752 + {
1.753 + __SRVSUBSESS_TRACE4("CServerSubSession::FindL (failed write) UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
1.754 + keyIdentifier.iIdMask,&p);
1.755 + }
1.756 +#endif
1.757 + }
1.758 + CleanupStack::PopAndDestroy(); //settingsToSend
1.759 +
1.760 + if (error != KErrNone)
1.761 + {
1.762 + iFindResult.Reset();
1.763 + if ((error != KErrNone) && (error != KErrNotFound))
1.764 + {
1.765 + // ServiceError will fail transaction
1.766 + User::Leave(error);
1.767 + }
1.768 + }
1.769 + return error;
1.770 + }
1.771 +
1.772 +TInt CServerSubSession::FindEqIntL(const TClientRequest& aMessage)
1.773 + {
1.774 + TInt val = aMessage.Int1();
1.775 + // PlatSec check done in FindValueL
1.776 + return FindValueL(aMessage, val);
1.777 + }
1.778 +
1.779 +TInt CServerSubSession::FindEqRealL(const TClientRequest& aMessage)
1.780 + {
1.781 + TReal val;
1.782 + TPckg<TReal> p(val);
1.783 + aMessage.Read(1, p);
1.784 + // PlatSec check done in FindValueL
1.785 + return FindValueL(aMessage, val);
1.786 + }
1.787 +
1.788 +TInt CServerSubSession::FindEqStringL(const TClientRequest& aMessage)
1.789 + {
1.790 + TBuf8<KMaxBinaryLength> val;
1.791 + aMessage.ReadL(1, val); // no error if too long, truncated instead
1.792 + // PlatSec check done in FindValueL
1.793 + return FindValueL(aMessage, val);
1.794 + }
1.795 +
1.796 +TInt CServerSubSession::FindNeqIntL(const TClientRequest& aMessage)
1.797 + {
1.798 + TInt val = aMessage.Int1();
1.799 + // PlatSec check done in FindValueL
1.800 + return FindValueL(aMessage, val, ENotEqual);
1.801 + }
1.802 +
1.803 +TInt CServerSubSession::FindNeqRealL(const TClientRequest& aMessage)
1.804 + {
1.805 + TReal val;
1.806 + TPckg<TReal> p(val);
1.807 + aMessage.Read(1, p);
1.808 + // PlatSec check done in FindValueL
1.809 + return FindValueL(aMessage, val, ENotEqual);
1.810 + }
1.811 +
1.812 +TInt CServerSubSession::FindNeqStringL(const TClientRequest& aMessage)
1.813 + {
1.814 + TBuf8<KMaxBinaryLength> val;
1.815 + aMessage.ReadL(1, val); // no error if too long, truncated instead
1.816 + // PlatSec check done in FindValueL
1.817 + return FindValueL(aMessage, val, ENotEqual);
1.818 + }
1.819 +
1.820 +template <class T>
1.821 +TInt CServerSubSession::FindValueL(const TClientRequest& aMessage, const T& aVal,TComparison aComparison)
1.822 + {
1.823 + // IMPORTANT PLATSEC NOTE:
1.824 + // MUST return KErrPermissionDenied if read policy of ANY setting in the search range not passed.
1.825 + // MUST NOT merely check read policy of matching entries, otherwise it is possible to determine
1.826 + // secret values by brute force: Using single-value ranges, cycling through the possible values and
1.827 + // confirming a match when it returns KErrPermissionDenied rather than KErrNotFound.
1.828 + TKeyFilter keyIdentifier;
1.829 + TPckg<TKeyFilter> p(keyIdentifier);
1.830 + aMessage.Read(0, p);
1.831 + // we reset results first since we do not police GetResult
1.832 + // and this way we can guarantee no results are available if access not granted
1.833 + iFindResult.Reset();
1.834 + RSettingPointerArray settings;
1.835 + CleanupClosePushL(settings);
1.836 + TInt error = iRepository.FindSettings(keyIdentifier.iPartialId, keyIdentifier.iIdMask, settings);
1.837 + if (error == KErrNone)
1.838 + {
1.839 + //perform the read checking policies first
1.840 + TUint32 dummyErrId;
1.841 + error=iRepository.CheckPermissions(settings,aMessage,
1.842 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::FindValueL - Attempt made to search settings"),ETrue,dummyErrId);
1.843 + if (error==KErrPermissionDenied)
1.844 + iFindResult.Reset();
1.845 +
1.846 + //now if everything passes, do perform the FindValue
1.847 + if (error==KErrNone)
1.848 + {
1.849 + TRAP(error,iRepository.FindCompareL(settings,aVal,aComparison,iFindResult));
1.850 + if (error==KErrNone)
1.851 + {
1.852 + const TInt numSettings = iFindResult.Count();
1.853 + const TInt numInitial = numSettings > KCentRepFindBufSize ? KCentRepFindBufSize : numSettings;
1.854 + RArray<TUint32> settingsToSend;
1.855 + CleanupClosePushL(settingsToSend);
1.856 +
1.857 + //reserve memory for everything that needs to be added to the array
1.858 + settingsToSend.ReserveL(numInitial + 1); // the plus one is for the numSettings value
1.859 +
1.860 + //first append the number of found settings
1.861 + settingsToSend.AppendL(numSettings);
1.862 +
1.863 + //now append up to KCentRepFindBufSize settings
1.864 + for(TInt i = 0; i < numInitial; i++)
1.865 + {
1.866 + settingsToSend.AppendL(iFindResult[0]);
1.867 + iFindResult.Remove(0);
1.868 + }
1.869 +
1.870 + if(iFindResult.Count() == 0)
1.871 + {
1.872 + iFindResult.Reset();
1.873 + }
1.874 +
1.875 + //send:
1.876 + //1 - the count of total settings found
1.877 + //2 - the settings that fit in the buffer allocated for the first IPC
1.878 + TPtrC8 p(reinterpret_cast<TUint8*>(&(settingsToSend[0])), (numInitial+1)*sizeof(TUint32));
1.879 + error = aMessage.Write(2, p);
1.880 +
1.881 + #ifdef SRVSUBSESS_TRACE
1.882 + TUid uid = RepositoryUid();
1.883 +
1.884 + __SRVSUBSESS_TRACE4("CServerSubSession::FindValueL UID: 0x%x Key=0x%x Mask=0x%x Value=%S\n",uid.iUid,keyIdentifier.iPartialId,
1.885 + keyIdentifier.iIdMask,&p);
1.886 + #endif
1.887 + CleanupStack::PopAndDestroy(); //settingsToSend
1.888 + }
1.889 + }
1.890 + }
1.891 + if ((error != KErrNone) && (error != KErrNotFound) && (error != KErrPermissionDenied))
1.892 + {
1.893 + iFindResult.Reset();
1.894 + CleanupStack::PopAndDestroy(); //settings
1.895 +
1.896 + // ServiceError will fail transaction
1.897 + User::Leave(error);
1.898 + }
1.899 +#ifdef SRVSUBSESS_TRACE
1.900 + else
1.901 + {
1.902 + TUid uid = RepositoryUid();
1.903 +
1.904 + __SRVSUBSESS_TRACE3("CServerSubSession::FindValueL **Failure** UID: 0x%x Key=0x%x Mask=0x%x\n",uid.iUid,keyIdentifier.iPartialId,
1.905 + keyIdentifier.iIdMask);
1.906 + }
1.907 +#endif
1.908 +
1.909 + CleanupStack::PopAndDestroy(); //settings
1.910 + return error;
1.911 + }
1.912 +
1.913 +TInt CServerSubSession::GetFindResultL(const TClientRequest& aMessage)
1.914 + {
1.915 + TInt n = iFindResult.Count();
1.916 + if (n==0)
1.917 + {
1.918 + return KErrNotFound;
1.919 + }
1.920 +
1.921 + TPtrC8 p(reinterpret_cast<TUint8*>(&(iFindResult[0])), n*sizeof(TUint32));
1.922 + TInt error = aMessage.Write(0, p);
1.923 + // Free up iFindResult - it's no longer needed
1.924 + iFindResult.Reset();
1.925 + // ServiceError will fail transaction
1.926 +
1.927 +#ifdef SRVSUBSESS_TRACE
1.928 + TUid uid = RepositoryUid();
1.929 +
1.930 + if (error == KErrNone)
1.931 + {
1.932 + __SRVSUBSESS_TRACE2("CServerSubSession::GetFindResultL UID: 0x%x Value=%S\n",uid.iUid,&p);
1.933 + }
1.934 + else
1.935 + {
1.936 + __SRVSUBSESS_TRACE1("CServerSubSession::GetFindResultL **Failure** UID: 0x%x\n",uid.iUid);
1.937 + }
1.938 +#endif
1.939 + return User::LeaveIfError(error);
1.940 + }
1.941 +
1.942 +TInt CServerSubSession::NotifyRequestCheck(const TClientRequest& aMessage)
1.943 + {
1.944 + TUint32 key = aMessage.Int0();
1.945 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.946 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::NotifyRequestCheck - Attempt made to check Notify request")))
1.947 + return KErrPermissionDenied;
1.948 +
1.949 + TInt error = iRepository.GetPersistentSetting(key) ? KErrNone : KErrNotFound;
1.950 +
1.951 +#ifdef SRVSUBSESS_TRACE
1.952 + TUid uid = RepositoryUid();
1.953 +
1.954 + if (error == KErrNone)
1.955 + {
1.956 + __SRVSUBSESS_TRACE2("CServerSubSession::NotifyRequestCheck UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.957 + }
1.958 + else
1.959 + {
1.960 + __SRVSUBSESS_TRACE1("CServerSubSession::NotifyRequestCheck **Failure** UID: 0x%x\n",uid.iUid);
1.961 + }
1.962 +#endif
1.963 + return error;
1.964 + }
1.965 +
1.966 +TInt CServerSubSession::NotifyRequest(const TClientRequest& aMessage)
1.967 + {
1.968 + TUint32 key = aMessage.Int0();
1.969 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetReadAccessPolicy(key),
1.970 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::NotifyRequest - Attempt made to register for Notify")))
1.971 + return KErrPermissionDenied;
1.972 + TInt error = iNotifier.AddRequest(key, aMessage);
1.973 +
1.974 +#ifdef SRVSUBSESS_TRACE
1.975 + TUid uid = RepositoryUid();
1.976 +
1.977 + if (error == KErrNone)
1.978 + {
1.979 + __SRVSUBSESS_TRACE2("CServerSubSession::NotifyRequest UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.980 + }
1.981 + else
1.982 + {
1.983 + __SRVSUBSESS_TRACE1("CServerSubSession::NotifyRequest **Failure** UID: 0x%x\n",uid.iUid);
1.984 + }
1.985 +#endif
1.986 +
1.987 + return (error == KErrNone) ? KDontCompleteMessage : error;
1.988 + }
1.989 +
1.990 +TInt CServerSubSession::NotifyCancel(const TClientRequest& aMessage)
1.991 + {
1.992 + TUint32 key = aMessage.Int0();
1.993 +
1.994 +#ifdef SRVSUBSESS_TRACE
1.995 + TUid uid = RepositoryUid();
1.996 +
1.997 + __SRVSUBSESS_TRACE2("CServerSubSession::NotifyCancel UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.998 +#endif
1.999 +
1.1000 + return iNotifier.CancelRequest(key);
1.1001 + }
1.1002 +
1.1003 +TInt CServerSubSession::NotifyCancelAll(const TClientRequest& /*aMessage*/)
1.1004 + {
1.1005 +#ifdef SRVSUBSESS_TRACE
1.1006 + TUid uid = RepositoryUid();
1.1007 +
1.1008 + __SRVSUBSESS_TRACE1("CServerSubSession::NotifyCancelAll UID: 0x%x\n",uid.iUid);
1.1009 +#endif
1.1010 + return iNotifier.CancelAllRequests();
1.1011 + }
1.1012 +
1.1013 +TInt CServerSubSession::GroupNotifyRequest(const TClientRequest& aMessage)
1.1014 + {
1.1015 + TUint32 partialId = aMessage.Int0();
1.1016 + TUint32 idMask = aMessage.Int1();
1.1017 + RSettingPointerArray settings;
1.1018 + TInt error = iRepository.FindPersistentSettings(partialId, idMask, settings);
1.1019 + if (error == KErrNone)
1.1020 + {
1.1021 + TUint32 dummyErrId;
1.1022 + error = iRepository.CheckPermissions(settings, aMessage,
1.1023 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::GroupNotifyRequest - Attempt made to register for group Notify"),ETrue,dummyErrId);
1.1024 + }
1.1025 + settings.Reset();
1.1026 + if (error != KErrNone)
1.1027 + {
1.1028 +#ifdef SRVSUBSESS_TRACE
1.1029 + TUid uid = RepositoryUid();
1.1030 +
1.1031 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest **Failure** UID: 0x%x\n PartialId=0x%x Mask=0x%x\n",
1.1032 + uid.iUid,partialId,idMask);
1.1033 +#endif
1.1034 +
1.1035 + return KErrPermissionDenied;
1.1036 + }
1.1037 +
1.1038 + error = iNotifier.AddRequest(partialId, idMask, aMessage);
1.1039 +
1.1040 +#ifdef SRVSUBSESS_TRACE
1.1041 + TUid uid = RepositoryUid();
1.1042 +
1.1043 + if (error == KErrNone)
1.1044 + {
1.1045 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest UID: 0x%x PartialId=0x%x Mask=0x%x\n",
1.1046 + uid.iUid,partialId,idMask);
1.1047 + }
1.1048 + else
1.1049 + {
1.1050 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyRequest **Failure** UID: 0x%x PartialId=0x%x Mask=0x%x\n",uid.iUid,
1.1051 + partialId,idMask);
1.1052 + }
1.1053 +#endif
1.1054 +
1.1055 + return error==KErrNone ? KDontCompleteMessage : error;
1.1056 + }
1.1057 +
1.1058 +TInt CServerSubSession::GroupNotifyCancel(const TClientRequest& aMessage)
1.1059 + {
1.1060 + TKeyFilter keyIdentifier;
1.1061 + TPckg<TKeyFilter> p(keyIdentifier);
1.1062 + aMessage.Read(0, p);
1.1063 +
1.1064 + RSettingPointerArray settings;
1.1065 + TInt error = iRepository.FindPersistentSettings(keyIdentifier.iPartialId, keyIdentifier.iIdMask, settings);
1.1066 + settings.Reset();
1.1067 + if (error != KErrNone)
1.1068 + {
1.1069 +#ifdef SRVSUBSESS_TRACE
1.1070 + TUid uid = RepositoryUid();
1.1071 +
1.1072 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel **Failure** UID: 0x%x\n PartialId=0x%x Mask=0x%x\n",
1.1073 + uid.iUid,keyIdentifier.iPartialId, keyIdentifier.iIdMask);
1.1074 +#endif
1.1075 + return error;
1.1076 + }
1.1077 +
1.1078 + error = iNotifier.CancelRequest(keyIdentifier.iPartialId, keyIdentifier.iIdMask);
1.1079 +
1.1080 +#ifdef SRVSUBSESS_TRACE
1.1081 + TUid uid = RepositoryUid();
1.1082 +
1.1083 + if (error == KErrNone)
1.1084 + {
1.1085 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel UID: 0x%x PartialId=0x%x Mask=0x%x\n",
1.1086 + uid.iUid,keyIdentifier.iPartialId, keyIdentifier.iIdMask);
1.1087 + }
1.1088 + else
1.1089 + {
1.1090 + __SRVSUBSESS_TRACE3("CServerSubSession::GroupNotifyCancel **Failure** UID: 0x%x PartialId=0x%x Mask=0x%x\n",uid.iUid,
1.1091 + keyIdentifier.iPartialId, keyIdentifier.iIdMask);
1.1092 + }
1.1093 +#endif
1.1094 +
1.1095 +
1.1096 + return error;
1.1097 + }
1.1098 +
1.1099 +TInt CServerSubSession::ResetL(const TClientRequest& aMessage)
1.1100 + {
1.1101 + // individual setting reset is not yet supported in transactions
1.1102 + ASSERT(!iRepository.IsInTransaction());
1.1103 + TUint32 key = aMessage.Int0();
1.1104 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetWriteAccessPolicy(key),
1.1105 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::ResetL - Attempt made to reset a setting")))
1.1106 + return iRepository.FailTransaction(KErrPermissionDenied, key);
1.1107 +
1.1108 + TInt error = iRepository.ResetL(key);
1.1109 +
1.1110 +#ifdef SRVSUBSESS_TRACE
1.1111 + TUid uid = RepositoryUid();
1.1112 +
1.1113 + if (error == KErrNone)
1.1114 + {
1.1115 + __SRVSUBSESS_TRACE2("CServerSubSession::ResetL UID: 0x%x Key=0x%x\n",
1.1116 + uid.iUid,key);
1.1117 + }
1.1118 + else
1.1119 + {
1.1120 + __SRVSUBSESS_TRACE2("CServerSubSession::ResetL **Failure** UID: 0x%x Key=0x%x\n",uid.iUid,key);
1.1121 + }
1.1122 +#endif
1.1123 +
1.1124 + return error;
1.1125 + }
1.1126 +
1.1127 +TInt CServerSubSession::ResetAllL(const TClientRequest& aMessage)
1.1128 + {
1.1129 + // factory reset operation is not yet supported in transactions
1.1130 + ASSERT(!iRepository.IsInTransaction());
1.1131 + if(KErrNone != CheckPolicy(aMessage,iRepository.GetDefaultWriteAccessPolicy(),
1.1132 + __PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerSession::ResetAllL - Attempt made to reset repository")))
1.1133 + return KErrPermissionDenied;
1.1134 +
1.1135 + iNotifier.IdReportingOff();
1.1136 + TInt error = iRepository.ResetAllL();
1.1137 + iNotifier.IdReportingOn();
1.1138 +
1.1139 + if (error == KErrNone)
1.1140 + {
1.1141 + iRepository.CommitChangesL(); // temporary measure
1.1142 + }
1.1143 +
1.1144 +#ifdef SRVSUBSESS_TRACE
1.1145 + TUid uid = RepositoryUid();
1.1146 +
1.1147 + if (error == KErrNone)
1.1148 + {
1.1149 + __SRVSUBSESS_TRACE1("CServerSubSession::ResetAllL UID: 0x%x\n",uid.iUid);
1.1150 + }
1.1151 + else
1.1152 + {
1.1153 + __SRVSUBSESS_TRACE1("CServerSubSession::ResetAllL **Failure** UID: 0x%x\n",uid.iUid);
1.1154 + }
1.1155 +#endif
1.1156 +
1.1157 + return error;
1.1158 + }
1.1159 +
1.1160 +TInt CServerSubSession::MoveL(const TClientRequest& aMessage)
1.1161 + {
1.1162 + if (iRepository.IsInActiveReadTransaction())
1.1163 + {
1.1164 + TKeyFilter keyIdentifier;
1.1165 + TPckg<TKeyFilter> p(keyIdentifier);
1.1166 + aMessage.Read(0, p);
1.1167 +
1.1168 +#ifdef SRVSUBSESS_TRACE
1.1169 + TUid uid = RepositoryUid();
1.1170 +
1.1171 + __SRVSUBSESS_TRACE3("CServerSubSession::MoveL **Failure** In Transaction UID: 0x%x PartialId=0x%x Mask=0x%x\n",
1.1172 + uid.iUid,keyIdentifier.iPartialId,keyIdentifier.iIdMask);
1.1173 +#endif
1.1174 +
1.1175 + // could not promote to read/write: fail & give the source partialKey as the error key
1.1176 + return iRepository.FailTransaction(KErrLocked, keyIdentifier.iPartialId);
1.1177 + }
1.1178 +
1.1179 + TUint32 errorKey = KUnspecifiedKey;
1.1180 + TInt result = iRepository.TransactionMoveL(aMessage, errorKey);
1.1181 +
1.1182 +#ifdef SRVSUBSESS_TRACE
1.1183 + TUid uid = RepositoryUid();
1.1184 +
1.1185 + if (result == KErrNone)
1.1186 + {
1.1187 + __SRVSUBSESS_TRACE1("CServerSubSession::MoveL UID: 0x%x\n",uid.iUid);
1.1188 + }
1.1189 + else
1.1190 + {
1.1191 + __SRVSUBSESS_TRACE2("CServerSubSession::MoveL **Failure** UID: 0x%x Error=%d\n",uid.iUid,errorKey);
1.1192 + }
1.1193 +#endif
1.1194 +
1.1195 + if (result != KErrNone && result!=KErrNotFound)
1.1196 + {
1.1197 + iRepository.FailTransaction(result, errorKey);
1.1198 + TPckg<TUint32> p(errorKey);
1.1199 + aMessage.WriteL(2, p);
1.1200 + }
1.1201 + return result;
1.1202 + }
1.1203 +
1.1204 +TInt CServerSubSession::TransactionStart(const TClientRequest& aMessage)
1.1205 + {
1.1206 + // check if we are already in a transaction
1.1207 + TBool inTransactionAlready = iRepository.IsInTransaction();
1.1208 +
1.1209 + // panic client if attempting to start a transaction when already in one
1.1210 + __ASSERT_ALWAYS(!inTransactionAlready, PanicClient(EStartAlreadyInTransaction, aMessage));
1.1211 +
1.1212 + // if the client has been panicked then we don't want to continue.
1.1213 + // client session will already have been taken down so don't want to complete the message
1.1214 + if (inTransactionAlready)
1.1215 + {
1.1216 +#ifdef SRVSUBSESS_TRACE
1.1217 + TUid uid = RepositoryUid();
1.1218 +
1.1219 + __SRVSUBSESS_TRACE1("CServerSubSession::TransactionStart **Failure** already in transaction UID=0x%x\n",uid.iUid);
1.1220 +#endif
1.1221 +
1.1222 + return KDontCompleteMessage;
1.1223 + }
1.1224 +
1.1225 + const TInt mode = aMessage.Int0();
1.1226 +
1.1227 + TInt error = iRepository.StartTransaction(mode);
1.1228 +
1.1229 +#ifdef SRVSUBSESS_TRACE
1.1230 +
1.1231 + TUid uid = RepositoryUid();
1.1232 +
1.1233 + // mode strings match transstate.h - if that is updated, this should be as well.
1.1234 + const TPtrC modeStrings[] =
1.1235 + {
1.1236 + _L("ENoTransaction"), // 0
1.1237 + _L("EReadTransaction"), // EReadBit 1
1.1238 + _L("EConcurrentReadWriteTransaction"), // EWriteBit 2
1.1239 + _L("EReadWriteTransaction|EAllTransactionBits"), //EReadBit | EWriteBit 3
1.1240 + _L("EFailedBit") // 4
1.1241 + };
1.1242 +
1.1243 + if (error == KErrNone)
1.1244 + {
1.1245 + __SRVSUBSESS_TRACE3("CServerSubSession::TransactionStart UID: 0x%x Mode=%d (%S)\n",uid.iUid,mode,&modeStrings[mode]);
1.1246 + }
1.1247 + else
1.1248 + {
1.1249 + __SRVSUBSESS_TRACE3("CServerSubSession::TransactionStart **Failure** UID: 0x%x Mode=%d (%S)\n",uid.iUid,mode,&modeStrings[mode]);
1.1250 + }
1.1251 +#endif
1.1252 +
1.1253 + return error;
1.1254 + }
1.1255 +
1.1256 +// serves as both rollback and async cancel
1.1257 +TInt CServerSubSession::TransactionCancel(const TClientRequest& /*aMessage*/)
1.1258 + {
1.1259 +#ifdef SRVSUBSESS_TRACE
1.1260 + TUid uid = RepositoryUid();
1.1261 +
1.1262 + __SRVSUBSESS_TRACE1("CServerSubSession::TransactionCancel UID: 0x%x",uid.iUid);
1.1263 +#endif
1.1264 + iRepository.CancelTransaction();
1.1265 + return KErrNone;
1.1266 + }
1.1267 +
1.1268 +TInt CServerSubSession::TransactionCommitL(const TClientRequest& aMessage)
1.1269 + {
1.1270 + // check if we are in a transaction
1.1271 + TBool inTransaction = iRepository.IsInTransaction();
1.1272 +
1.1273 + // panic client if attempting to commit a transaction when we are not in one
1.1274 + __ASSERT_ALWAYS(inTransaction, PanicClient(ECommitNotInTransaction, aMessage));
1.1275 +
1.1276 + // if the client has been panicked then we don't want to continue.
1.1277 + // client session will already have been taken down so don't want to complete the message
1.1278 + if (!inTransaction)
1.1279 + {
1.1280 +#ifdef SRVSUBSESS_TRACE
1.1281 + TUid uid = RepositoryUid();
1.1282 +
1.1283 + __SRVSUBSESS_TRACE1("CServerSubSession::TransactionCommitL **Failure** In Transaction UID: 0x%x TransactionKey=%d\n",uid.iUid);
1.1284 +#endif
1.1285 + return KDontCompleteMessage;
1.1286 + }
1.1287 +
1.1288 + TUint32 keyInfo = KUnspecifiedKey;
1.1289 + TInt result = iRepository.CommitTransaction(keyInfo);
1.1290 +
1.1291 + TPckg<TUint32> p(keyInfo);
1.1292 + aMessage.WriteL(0, p);
1.1293 +
1.1294 +#ifdef SRVSUBSESS_TRACE
1.1295 + TUid uid = RepositoryUid();
1.1296 +
1.1297 + if (result == KErrNone)
1.1298 + {
1.1299 + __SRVSUBSESS_TRACE2("CServerSubSession::TransactionCommitL UID: 0x%x TransactionKey=%d\n",uid.iUid,keyInfo);
1.1300 + }
1.1301 + else
1.1302 + {
1.1303 + __SRVSUBSESS_TRACE2("CServerSubSession::TransactionCommitL **Failure** UID: 0x%x TransactionKey=%d\n",uid.iUid,keyInfo);
1.1304 + }
1.1305 +#endif
1.1306 + return result;
1.1307 + }
1.1308 +
1.1309 +TInt CServerSubSession::DeleteRangeL(const TClientRequest& aMessage)
1.1310 + {
1.1311 + if (iRepository.IsInActiveReadTransaction())
1.1312 + {
1.1313 + // could not promote to read/write: fail & give the partialKey as the error key
1.1314 + TUint32 partialKey = aMessage.Int0();
1.1315 + return iRepository.FailTransaction(KErrLocked, partialKey);
1.1316 + }
1.1317 + TUint32 errorKey = KUnspecifiedKey;
1.1318 + TInt result = iRepository.TransactionDeleteRangeL(aMessage, errorKey);
1.1319 + if (result != KErrNone)
1.1320 + {
1.1321 + TPckg<TUint32> p(errorKey);
1.1322 + aMessage.WriteL(2, p);
1.1323 + }
1.1324 +
1.1325 +#ifdef SRVSUBSESS_TRACE
1.1326 + TUid uid = RepositoryUid();
1.1327 + TUint32 partialKey = aMessage.Int0();
1.1328 + TUint32 keyMask = aMessage.Int1();
1.1329 +
1.1330 + if (result == KErrNone)
1.1331 + {
1.1332 + __SRVSUBSESS_TRACE3("CServerSubSession::DeleteRangeL UID: 0x%x Key=0x%x Mask=0x%x\n",uid.iUid,partialKey,keyMask);
1.1333 + }
1.1334 + else
1.1335 + {
1.1336 + __SRVSUBSESS_TRACE2("CServerSubSession::DeleteRangeL **Failure** UID: 0x%x ErrorKey=%d\n",uid.iUid,errorKey);
1.1337 + }
1.1338 +#endif
1.1339 +
1.1340 + return result;
1.1341 + }
1.1342 +
1.1343 +TInt CServerSubSession::TransactionStateL(const TClientRequest& aMessage)
1.1344 + {
1.1345 + TInt iState = iRepository.TransactionState();
1.1346 +
1.1347 + TPckg<TInt> p(iState);
1.1348 + aMessage.WriteL(0, p);
1.1349 +
1.1350 +#ifdef SRVSUBSESS_TRACE
1.1351 + TUid uid = RepositoryUid();
1.1352 +
1.1353 + __SRVSUBSESS_TRACE2("CServerSubSession::TransactionStateL UID: 0x%x State=%d\n",uid.iUid,iState);
1.1354 +#endif
1.1355 +
1.1356 + return KErrNone;
1.1357 + }
1.1358 +
1.1359 +TInt CServerSubSession::TransactionFail(const TClientRequest& aMessage)
1.1360 + {
1.1361 +#ifdef SRVSUBSESS_TRACE
1.1362 + TUid uid = RepositoryUid();
1.1363 +
1.1364 + __SRVSUBSESS_TRACE1("CServerSubSession::TransactionFail UID: 0x%x",uid.iUid);
1.1365 +#endif
1.1366 +
1.1367 + iRepository.FailTransaction(aMessage.Int0(), KUnspecifiedKey);
1.1368 + return KErrNone;
1.1369 + }
1.1370 +
1.1371 +//Check the security policy against a RMessage.
1.1372 +TInt CServerSubSession::CheckPolicy(const TClientRequest& msg,
1.1373 + const TSecurityPolicy& aPolicy,
1.1374 + const char *aDiagnostic)
1.1375 + {
1.1376 + return msg.CheckPolicy(aPolicy,aDiagnostic) ? KErrNone : KErrPermissionDenied;
1.1377 + }