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 +