Added showdebug command.
Also:
* Added an exported constructor to RChildProcess so the iProcess handle was set to zero on construction.
* Fixed bug in fshell_builddocs script that created HTML relative links with backslashes instead of forward slashes.
// shutapp.cpp
//
// Copyright (c) 2007 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//
#include <w32std.h>
#include <apgtask.h>
#include <apgwgnam.h>
#include "shutapp.h"
CCommandBase* CCmdShutApp::NewLC()
{
CCmdShutApp* self = new(ELeave) CCmdShutApp();
CleanupStack::PushL(self);
self->BaseConstructL();
return self;
}
CCmdShutApp::~CCmdShutApp()
{
iWgIds.Close();
iWgNames.ResetAndDestroy();
}
CCmdShutApp::CCmdShutApp()
: iTimeout(5)
{
}
const TDesC& CCmdShutApp::Name() const
{
_LIT(KName, "shutapp");
return KName;
}
void CCmdShutApp::DoRunL()
{
RWsSession wsSession;
User::LeaveIfError(wsSession.Connect());
CleanupClosePushL(wsSession);
const TInt numIds = iWgIds.Count();
for (TInt i = 0; i < numIds; ++i)
{
ShutL(wsSession, iWgIds[i]);
}
const TInt numNames = iWgNames.Count();
for (TInt i = 0; i < numNames; ++i)
{
const TDesC& name = *(iWgNames[i]);
TInt id = 0;
while ((id = wsSession.FindWindowGroupIdentifier(id, name)) != KErrNotFound)
{
ShutL(wsSession, id);
}
}
if (iAll)
{
TInt numWgs = wsSession.NumWindowGroups(0);
if (numWgs > 0)
{
CArrayFixFlat<TInt>* wgIds = new(ELeave) CArrayFixFlat<TInt>(numWgs);
CleanupStack::PushL(wgIds);
User::LeaveIfError(wsSession.WindowGroupList(0, wgIds));
numWgs = wgIds->Count();
for (TInt i = 0; i < numWgs; ++i)
{
ShutL(wsSession, (*wgIds)[i]);
}
CleanupStack::PopAndDestroy(wgIds);
}
}
CleanupStack::PopAndDestroy(&wsSession);
}
void CCmdShutApp::ShutL(RWsSession& aWsSession, TInt aWindowGroupId)
{
CApaWindowGroupName* wgn = CApaWindowGroupName::NewLC(aWsSession, aWindowGroupId);
if (iVerbose)
{
_LIT(KUnknown, "not named");
TPtrC caption(wgn->Caption());
if (caption.Length() == 0)
{
caption.Set(KUnknown);
}
Printf(_L("Shutting down %d (%S)\r\n"), aWindowGroupId, &caption);
}
TThreadId threadId;
User::LeaveIfError(aWsSession.GetWindowGroupClientThreadId(aWindowGroupId, threadId));
RThread thread;
User::LeaveIfError(thread.Open(threadId));
CleanupClosePushL(thread);
TRequestStatus threadStatus;
thread.Logon(threadStatus);
if (threadStatus != KRequestPending)
{
User::WaitForRequest(threadStatus);
User::Leave(KErrGeneral);
}
RTimer timer;
User::LeaveIfError(timer.CreateLocal());
CleanupClosePushL(timer);
TRequestStatus timeoutStatus;
timer.After(timeoutStatus, iTimeout * 1000000);
TApaTask task(aWsSession);
task.SetWgId(aWindowGroupId);
#ifdef EKA2
if (iForce)
{
task.SendSystemEvent(EApaSystemEventSecureShutdown);
}
else
{
task.SendSystemEvent(EApaSystemEventShutdown);
}
#else
task.SendSystemEvent(EApaSystemEventShutdown);
#endif
User::WaitForRequest(threadStatus, timeoutStatus);
if (timeoutStatus != KRequestPending)
{
// Timeout occurred.
thread.LogonCancel(threadStatus);
User::WaitForRequest(threadStatus);
User::Leave(KErrTimedOut);
}
else
{
timer.Cancel();
User::WaitForRequest(timeoutStatus);
}
CleanupStack::PopAndDestroy(3, wgn);
}
void CCmdShutApp::OptionsL(RCommandOptionList& aOptions)
{
_LIT(KOptWgId, "id");
aOptions.AppendUintL(iWgIds, KOptWgId);
_LIT(KOptWgPattern, "match");
aOptions.AppendStringL(iWgNames, KOptWgPattern);
_LIT(KOptTimeout, "timeout");
aOptions.AppendIntL(iTimeout, KOptTimeout);
_LIT(KOptVerbose, "verbose");
aOptions.AppendBoolL(iVerbose, KOptVerbose);
_LIT(KOptAll, "all");
aOptions.AppendBoolL(iAll, KOptAll);
#ifdef EKA2
_LIT(KOptForce, "force");
aOptions.AppendBoolL(iForce, KOptForce);
#endif
}
void CCmdShutApp::ArgumentsL(RCommandArgumentList&)
{
}
#ifdef EXE_BUILD
EXE_BOILER_PLATE(CCmdShutApp)
#endif