cryptomgmtlibs/securitycommonutils/source/scsserver/scssession.cpp
changeset 8 35751d3474b7
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     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