os/security/authorisation/userpromptservice/server/source/upsserver/upssession.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 * Implements CUpsSession.	 See class and function definitions for
    16 * more information.
    17 *
    18 */
    19 
    20 
    21 /**
    22  @file
    23 */
    24 
    25 #include "upsserver.h"
    26 #include "policycache.h"
    27 #include <ups/upsdbw.h>
    28 #include <scs/ipcstream.h>
    29 #include <scs/nullstream.h>
    30 #include "pluginmanager.h"
    31 #include "viewevaluator.h"
    32 #include "updateevaluator.h"
    33 #include "policychangeevaluator.h"
    34 
    35 namespace UserPromptService
    36 {
    37 
    38 CUpsSession* CUpsSession::NewL(CUpsServer &aServer)
    39 /**
    40 	Factory function allocates new instance of CUpsSession.
    41 
    42 	@return					New, initialized instance of CUpsSession
    43 							which is owned by the caller.
    44  */
    45 	{
    46 	CUpsSession* self = new(ELeave) CUpsSession(aServer);
    47 	CleanupStack::PushL(self);
    48 	self->ConstructL();			// CScsSession implementation
    49 	CleanupStack::Pop(self);
    50 	return self;
    51 	}
    52 
    53 CUpsSession::CUpsSession(CUpsServer &aServer)
    54 /**
    55 	This private constructor prevents direct instantiation.
    56  */
    57  :	CScsSession(aServer), iDbViewHandle(aServer.iDbHandle, this)
    58 	{
    59 	// empty.
    60 	//RDebug::Printf("0x%x CUpsSession(server %x) (&iDbViewHandle %x)\n", this, &aServer, &iDbViewHandle);
    61 	}
    62 
    63 CUpsSession::~CUpsSession()
    64 /**
    65 	The base class destructor destroys any remaining subsessions
    66 	or outstanding requests.
    67  */
    68 	{
    69 	//RDebug::Printf("0x%x ~CUpsSession (&iDbViewHandle %x)\n", this, &iDbViewHandle);
    70 	CleanupView();
    71 	iServiceConfig.Close();
    72 
    73 	iDbViewHandle.Close();
    74 	}
    75 
    76 TBool CUpsSession::DoServiceL(TInt aFunction, const RMessage2& aMessage)
    77 /**
    78 	Implement CScsSession by handling the supplied message.
    79 
    80 	Note the subsession creation command is automatically sent to
    81 	DoCreateSubsessionL, and not this function.
    82 
    83 	@param	aFunction		Function identifier without SCS code.
    84 	@param	aMessage		Standard server-side handle to message.	 Not used.
    85  */
    86 	{
    87 	TSessionFunction f = static_cast<TSessionFunction>(aFunction);
    88 	//RDebug::Printf("0x%x CUpsSession::DoServiceL function %d\n", this, f);
    89 	switch (f)
    90 		{
    91 		case EGetClientConfigLength:
    92 			{
    93 			iServiceConfig.Close();
    94 			UpsServer()->iPolicyCache->ServiceConfigL(aMessage.SecureId(), iServiceConfig);
    95 
    96 			TPckgBuf<TInt> lengthBuf;
    97 			lengthBuf() = iServiceConfig.Count();
    98 			aMessage.WriteL(0, lengthBuf);
    99 			return ETrue; // Complete request with KErrNone
   100 			}
   101 
   102 		case EGetClientConfigData:
   103 			{
   104 			TInt count = iServiceConfig.Count();
   105 			for(TInt i=0; i < count; ++i)
   106 				{
   107 				const TServiceConfig &sc = iServiceConfig[i];
   108 				TPtrC8 ptr((TUint8 *) &sc, sizeof(TServiceConfig));
   109 				aMessage.WriteL(0, ptr, i*sizeof(TServiceConfig));
   110 				}
   111 			iServiceConfig.Close();
   112 			return ETrue; // Complete request with KErrNone
   113 			}
   114 
   115 		case EDeleteDatabase:
   116 			TRAPD(err, UpsServer()->iDbHandle->DeleteDatabaseL(UpsServer()->iFs));
   117 			UpsServer()->iDbHandle.Close();
   118 			User::LeaveIfError(err);
   119 			return ETrue; // Complete request with KErrNone
   120 
   121 		case ECreateView:
   122 			{
   123 			if(iManagementView != 0)
   124 				{
   125 				User::Leave(KErrServerBusy);
   126 				}
   127 			
   128 			CViewEvaluator *viewEvaluator = CViewEvaluator::NewLC(this, aMessage);
   129 			viewEvaluator->TransferToScsFrameworkL();
   130 			CleanupStack::Pop(viewEvaluator); // view now owned by SCS framework
   131 
   132 			/**
   133 			   	The CViewEvaluator is now responsible for completing the request,
   134 	   			so we must NOT leave.
   135 	   		*/
   136 			viewEvaluator->StartEvaluatingView();
   137 			return EFalse; // Do not complete client request - view evaulator will...
   138 			}
   139 
   140 		case ENextMatch:
   141 			{
   142 			if((iManagementView == 0) || (iRecord == 0))
   143 				{
   144 				User::Leave(KErrAbort);
   145 				}
   146 
   147 			// Copy the record to arg 0
   148 			RIpcWriteStream ipcstream;
   149 			ipcstream.Open(aMessage, 0);
   150 			CleanupClosePushL(ipcstream);
   151 
   152 			ipcstream << *iRecord;
   153 
   154 			CleanupStack::PopAndDestroy(&ipcstream);
   155 
   156 			// Update arg 1 with the length of the next record.
   157 			PrefetchRecordAndWriteLengthToClientL(aMessage);
   158 			return ETrue; // Complete client request with KErrNone
   159 			}
   160 
   161 		case ECloseView:
   162 			{
   163 			CleanupView();
   164 			return ETrue; // Complete client request with KErrNone
   165 			}
   166 
   167 		case ERemoveDecisions:
   168 			{
   169 			// Read filter from the client arg 0
   170 			RIpcReadStream ipcstream;
   171 			ipcstream.Open(aMessage, 0);
   172 			CleanupClosePushL(ipcstream);
   173 			CDecisionFilter *filter = CDecisionFilter::NewLC();
   174 			ipcstream >> *filter;
   175 
   176 			UpsServer()->iDbHandle->RemoveDecisionsL(*filter);
   177 
   178 			CleanupStack::PopAndDestroy(filter);
   179 			CleanupStack::PopAndDestroy(&ipcstream);
   180 			return ETrue; // Complete client request with KErrNone
   181 			}
   182 
   183 		case EUpdateDecision:
   184 			{
   185 			CUpdateEvaluator *updateEvaluator = CUpdateEvaluator::NewLC(this, aMessage);
   186 			updateEvaluator->TransferToScsFrameworkL();
   187 			CleanupStack::Pop(updateEvaluator); // view now owned by SCS framework
   188 
   189 			/**
   190 			   	The CViewEvaluator is now responsible for completing the request,
   191 	   			so we must NOT leave.
   192 	   		*/
   193 			updateEvaluator->StartUpdate();
   194 			return EFalse; // Do not complete client request - view evaulator will...
   195 			}
   196 
   197 		case EDeleteDecisionsForExe:
   198 			{
   199 			TUid exeSid;
   200 			exeSid.iUid = aMessage.Int0();
   201 
   202 			CDecisionFilter *filter = CDecisionFilter::NewLC();
   203 			filter->SetClientSid(exeSid, EEqual);
   204 
   205 			UpsServer()->iDbHandle->RemoveDecisionsL(*filter);
   206 
   207 			CleanupStack::PopAndDestroy(filter);
   208 
   209 			return ETrue; // Complete client request with KErrNone
   210 			}
   211 			
   212 		case ENotifyPluginsMayHaveChanged:
   213 			// Tell plugin manager to unload, and hence reload, plugins ASAP.
   214 			UpsServer()->iPluginManager->Unload();
   215 			return ETrue; // Complete client request with KErrNone
   216 			
   217 		case ENotifyPolicyFilesChanged:
   218 			{
   219 			CPolicyChangeEvaluator *changeEvaluator = CPolicyChangeEvaluator::NewLC(UpsServer()->iPolicyCache, this, aMessage);
   220 			changeEvaluator->TransferToScsFrameworkL();
   221 			CleanupStack::Pop(changeEvaluator); // Nnow owned by SCS framework
   222 
   223 			/**
   224 			   	The CPolicyChangeEvaluator is now responsible for completing the request,
   225 	   			so we must NOT leave.
   226 	   		*/
   227 			changeEvaluator->StartUpdate();
   228 
   229 			// Release our reference to the policy cache
   230 			UpsServer()->iPolicyCache.Release();
   231 			
   232 			return EFalse; // Do not complete client request - policy change  evaluator will...
   233 			}
   234 		BULLSEYE_OFF
   235 		default:
   236 			break;
   237 		BULLSEYE_RESTORE
   238 		}
   239 
   240 	BULLSEYE_OFF
   241 	User::Leave(KErrNotSupported);
   242 	/*lint -unreachable */
   243 	return ETrue;
   244 	BULLSEYE_RESTORE
   245 	}
   246 
   247 CScsSubsession* CUpsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
   248 /**
   249 	Override CScsSession by allocating a new subsession object.
   250 
   251 	@param	aFunction		Function identifier without SCS code.
   252 	@param	aMessage		Standard server-side handle to message.	 Not used.
   253 	@return					New, initialized instance of CUpsSubsession, which is
   254 							owned by the caller.
   255  */
   256 	{
   257 	TSessionFunction f = static_cast<TSessionFunction>(aFunction);
   258 
   259 	switch (f)
   260 		{
   261 	case ESessSubsessFromThreadId:
   262 		// create a subsession object curried on the supplied thread ID.
   263 		return CUpsSubsession::NewL(*this, aMessage);
   264 
   265 	default:
   266 		User::Leave(KErrNotSupported);
   267 		/*lint -unreachable */
   268 		return 0;			// avoid compiler warning
   269 		}
   270 	}
   271 
   272 void CUpsSession::PrefetchRecordAndWriteLengthToClientL(const RMessagePtr2& aMessage)
   273 /**
   274 	Retrieve the next record from the iManagementView and return its length to the 
   275 	client in arg 1.
   276 */
   277 	{
   278 	if(iManagementView == 0)
   279 		{
   280 		User::Leave(KErrEof);
   281 		}
   282 
   283 	TPckgBuf<TUint32> nextRecordLenghthBuf;
   284 
   285 	delete iRecord;
   286 	iRecord = 0;
   287 	TRAPD(err, iRecord = iManagementView->NextDecisionL());
   288 	if((err != KErrNone) || (iRecord == 0))
   289 		{
   290 		nextRecordLenghthBuf() = 0;
   291 		}
   292 	else
   293 		{
   294 		RNullWriteStream nullstream;
   295 		nullstream << *iRecord;
   296 		nextRecordLenghthBuf() = nullstream.BytesWritten();
   297 		}
   298 
   299 	aMessage.WriteL(1, nextRecordLenghthBuf);
   300 	}
   301 
   302 void CUpsSession::CleanupView()
   303 /**
   304 	Cleanup view objects
   305 */
   306 	{
   307 	delete iManagementView;
   308 	iManagementView = 0;
   309 	delete iRecord;
   310 	iRecord = 0;
   311 	}
   312 
   313 void CUpsSession::DbHandleAboutToBeDeleted()
   314 /**
   315 	Master DB handle is about to be deleted, so we must delete our view now.
   316 	This will also cause the next RUpsManageMent::NextMatchL call to leave.
   317 */
   318 	{
   319 	if(iManagementView)
   320 		{
   321 		iManagementView->Cancel();
   322 		CleanupView();
   323 		}
   324 	}
   325 
   326 } // End of namespace UserPromptService
   327 // End of file