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