os/security/cryptomgmtlibs/securitycommonutils/source/scsserver/scssession.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 * CScsSession implementation.	 See class and function definitions
    16 * for more detail.
    17 *
    18 */
    19 
    20 
    21 /**
    22  @file
    23 */
    24 
    25 
    26 #include <scs/scsserver.h>
    27 #include "scsserverconstants.h"
    28 
    29 EXPORT_C void CScsSession::ConstructL()
    30 /**
    31 	The subsession [handle] container could be constructed
    32 	here, but that is deferred until the subsession is allocated to
    33 	avoid the memory overhead for sessions which may not require
    34 	subsessions.
    35  */
    36 	{
    37 	iServer.IncrementSessionCount();
    38 	}
    39 
    40 EXPORT_C CScsSession::CScsSession(CScsServer &aServer)
    41 	: iServer(aServer)
    42 /**
    43    Setup the iServer member variable so it can be used during construction
    44  */
    45 	{
    46 	}
    47 
    48 
    49 EXPORT_C CScsSession::~CScsSession()
    50 /**
    51 	Deletes any subsessions.
    52 
    53 	Deletes any outstanding requests.
    54 
    55 	Decrements the server's session count so the server can be shut down
    56 	if there are no open sessions.
    57  */
    58 	{
    59 	iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ EFalse);
    60 	
    61 	DeleteSubsessionContainers();	// closes any remaining subsessions
    62 	
    63 	// decrement the session count, so the server can be shut down if
    64 	// there are no more open sessions.
    65 	iServer.DecrementSessionCount();
    66 	}
    67 	
    68 EXPORT_C void CScsSession::CloseAllSubsessionsL()
    69 	{
    70 	DeleteSubsessionContainers();
    71 	}
    72 
    73 EXPORT_C void CScsSession::ServiceL(const RMessage2& aMessage)
    74 /**
    75 	Implement CSession2 by handling any SCS-specific messages, and
    76 	otherwise delegating to the subclass' implementation.
    77 
    78 	@param	aMessage		Standard server-side message object.
    79  */
    80 	{
    81 	ScsImpl::TScsFunction scsFunc;
    82 	TInt implFunc;
    83 	ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, &implFunc);
    84 	TBool completeMessage = ETrue;
    85 	
    86 	switch (scsFunc)
    87 		{
    88 	// sessions
    89 	case ScsImpl::ECallSessionFunc:
    90 		completeMessage = DoServiceL(implFunc, aMessage);
    91 		break;
    92 	
    93 	case ScsImpl::EPreCloseSession:
    94 		PreCloseSession();
    95 		break;
    96 	
    97 	case ScsImpl::ECancelSessionFunc:
    98 		CancelAsyncSessionRequestL(implFunc);
    99 		break;
   100 
   101 	case ScsImpl::EGetServerPid:
   102 		{
   103 		TPckgBuf<TProcessId> idBuf;
   104 		RProcess proc;
   105 		idBuf() = proc.Id();
   106 		aMessage.WriteL(0, idBuf);
   107 		break;
   108 		}
   109 
   110 	case ScsImpl::EShutdownAsap:
   111 		iServer.ShutdownWhenIdleL();
   112 		break;
   113 
   114 	// subsessions
   115 	case ScsImpl::ECreateSubsession:
   116 		// if there are no open subsessions before this attempt then clean up
   117 		// the containers if it fails.	This is to ensure the server heap balances
   118 		// in the event of failure.
   119 		iPreCreateSubsessionCount = iSsHandles ? iSsHandles->ActiveCount() : 0;
   120 		CreateSubsessionL(implFunc, aMessage);
   121 		break;
   122 	
   123 	case ScsImpl::ECloseSubsession:
   124 		CloseSubsessionL(aMessage);
   125 		break;
   126 	
   127 	case ScsImpl::ECallSubsessionFunc:
   128 		completeMessage = CallSubsessionFunctionL(implFunc, aMessage);
   129 		break;
   130 	
   131 	case ScsImpl::ECancelSubsessionFunc:
   132 		CancelAsyncSubsessionRequestL(implFunc, aMessage);
   133 		break;
   134 	
   135 	// server heap testing
   136 	case ScsImpl::EUHeapSetFail:
   137 #ifdef _DEBUG
   138 		iServer.DoPreHeapMarkOrCheckL();
   139 		__UHEAP_MARK;
   140 		__UHEAP_SETFAIL(RAllocator::EDeterministic, aMessage.Int0());
   141 		iServer.DoPostHeapMarkOrCheckL();
   142 #endif
   143 		break;
   144 	
   145 	case ScsImpl::EUHeapResetFail:
   146 #ifdef _DEBUG
   147 		iServer.DoPreHeapMarkOrCheckL();
   148 		__UHEAP_RESET;
   149 		__UHEAP_MARKEND;
   150 		iServer.DoPostHeapMarkOrCheckL();
   151 #endif
   152 		break;
   153 	
   154 	// unrecognized SCS code, so fail with KErrNotSupported
   155 	default:
   156 		User::Leave(KErrNotSupported);
   157 		}
   158 	
   159 	// None of the delegate functions have left so complete with KErrNone.
   160 	if(completeMessage)
   161 		{
   162 		aMessage.Complete(KErrNone);
   163 		}
   164 	}
   165 
   166 EXPORT_C void CScsSession::ServiceError(const RMessage2& aMessage, TInt aError)
   167 /**
   168 	Override CSession2 by handling any leave which occurred during the ServiceL.
   169 
   170 	Panick the client if the leave is because of a bad descriptor or subsession
   171 	handle.	 Otherwise, complete the request with the error code.
   172 
   173 	@param	aMessage		Message which caused leave to occur.
   174 	@param	aError			Leave code.	 This is a Symbian OS error code.
   175 	@see CSession2::ServiceError
   176  */
   177 	{
   178 	// if failed to create first subsession then free containers so heap
   179 	// balances after message has been completed.
   180 	
   181 	ScsImpl::TScsFunction scsFunc;
   182 	ScsImpl::ExtractScsAndImplFunctions(aMessage, &scsFunc, NULL);
   183 	
   184 	if (scsFunc == ScsImpl::ECreateSubsession && iPreCreateSubsessionCount == 0)
   185 		DeleteSubsessionContainers();
   186 	
   187 	switch (aError)
   188 		{
   189 	case KErrBadDescriptor:
   190 		PanicClient(aMessage, ScsImpl::EScsClBadDesc);
   191 		break;
   192 	
   193 	case KErrBadHandle:
   194 		PanicClient(aMessage, ScsImpl::EScsClBadHandle);
   195 		break;
   196 	
   197 	case KErrScsAsyncAlreadyQueued:
   198 		PanicClient(aMessage, ScsImpl::EScsClAsyncAlreadyQueued);
   199 		break;
   200 
   201 	default:
   202 		aMessage.Complete(aError);
   203 		break;
   204 		}
   205 	}
   206 
   207 // -------- session close --------
   208 
   209 void CScsSession::PreCloseSession()
   210 /**
   211 	This function is invoked from RScsClientBase::Close
   212 	just before the session is closed, to cancel any
   213 	outstanding requests.
   214  */
   215 	{
   216 	iServer.CancelOutstandingRequests(this, /* aCompleteClientRequests */ ETrue);
   217 	}
   218 
   219 // -------- asynchronous requests --------
   220 
   221 void CScsSession::CancelAsyncSessionRequestL(TInt aFunction)
   222 /**
   223 	This function is called when handling an ECancelSessionFunction message.
   224 	If the outstanding function cannot be found, this function does nothing.
   225 
   226 	@param aFunction		Implementation function without SCS code.
   227  */
   228 	{
   229 	iServer.CancelAsyncRequest(this, /* aSubsession */ 0, aFunction);
   230 	}
   231 
   232 // -------- subsessions --------
   233 
   234 CScsSubsession* CScsSession::GetSubsessionL(const RMessage2& aMessage)
   235 /**
   236 	Extract subsession handle from the supplied message and return
   237 	a pointer to the corresponding subsession object.
   238 	
   239 	@param	aMessage		Standard server-side message object.  The fourth
   240 							argument is the subsession handle.
   241 	@return					Pointer to corresponding subsession object.
   242 	@leave					KErrBadHandle if the handle does not identify a
   243 							current subsession.
   244  */
   245 	{
   246 	TInt handle = aMessage.Int3();
   247 	CObject* obj = iSsHandles->AtL(handle);	// leaves with KErrBadHandle if not found
   248 	return static_cast<CScsSubsession*>(obj);
   249 	}
   250 
   251 void CScsSession::DeleteSubsessionContainers()
   252 /**
   253 	Free the handle and object containers which this session uses
   254 	to manage subsessions.	It is safe to call this function if the
   255 	containers were not set up successfully.
   256  */
   257 	{
   258 	delete iSsHandles;
   259 	iSsHandles = 0;
   260 
   261 	if (iSsObjects != 0)
   262 		{
   263 		iServer.iContainerIndex->Remove(iSsObjects);
   264 		iSsObjects = 0;
   265 		}
   266 	}
   267 
   268 void CScsSession::CreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
   269 /**
   270 	Attempt to allocate a subsession object for this session.  The actual
   271 	subsession allocation is delegated to the subclass's implementation
   272 	of DoCreateSubsessionL.	 If the subclass has not reimplemented this
   273 	function, then default implementation leaves with KErrNotSupported.
   274 	
   275 	@param	aFunction		Function identifier without SCS code.
   276 	@param	aMessage		Standard server-side message object.
   277  */
   278 	{
   279 	// if this is the first subsession then create the object container and index
   280 	if (iSsObjects == 0)
   281 		{
   282 		iSsObjects = iServer.iContainerIndex->CreateL();
   283 		iSsHandles = CObjectIx::NewL();
   284 		}
   285 	
   286 	CScsSubsession* ss = DoCreateSubsessionL(aFunction, aMessage);
   287 	CleanupClosePushL(*ss);
   288 
   289 	iSsObjects->AddL(ss);
   290 	TInt handle = iSsHandles->AddL(ss);
   291 	CleanupStack::Pop(ss);
   292 	
   293 	TPckg<TInt> handlePckg(handle);
   294 	TInt r = aMessage.Write(3, handlePckg);
   295 	User::LeaveIfError(r);
   296 	}
   297 
   298 #ifdef _BullseyeCoverage
   299 static const char * const bull1="BullseyeCoverage save off";
   300 #endif
   301 EXPORT_C CScsSubsession* CScsSession::DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage)
   302 /**
   303 	This default implementation leaves with KErrNotSupported.  The subclass
   304 	does not have to supply its own implementation unless it actually wants
   305 	to support subsessions.
   306 	
   307 	@param	aFunction		Function identifier without SCS code.  The subclass
   308 							implementation of this function would use this to decide
   309 							what kind of subsession object to create.
   310 	@param	aMessage		Client message.	 Not used.
   311 	@leave					KErrNotSupported.
   312  */
   313 	{
   314 	(void) aFunction;
   315 	(void) aMessage;
   316 	
   317 	User::Leave(KErrNotSupported);	
   318 	/*lint -unreachable*/ // Avoid compiler warning and keep lint happy
   319 	return 0;	
   320 	}
   321 #ifdef _BullseyeCoverage
   322 static const char * const bull2="BullseyeCoverage restore";
   323 #endif
   324 
   325 void CScsSession::CloseSubsessionL(const RMessage2& aMessage)
   326 /**
   327 	Delete the subsession identified in the supplied message.
   328 
   329 	If the subsession cannot be found this function leaves with KErrBadHandle,
   330 	and the client is panicked in ServiceError.
   331 
   332 	@param	aMessage		Standard server-side message handle.  The fourth
   333 							integer contains the subsession handle.
   334  */
   335 	{
   336 	TInt handle = aMessage.Int3();
   337 	CObject* obj = iSsHandles->AtL(handle);	// leaves with KErrBadHandle if not found
   338 	CScsSubsession* ss = static_cast<CScsSubsession*>(obj);
   339 	
   340 	iServer.CancelOutstandingRequests(this, ss, /* aCancelClientRequests */ ETrue);
   341 
   342 	iSsHandles->Remove(handle);
   343 	
   344 	// close the container objects to ensure the heap balances when the last subsession is closed
   345 	if (iSsHandles->ActiveCount() == 0)
   346 		DeleteSubsessionContainers();
   347 	}
   348 
   349 TBool CScsSession::CallSubsessionFunctionL(TInt aFunction, const RMessage2& aMessage)
   350 /**
   351 	Pass the supplied function identifier and message to the subsession
   352 	which is identified in the message.
   353 
   354 	If the subsession cannot be found this function leaves with KErrBadHandle,
   355 	and the client is panicked in ServiceError.
   356 
   357 	@param	aFunction		Function identifier without SCS code.
   358 	@param	aMessage		Client message.
   359 	@return ETrue means complete client request now.
   360 
   361  */
   362 	{
   363 	CScsSubsession* ss = GetSubsessionL(aMessage);
   364 	return ss->DoServiceL(aFunction, aMessage);
   365 	}
   366 
   367 void CScsSession::CancelAsyncSubsessionRequestL(TInt aFunction, const RMessage2& aMessage)
   368 /**
   369 	Cancel an outstanding asynchronous request for the subsession
   370 	identified in the supplied message.
   371 
   372 	@param	aFunction		Function identifier without SCS code.
   373 	@param	aMessage		Standard server-side message handle.  The fourth
   374 							integer contains the subsession handle.
   375  */
   376 	{
   377 	CScsSubsession* ss = GetSubsessionL(aMessage);
   378 	iServer.CancelAsyncRequest(this, ss, aFunction);
   379 	}
   380