os/security/cryptomgmtlibs/securitycommonutils/source/scsserver/scssession.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptomgmtlibs/securitycommonutils/source/scsserver/scssession.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,380 @@
     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 +* CScsSession implementation.	 See class and function definitions
    1.19 +* for more detail.
    1.20 +*
    1.21 +*/
    1.22 +
    1.23 +
    1.24 +/**
    1.25 + @file
    1.26 +*/
    1.27 +
    1.28 +
    1.29 +#include <scs/scsserver.h>
    1.30 +#include "scsserverconstants.h"
    1.31 +
    1.32 +EXPORT_C void CScsSession::ConstructL()
    1.33 +/**
    1.34 +	The subsession [handle] container could be constructed
    1.35 +	here, but that is deferred until the subsession is allocated to
    1.36 +	avoid the memory overhead for sessions which may not require
    1.37 +	subsessions.
    1.38 + */
    1.39 +	{
    1.40 +	iServer.IncrementSessionCount();
    1.41 +	}
    1.42 +
    1.43 +EXPORT_C CScsSession::CScsSession(CScsServer &aServer)
    1.44 +	: iServer(aServer)
    1.45 +/**
    1.46 +   Setup the iServer member variable so it can be used during construction
    1.47 + */
    1.48 +	{
    1.49 +	}
    1.50 +
    1.51 +
    1.52 +EXPORT_C CScsSession::~CScsSession()
    1.53 +/**
    1.54 +	Deletes any subsessions.
    1.55 +
    1.56 +	Deletes any outstanding requests.
    1.57 +
    1.58 +	Decrements the server's session count so the server can be shut down
    1.59 +	if there are no open sessions.
    1.60 + */
    1.61 +	{
    1.62 +	iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ EFalse);
    1.63 +	
    1.64 +	DeleteSubsessionContainers();	// closes any remaining subsessions
    1.65 +	
    1.66 +	// decrement the session count, so the server can be shut down if
    1.67 +	// there are no more open sessions.
    1.68 +	iServer.DecrementSessionCount();
    1.69 +	}
    1.70 +	
    1.71 +EXPORT_C void CScsSession::CloseAllSubsessionsL()
    1.72 +	{
    1.73 +	DeleteSubsessionContainers();
    1.74 +	}
    1.75 +
    1.76 +EXPORT_C void CScsSession::ServiceL(const RMessage2& aMessage)
    1.77 +/**
    1.78 +	Implement CSession2 by handling any SCS-specific messages, and
    1.79 +	otherwise delegating to the subclass' implementation.
    1.80 +
    1.81 +	@param	aMessage		Standard server-side message object.
    1.82 + */
    1.83 +	{
    1.84 +	ScsImpl::TScsFunction scsFunc;
    1.85 +	TInt implFunc;
    1.86 +	ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, &implFunc);
    1.87 +	TBool completeMessage = ETrue;
    1.88 +	
    1.89 +	switch (scsFunc)
    1.90 +		{
    1.91 +	// sessions
    1.92 +	case ScsImpl::ECallSessionFunc:
    1.93 +		completeMessage = DoServiceL(implFunc, aMessage);
    1.94 +		break;
    1.95 +	
    1.96 +	case ScsImpl::EPreCloseSession:
    1.97 +		PreCloseSession();
    1.98 +		break;
    1.99 +	
   1.100 +	case ScsImpl::ECancelSessionFunc:
   1.101 +		CancelAsyncSessionRequestL(implFunc);
   1.102 +		break;
   1.103 +
   1.104 +	case ScsImpl::EGetServerPid:
   1.105 +		{
   1.106 +		TPckgBuf<TProcessId> idBuf;
   1.107 +		RProcess proc;
   1.108 +		idBuf() = proc.Id();
   1.109 +		aMessage.WriteL(0, idBuf);
   1.110 +		break;
   1.111 +		}
   1.112 +
   1.113 +	case ScsImpl::EShutdownAsap:
   1.114 +		iServer.ShutdownWhenIdleL();
   1.115 +		break;
   1.116 +
   1.117 +	// subsessions
   1.118 +	case ScsImpl::ECreateSubsession:
   1.119 +		// if there are no open subsessions before this attempt then clean up
   1.120 +		// the containers if it fails.	This is to ensure the server heap balances
   1.121 +		// in the event of failure.
   1.122 +		iPreCreateSubsessionCount = iSsHandles ? iSsHandles->ActiveCount() : 0;
   1.123 +		CreateSubsessionL(implFunc, aMessage);
   1.124 +		break;
   1.125 +	
   1.126 +	case ScsImpl::ECloseSubsession:
   1.127 +		CloseSubsessionL(aMessage);
   1.128 +		break;
   1.129 +	
   1.130 +	case ScsImpl::ECallSubsessionFunc:
   1.131 +		completeMessage = CallSubsessionFunctionL(implFunc, aMessage);
   1.132 +		break;
   1.133 +	
   1.134 +	case ScsImpl::ECancelSubsessionFunc:
   1.135 +		CancelAsyncSubsessionRequestL(implFunc, aMessage);
   1.136 +		break;
   1.137 +	
   1.138 +	// server heap testing
   1.139 +	case ScsImpl::EUHeapSetFail:
   1.140 +#ifdef _DEBUG
   1.141 +		iServer.DoPreHeapMarkOrCheckL();
   1.142 +		__UHEAP_MARK;
   1.143 +		__UHEAP_SETFAIL(RAllocator::EDeterministic, aMessage.Int0());
   1.144 +		iServer.DoPostHeapMarkOrCheckL();
   1.145 +#endif
   1.146 +		break;
   1.147 +	
   1.148 +	case ScsImpl::EUHeapResetFail:
   1.149 +#ifdef _DEBUG
   1.150 +		iServer.DoPreHeapMarkOrCheckL();
   1.151 +		__UHEAP_RESET;
   1.152 +		__UHEAP_MARKEND;
   1.153 +		iServer.DoPostHeapMarkOrCheckL();
   1.154 +#endif
   1.155 +		break;
   1.156 +	
   1.157 +	// unrecognized SCS code, so fail with KErrNotSupported
   1.158 +	default:
   1.159 +		User::Leave(KErrNotSupported);
   1.160 +		}
   1.161 +	
   1.162 +	// None of the delegate functions have left so complete with KErrNone.
   1.163 +	if(completeMessage)
   1.164 +		{
   1.165 +		aMessage.Complete(KErrNone);
   1.166 +		}
   1.167 +	}
   1.168 +
   1.169 +EXPORT_C void CScsSession::ServiceError(const RMessage2& aMessage, TInt aError)
   1.170 +/**
   1.171 +	Override CSession2 by handling any leave which occurred during the ServiceL.
   1.172 +
   1.173 +	Panick the client if the leave is because of a bad descriptor or subsession
   1.174 +	handle.	 Otherwise, complete the request with the error code.
   1.175 +
   1.176 +	@param	aMessage		Message which caused leave to occur.
   1.177 +	@param	aError			Leave code.	 This is a Symbian OS error code.
   1.178 +	@see CSession2::ServiceError
   1.179 + */
   1.180 +	{
   1.181 +	// if failed to create first subsession then free containers so heap
   1.182 +	// balances after message has been completed.
   1.183 +	
   1.184 +	ScsImpl::TScsFunction scsFunc;
   1.185 +	ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, NULL);
   1.186 +	
   1.187 +	if (scsFunc == ScsImpl::ECreateSubsession && iPreCreateSubsessionCount == 0)
   1.188 +		DeleteSubsessionContainers();
   1.189 +	
   1.190 +	switch (aError)
   1.191 +		{
   1.192 +	case KErrBadDescriptor:
   1.193 +		PanicClient(aMessage, ScsImpl::EScsClBadDesc);
   1.194 +		break;
   1.195 +	
   1.196 +	case KErrBadHandle:
   1.197 +		PanicClient(aMessage, ScsImpl::EScsClBadHandle);
   1.198 +		break;
   1.199 +	
   1.200 +	case KErrScsAsyncAlreadyQueued:
   1.201 +		PanicClient(aMessage, ScsImpl::EScsClAsyncAlreadyQueued);
   1.202 +		break;
   1.203 +
   1.204 +	default:
   1.205 +		aMessage.Complete(aError);
   1.206 +		break;
   1.207 +		}
   1.208 +	}
   1.209 +
   1.210 +// -------- session close --------
   1.211 +
   1.212 +void CScsSession::PreCloseSession()
   1.213 +/**
   1.214 +	This function is invoked from RScsClientBase::Close
   1.215 +	just before the session is closed, to cancel any
   1.216 +	outstanding requests.
   1.217 + */
   1.218 +	{
   1.219 +	iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ ETrue);
   1.220 +	}
   1.221 +
   1.222 +// -------- asynchronous requests --------
   1.223 +
   1.224 +void CScsSession::CancelAsyncSessionRequestL(TInt aFunction)
   1.225 +/**
   1.226 +	This function is called when handling an ECancelSessionFunction message.
   1.227 +	If the outstanding function cannot be found, this function does nothing.
   1.228 +
   1.229 +	@param aFunction		Implementation function without SCS code.
   1.230 + */
   1.231 +	{
   1.232 +	iServer.CancelAsyncRequest(this, /* aSubsession */ 0, aFunction);
   1.233 +	}
   1.234 +
   1.235 +// -------- subsessions --------
   1.236 +
   1.237 +CScsSubsession* CScsSession::GetSubsessionL(const RMessage2& aMessage)
   1.238 +/**
   1.239 +	Extract subsession handle from the supplied message and return
   1.240 +	a pointer to the corresponding subsession object.
   1.241 +	
   1.242 +	@param	aMessage		Standard server-side message object.  The fourth
   1.243 +							argument is the subsession handle.
   1.244 +	@return					Pointer to corresponding subsession object.
   1.245 +	@leave					KErrBadHandle if the handle does not identify a
   1.246 +							current subsession.
   1.247 + */
   1.248 +	{
   1.249 +	TInt handle = aMessage.Int3();
   1.250 +	CObject* obj = iSsHandles->AtL(handle);	// leaves with KErrBadHandle if not found
   1.251 +	return static_cast<CScsSubsession*>(obj);
   1.252 +	}
   1.253 +
   1.254 +void CScsSession::DeleteSubsessionContainers()
   1.255 +/**
   1.256 +	Free the handle and object containers which this session uses
   1.257 +	to manage subsessions.	It is safe to call this function if the
   1.258 +	containers were not set up successfully.
   1.259 + */
   1.260 +	{
   1.261 +	delete iSsHandles;
   1.262 +	iSsHandles = 0;
   1.263 +
   1.264 +	if (iSsObjects != 0)
   1.265 +		{
   1.266 +		iServer.iContainerIndex->Remove(iSsObjects);
   1.267 +		iSsObjects = 0;
   1.268 +		}
   1.269 +	}
   1.270 +
   1.271 +void CScsSession::CreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
   1.272 +/**
   1.273 +	Attempt to allocate a subsession object for this session.  The actual
   1.274 +	subsession allocation is delegated to the subclass's implementation
   1.275 +	of DoCreateSubsessionL.	 If the subclass has not reimplemented this
   1.276 +	function, then default implementation leaves with KErrNotSupported.
   1.277 +	
   1.278 +	@param	aFunction		Function identifier without SCS code.
   1.279 +	@param	aMessage		Standard server-side message object.
   1.280 + */
   1.281 +	{
   1.282 +	// if this is the first subsession then create the object container and index
   1.283 +	if (iSsObjects == 0)
   1.284 +		{
   1.285 +		iSsObjects = iServer.iContainerIndex->CreateL();
   1.286 +		iSsHandles = CObjectIx::NewL();
   1.287 +		}
   1.288 +	
   1.289 +	CScsSubsession* ss = DoCreateSubsessionL(aFunction, aMessage);
   1.290 +	CleanupClosePushL(*ss);
   1.291 +
   1.292 +	iSsObjects->AddL(ss);
   1.293 +	TInt handle = iSsHandles->AddL(ss);
   1.294 +	CleanupStack::Pop(ss);
   1.295 +	
   1.296 +	TPckg<TInt> handlePckg(handle);
   1.297 +	TInt r = aMessage.Write(3, handlePckg);
   1.298 +	User::LeaveIfError(r);
   1.299 +	}
   1.300 +
   1.301 +#ifdef _BullseyeCoverage
   1.302 +static const char * const bull1="BullseyeCoverage save off";
   1.303 +#endif
   1.304 +EXPORT_C CScsSubsession* CScsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
   1.305 +/**
   1.306 +	This default implementation leaves with KErrNotSupported.  The subclass
   1.307 +	does not have to supply its own implementation unless it actually wants
   1.308 +	to support subsessions.
   1.309 +	
   1.310 +	@param	aFunction		Function identifier without SCS code.  The subclass
   1.311 +							implementation of this function would use this to decide
   1.312 +							what kind of subsession object to create.
   1.313 +	@param	aMessage		Client message.	 Not used.
   1.314 +	@leave					KErrNotSupported.
   1.315 + */
   1.316 +	{
   1.317 +	(void) aFunction;
   1.318 +	(void) aMessage;
   1.319 +	
   1.320 +	User::Leave(KErrNotSupported);	
   1.321 +	/*lint -unreachable*/ // Avoid compiler warning and keep lint happy
   1.322 +	return 0;	
   1.323 +	}
   1.324 +#ifdef _BullseyeCoverage
   1.325 +static const char * const bull2="BullseyeCoverage restore";
   1.326 +#endif
   1.327 +
   1.328 +void CScsSession::CloseSubsessionL(const RMessage2& aMessage)
   1.329 +/**
   1.330 +	Delete the subsession identified in the supplied message.
   1.331 +
   1.332 +	If the subsession cannot be found this function leaves with KErrBadHandle,
   1.333 +	and the client is panicked in ServiceError.
   1.334 +
   1.335 +	@param	aMessage		Standard server-side message handle.  The fourth
   1.336 +							integer contains the subsession handle.
   1.337 + */
   1.338 +	{
   1.339 +	TInt handle = aMessage.Int3();
   1.340 +	CObject* obj = iSsHandles->AtL(handle);	// leaves with KErrBadHandle if not found
   1.341 +	CScsSubsession* ss = static_cast<CScsSubsession*>(obj);
   1.342 +	
   1.343 +	iServer.CancelOutstandingRequests(this, ss, /* aCancelClientRequests */ ETrue);
   1.344 +
   1.345 +	iSsHandles->Remove(handle);
   1.346 +	
   1.347 +	// close the container objects to ensure the heap balances when the last subsession is closed
   1.348 +	if (iSsHandles->ActiveCount() == 0)
   1.349 +		DeleteSubsessionContainers();
   1.350 +	}
   1.351 +
   1.352 +TBool CScsSession::CallSubsessionFunctionL(TInt aFunction, const RMessage2& aMessage)
   1.353 +/**
   1.354 +	Pass the supplied function identifier and message to the subsession
   1.355 +	which is identified in the message.
   1.356 +
   1.357 +	If the subsession cannot be found this function leaves with KErrBadHandle,
   1.358 +	and the client is panicked in ServiceError.
   1.359 +
   1.360 +	@param	aFunction		Function identifier without SCS code.
   1.361 +	@param	aMessage		Client message.
   1.362 +	@return ETrue means complete client request now.
   1.363 +
   1.364 + */
   1.365 +	{
   1.366 +	CScsSubsession* ss = GetSubsessionL(aMessage);
   1.367 +	return ss->DoServiceL(aFunction, aMessage);
   1.368 +	}
   1.369 +
   1.370 +void CScsSession::CancelAsyncSubsessionRequestL(TInt aFunction, const RMessage2& aMessage)
   1.371 +/**
   1.372 +	Cancel an outstanding asynchronous request for the subsession
   1.373 +	identified in the supplied message.
   1.374 +
   1.375 +	@param	aFunction		Function identifier without SCS code.
   1.376 +	@param	aMessage		Standard server-side message handle.  The fourth
   1.377 +							integer contains the subsession handle.
   1.378 + */
   1.379 +	{
   1.380 +	CScsSubsession* ss = GetSubsessionL(aMessage);
   1.381 +	iServer.CancelAsyncRequest(this, ss, aFunction);
   1.382 +	}
   1.383 +