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