--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/systemhealthmanagement/systemhealthmgr/sysmonsrc/sysmonservsess.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,226 @@
+// Copyright (c) 2006-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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <e32capability.h>
+#include "sysmonservsess.h"
+#include "sysmoncliserv.h"
+#include "sysmonserver.h"
+#include "monitor.h"
+#include <startupproperties.h>
+#include <hal.h>
+#include <hal_data.h>
+
+#include "shmadebug.h"
+
+
+CSysMonSession::~CSysMonSession()
+ {
+ }
+
+
+CSysMonSession::CSysMonSession()
+ {
+ }
+
+
+CSysMonSession* CSysMonSession::NewL()
+ {
+ CSysMonSession *session = new(ELeave) CSysMonSession();
+ return session;
+ }
+
+
+void CSysMonSession::ServiceL(const RMessage2 &aMessage)
+ {
+ DEBUGPRINT1(_L("SysMonServSess: Received message"));
+
+ iMessage = const_cast<RMessage2&> (aMessage);
+ switch (iMessage.Function())
+ {
+ case EMonitor:
+ DoMonitorL(EFalse);
+ iMessage.Complete(KErrNone);
+ break;
+ case EMonitorSelf:
+ DoMonitorL(ETrue);
+ iMessage.Complete(KErrNone);
+ break;
+ case ECancelSelf:
+ CancelMonitorSelfL();
+ iMessage.Complete(KErrNone);
+ break;
+ case ECancelAllMonitors:
+ {
+ SysMonServer()->CancelAllMonitors();
+ iMessage.Complete(KErrNone);
+ break;
+ }
+ default:
+ iMessage.Complete(KErrNotSupported);
+ break;
+ }
+ }
+
+
+void CSysMonSession::ServiceError(const RMessage2 &aMessage, TInt aError)
+ {
+ aMessage.Complete(aError);
+ }
+
+
+/*
+Handles EMonitor and EMonitorSelf message to monitor a process
+*/
+void CSysMonSession::DoMonitorL(TBool aMonitorSelf)
+ {
+ // no new process monitoring will be initiate if shut down is in progress
+ if (SysMonServer()->ShutDownInProgress())
+ {
+ User::Leave(KErrCancel);
+ }
+
+ HBufC8 *msg = HBufC8::NewL(iMessage.GetDesLengthL(0));
+ CleanupStack::PushL(msg);
+
+ TPtr8 msgPtr(msg->Des());
+ iMessage.ReadL(0, msgPtr);
+
+ CStartupProperties *prop = CStartupProperties::NewL();
+ CleanupStack::PushL(prop);
+
+ prop->InternalizeL(msgPtr);
+
+ // Retrieve process id depending function type and check for platform security
+ // For self monitoring, EIgnoreOnFailure does not require any capability
+ // For moniting other process, EIgnoreOnFailure require capability ProtServ
+ TProcessId id;
+ if (aMonitorSelf)
+ {
+ RThread thread;
+ User::LeaveIfError(iMessage.Client(thread));
+
+ RProcess process;
+ User::LeaveIfError(thread.Process(process));
+
+ id = process.Id();
+
+ // Use the filename from the proces
+ TFileName name = process.FileName();
+ prop->SetFileParamsL(name, prop->Args());
+
+ process.Close();
+ thread.Close();
+ }
+ else
+ {
+ if (prop->RecoveryMethod() == EIgnoreOnFailure)
+ {
+ if (!iMessage.HasCapability(ECapabilityProtServ))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+ }
+
+ TPckg<TProcessId> procPckg(id);
+ iMessage.ReadL(1, procPckg);
+ }
+
+ // For ERestartOS and ECriticalNoRetries, capability ProtServ is required for both self-monitoring and monitoring other
+ if (prop->RecoveryMethod() == ERestartOS || prop->RecoveryMethod() == ECriticalNoRetries)
+ {
+ if (!iMessage.HasCapability(ECapabilityProtServ))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+ }
+ // For ERestartOSWithMode, capability ProtServ and PowerMgmt are required for both self-monitoring and monitoring other
+ else if (prop->RecoveryMethod() == ERestartOSWithMode)
+ {
+ if ((!iMessage.HasCapability(ECapabilityProtServ)) || (!iMessage.HasCapability(ECapabilityPowerMgmt)))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+#ifndef __WINS__ // HAL::Get(EMaximumRestartStartupModes...) is only supported in H4
+ // check that the startup mode is valid, first retrieve max startup mode if not retrieved yet
+ TInt maxStartupMode = 0;
+ TInt err = HAL::Get(HALData::EMaximumRestartStartupModes, maxStartupMode);
+ if (err != KErrNone)
+ {
+ DEBUGPRINT2(_L("Failed to get max startup mode err=%d"), err);
+ User::Leave(err);
+ }
+
+ if (prop->RestartMode() > maxStartupMode)
+ {
+ DEBUGPRINT2(_L("Invalid startupMode=%d"), prop->RestartMode());
+ User::Leave(KErrArgument);
+ }
+#endif
+ }
+
+#ifdef _DEBUG
+ TPtrC fileName = prop->FileName();
+ DEBUGPRINT2(_L("SysMonServSess: Creating monitor for %S"), &fileName);
+#endif
+
+ const TBool KExecuteRecoveryMethodOnFailure = iMessage.Int2();
+ CMonitor *monitor = CMonitor::NewL(*SysMonServer(), id, prop, KExecuteRecoveryMethodOnFailure); // a new monitor is created - ownership of prop transferred
+
+ CleanupStack::Pop(prop); // ownership of prop is passed into monitor
+ CleanupStack::PushL(monitor);
+
+ DEBUGPRINT1(_L("SysMonServSess: Monitor created."));
+
+ // new monitor is added to the list maintained by SysMonServer - ownership of monitor transferred.
+ // monitor will be popped from cleanup stack in AddMonitorL
+ SysMonServer()->AddAndStartMonitorL(monitor);
+
+ CleanupStack::PopAndDestroy(msg);
+ }
+
+
+/*
+CSysMonSession::CancelMonitorSelfL() is invoked to cancel self-monitoring
+*/
+void CSysMonSession::CancelMonitorSelfL() const
+ {
+ RThread thread;
+ User::LeaveIfError(iMessage.Client(thread));
+
+ RProcess process;
+ User::LeaveIfError(thread.Process(process));
+
+ SysMonServer()->CancelMonitor(process.Id());
+
+ DEBUGPRINT2(_L("SysMonServSess: Monitor Cancelled. ProcessId=%Lu"), process.Id().Id());
+
+ process.Close();
+ thread.Close();
+ }
+
+
+/*
+CSysMonSession::SysMonServer() returns a pointer to the server object
+*/
+CSysMonServer* CSysMonSession::SysMonServer() const
+ {
+ return static_cast<CSysMonServer*> (const_cast<CServer2*> (Server()));
+ }