sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Template_plugin.cpp sl@0: // sl@0: // sl@0: sl@0: #include "exclusiveaccess_plugin.h" sl@0: #include "plugincommon.h" sl@0: #include sl@0: sl@0: /** sl@0: Leaving New function for the plugin sl@0: @internalComponent sl@0: */ sl@0: CExclusiveAccessPlugin* CExclusiveAccessPlugin::NewL() sl@0: { sl@0: CExclusiveAccessPlugin* self = new(ELeave) CExclusiveAccessPlugin; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Constructor for the plugin sl@0: @internalComponent sl@0: */ sl@0: CExclusiveAccessPlugin::CExclusiveAccessPlugin() : iInterceptsEnabled(EFalse), sl@0: iLogging(ETrue) sl@0: { sl@0: } sl@0: sl@0: sl@0: void CExclusiveAccessPlugin::ConstructL() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: The destructor for the plugin sl@0: @internalComponent sl@0: */ sl@0: CExclusiveAccessPlugin::~CExclusiveAccessPlugin() sl@0: { sl@0: iFs.Close(); sl@0: } sl@0: sl@0: /** sl@0: Initialise the plugin. sl@0: @internalComponent sl@0: */ sl@0: void CExclusiveAccessPlugin::InitialiseL() sl@0: { sl@0: User::LeaveIfError(iFs.Connect()); sl@0: CleanupClosePushL(iFs); sl@0: sl@0: _LOG(_L("CExclusiveAccessPlugin InitialiseL")); sl@0: EnableInterceptsL(); sl@0: sl@0: CleanupStack::Pop(); // iFs sl@0: } sl@0: sl@0: /** sl@0: Enable the plugin's intercepts. sl@0: @internalComponent sl@0: */ sl@0: void CExclusiveAccessPlugin::EnableInterceptsL() sl@0: { sl@0: if (iInterceptsEnabled) return; sl@0: sl@0: User::LeaveIfError(RegisterIntercept(EFsFileRead, EPrePostIntercept)); sl@0: User::LeaveIfError(RegisterIntercept(EFsFileWrite, EPrePostIntercept)); sl@0: sl@0: _LOG(_L("CExclusiveAccessPlugin : Enabled intercepts.")); sl@0: sl@0: iInterceptsEnabled = ETrue; sl@0: } sl@0: sl@0: /** sl@0: Disable the plugin's intercepts. sl@0: @internalComponent sl@0: */ sl@0: void CExclusiveAccessPlugin::DisableInterceptsL() sl@0: { sl@0: if (!iInterceptsEnabled) return; sl@0: sl@0: User::LeaveIfError(UnregisterIntercept(EFsFileRead, EPrePostIntercept)); sl@0: User::LeaveIfError(UnregisterIntercept(EFsFileWrite, EPrePostIntercept)); sl@0: _LOG(_L("CExclusiveAccessPlugin : Disabled intercepts.")); sl@0: sl@0: iInterceptsEnabled = EFalse; sl@0: } sl@0: sl@0: /** sl@0: Handle requests sl@0: @internalComponent sl@0: */ sl@0: TInt CExclusiveAccessPlugin::DoRequestL(TFsPluginRequest& aRequest) sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: TInt function = aRequest.Function(); sl@0: sl@0: switch(function) sl@0: { sl@0: case EFsFileRead: sl@0: err = FsFileReadL(aRequest); sl@0: break; sl@0: case EFsFileWrite: sl@0: err = FsFileWriteL(aRequest); sl@0: break; sl@0: default: sl@0: //Only registered for Read/Write sl@0: break; sl@0: } sl@0: sl@0: return err; sl@0: } sl@0: sl@0: /*Test to ensure that when a file has been opened for exclusive access, sl@0: * i.e. readonly, that froma plugin we can still read from it sl@0: */ sl@0: TInt CExclusiveAccessPlugin::FsFileReadL(TFsPluginRequest& aRequest) sl@0: { sl@0: if(!aRequest.IsPostOperation()) // pre-operation sl@0: { sl@0: RFilePlugin file(aRequest); sl@0: sl@0: TInt err = file.AdoptFromClient(); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TInt64 pos; sl@0: err = aRequest.Read(TFsPluginRequest::EPosition, pos); // get pos sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TInt length; sl@0: err = aRequest.Read(TFsPluginRequest::ELength, length); //get length sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: if(length>265) sl@0: length=256; sl@0: sl@0: //we should check that this file is in fact registered as read only? sl@0: //if not.. User::Invariant()? sl@0: TEntry entry; sl@0: RFsPlugin rfsplugin(aRequest); sl@0: err = rfsplugin.Connect(); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TFileName fileName; sl@0: err = aRequest.FileName(fileName); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: err = rfsplugin.Entry(fileName, entry); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: //can we read a readonly file? - should be fine. sl@0: TBuf8<256> data; sl@0: err = file.Read(pos,data,length); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: file.Close(); sl@0: rfsplugin.Close(); sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: /*Test to ensure that when a file has been opened for exclusive access, sl@0: * i.e. readonly, that from a plugin we can still write to it regardless sl@0: */ sl@0: TInt CExclusiveAccessPlugin::FsFileWriteL(TFsPluginRequest& aRequest) sl@0: { sl@0: if(!aRequest.IsPostOperation()) // pre-operation sl@0: { sl@0: //Make sure that the file is read only. sl@0: sl@0: RFilePlugin file(aRequest); sl@0: TInt err = file.AdoptFromClient(); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: RFsPlugin rfsplugin(aRequest); sl@0: err = rfsplugin.Connect(); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TEntry entry; sl@0: err = rfsplugin.Entry(aRequest.Src().FullName(), entry); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: // if(!entry.IsReadOnly()) sl@0: // { sl@0: // //this test should only being being used for read only files. sl@0: // User::Invariant(); sl@0: // } sl@0: sl@0: TInt64 pos; sl@0: err = aRequest.Read(TFsPluginRequest::EPosition, pos); //get pos sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TInt length; sl@0: err = aRequest.Read(TFsPluginRequest::ELength, length); //get length sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: TBuf8<1024> data; sl@0: err = aRequest.Read(TFsPluginRequest::EData, data); //get data to write sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: //Now test that we can actually write to this read-only file sl@0: //Should pass, kerrnone. sl@0: err = file.Write(pos,data,length); sl@0: iLastError = err; sl@0: iLineNumber = __LINE__; sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: file.Close(); sl@0: sl@0: //We've performed the efsfilewrite, so return kerrcompletion. sl@0: return KErrCompletion; sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: sl@0: CFsPluginConn* CExclusiveAccessPlugin::NewPluginConnL() sl@0: { sl@0: return new(ELeave) CExclusiveAccessPluginConn(); sl@0: } sl@0: sl@0: sl@0: //Synchronous RPlugin::DoControl sl@0: TInt CExclusiveAccessPlugin::FsPluginDoControlL(CFsPluginConnRequest& aRequest) sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: //We can use this to set the drive sl@0: //We can store this as a member of this class. sl@0: TInt function = aRequest.Function(); sl@0: TPckg errCodeDes(iLastError); sl@0: TPckg lineNumberDes(iLineNumber); sl@0: sl@0: switch(function) sl@0: { sl@0: case KPluginGetError: sl@0: { sl@0: TRAP(err,aRequest.WriteParam1L(errCodeDes)); sl@0: TRAP(err,aRequest.WriteParam2L(lineNumberDes)); sl@0: break; sl@0: } sl@0: default: sl@0: break; sl@0: } sl@0: sl@0: return err; sl@0: } sl@0: sl@0: sl@0: TInt CExclusiveAccessPluginConn::DoControl(CFsPluginConnRequest& aRequest) sl@0: { sl@0: return ((CExclusiveAccessPlugin*)Plugin())->FsPluginDoControlL(aRequest); sl@0: } sl@0: sl@0: void CExclusiveAccessPluginConn::DoRequest(CFsPluginConnRequest& aRequest) sl@0: { sl@0: DoControl(aRequest); sl@0: } sl@0: sl@0: void CExclusiveAccessPluginConn::DoCancel(TInt /*aReqMask*/) sl@0: { sl@0: } sl@0: sl@0: sl@0: //factory functions sl@0: sl@0: class CExclusiveAccessPluginFactory : public CFsPluginFactory sl@0: { sl@0: public: sl@0: CExclusiveAccessPluginFactory(); sl@0: virtual TInt Install(); sl@0: virtual CFsPlugin* NewPluginL(); sl@0: virtual CFsPlugin* NewPluginConnL(); sl@0: virtual TInt UniquePosition(); sl@0: }; sl@0: sl@0: /** sl@0: Constructor for the plugin factory sl@0: @internalComponent sl@0: */ sl@0: CExclusiveAccessPluginFactory::CExclusiveAccessPluginFactory() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Install function for the plugin factory sl@0: @internalComponent sl@0: */ sl@0: TInt CExclusiveAccessPluginFactory::Install() sl@0: { sl@0: SetSupportedDrives(KPluginSupportAllDrives); sl@0: return(SetName(&KExclusiveAccessPluginName)); sl@0: } sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: TInt CExclusiveAccessPluginFactory::UniquePosition() sl@0: { sl@0: return(KExclusiveAccessPos); sl@0: } sl@0: sl@0: /** sl@0: Plugin factory function sl@0: @internalComponent sl@0: */ sl@0: CFsPlugin* CExclusiveAccessPluginFactory::NewPluginL() sl@0: sl@0: { sl@0: return CExclusiveAccessPlugin::NewL(); sl@0: } sl@0: sl@0: /** sl@0: Plugin factory function sl@0: @internalComponent sl@0: */ sl@0: CFsPlugin* CExclusiveAccessPluginFactory::NewPluginConnL() sl@0: sl@0: { sl@0: return CExclusiveAccessPlugin::NewL(); sl@0: } sl@0: sl@0: /** sl@0: Create a new Plugin sl@0: @internalComponent sl@0: */ sl@0: extern "C" { sl@0: sl@0: EXPORT_C CFsPluginFactory* CreateFileSystem() sl@0: { sl@0: return(new CExclusiveAccessPluginFactory()); sl@0: } sl@0: } sl@0: