os/security/authorisation/userpromptservice/server/source/upsserver/upssession.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/authorisation/userpromptservice/server/source/upsserver/upssession.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,327 @@
1.4 +/*
1.5 +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* Implements CUpsSession. See class and function definitions for
1.19 +* more information.
1.20 +*
1.21 +*/
1.22 +
1.23 +
1.24 +/**
1.25 + @file
1.26 +*/
1.27 +
1.28 +#include "upsserver.h"
1.29 +#include "policycache.h"
1.30 +#include <ups/upsdbw.h>
1.31 +#include <scs/ipcstream.h>
1.32 +#include <scs/nullstream.h>
1.33 +#include "pluginmanager.h"
1.34 +#include "viewevaluator.h"
1.35 +#include "updateevaluator.h"
1.36 +#include "policychangeevaluator.h"
1.37 +
1.38 +namespace UserPromptService
1.39 +{
1.40 +
1.41 +CUpsSession* CUpsSession::NewL(CUpsServer &aServer)
1.42 +/**
1.43 + Factory function allocates new instance of CUpsSession.
1.44 +
1.45 + @return New, initialized instance of CUpsSession
1.46 + which is owned by the caller.
1.47 + */
1.48 + {
1.49 + CUpsSession* self = new(ELeave) CUpsSession(aServer);
1.50 + CleanupStack::PushL(self);
1.51 + self->ConstructL(); // CScsSession implementation
1.52 + CleanupStack::Pop(self);
1.53 + return self;
1.54 + }
1.55 +
1.56 +CUpsSession::CUpsSession(CUpsServer &aServer)
1.57 +/**
1.58 + This private constructor prevents direct instantiation.
1.59 + */
1.60 + : CScsSession(aServer), iDbViewHandle(aServer.iDbHandle, this)
1.61 + {
1.62 + // empty.
1.63 + //RDebug::Printf("0x%x CUpsSession(server %x) (&iDbViewHandle %x)\n", this, &aServer, &iDbViewHandle);
1.64 + }
1.65 +
1.66 +CUpsSession::~CUpsSession()
1.67 +/**
1.68 + The base class destructor destroys any remaining subsessions
1.69 + or outstanding requests.
1.70 + */
1.71 + {
1.72 + //RDebug::Printf("0x%x ~CUpsSession (&iDbViewHandle %x)\n", this, &iDbViewHandle);
1.73 + CleanupView();
1.74 + iServiceConfig.Close();
1.75 +
1.76 + iDbViewHandle.Close();
1.77 + }
1.78 +
1.79 +TBool CUpsSession::DoServiceL(TInt aFunction, const RMessage2& aMessage)
1.80 +/**
1.81 + Implement CScsSession by handling the supplied message.
1.82 +
1.83 + Note the subsession creation command is automatically sent to
1.84 + DoCreateSubsessionL, and not this function.
1.85 +
1.86 + @param aFunction Function identifier without SCS code.
1.87 + @param aMessage Standard server-side handle to message. Not used.
1.88 + */
1.89 + {
1.90 + TSessionFunction f = static_cast<TSessionFunction>(aFunction);
1.91 + //RDebug::Printf("0x%x CUpsSession::DoServiceL function %d\n", this, f);
1.92 + switch (f)
1.93 + {
1.94 + case EGetClientConfigLength:
1.95 + {
1.96 + iServiceConfig.Close();
1.97 + UpsServer()->iPolicyCache->ServiceConfigL(aMessage.SecureId(), iServiceConfig);
1.98 +
1.99 + TPckgBuf<TInt> lengthBuf;
1.100 + lengthBuf() = iServiceConfig.Count();
1.101 + aMessage.WriteL(0, lengthBuf);
1.102 + return ETrue; // Complete request with KErrNone
1.103 + }
1.104 +
1.105 + case EGetClientConfigData:
1.106 + {
1.107 + TInt count = iServiceConfig.Count();
1.108 + for(TInt i=0; i < count; ++i)
1.109 + {
1.110 + const TServiceConfig &sc = iServiceConfig[i];
1.111 + TPtrC8 ptr((TUint8 *) &sc, sizeof(TServiceConfig));
1.112 + aMessage.WriteL(0, ptr, i*sizeof(TServiceConfig));
1.113 + }
1.114 + iServiceConfig.Close();
1.115 + return ETrue; // Complete request with KErrNone
1.116 + }
1.117 +
1.118 + case EDeleteDatabase:
1.119 + TRAPD(err, UpsServer()->iDbHandle->DeleteDatabaseL(UpsServer()->iFs));
1.120 + UpsServer()->iDbHandle.Close();
1.121 + User::LeaveIfError(err);
1.122 + return ETrue; // Complete request with KErrNone
1.123 +
1.124 + case ECreateView:
1.125 + {
1.126 + if(iManagementView != 0)
1.127 + {
1.128 + User::Leave(KErrServerBusy);
1.129 + }
1.130 +
1.131 + CViewEvaluator *viewEvaluator = CViewEvaluator::NewLC(this, aMessage);
1.132 + viewEvaluator->TransferToScsFrameworkL();
1.133 + CleanupStack::Pop(viewEvaluator); // view now owned by SCS framework
1.134 +
1.135 + /**
1.136 + The CViewEvaluator is now responsible for completing the request,
1.137 + so we must NOT leave.
1.138 + */
1.139 + viewEvaluator->StartEvaluatingView();
1.140 + return EFalse; // Do not complete client request - view evaulator will...
1.141 + }
1.142 +
1.143 + case ENextMatch:
1.144 + {
1.145 + if((iManagementView == 0) || (iRecord == 0))
1.146 + {
1.147 + User::Leave(KErrAbort);
1.148 + }
1.149 +
1.150 + // Copy the record to arg 0
1.151 + RIpcWriteStream ipcstream;
1.152 + ipcstream.Open(aMessage, 0);
1.153 + CleanupClosePushL(ipcstream);
1.154 +
1.155 + ipcstream << *iRecord;
1.156 +
1.157 + CleanupStack::PopAndDestroy(&ipcstream);
1.158 +
1.159 + // Update arg 1 with the length of the next record.
1.160 + PrefetchRecordAndWriteLengthToClientL(aMessage);
1.161 + return ETrue; // Complete client request with KErrNone
1.162 + }
1.163 +
1.164 + case ECloseView:
1.165 + {
1.166 + CleanupView();
1.167 + return ETrue; // Complete client request with KErrNone
1.168 + }
1.169 +
1.170 + case ERemoveDecisions:
1.171 + {
1.172 + // Read filter from the client arg 0
1.173 + RIpcReadStream ipcstream;
1.174 + ipcstream.Open(aMessage, 0);
1.175 + CleanupClosePushL(ipcstream);
1.176 + CDecisionFilter *filter = CDecisionFilter::NewLC();
1.177 + ipcstream >> *filter;
1.178 +
1.179 + UpsServer()->iDbHandle->RemoveDecisionsL(*filter);
1.180 +
1.181 + CleanupStack::PopAndDestroy(filter);
1.182 + CleanupStack::PopAndDestroy(&ipcstream);
1.183 + return ETrue; // Complete client request with KErrNone
1.184 + }
1.185 +
1.186 + case EUpdateDecision:
1.187 + {
1.188 + CUpdateEvaluator *updateEvaluator = CUpdateEvaluator::NewLC(this, aMessage);
1.189 + updateEvaluator->TransferToScsFrameworkL();
1.190 + CleanupStack::Pop(updateEvaluator); // view now owned by SCS framework
1.191 +
1.192 + /**
1.193 + The CViewEvaluator is now responsible for completing the request,
1.194 + so we must NOT leave.
1.195 + */
1.196 + updateEvaluator->StartUpdate();
1.197 + return EFalse; // Do not complete client request - view evaulator will...
1.198 + }
1.199 +
1.200 + case EDeleteDecisionsForExe:
1.201 + {
1.202 + TUid exeSid;
1.203 + exeSid.iUid = aMessage.Int0();
1.204 +
1.205 + CDecisionFilter *filter = CDecisionFilter::NewLC();
1.206 + filter->SetClientSid(exeSid, EEqual);
1.207 +
1.208 + UpsServer()->iDbHandle->RemoveDecisionsL(*filter);
1.209 +
1.210 + CleanupStack::PopAndDestroy(filter);
1.211 +
1.212 + return ETrue; // Complete client request with KErrNone
1.213 + }
1.214 +
1.215 + case ENotifyPluginsMayHaveChanged:
1.216 + // Tell plugin manager to unload, and hence reload, plugins ASAP.
1.217 + UpsServer()->iPluginManager->Unload();
1.218 + return ETrue; // Complete client request with KErrNone
1.219 +
1.220 + case ENotifyPolicyFilesChanged:
1.221 + {
1.222 + CPolicyChangeEvaluator *changeEvaluator = CPolicyChangeEvaluator::NewLC(UpsServer()->iPolicyCache, this, aMessage);
1.223 + changeEvaluator->TransferToScsFrameworkL();
1.224 + CleanupStack::Pop(changeEvaluator); // Nnow owned by SCS framework
1.225 +
1.226 + /**
1.227 + The CPolicyChangeEvaluator is now responsible for completing the request,
1.228 + so we must NOT leave.
1.229 + */
1.230 + changeEvaluator->StartUpdate();
1.231 +
1.232 + // Release our reference to the policy cache
1.233 + UpsServer()->iPolicyCache.Release();
1.234 +
1.235 + return EFalse; // Do not complete client request - policy change evaluator will...
1.236 + }
1.237 + BULLSEYE_OFF
1.238 + default:
1.239 + break;
1.240 + BULLSEYE_RESTORE
1.241 + }
1.242 +
1.243 + BULLSEYE_OFF
1.244 + User::Leave(KErrNotSupported);
1.245 + /*lint -unreachable */
1.246 + return ETrue;
1.247 + BULLSEYE_RESTORE
1.248 + }
1.249 +
1.250 +CScsSubsession* CUpsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
1.251 +/**
1.252 + Override CScsSession by allocating a new subsession object.
1.253 +
1.254 + @param aFunction Function identifier without SCS code.
1.255 + @param aMessage Standard server-side handle to message. Not used.
1.256 + @return New, initialized instance of CUpsSubsession, which is
1.257 + owned by the caller.
1.258 + */
1.259 + {
1.260 + TSessionFunction f = static_cast<TSessionFunction>(aFunction);
1.261 +
1.262 + switch (f)
1.263 + {
1.264 + case ESessSubsessFromThreadId:
1.265 + // create a subsession object curried on the supplied thread ID.
1.266 + return CUpsSubsession::NewL(*this, aMessage);
1.267 +
1.268 + default:
1.269 + User::Leave(KErrNotSupported);
1.270 + /*lint -unreachable */
1.271 + return 0; // avoid compiler warning
1.272 + }
1.273 + }
1.274 +
1.275 +void CUpsSession::PrefetchRecordAndWriteLengthToClientL(const RMessagePtr2& aMessage)
1.276 +/**
1.277 + Retrieve the next record from the iManagementView and return its length to the
1.278 + client in arg 1.
1.279 +*/
1.280 + {
1.281 + if(iManagementView == 0)
1.282 + {
1.283 + User::Leave(KErrEof);
1.284 + }
1.285 +
1.286 + TPckgBuf<TUint32> nextRecordLenghthBuf;
1.287 +
1.288 + delete iRecord;
1.289 + iRecord = 0;
1.290 + TRAPD(err, iRecord = iManagementView->NextDecisionL());
1.291 + if((err != KErrNone) || (iRecord == 0))
1.292 + {
1.293 + nextRecordLenghthBuf() = 0;
1.294 + }
1.295 + else
1.296 + {
1.297 + RNullWriteStream nullstream;
1.298 + nullstream << *iRecord;
1.299 + nextRecordLenghthBuf() = nullstream.BytesWritten();
1.300 + }
1.301 +
1.302 + aMessage.WriteL(1, nextRecordLenghthBuf);
1.303 + }
1.304 +
1.305 +void CUpsSession::CleanupView()
1.306 +/**
1.307 + Cleanup view objects
1.308 +*/
1.309 + {
1.310 + delete iManagementView;
1.311 + iManagementView = 0;
1.312 + delete iRecord;
1.313 + iRecord = 0;
1.314 + }
1.315 +
1.316 +void CUpsSession::DbHandleAboutToBeDeleted()
1.317 +/**
1.318 + Master DB handle is about to be deleted, so we must delete our view now.
1.319 + This will also cause the next RUpsManageMent::NextMatchL call to leave.
1.320 +*/
1.321 + {
1.322 + if(iManagementView)
1.323 + {
1.324 + iManagementView->Cancel();
1.325 + CleanupView();
1.326 + }
1.327 + }
1.328 +
1.329 +} // End of namespace UserPromptService
1.330 +// End of file