commsprocess/commsrootserverconfig/configurator/src/c32startserv.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsprocess/commsrootserverconfig/configurator/src/c32startserv.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,315 @@
+// Copyright (c) 2005-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:
+// Implementation of the Configurator server for on demand loading of CPMs.
+// 
+//
+
+#include <cfextras.h>
+#include <e32svr.h>
+#include <e32uid.h>
+#include <e32base.h>
+#include "c32startshared.h"
+#include "c32startserv.h"
+#include "c32startPolicy.h"
+
+/**
+@file 
+Implements the Configurator Server side.
+
+@internalTechnology
+*/
+
+CRsConfiguratorServer::CRsConfiguratorServer(CCommsProcessStarter& aCommsProcess)
+	: CPolicyServer(CActive::EPriorityStandard,iPolicy,ESharableSessions),
+	iCommsProcess(aCommsProcess)
+	/** C'tor 
+	@param aCommsProcess base class for managing CPMs
+	*/
+	{
+	}
+
+CRsConfiguratorServer::~CRsConfiguratorServer()
+	/** D'tor
+	*/
+	{
+	}
+CSession2* CRsConfiguratorServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
+	/** Create new session object.Connect API is policed for its capability.
+     @internalComponent
+     */
+	{
+	return new(ELeave) CRsConfiguratorServerSession(this);
+	}
+
+
+CRsConfiguratorServer* CRsConfiguratorServer::NewL(CCommsProcessStarter& aCommsProcess)
+	 /** Create new Configurator Server instance.
+     This is the only way of instantiation
+     @internalComponent
+     @param aCommsProcess base class for CPM management
+     */
+	{
+	CRsConfiguratorServer* self = new(ELeave) CRsConfiguratorServer(aCommsProcess);
+	CleanupStack::PushL(self);
+	self->ConstructL();	
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CRsConfiguratorServer* CRsConfiguratorServer::NewLC(CCommsProcessStarter& aCommsProcess)
+	/** Create new Configurator Server instance.
+     This is the only way of instantiation
+     @internalComponent
+     @param aCommsProcess base class for CPM management
+     */
+	{
+	CRsConfiguratorServer* self=new(ELeave) CRsConfiguratorServer(aCommsProcess);
+	CleanupStack::PushL(self);
+	self->ConstructL();	
+	return self;
+	}
+
+void CRsConfiguratorServer::ConstructL()
+	/** Second level construction of ConfiguratorServer.
+	Configurator Server is started
+	@internalComponent
+	*/
+	{
+	StartL(KRsConfiguratorServerName);
+	}
+
+
+TInt CRsConfiguratorServer::EnumerateModules(const TCFGroupNameF& aGroupName, TInt& aStartAt, TCFModuleNameF& aName)
+	/** Returns a module name from list of modules which matches the group name
+	@param aGroupName name of a group to which module belongs.
+	@param aStartAt search for aName starting at this position.
+	@param aName returns the name for matching group.
+	*/
+	{
+	RPointerArray<CModuleRef>& modules=GetModulesList();
+	TInt count = modules.Count();
+    if(aStartAt >= count)
+    	{
+    	return KErrEof;
+    	}
+    
+    for(TInt i=aStartAt;i<count;i++)
+    	{
+    	CModuleRef* pModule = modules[i];
+		if(aGroupName == pModule->GroupName())
+			{
+			aName = pModule->Name();
+			aStartAt = i; // to retain the last found position
+			__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::EnumerateModules Module Found (%S)"),&aName);
+			return KErrNone;
+			}
+    	}
+     __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::EnumerateModules RSModuleUnknown For Group (%S)"),&aGroupName);    
+   	return KErrRSModuleUnknown;
+	}
+
+TInt CRsConfiguratorServer::LoadCpm(const TCFModuleNameF& aName,const RMessage2& aMessage)
+	/** Loads the CPM module.
+	retunrs KErrNone on succesfull load request.
+	KErrRSModuleAlreadyExist if module is already loaded.
+	KErrRSModuleUnknown if Module is not listed.
+	KErrRSModuleNotLoaded if load is fails.
+	@param aName name of the module to be loaded.
+	*/
+	{
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::LoadCpm (%S)"),&aName);    
+	CModuleRef* pModule;
+    if((pModule = FindCpm(aName)) != NULL)
+		{
+		if(pModule->State()==ENotLoaded)
+			{
+			// RMessage set here, determines if a module's message can be completed or not.
+			// message completion is not on "OnDemand" property, as a boot time module can also be On-Demand loaded.
+			pModule->SetRMessage(aMessage);
+			// check if any of the bindings has this OnDemand module, if yes, set iHasBinding = ETrue
+			RPointerArray<CBindingRef>& bindings = iCommsProcess.GetBindingList();
+			for(TInt i=0; i<bindings.Count(); i++)
+				{
+				const CBindingRef& bind(*bindings[i]);
+				if(pModule->Name() == bind.FromModule().Module() || pModule->Name() == bind.ToModule().Module())
+					{
+					pModule->SetHasBindings();
+					break;
+					}
+				}
+			iCommsProcess.LoadOnDemandModule(*pModule);
+			return KErrNone;
+			}
+		else if ((pModule->State()==ELoaded) || (pModule->State()==ELoading))
+			{
+			__FLOG_1(_L8("CRsConfiguratorServer::LoadCpm - %S ModuleAlreadyExist"),&aName);
+			return KErrRSModuleAlreadyExist;
+			}
+		}
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::LoadCpm (%S) ModuleUnknown"),&aName);
+	return KErrRSModuleUnknown;
+	}
+
+TInt CRsConfiguratorServer::GetModuleIniData(const TCFModuleNameF& aName,const RMessage2& aMessage)
+	/** Get the data from [inidata] section for a given module name.
+	@param aName name of the module for which inidata section has to be retrieved.
+	@param aInidata contains inidata for given module name.
+	@param aActualSize on return contains actual size of [inidata]
+	@return an error code.  
+	*/
+	{
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::GetModuleIniData (%S) "),&aName);
+	CModuleRef* pModule;
+    TPckgBuf<TInt> actualLength;
+    if((pModule = FindCpm(aName)) != NULL)
+		{
+		TInt deslength = aMessage.GetDesMaxLength(1); // Buffer length to get the contents
+		if(deslength <0)
+			{
+			return deslength;
+			}
+		HBufC8* inidata = pModule->GetIniData();
+		if(inidata != NULL)
+			{
+			actualLength = inidata->Length(); // Actual length of the inidata
+			TInt err = aMessage.Write(2, actualLength);
+			if (err == KErrNone )
+				{
+				if(inidata->Length() <= deslength)
+					{
+					err = aMessage.Write(1, *inidata);
+					}
+				else
+					{
+					return KErrOverflow;	
+					}	
+				}
+			return err;	
+			}
+		else // No inidata Section return actual size as 0"Zero".	
+			{
+			actualLength = 0;
+			TInt err = aMessage.Write(2, actualLength);	
+			return KErrNone; 
+			}	
+		}
+		
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::GetModuleIniData (%S) ModuleUnknown "),&aName);
+	return KErrRSModuleUnknown;	
+	
+	}
+	
+TInt CRsConfiguratorServer::UnLoadCpm(const TCFModuleNameF& aName, const RMessage2& aMessage)
+	/** Unloads module loaded by configurator itself. This calls root server UnloadCpm() internally. 
+	@param aName name of the module to be unloaded.
+	@param aMessage which is to be completed once the root server unloads the module. 
+		Else message would be completed by the Configurator server session ServiceL with error returned from here.
+	@return an error code.  
+	*/
+	{
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::UnLoadCpm (%S)"),&aName);
+	
+	CModuleRef* pModule;
+	TRSUnLoadType unloadType = (TRSUnLoadType) aMessage.Int1();
+    if((pModule = FindCpm(aName)) != NULL)
+		{
+		if(pModule->State()==ELoaded)
+			{
+			// RMessage set here, determines if a module's message can be completed or not.
+			// message completion is not on "OnDemand" property, as a boot time module can also be On-Demand unloaded.
+			pModule->SetRMessage(aMessage);
+			pModule->UnLoadCpm(aName,unloadType);
+			return KErrNone;
+			}
+		else
+			{
+			return KErrRSModuleNotLoaded;	
+			}	
+		}
+	
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::UnLoadCpm (%S) ModuleUnknown "),&aName);
+	return KErrRSModuleUnknown;
+	}
+	
+TInt CRsConfiguratorServer::CancelUnLoadCpm(const TCFModuleNameF& aName)	
+	/** Cancel asynchronous unloading of a comms Provider Module. 
+	There is no guarantee the module unloading is canceled. 
+	A best effort is made and the asynchronous request waiting for the module 
+	to load returns KErrCanceled on success.
+	
+	@param aName name of the unloading module.
+	@return an error code.
+	*/
+	{
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelUnLoadCpm (%S)"),&aName);
+	
+	CModuleRef* pModule;
+    if((pModule = FindCpm(aName)) != NULL)
+		{
+		pModule->CancelUnLoadCpm(aName);
+		return KErrNone;
+		}
+	
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelUnLoadCpm (%S) ModuleUnknown "),&aName);
+	return KErrRSModuleUnknown;
+	}
+	
+TInt CRsConfiguratorServer::CancelLoadCpm(const TCFModuleNameF& aName)	
+	/**Cancels asynchronous loading of a comms Provider Module. 
+	There is no guarantee the module loading is canceled. 
+	A best effort is made and the asynchronous request waiting for the module 
+	to load returns with KErrCanceled on success. 
+	
+	@param aName name of the unloading module.
+	@return an error code.
+	*/
+	{
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelLoadCpm (%S)"),&aName);
+	
+	CModuleRef* pModule;
+    if((pModule = FindCpm(aName)) != NULL)
+		{
+		pModule->CancelLoadCpm(aName);
+		return KErrNone;
+		}
+	
+	__FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelLoadCpm (%S) ModuleUnknown "),&aName);
+	return KErrRSModuleUnknown;
+	}	
+	
+CModuleRef* CRsConfiguratorServer::FindCpm(const TCFModuleNameF& aName)		
+	/**Find a comms provider module by name.
+	Search the modules array for a cpm with the matching name
+    if found return a pointer, otherwise return NULL.
+    @param aName The name of the cpm to be found.
+    @return The cpm found or NULL
+	@internalComponent	
+	*/
+	{
+	RPointerArray<CModuleRef>& modules = GetModulesList();
+	TInt count = modules.Count();
+	for(TInt i=0;i<count;i++)
+		{
+		CModuleRef* pModule = modules[i];
+		if(aName == pModule->Name())
+			{
+			return pModule;
+			}
+		}
+	return NULL;
+	}
+
+
+
+