Catchup.
// ffstrace.cpp
//
// Copyright (c) 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 <fshell/extrabtrace.h>
#include <fshell/btrace_parser.h>
#include <fshell/ioutils.h>
#include <fshell/common.mmh>
using namespace IoUtils;
class CCmdFfstrace : public CCommandBase, public MBtraceObserver
{
public:
static CCommandBase* NewLC();
~CCmdFfstrace();
private:
CCmdFfstrace();
void HandleBtraceFrameL(const TBtraceFrame& aFrame);
private: // From CCommandBase.
virtual const TDesC& Name() const;
virtual void DoRunL();
virtual void ArgumentsL(RCommandArgumentList& aArguments);
virtual void OptionsL(RCommandOptionList& aOptions);
private:
enum TCmd
{
EMonitor,
ELoad,
EUnload,
};
TCmd iCommand;
private:
CBtraceReader* iBtraceReader;
};
EXE_BOILER_PLATE(CCmdFfstrace)
CCommandBase* CCmdFfstrace::NewLC()
{
CCmdFfstrace* self = new(ELeave) CCmdFfstrace();
CleanupStack::PushL(self);
self->BaseConstructL();
return self;
}
CCmdFfstrace::~CCmdFfstrace()
{
delete iBtraceReader;
}
CCmdFfstrace::CCmdFfstrace()
: CCommandBase(EManualComplete)
{
}
const TDesC& CCmdFfstrace::Name() const
{
_LIT(KName, "ffstrace");
return KName;
}
void CCmdFfstrace::ArgumentsL(RCommandArgumentList& aArguments)
{
aArguments.AppendEnumL((TInt&)iCommand, _L("command"));
}
void CCmdFfstrace::OptionsL(RCommandOptionList& /*aOptions*/)
{
//TODO: aOptions.AppendBoolL(iOpt, _L("example_opt"));
//TODO: Also remember to update the CIF file for any options you add.
}
void CCmdFfstrace::DoRunL()
{
_LIT(KPluginDll, "ffstraceplugin.fxt");
_LIT(KFfsTracerPluginName, "FfsTracePlugin");
if (iCommand == EMonitor || iCommand == ELoad)
{
TInt err = FsL().AddPlugin(KPluginDll);
if (err && err != KErrAlreadyExists) LeaveIfErr(err, _L("Couldn't load filesystem plugin %S"), &KPluginDll);
err = FsL().MountPlugin(KFfsTracerPluginName);
//TODO handle this being called repeatedly
LeaveIfErr(err, _L("Couldn't mount filesystem plugin %S"), &KFfsTracerPluginName);
}
else if (iCommand == EUnload)
{
FsL().DismountPlugin(KFfsTracerPluginName);
LeaveIfErr(FsL().RemovePlugin(KFfsTracerPluginName), _L("No plugin to unload"));
}
if (iCommand == EMonitor)
{
iBtraceReader = CBtraceReader::NewL(CBtraceReader::EFlushOnBtraceThreshold, 1024*1024, 512*1024);
iBtraceReader->AddObserverL(BTrace::EFfsTrace, *this);
iBtraceReader->SetMultipartReassemblyL(10);
TBtraceTickCount now;
now.SetToNow();
iBtraceReader->Start(now, 1000000);
}
else
{
Complete(KErrNone);
}
}
void CCmdFfstrace::HandleBtraceFrameL(const TBtraceFrame& aFrame)
{
if (aFrame.iCategory == BTrace::EFfsTrace)
{
TInt fn = aFrame.iSubCategory & ~BTrace::EFfsPost;
TBool post = aFrame.iSubCategory & BTrace::EFfsPost;
TUint threadId = *(TUint*)aFrame.iData.Ptr();
TPtrC name((TUint16*)(aFrame.iData.Ptr()+4), (aFrame.iData.Size()-4)/2);
TPtrC newName;
// Not everything gets as far as post - if an error occurs during the pre checking for eg
if (post) Printf(_L("-"));
else Printf(_L("+"));
TBool twoNames = (fn == BTrace::EFfsRename || fn == BTrace::EFfsFileRename);
if (twoNames)
{
TInt separator = name.Locate(0);
if (separator != KErrNotFound)
{
newName.Set(name.Mid(separator+1));
name.Set(name.Left(separator));
}
}
switch (fn)
{
case BTrace::EFfsDelete:
Printf(_L("Delete %S"), &name);
break;
case BTrace::EFfsFileOpen:
Printf(_L("Open %S"), &name);
break;
case BTrace::EFfsFileCreate:
Printf(_L("Create %S"), &name);
break;
case BTrace::EFfsFileSubClose:
Printf(_L("Close %S"), &name);
break;
case BTrace::EFfsFileReplace:
Printf(_L("Replace %S"), &name);
break;
case BTrace::EFfsFileTemp:
Printf(_L("Open temp %S"), &name);
break;
case BTrace::EFfsRename:
case BTrace::EFfsFileRename:
Printf(_L("Rename from %S to %S"), &name, &newName);
break;
case BTrace::EFfsEntry:
Printf(_L("RFs::Entry %S"), &name);
break;
default:
Printf(_L("Event %d"), fn);
break;
}
Printf(_L(" from thread %u"), threadId);
RThread thread;
TInt err = thread.Open(threadId);
if (err == KErrNone)
{
Printf(_L(" "));
TFullName name = thread.FullName();
Write(name);
thread.Close();
}
Printf(_L("\r\n"));
}
}