diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstarter/sysmonsrc/sysmonservsess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysstatemgmt/systemstarter/sysmonsrc/sysmonservsess.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,220 @@ +// 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 +#include "sysmonservsess.h" +#include "sysmoncliserv.h" +#include "sysmonserver.h" +#include "monitor.h" +#include +#include +#include + +#include "../src/SysStartDebug.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 (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; + 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 procPckg(id); + iMessage.ReadL(1, procPckg); + } + + // For ERestartOS, capability ProtServ is required for both self-monitoring and monitoring other + if (prop->RecoveryMethod() == ERestartOS) + { + 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 (const_cast (Server())); + }