diff -r 000000000000 -r 2c201484c85f cryptoservices/filebasedcertificateandkeystores/source/generic/server/fsserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/filebasedcertificateandkeystores/source/generic/server/fsserver.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,302 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* fstokenserver.cpp +* +*/ + + +#include "fsserver.h" +#include "fstokenutil.h" +#include "cfskeystoreserver.h" +#include "CKeyStoreSession.h" +#include "filecertstore.h" +#include "CCertStoreSession.h" +#include "CFSCertAppsServer.h" +#include "CCertAppsSession.h" +#include "FSResources.h" +#include "FSDialog.h" +#include "tokenserverdebug.h" +#include "fstokenservername.h" + +// CTokenServerSession ///////////////////////////////////////////////////////// + +CTokenServerSession::CTokenServerSession() + { + } + +inline CTokenServer& CTokenServerSession::Server() + { + return static_cast(const_cast(*CSession2::Server())); + } + +void CTokenServerSession::CreateL() + { + Server().AddSession(); + } + +CTokenServerSession::~CTokenServerSession() + { + Server().DropSession(); + } + +/** + * Handle a client request. Leaving is handled by + * CTokenServerSession::ServiceError() which reports the error code to the + * client. + */ +void CTokenServerSession::ServiceL(const RMessage2& aMessage) + { +#ifdef _DEBUG + // OOM testing + switch (aMessage.Function()) + { + case EStartOOMTest: + TokenServerDebug::StartOOMTest(); + aMessage.Complete(KErrNone); + return; + + case EIncHeapFailPoint: + TokenServerDebug::IncHeapFailPoint(); + aMessage.Complete(KErrNone); + return; + + case EResetHeapFail: + TokenServerDebug::ResetHeapFail(); + aMessage.Complete(KErrNone); + return; + + case EAllocCount: + aMessage.Complete(User::CountAllocCells()); + return; + } +#endif + + DoServiceL(aMessage); + } + +/** + * Handle an error from ServiceL() A bad descriptor error implies a badly + * programmed client, so panic it - otherwise report the error to the client. + */ +void CTokenServerSession::ServiceError(const RMessage2& aMessage, TInt aError) + { + if (aError==KErrBadDescriptor) + { + PanicClient(aMessage, EPanicBadDescriptor); + } + + CSession2::ServiceError(aMessage, aError); + } + +// CTokenServer //////////////////////////////////////////////////////////////// + +inline CTokenServer::CTokenServer() : + CServer2(0, ESharableSessions) + { + } + +CServer2* CTokenServer::NewLC() + { + CTokenServer* self=new(ELeave) CTokenServer; + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CTokenServer::~CTokenServer() + { + FSResources::Cleanup(); + FSDialog::Cleanup(); + + delete iKeyStoreServer; + delete iCertStoreServer; + delete iCertAppsServer; + } + +/** 2nd phase construction - ensure the timer and server objects are running. */ +void CTokenServer::ConstructL() + { + FSResources::InitialiseL(); + FSDialog::InitialiseL(); + StartL(KFSTokenServerName); + + // Ensure that the server still exits even if the 1st client fails to connect + iShutdown.ConstructL(); + iShutdown.Start(); + } + +/** A new session is being created - cancel the shutdown timer if it was running. */ +void CTokenServer::AddSession() + { + ++iSessionCount; + iShutdown.Cancel(); + } + +/** A session is being destroyed - start the shutdown timer if it is the last session. */ +void CTokenServer::DropSession() + { + if (--iSessionCount==0) + { + iShutdown.Start(); + } + } + +/** Lazily create key store server object. */ +CFSKeyStoreServer& CTokenServer::KeyStoreServerL() const + { + if (!iKeyStoreServer) + { + iKeyStoreServer = CFSKeyStoreServer::NewL(); + } + + return *iKeyStoreServer; + } + +/** Lazily create cert store server object. */ +CFSCertStoreServer& CTokenServer::CertStoreServerL() const + { + if (!iCertStoreServer) + { + iCertStoreServer = CFSCertStoreServer::NewL(); + } + + return *iCertStoreServer; + } + +/** Lazily create cert apps server object. */ +CFSCertAppsServer& CTokenServer::CertAppsServerL() const + { + if (!iCertAppsServer) + { + iCertAppsServer = CFSCertAppsServer::NewL(); + } + + return *iCertAppsServer; + } + +/** Create a new client session. */ +CSession2* CTokenServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const + { + // The token the client wants to talk to is encoded in the major version number + ETokenEnum token = static_cast(aVersion.iMajor); + + // The minor version number represents the version of the protocol + if (aVersion.iMinor != KFSProtolVersion) + { + User::Leave(KErrNotSupported); + } + + CTokenServerSession* result = NULL; + + switch (token) + { + case EFileKeyStore: + result = KeyStoreServerL().CreateSessionL(); + break; + + case EFileCertStore: + result = CertStoreServerL().CreateSessionL(); + break; + + case EFileCertApps: + result = CertAppsServerL().CreateSessionL(); + break; + + default: + User::Leave(KErrNotSupported); + break; + } + + return result; + } + +// CShutdown /////////////////////////////////////////////////////////////////// + +inline CShutdown::CShutdown() : + CTimer(-1) + { + CActiveScheduler::Add(this); + } + +inline void CShutdown::ConstructL() + { + CTimer::ConstructL(); + } + +inline void CShutdown::Start() + { + After(KServerShutdownDelay); + } + +/** Initiate server exit when the timer expires. */ +void CShutdown::RunL() + { + CActiveScheduler::Stop(); + } + +// Server startup ////////////////////////////////////////////////////////////// + +/** + * Perform all server initialisation, in particular creation of the scheduler + * and server and then run the scheduler. + */ +static void RunServerL() + { + // Naming the server thread after the server helps to debug panics + User::LeaveIfError(User::RenameThread(KFSTokenServerName)); + + // Create and install the active scheduler we need + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + + // Create the server and leave it on the cleanup stack + CTokenServer::NewLC(); + + // Before starting the server, notify client that initialisation is + // complete. + // (note that WINS on EKA1 uses threads since it lacks process emulation) + RProcess::Rendezvous(KErrNone); + + // Ready to run + CActiveScheduler::Start(); + + // Cleanup the server and scheduler + CleanupStack::PopAndDestroy(2); + } + +/** Server process entry point. */ +TInt E32Main() + { +#ifdef _DEBUG + TokenServerDebug::HeapCheckStart(); +#endif + + CTrapCleanup* cleanup=CTrapCleanup::New(); + TInt r=KErrNoMemory; + if (cleanup) + { + TRAP(r,RunServerL()); + delete cleanup; + } + +#ifdef _DEBUG + TokenServerDebug::HeapCheckEnd(); +#endif + return r; + } + +// Only for wins on EKA1 - WINS loads a DLL and starts a new thread +// by calling WinsMain which does the "server" startup