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<CTokenServer&>(const_cast<CServer2&>(*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<ETokenEnum>(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