--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/sus/src/susutilserver.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,246 @@
+// 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:
+//
+
+#include "susutilserver.h"
+#include "susutilsession.h"
+#include "susutilclisrv.h"
+#include "suspluginloader.h"
+#include "suspluginframe.h"
+#include "suspanic.h"
+#include "ssmdebug.h"
+
+
+// ------------------- Policy Server Security Setup ----------------------
+
+const TUint KRangeCount = 3;
+const TInt KRanges[KRangeCount] =
+ {
+ 0,
+ KSusUtilServFirstUsedOpCode, //range: KFirstUsedSsmOpCode...(EEndOfSusUtilOpCodes-1) inclusive
+#ifdef _DEBUG
+ EEndOfSusUtilOpCodes+1 // this op-code is used to shutdown server in debug builds
+#else
+ EEndOfSusUtilOpCodes
+#endif //_DEBUG
+ };
+
+/**
+ Maps to index 0 in the array KPolicyElements
+ */
+const TInt KCapabilitiesInSsmServer = 0;
+
+/**
+ Specifies the appropriate action to take for each range in KRanges.
+ The n:th element of KElementsIndex specifies the appropriate action to take for the n:th range in KRanges.
+ */
+const TUint8 KElementsIndex[KRangeCount] =
+ {
+ CPolicyServer::ENotSupported,
+ KCapabilitiesInSsmServer,
+ CPolicyServer::ENotSupported,
+ };
+
+/**
+ Array containing the different security checks performed by this server
+ */
+const CPolicyServer::TPolicyElement KPolicyElements[] =
+ {
+ {_INIT_SECURITY_POLICY_C6(ECapabilityDiskAdmin, ECapabilityPowerMgmt, ECapabilityProtServ, ECapabilitySwEvent, ECapabilityWriteDeviceData, ECapabilityReadDeviceData), CPolicyServer::EFailClient} //lint !e778 suppress Constant expression evaluates to 0 in operation '+'
+ };
+
+/**
+ Setup a security policy which require all caps used by the SsmServer for all requests
+ including creating a connection. We don't yet have a usecase for anyone else than
+ SsmServer using SusUtilServer. The caller's SID will also be matched against SsmServer's
+ SID in each ServiceL call.
+ */
+const CPolicyServer::TPolicy KSusUtilServerPolicy =
+ {
+ KCapabilitiesInSsmServer, // map connection attempts as well to index [0] in KPolicyElements[]
+ KRangeCount,
+ KRanges,
+ KElementsIndex,
+ KPolicyElements
+ };
+
+// ------------------- SusUtilServer Implementation ----------------------
+
+/**
+ */
+CSusUtilServer::CSusUtilServer(TSecureId aClientSecureId)
+ : CPolicyServer(EPriorityStandard, KSusUtilServerPolicy), iClientSecureId(aClientSecureId)
+ {
+ } //lint !e1746 suppress parameter 'aClientSecureId' could be made const reference
+
+/**
+ */
+CSusUtilServer::~CSusUtilServer()
+ {
+ const TInt ignore = User::SetCritical(User::ENotCritical);
+ iLoadedPlugins.ResetAndDestroy();
+ } //lint !e529 suppress Symbol 'ignore' not subsequently referenced
+
+/**
+ Factory method used by production code.
+ */
+CSusUtilServer* CSusUtilServer::NewLC( )
+ {
+ TSecureId uidOfSysStateMgr(0x2000D75B); //The SID of the only process that will allowed to use this server.
+ return CSusUtilServer::NewLC(KSusUtilServerName, uidOfSysStateMgr);
+ }
+
+/**
+ Factory method to be used by testcode only.
+
+ @param aServerName A non-production server-name is required if the real server was started
+ during TechView startup.
+ @param aClientSecureId The SID of the only process that will allowed to use this server.
+ @internalComponent
+ @released
+ */
+CSusUtilServer* CSusUtilServer::NewLC(const TDesC& aServerName, TSecureId aClientSecureId)
+ {
+ CSusUtilServer* server = new(ELeave) CSusUtilServer(aClientSecureId);
+ CleanupStack::PushL(server);
+ server->ConstructL(aServerName);
+ return server;
+ } //lint !e1746 suppress parameter 'aClientSecureId' could be made const reference
+
+/**
+ Second-phase construct and start this server. Will rename current thread to
+ KSusUtilServerName and set it to ESystemCritical.
+ @internalComponent
+ @released
+ */
+void CSusUtilServer::ConstructL(const TDesC& aServerName)
+ {
+ __ASSERT_ALWAYS( KErrNone == User::SetCritical(User::ESystemCritical),
+ User::Panic(KPanicSsmSus, EUtilServerError1));
+
+ __ASSERT_ALWAYS( KErrNone == User::RenameThread(KSusUtilServerName),
+ User::Panic(KPanicSsmSus, EUtilServerError2));
+
+ const TInt err = Start(aServerName);
+ SSMLOGLEAVEIFERROR( err );
+ }
+
+/**
+ Create a new session. Boilerplate code for Symbian Client-Server framework.
+ @internalComponent
+ @released
+ */
+CSession2* CSusUtilServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
+ {
+ // Check we're the right version
+ TVersion v(KSusUtilServMajorVersionNumber, KSusUtilServMinorVersionNumber,
+ KSusUtilServBuildVersionNumber);
+
+ if ( !User::QueryVersionSupported(v,aVersion) )
+ {
+ User::Leave (KErrNotSupported );
+ }
+
+ // version supported, go ahead
+ return CSusUtilSession::NewL ( );
+ }
+
+/**
+ The SID of the only process that will allowed to use this server.
+ @internalComponent
+ @released
+ */
+TSecureId CSusUtilServer::ClientSecureId() const
+ {
+ return iClientSecureId;
+ }
+
+/**
+ Attempt to load the DLL file named in aSupInfo. If successful, instantiate, initialize and start
+ the contained uitility plugin using the ordinal function specified in aSupInfo and the MSsmUtility
+ interface.
+ @internalComponent
+ @released
+ */
+void CSusUtilServer::LoadUtilityPluginL(TSsmSupInfo& aSupInfo)
+ {
+ RLibrary lib;
+ SusPluginLoader::LoadDllFileLC(lib, aSupInfo); // open handle on CleanupStack
+
+ if (KErrNotFound != IndexOf(lib, aSupInfo.NewLOrdinal()))
+ {
+ //will leave in release builds as well
+ SSMLOGLEAVE(KErrAlreadyExists); //lint !e527 Unreachable
+ }
+
+ const TInt newL = aSupInfo.NewLOrdinal();
+ CSusPluginFrame* plugin = SusPluginLoader::CreatePluginLC(lib, newL);
+ iLoadedPlugins.AppendL(plugin);
+ CleanupStack::Pop(plugin);
+ plugin->SetLibrary(lib); // takes ownership of open library handle
+
+ CleanupStack::Pop(&lib);
+ }
+
+/**
+ Check if a Utility Plugin is already loaded.
+
+ @param A RLibrary based on the DLL file which we want to investigate if its already
+ included in iLoadedPlugins.
+ @return The index of any CSusPluginFrame in iLoadedPlugins which is based on the same DLL file
+ as given in parameter aLibrary.
+ @internalComponent
+ @released
+ */
+TInt CSusUtilServer::IndexOf(const RLibrary& aLibrary, TInt aNewLOrdinal) const
+ {
+ const TFileName nameToLookFor = aLibrary.FileName();
+ const TInt count = iLoadedPlugins.Count();
+ for(TInt i=0; i<count; i++)
+ {
+ if(0 == nameToLookFor.CompareF(iLoadedPlugins[i]->FileName()) && aNewLOrdinal == iLoadedPlugins[i]->NewLOrdinal())
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+/**
+ @return 0 or a positive integer if a plugin was released and deleted, otherwise KErrNotFound
+ @internalComponent
+ @released
+ */
+TInt CSusUtilServer::UnLoadUtilityPluginL(TSsmSupInfo& aSupInfo)
+ {
+ RLibrary lib;
+ SusPluginLoader::LoadDllFileLC(lib, aSupInfo); // open handle on CleanupStack
+ const TInt index = IndexOf(lib, aSupInfo.NewLOrdinal());
+ if( index > KErrNotFound )
+ {
+ CSusPluginFrame* frame = iLoadedPlugins[index];
+ iLoadedPlugins.Remove(index);
+ delete frame;
+ }
+ CleanupStack::PopAndDestroy(&lib);
+ return index;
+ }
+
+#ifdef _DEBUG
+// Used for testing memory leaks on server.
+void CSusUtilServer::CompressPluginArray()
+ {
+ iLoadedPlugins.Compress();
+ }
+#endif