userlibandfileserver/fileserver/sfile/sf_plugin_ops.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:26:05 +0100
branchRCL_3
changeset 136 743008598095
parent 0 a41df078684a
child 147 bbf8bed59bcb
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "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:
// f32\sfile\sf_plugin_ops.cpp
// 
//

#include "sf_std.h"
#include "sf_plugin_priv.h"
#include "sf_file_cache.h"

/**
Platform security check
*/
TInt TFsAddPlugin::Initialise(CFsRequest* aRequest)
	{
	if (!KCapFsPlugin.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount Plugin")))
		return KErrPermissionDenied;

	return(KErrNone);
	}

/**
Adds the plugin and installs plugin factory
*/
TInt TFsAddPlugin::DoRequestL(CFsRequest* aRequest)
	{
	__PRINT(_L("TFsAddPlugin::DoRequestL(CFsRequest* aRequest)"));
	
	RLibrary lib;
	lib.SetHandle(aRequest->Message().Int0());				
	if (lib.Type()[1]!=TUid::Uid(KFileSystemUidValue))		
		return KErrNotSupported;

	TPluginNew e=(TPluginNew)lib.Lookup(1);					
	if (!e)
		return KErrCorrupt;

	CFsPluginFactory* pF=(*e)();
	if(!pF)													
		return KErrNoMemory;
	
	TInt r = FsPluginManager::InstallPluginFactory(pF,lib);
	return(r);
	}

/**
Platform security checking
*/
TInt TFsRemovePlugin::Initialise(CFsRequest* aRequest)
	{
	if (!KCapFsPlugin.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount Plugin")))
		return KErrPermissionDenied;
	return KErrNone;
	}

/**
Removes the plugin from session. Can't remove if have plugin mounted. 
*/
TInt TFsRemovePlugin::DoRequestL(CFsRequest* aRequest)
	{
	TFullName name;
	aRequest->ReadL(KMsgPtr0,name);	
	
	CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(name);			
	if (pF==NULL)								
		return(KErrNotFound);

	// Check if any plugin is mounted in the chain
	if(pF->MountedPlugins()!=0)
		return KErrInUse;	

	TInt r=pF->Remove();						
	if (r!=KErrNone)
		return(r);
	RLibrary lib=pF->Library();					
	pF->Close();								
	lib.Close();								
	return(KErrNone);
	}

/**
Platform security check.
Finding the plugin factory & checking if the drive supports the plugin
*/
TInt TFsMountPlugin::Initialise(CFsRequest* aRequest)
	{
	
	if (!KCapFsPlugin.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount Plugin")))
		return KErrPermissionDenied;
	
	TFullName pluginName;
	TRAPD(err,aRequest->ReadL(KMsgPtr0,pluginName));
	if(err != KErrNone)
		return err;

	CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(pluginName);
	if (pF==NULL)
		return(KErrNotFound);

	if(pF->IsDriveSupported(aRequest->Message().Int1()) == EFalse)
		return KErrNotSupported;

	aRequest->SetScratchValue((TUint)pF);

	return KErrNone;
	}

/**
Mounts the plugin
*/
TInt TFsMountPlugin::DoRequestL(CFsRequest* aRequest)
	{
	CFsPluginFactory* pF = (CFsPluginFactory*)aRequest->ScratchValue();
	if(pF == NULL)
		return KErrNotFound;

	// empty the closed file queue
	TClosedFileUtils::Remove();

	TInt err = FsPluginManager::MountPlugin(*pF,aRequest->Message().Int1(),aRequest->Message().Int2());
	return err;
	}

/**
Platform security check.
Finding the plugin factory & checking if the drive supports the plugin
*/
TInt TFsDismountPlugin::Initialise(CFsRequest* aRequest)
	{
	if (!KCapFsPlugin.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount Plugin")))
		return KErrPermissionDenied;

	TFullName name;
	TRAPD(err, aRequest->ReadL(KMsgPtr0,name));					//get plugin name
	if(err!=KErrNone)
		return err;

	TInt drive = aRequest->Message().Int1();
	CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(name);				
	if (!pF || pF->MountedPlugins()==0)
		return(KErrNotFound);
	if(pF->IsDriveSupported(drive) == EFalse)
		return KErrNotSupported;

	FsPluginManager::LockChain();
	err = FsPluginManager::IsInChain(pF->UniquePosition(),aRequest->Message().Int2(),aRequest->Message().Int1(), pF);

	// plugin might have been mounted in different pos and drive. Find the right one
	if(err >= 0)
		{
		TInt pos = err;
		CFsPlugin* plugin = NULL;
		err = FsPluginManager::Plugin(plugin, pos);
		if(err == KErrNone)
			{
			//If we're version2 plugin, and we're dismounting a single drive
			// but we're mounted on many drives, then
			// just remove drive from iMountedOn and return KErrCompletion.
			//
			//NB: Already checked that we're mounted on 'drive' in IsInChain
			
			if(pF->SupportedDrives()&KPluginVersionTwo && drive!=KPluginAutoAttach)
				{
				//Special Case:
				//Z Drive
				if(drive==KPluginMountDriveZ)
					{
					drive = 25;
					}
				
				//Are we mounted on many drives?
				if((plugin->iMountedOn&(~1<<drive)) > 0) //without 'drive' is there still a drive set?
					{
					plugin->iMountedOn &= ~1<<drive;
					FsPluginManager::UnlockChain();
					return KErrCompletion; //don't go to dorequestl
					}
				}
			
			plugin->RegisterIntercept(EFsDismountPlugin, CFsPlugin::EPreIntercept);
			aRequest->SetScratchValue((TUint)pF);
			}
		}
	// pos contains an error code
	FsPluginManager::UnlockChain();
	return err;
	}

/**
Dismount the plugin from the stack
*/
TInt TFsDismountPlugin::DoRequestL(CFsRequest* aRequest)
	{

	CFsPluginFactory* pF = (CFsPluginFactory*)aRequest->ScratchValue();
	if(pF == NULL)
		return KErrNone;	// The plugin has already been dismounted

	TInt drive = aRequest->Message().Int1();

	FsPluginManager::LockChain();

	TInt err = FsPluginManager::IsInChain(pF->UniquePosition(),aRequest->Message().Int2(),drive, pF);
	if(err >= 0)
		{
		TInt pos = err;
		CFsPlugin* plugin = NULL;
		err = FsPluginManager::Plugin(plugin, pos);
		if(err == KErrNone)
			{
			if(aRequest->iCurrentPlugin == plugin)
				{
				FsPluginManager::DismountPlugin(*pF,pos);
				aRequest->SetScratchValue(0);
				}
			}
		}
	FsPluginManager::UnlockChain();
	return err;
	}


/**
Validates the drive
*/
TInt TFsPluginName::Initialise(CFsRequest* aRequest)
	{
	TInt r=ValidateDrive(aRequest->Message().Int1(),aRequest);
	if(r!=KErrNone)
		return r;
	if(aRequest->Drive()->IsSubsted())
		return KErrNotSupported;
	return r;
	}

/**
Return the name of a plugin for a given drive and plugin chain position
*/
TInt TFsPluginName::DoRequestL(CFsRequest* aRequest)
	{
	CFsPlugin* plugin=NULL;
	FsPluginManager::LockChain();
	TInt err = FsPluginManager::Plugin(plugin, aRequest->Message().Int2());
	if(err != KErrNone)
		return err;

	TInt r = KErrNotFound;
	if(plugin)
		{
		aRequest->WriteL(KMsgPtr0, plugin->Name());
		r = KErrNone;
		}
	FsPluginManager::UnlockChain();
	return r;
	}
/**
Open a plugin
*/
TInt TFsPluginOpen::Initialise(CFsRequest* aRequest)
	{
	TInt pluginPos = aRequest->Message().Int0();
	CFsPlugin* pP = FsPluginManager::FindByUniquePosition(pluginPos);
	if(pP == NULL)
		return KErrNotFound;

	aRequest->iCurrentPlugin = pP;
	aRequest->SetDriveNumber(-1);
	
	RThread thread;
	aRequest->Message().Client(thread, EOwnerThread);
	aRequest->SetScratchValue((TUint)(thread.Id()));
	thread.Close();
	
	return KErrNone;
	}

/**
open the plugin
*/
TInt TFsPluginOpen::DoRequestL(CFsRequest* aRequest)
	{
	TInt pluginPos = aRequest->Message().Int0();
	CFsPluginConn* pC = FsPluginManager::CreatePluginConnL(pluginPos, aRequest->ScratchValue());

	TInt handle = aRequest->Session()->Handles().AddL(pC,ETrue);
	TPtrC8 pH((TUint8*)&handle, sizeof(TInt));
	aRequest->WriteL(KMsgPtr3, pH);
	aRequest->Session()->IncResourceCount();
	
	return KErrNone;
	}

/**
Initialising the plugin control
*/
LOCAL_C TInt InitPluginControl(CFsRequest* aRequest)
	{
	CFsPluginConn* pC = FsPluginManager::GetPluginConnFromHandle(aRequest->Session(), aRequest->Message().Int3());
	if(pC == NULL)
		return KErrBadHandle;

	aRequest->iCurrentPlugin = pC->Plugin();
	aRequest->SetDriveNumber(-1);

	CFsPluginConnRequest* request = new CFsPluginConnRequest(pC);
	if(request == NULL)
		return KErrNoMemory;

	aRequest->SetScratchValue((TUint)request);
	return KErrNone;
	}

/**
Initialises the plugin control and gets the request
*/
TInt TFsPluginDoControl::Initialise(CFsRequest* aRequest)
	{
	TInt err = InitPluginControl(aRequest);
	if(err != KErrNone)
		return err;

	CFsPluginConnRequest* request = (CFsPluginConnRequest*)aRequest->ScratchValue();
	return request->InitControl(aRequest);
	}

/**
does handle the control request
*/
TInt TFsPluginDoControl::DoRequestL(CFsRequest* aRequest)
	{
	CFsPluginConnRequest* pRequest = (CFsPluginConnRequest*)aRequest->ScratchValue();	
	TInt r = pRequest->DoControl();
	delete pRequest;
	return r;
	}


/**
Initialises the request 
*/
TInt TFsPluginDoRequest::Initialise(CFsRequest* aRequest)
	{
	TInt err = InitPluginControl(aRequest);
	if(err != KErrNone)
		return err;

	CFsPluginConnRequest* request = (CFsPluginConnRequest*)aRequest->ScratchValue();
	return request->InitRequest(aRequest);
	}

/**
Handles the request adding it to the queue of the requests
*/
TInt TFsPluginDoRequest::DoRequestL(CFsRequest* aRequest)
	{
	CFsPluginConnRequest* pRequest = (CFsPluginConnRequest*)aRequest->ScratchValue();	
	pRequest->DoRequest();
	return KErrNone;
	}

/**
Initialises the request
*/
TInt TFsPluginDoCancel::Initialise(CFsRequest* aRequest)
	{
	CFsPluginConn* pC = FsPluginManager::GetPluginConnFromHandle(aRequest->Session(), aRequest->Message().Int3());
	if(pC == NULL)
		return KErrBadHandle;

	aRequest->iCurrentPlugin = pC->Plugin();
	aRequest->SetDriveNumber(-1);
	aRequest->SetScratchValue((TUint)pC);
	
	return KErrNone;
	}

/**
Cancels the outstanding request
*/
TInt TFsPluginDoCancel::DoRequestL(CFsRequest* aRequest)
	{
	CFsPluginConn* pC = (CFsPluginConn*)aRequest->ScratchValue();	
	pC->DoCancel(aRequest->Message().Int0());
	return KErrNone;
	}