--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/ffstrace/ffstraceplugin.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,230 @@
+// ffstraceplugin.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 <f32plugin.h>
+#include <f32pluginutils.h>
+#include <fshell/ltkutils.h>
+
+//#define LOG_FUNC() RDebug::Printf(__PRETTY_FUNCTION__)
+//#define LOG(args...) RDebug::Printf(args)
+//#define LOGW(args...) RDebug::Print(args)
+#define LOG_FUNC()
+#define LOG(args...)
+#define LOGW(args...)
+
+
+NONSHARABLE_CLASS(CFfsTracerPluginFactory) : public CFsPluginFactory
+ {
+public:
+ static CFfsTracerPluginFactory* NewL();
+
+ // from CFsPluginFactory
+ virtual TInt Install();
+ virtual CFsPlugin* NewPluginL();
+ virtual TInt UniquePosition();
+
+private:
+ CFfsTracerPluginFactory();
+ };
+
+NONSHARABLE_CLASS(CFfsTracerFsPlugin) : public CFsPlugin
+ {
+public:
+ static CFfsTracerFsPlugin* NewL();
+ virtual ~CFfsTracerFsPlugin();
+
+ // from CFsPlugin
+ virtual void InitialiseL();
+ TInt SessionDisconnect(CSessionFs* aSession);
+ virtual TInt DoRequestL(TFsPluginRequest& aRequest);
+ virtual CFsPluginConn* NewPluginConnL();
+private:
+ CFfsTracerFsPlugin();
+ };
+
+class CFfsTracerFsPluginConn : public CFsPluginConn
+ {
+public:
+ CFfsTracerFsPluginConn();
+
+ // from CFsPluginConn
+ virtual TInt DoControl(CFsPluginConnRequest& aRequest);
+ virtual void DoRequest(CFsPluginConnRequest& aRequest);
+ virtual void DoCancel(TInt aReqMask);
+ };
+
+extern "C" EXPORT_C CFsPluginFactory* CreateFileSystem()
+ {
+ return CFfsTracerPluginFactory::NewL();
+ }
+
+CFfsTracerPluginFactory* CFfsTracerPluginFactory::NewL()
+ {
+ return(new(ELeave) CFfsTracerPluginFactory());
+ }
+
+CFfsTracerPluginFactory::CFfsTracerPluginFactory()
+ {
+ }
+
+_LIT(KFfsTracerPluginName, "FfsTracePlugin");
+
+TInt CFfsTracerPluginFactory::Install()
+ {
+ LOG_FUNC();
+ iSupportedDrives = 0x7FFFFFF; // KPluginSupportAllDrives | KPluginVersionTwo. Not specified symbolically to be compatible with fileservers that didn't support v2 plugins
+
+ TInt err;
+ err = SetName(&KFfsTracerPluginName);
+ LOG(" returned %d", err);
+ return err;
+ }
+
+CFsPlugin* CFfsTracerPluginFactory::NewPluginL()
+ {
+ return CFfsTracerFsPlugin::NewL();
+ }
+
+TInt CFfsTracerPluginFactory::UniquePosition()
+ {
+ return 1; // Isn't used, apparently
+ }
+
+//
+
+CFfsTracerFsPluginConn::CFfsTracerFsPluginConn()
+ {
+ }
+
+TInt CFfsTracerFsPluginConn::DoControl(CFsPluginConnRequest& /*aRequest*/)
+ {
+ return KErrNone;
+ }
+
+void CFfsTracerFsPluginConn::DoRequest(CFsPluginConnRequest& /*aRequest*/)
+ {
+ }
+
+void CFfsTracerFsPluginConn::DoCancel(TInt /*aReqMask*/)
+ {
+ }
+
+//
+
+CFfsTracerFsPlugin* CFfsTracerFsPlugin::NewL()
+ {
+ return new(ELeave) CFfsTracerFsPlugin();
+ }
+
+CFfsTracerFsPlugin::CFfsTracerFsPlugin()
+ {
+ LOG_FUNC();
+ }
+
+static const TFsMessage KMessages[] =
+ {
+ EFsDelete,
+ EFsRename,
+ EFsReplace,
+ EFsEntry,
+ EFsFileSubClose,
+ EFsFileOpen,
+ EFsFileCreate,
+ EFsFileReplace,
+ EFsFileTemp,
+ EFsFileRename,
+ };
+static const TInt KMessageCount = sizeof(KMessages) / sizeof(TFsMessage);
+
+CFfsTracerFsPlugin::~CFfsTracerFsPlugin()
+ {
+ LOG_FUNC();
+ for (TInt i = 0; i < KMessageCount; i++)
+ {
+ UnregisterIntercept(KMessages[i], CFsPlugin::EPrePostIntercept);
+ }
+ }
+
+void CFfsTracerFsPlugin::InitialiseL()
+ {
+ // intercept all calls at start
+ for (TInt i = 0; i < KMessageCount; i++)
+ {
+ RegisterIntercept(KMessages[i], CFsPlugin::EPrePostIntercept);
+ }
+ }
+
+TInt CFfsTracerFsPlugin::SessionDisconnect(CSessionFs* /*aSession*/)
+ {
+ // CSessionFs is a private class! It's in the main file server and
+ // has no exported methods! What's the use of passing it here?
+ return KErrNone;
+ }
+
+CFsPluginConn* CFfsTracerFsPlugin::NewPluginConnL()
+ {
+ LOG_FUNC();
+ return new(ELeave) CFfsTracerFsPluginConn();
+ }
+
+TInt CFfsTracerFsPlugin::DoRequestL(TFsPluginRequest& aRequest)
+ {
+ // This is where it all happens
+
+ TInt subcat = 0;
+ TInt fn = aRequest.Function();
+ // Map from FS opcodes to the compacted btrace ones
+ switch (fn)
+ {
+ case EFsDelete: subcat = BTrace::EFfsDelete; break;
+ case EFsRename: subcat = BTrace::EFfsRename; break;
+ case EFsReplace: subcat = BTrace::EFfsReplace; break;
+ case EFsEntry: subcat = BTrace::EFfsEntry; break;
+ case EFsFileSubClose: subcat = BTrace::EFfsFileSubClose; break;
+ case EFsFileOpen: subcat = BTrace::EFfsFileOpen; break;
+ case EFsFileCreate: subcat = BTrace::EFfsFileCreate; break;
+ case EFsFileReplace: subcat = BTrace::EFfsFileReplace; break;
+ case EFsFileTemp: subcat = BTrace::EFfsFileTemp; break;
+ case EFsFileRename: subcat = BTrace::EFfsFileRename; break;
+ default:
+ // An operation we're not interested in
+ return KErrNone;
+ }
+ if (aRequest.IsPostOperation()) subcat |= BTrace::EFfsPost;
+
+ TBuf<513> name; // Twice as big as a max filename because for renames we need it to fit two TFileNames
+ GetName(&aRequest, name);
+
+ if (fn == EFsRename || fn == EFsFileRename)
+ {
+ name.Append(TChar(0));
+ TPtr newName((TUint16*)(name.Ptr() + name.Length()), 0, name.MaxLength() - name.Length());
+ GetNewName(&aRequest, newName);
+ LOGW(_L("new name is %S"), &newName);
+ name.SetLength(name.Length() + newName.Length());
+ }
+
+ // Only try to use request.Message() if it's a valid handle
+ TUint threadId = 0xFFFFFFFFu;
+ if(aRequest.Message().Handle() != KNullHandle)
+ {
+ RThread clientThread;
+ aRequest.Message().Client(clientThread, EOwnerThread);
+ threadId = clientThread.Id();
+ clientThread.Close();
+ }
+
+ BTraceBig(BTrace::EFfsTrace, subcat, threadId, name.Ptr(), name.Size());
+
+ return KErrNone;
+ }