sysstatemgmt/systemstatemgr/ssm/src/ssmswppolicysrv.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/ssm/src/ssmswppolicysrv.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,599 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// ssmpolicysrv.cpp
+// 
+//
+
+#include <e32debug.h>
+#include <e32math.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <ssm/ssmcommandlist.h>
+
+#include "ssmswppolicysrv.h"
+#include "ssmswppolicysess.h"
+#include "ssmswppolicyconst.h"
+#include "ssmdebug.h"
+#include "ssmserverpanic.h"
+
+// ------------------- SsmSwpPolicy Server Security Setup ----------------------
+
+const TInt KSsmServerSid = 0x2000D75B; //UID3 of sysstatemgr.exe
+
+const TUint  KRangeCount = 3;
+const TInt   KRanges[KRangeCount] =
+	{
+	0,
+	KFirstUsedOpCode,		//range: 1...(EEndOfSsmSwpPolicySrvOpCodes-1) inclusive
+	EEndOfSsmSwpPolicySrvOpCodes
+	};
+
+/**
+ Maps to index 0 in the array KPolicyElements
+ */
+const TInt KSsmServerSidCheck = 0;
+
+/**
+ Specifies the appropriate action for each range in KRanges.
+ The nth element of KElementsIndex specifies the appropriate action for the nth range in KRanges.
+ */
+const TUint8 KElementsIndex[KRangeCount] =
+	{
+	CPolicyServer::ENotSupported,
+	KSsmServerSidCheck,
+	CPolicyServer::ENotSupported,
+	};
+
+/**
+ Array containing the different security checks performed by this server
+ */
+const CPolicyServer::TPolicyElement KPolicyElements[] =
+	{
+	{_INIT_SECURITY_POLICY_S0(KSsmServerSid), CPolicyServer::EFailClient} //lint !e778 suppress Constant expression evaluates to 0 in operation '+'
+	};
+
+/**
+ Setup a security policy which requires all caps to be used by the SsmServer for all requests
+ including creating a connection. The caller's SID is matched against SsmServer's
+ SID in each ServiceL call
+ */
+const CPolicyServer::TPolicy KSsmSwpPolicyServerPolicy =
+	{
+	KSsmServerSidCheck,	// map connection attempts as well to index [0] in KPolicyElements[]
+	KRangeCount,
+	KRanges,
+	KElementsIndex,
+	KPolicyElements
+	};
+
+/**
+CSsmSwpPolicyStepCompletion is an active object used for executing all the steps involved in 
+the swp transition. Initial state for the active object is set as EIdle.
+*/
+CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion* CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::NewL(MSsmSwpPolicy* aSwpPolicy, CSsmSwpPolicyServer& aServer, const TInt aSessionIndex)
+	{
+	CSsmSwpPolicyStepCompletion* self = new(ELeave)CSsmSwpPolicyStepCompletion(aSwpPolicy, aServer, aSessionIndex);
+	return self;
+	}
+
+CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::CSsmSwpPolicyStepCompletion(MSsmSwpPolicy* aSwpPolicy, CSsmSwpPolicyServer& aServer, const TInt aSessionIndex)
+	: CActive(EPriorityStandard), iStep(EIdle), iSwpPolicy(aSwpPolicy), iSessionIndex(aSessionIndex), iServer(aServer)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::~CSsmSwpPolicyStepCompletion()
+	{
+	Cancel();
+	}
+
+/**
+Calls Initialize of the SwpPolicy. Sets the active object state as EInitialize.
+*/
+void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartInitialize(const RMessagePtr2& aMessagePtr2)
+	{
+	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError1));
+	__ASSERT_DEBUG(iStep == EIdle, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError1));
+
+	// This message will be completed in RunL().
+	iMessagePtr = aMessagePtr2;
+
+	// Initialize is the first step in the process of swp transition.
+	// CSsmSwpPolicyFrame does	all the step checking before giving the request to ssmswppolicyserver 
+	// so no further checking is required here.
+	iStep = EInitialize;
+	iSwpPolicy->Initialize(iStatus);
+	SetActive();
+	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
+	}
+
+/**
+Calls PrepareCommandList of the SwpPolicy. Sets the active object state as EPrepareCommandList.
+*/
+void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartPrepareCommandList(const TSsmSwp& aSwp, const RMessagePtr2& aMessagePtr2)
+	{
+	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError2));
+	__ASSERT_DEBUG(iStep == EInitialize, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError2));
+
+	// This message will be completed in RunL().
+	iMessagePtr = aMessagePtr2;
+
+	// PrepareCommandList should be called only after initializing the swp policy.  
+	// CSsmSwpPolicyFrame does all the step checking before giving the request to ssmswppolicyserver 
+	// so no further checking is required here.
+	iStep = EPrepareCommandList;
+	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
+	iSwpPolicy->PrepareCommandList(aSwp, iStatus);
+	SetActive();
+	}
+
+/**
+Calls HandleCleReturnValue of the SwpPolicy.
+*/
+void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartHandleCleReturnValue(const TSsmSwp& aSwp, TInt aError, TInt aSeverity, const RMessagePtr2& aMessagePtr2)
+	{
+	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError4));
+	__ASSERT_DEBUG(iStep == ECallCommandList, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError4));
+
+	// This message will be completed in RunL().
+	iMessagePtr = aMessagePtr2;
+
+	// HandleCleReturnValue should be called only after executing the command list which is returned by swp policy.
+	// CSsmSwpPolicyFrame does all the step checking before giving the request to ssmswppolicyserver so no further checking is required here.
+	iStep = EHandleCleReturnValue;
+	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
+	iSwpPolicy->HandleCleReturnValue(aSwp, aError, aSeverity, iStatus);
+	SetActive();
+	}
+
+void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::RunL()
+	{
+	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
+	// Completes the message
+	iMessagePtr.Complete(iStatus.Int());
+
+	// swp transition will be marked as complete only after the execution of HandleCleReturnValue method
+	if (iStep == EHandleCleReturnValue)
+		{
+		// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
+		// and the same session can be used for the next similar swp transition.
+		iServer.DeleteSSwpPolicySessionInfo(iSessionIndex);
+		}
+	}
+
+/**
+Cancels any outstanding request, based on the state of the active object.
+*/
+void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::DoCancel()
+	{
+	switch(iStep)
+		{
+		case EInitialize:
+			{
+			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the Initization of SwpPolicy"));
+			iSwpPolicy->InitializeCancel();
+			iMessagePtr.Complete(KErrCancel);
+			break;
+			}
+		case EPrepareCommandList:
+			{
+			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the Preparation of the commandlist"));
+			iSwpPolicy->PrepareCommandListCancel();
+			iMessagePtr.Complete(KErrCancel);
+			break;
+			}
+		case EHandleCleReturnValue:
+			{
+			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the HandleCleReturnValue"));
+			iSwpPolicy->HandleCleReturnValueCancel();
+			iMessagePtr.Complete(KErrCancel);
+			break;
+			}
+		default:
+			{
+			break;
+			}
+		};
+	}
+
+/** 
+Current RunL() implemenation doesn't leave, so RunError will never be called.
+*/
+TInt CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::RunError()
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: RunError"));
+	return KErrNone;
+	}
+
+/**
+Gets the dll handle to SwpPolicy and initializes the SwpPolicy
+*/
+void CSsmSwpPolicyServer::CallSetDllHandleAndInitializeL(const RMessage2& aMessage, const TInt aSessionIndex)
+	{
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+
+	RLibrary library;
+	// Sets the swp policy library handle.  Library is owned by the CSsmSwpRequestHandler.
+	library.SetHandle(aMessage.Int0());
+
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: SwpPolicy handle is set"));
+	iSessionInfoArray[aSessionIndex].iSwpPolicy = reinterpret_cast<MSsmSwpPolicy*>(library.Lookup(1)());
+
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Create CSsmSwpPolicyStepCompletion active object"));
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion = CSsmSwpPolicyStepCompletion::NewL(iSessionInfoArray[aSessionIndex].iSwpPolicy, *this, aSessionIndex);
+
+	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
+	// when the Initialization of the swp policy is completed.
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->StartInitialize(aMessage);
+	}
+
+/**
+Cancels the Initialization of the swppolicy, if any Initialization request is pending.
+*/
+void CSsmSwpPolicyServer::CallInitializeCancel(TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallInitializeCancel"));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError1));
+
+	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, , so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method,
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
+	
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as Initialize is cancelled"));
+	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
+	// and the same session can be used for the next similar swp transition.
+	DeleteSSwpPolicySessionInfo(aSessionIndex);
+	}
+
+/**
+Prepares the commandlist in swppolicy
+*/
+void CSsmSwpPolicyServer::CallPrepareCommandListL(const RMessage2& aMessage, TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Call SwpPolicy's PrepareCommandList "));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError2));
+
+	TSsmSwp ssmSwp(0,0);
+	TPckg<TSsmSwp> swpBuf(ssmSwp);
+    aMessage.ReadL(0, swpBuf);
+
+	// CSsmSwpPolicyFrame checks whether initialize is called before CallHandleCleReturnValue is called, so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+
+	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
+	// when the preparation of the commandlist is completed.
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->StartPrepareCommandList(ssmSwp, aMessage);
+	}
+
+/**
+Cancels the preparation of the commandlist, if any PrepareCommandList request is pending.
+*/
+void CSsmSwpPolicyServer::CallPrepareCommandListCancel(TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallPrepareCommandListCancel"));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError3));
+
+	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method,
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
+	
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as PrepareCommandList is cancelled"));
+	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
+	// and the same session can be used for the next similar swp transition.
+	DeleteSSwpPolicySessionInfo(aSessionIndex);
+	}
+
+/**
+Returns the commandlist to the client from swppolicy.
+@return A pointer to commandlist.
+*/
+void CSsmSwpPolicyServer::CallCommandListL(const RMessage2& aMessage, TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallCommandListL"));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError4));
+		// CommandList should be called only after preparing the command list, so the active object state should be EPrepareCommandList.
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->CurrentStep() == CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::EPrepareCommandList, 
+			PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError3));
+	
+	// CSsmSwpPolicyFrame checks whether initialize is called before CallCommandList is called, so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+	// Sets the current step to CallCommandList
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->SetCurrentStep(CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::ECallCommandList);
+	CSsmCommandList* ssmCmdList = (iSessionInfoArray[aSessionIndex].iSwpPolicy)->CommandList();
+	CleanupStack::PushL(ssmCmdList);
+	CBufFlat* buf = CBufFlat::NewL(KSsmSwpPolicyStreamBufMaxSize);
+	CleanupStack::PushL(buf);
+	
+	RBufWriteStream writeStream(*buf);
+	CleanupClosePushL(writeStream);
+	
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Externalizes the commandlist"));
+	ssmCmdList->ExternalizeL(writeStream);
+
+	// Ensure any memory that might already have been allocated  is disposed of. 
+	// Transfer the streamed cmd list from the CBuf.
+	RBuf8 cmdListBuf;
+	cmdListBuf.CreateL(buf->Size());
+	CleanupClosePushL(cmdListBuf);	
+	buf->Read(0, cmdListBuf);
+	
+	aMessage.WriteL(0, cmdListBuf);
+	
+	aMessage.Complete(KErrNone);
+	CleanupStack::PopAndDestroy(4, ssmCmdList);	//	buf, writeStream and cmdListBuf
+	}
+
+/**
+Handles the value returned by Cle.
+*/
+void CSsmSwpPolicyServer::CallHandleCleReturnValueL(const RMessage2& aMessage, TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallHandleCleReturnValueL"));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError5));
+
+	TSsmSwp ssmSwp(0,0);
+	TPckg<TSsmSwp> swpBuf(ssmSwp);
+	aMessage.ReadL(0, swpBuf);
+
+	const TInt error = aMessage.Int1();
+	const TInt severity = aMessage.Int2();
+
+	// CSsmSwpPolicyFrame checks whether initialize is called before CallHandleCleReturnValue is called, so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+
+	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
+	// when the cle's return value is handled by the swppolicy.
+	(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion)->StartHandleCleReturnValue(ssmSwp, error, severity, aMessage);
+	}
+
+/**
+Cancels the HandleCleReturnValue, if any HandleCleReturnValue request is pending.
+*/
+void CSsmSwpPolicyServer::CallHandleCleReturnValueCancel(TInt aSessionIndex)
+	{
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallHandleCleReturnValueCancel"));
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError6));
+
+	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, so no need to check
+	// for valid iSsmSwpPolicyStepCompletion pointer.
+	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method.
+	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
+	
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as HandleCleReturnValue is cancelled"));
+	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
+	// and the same session can be used for the next similar swp transition.
+	DeleteSSwpPolicySessionInfo(aSessionIndex);
+	}
+
+/**
+Iterate through iSessionInfoArray to find an unused array element
+If found, use it. Otherwise, Append() a new SSwpPolicySessionInfo.
+This function is called during CSession construction.
+*/
+void CSsmSwpPolicyServer::RegisterSessionL(TInt& aSessionIndex)
+	{
+	const TInt count = iSessionInfoArray.Count();
+	TBool slotFound = EFalse;
+	
+	for(TInt i = 0; i < count; ++i)
+		{
+		if(!iSessionInfoArray[i].iInUse)
+			{
+			DEBUGPRINT1(_L("CSsmSwpPolicyServer: Using the free slot of the sessionarray"));
+			iSessionInfoArray[i].iInUse = ETrue;
+			__ASSERT_ALWAYS(NULL, iSessionInfoArray[i].iSwpPolicy);
+			aSessionIndex = i;
+			slotFound = ETrue;
+			break;
+			}
+		}
+	
+	if(!slotFound)
+		{
+		DEBUGPRINT1(_L("CSsmSwpPolicyServer: No free slot found, so appending a new member to the sessionarray"));
+		SSwpPolicySessionInfo sessionInfo;
+		sessionInfo.iInUse = ETrue;
+		sessionInfo.iSwpPolicy = NULL;
+		sessionInfo.iSsmSwpPolicyStepCompletion = NULL;
+		iSessionInfoArray.AppendL(sessionInfo);
+		// using count instead of iSessionInfoArray.Count()-1 as it is set before appending the element to the array,
+		// and its value is equal to iSessionInfoArray.Count()-1
+		aSessionIndex = count;
+		}
+	DEBUGPRINT2(_L("Registered SsmSwpPolicyCli in slot %d"), aSessionIndex);
+	}
+
+/**
+This method is used to delete the session information once the swp transition is complete.
+This is required as the same session can be used for more than one individual swp transition.
+*/
+void CSsmSwpPolicyServer::DeleteSSwpPolicySessionInfo(TInt aSessionIndex)
+	{
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+
+	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deletes the SwpPolicySession information."));
+	if(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion)
+		{
+		delete iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion;
+		iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion = NULL;
+		}
+
+	if(iSessionInfoArray[aSessionIndex].iSwpPolicy)
+		{
+		DEBUGPRINT1(_L("CSsmSwpPolicyServer: Releases the SwpPolicy"));
+		(iSessionInfoArray[aSessionIndex].iSwpPolicy)->Release();
+		iSessionInfoArray[aSessionIndex].iSwpPolicy = NULL;
+		}
+	}
+
+/**
+Called from CSession destructor.
+*/
+void CSsmSwpPolicyServer::DeregisterSession(const TInt& aSessionIndex)
+	{
+	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
+	
+	DeleteSSwpPolicySessionInfo(aSessionIndex);
+	iSessionInfoArray[aSessionIndex].iInUse = EFalse;
+
+	// Remove unused elements at the end of the array, so iSessionInfoArray can be (granular) shrunk 
+    const TInt count = iSessionInfoArray.Count(); 
+    TBool slotRemoved = EFalse; 
+    for (TInt i = count-1; i >= 0 ; i--) 
+         {
+        if (!iSessionInfoArray[i].iInUse) 
+        	{
+            iSessionInfoArray.Remove(i); 
+            slotRemoved = ETrue; 
+        	}
+        else 
+        	{
+        	break;
+        	}
+         } 
+	   if (slotRemoved) 
+		   { 
+		   iSessionInfoArray.GranularCompress(); 
+		   } 
+	DEBUGPRINT2(_L("De-registered SsmSwpPolicyCli slot %d"), aSessionIndex);
+ 	}
+
+/**
+Used to create a new server-side session.
+@return A pointer to the new instance of CSession2.
+@leave KErrNotSupported if versions are incompatible.
+*/
+EXPORT_C CSession2* CSsmSwpPolicyServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
+	{
+	TVersion version(KSsmSwpPolicySrvVersionMajor, KSsmSwpPolicySrvVersionMinor, KSsmSwpPolicySrvVersionBuild);
+
+	if(!User::QueryVersionSupported(version, aVersion))
+		{
+		DEBUGPRINT1(_L("CSsmSwpPolicyServer: Server version not supported"));
+		User::Leave(KErrNotSupported);
+		}
+
+	CSsmSwpPolicyServer& mutatedSelf = const_cast< CSsmSwpPolicyServer& >(*this);
+	return CSsmSwpPolicySession::NewL(mutatedSelf); 
+	}
+	
+/**
+Used to create a new CSsmSwpPolicyServer
+@return A pointer to the CSsmSwpPolicyServer
+*/
+CSsmSwpPolicyServer* CSsmSwpPolicyServer::NewLC(const TDesC& aServerName)
+	{
+	CSsmSwpPolicyServer* self = new(ELeave) CSsmSwpPolicyServer;	
+	CleanupStack::PushL(self);
+	self->ConstructL(aServerName);
+	return self;	
+	}
+
+/**
+Static function used to create and start CSsmSwpPolicyServer
+@return KErrAlreadyExists if the server is already running
+*/
+EXPORT_C TInt CSsmSwpPolicyServer::StartSsmSwpPolicySrv(const TDesC& aServerName)
+	{
+	TAny* threadParam = reinterpret_cast<TAny*>(const_cast<TDesC*>(&aServerName));
+
+	// Create a Unique name for the thread name
+	TName name(aServerName);
+	_LIT(KUnderScore, "_");
+	name.Append(KUnderScore);
+	name.AppendNum(Math::Random(), EHex);
+
+	const TInt KSsmPolicySrvMinHeapSize = 0x2000;	// 8kB
+	const TInt KSsmPolicySrvMaxHeapSize = 10 * KSsmPolicySrvMinHeapSize;
+	RThread srvThread;
+	TInt err = srvThread.Create(name, &CSsmSwpPolicyServer::SsmSwpPolicySrvThreadFn, 
+								 KDefaultStackSize, KSsmPolicySrvMinHeapSize, KSsmPolicySrvMaxHeapSize, 
+								 threadParam, EOwnerProcess);
+
+	DEBUGPRINT2(_L("CSsmSwpPolicyServer: SsmSwpPolicyServer created with %d") ,err);
+	if(KErrNone == err)
+		{
+		TRequestStatus trs;
+	
+		srvThread.Rendezvous(trs);
+		srvThread.Resume();
+		
+		User::WaitForRequest(trs);	
+		err = trs.Int();
+		srvThread.Close();
+		}
+
+	return err;
+	}
+
+/**
+Creates the ssmSwpPolicyServer
+*/
+TInt CSsmSwpPolicyServer::SsmSwpPolicySrvThreadFn(TAny* aAny)
+	{
+	const TDesC* serverName = const_cast<const TDesC*>(static_cast<TDesC*>(aAny));
+	TInt err = KErrNoMemory;
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    if(cleanup)
+    	{
+	    TRAP(err,
+	        {
+	        CActiveScheduler* sched = new(ELeave) CActiveScheduler();
+	        CleanupStack::PushL(sched);
+	        CActiveScheduler::Install(sched);
+	
+	        CSsmSwpPolicyServer* ssmSwpPolicySrv = CSsmSwpPolicyServer::NewLC(*serverName);
+	        RThread::Rendezvous(KErrNone);
+	    	// Must not use serverName after rendezvousing with client
+	        serverName = NULL;
+	        
+	        CActiveScheduler::Start();
+	
+	        CleanupStack::PopAndDestroy(ssmSwpPolicySrv);
+	        CleanupStack::PopAndDestroy(sched);
+	        });
+
+	    delete cleanup;
+    	}
+ 
+    return err;
+	}
+
+CSsmSwpPolicyServer::CSsmSwpPolicyServer()
+	: CPolicyServer(EPriorityHigh, KSsmSwpPolicyServerPolicy, EUnsharableSessions)
+	{
+	}
+
+/**
+Starts the ssmSwpPolicyServer
+*/
+void CSsmSwpPolicyServer::ConstructL(const TDesC& aServerName)
+	{
+	StartL(aServerName);
+	// The starting thread is signalled in the thread function.
+	}
+
+CSsmSwpPolicyServer::~CSsmSwpPolicyServer()
+	{
+	iSessionInfoArray.Close();
+	}
+