userlibandfileserver/fileserver/sfile/sf_plugin.cpp
changeset 9 96e5fb8b040d
child 6 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_plugin.cpp	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,835 @@
+// 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.cpp
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+
+#include "sf_std.h"
+#include "sf_plugin_priv.h"
+
+
+EXPORT_C CFsPluginFactory::CFsPluginFactory()
+	{}
+
+EXPORT_C CFsPluginFactory::~CFsPluginFactory()
+	{}
+
+/**
+
+Uninstalls the plugin factory.
+
+This is called just before the plugin factory object is destroyed, and allows
+any clean up to be carried out.
+
+The default implementation does nothing except return KErrNone.
+Implementations should return an error code on error detection.
+
+@return KErrNone if successful, otherwise one of the other system wide error
+        codes.
+*/
+EXPORT_C TInt CFsPluginFactory::Remove()
+	{
+	return(KErrNone);
+	}
+
+/**
+
+Sets the plugin factory's resource library.
+This library represents the loaded plugin factory.
+This is called internally by InstallPluginFactory().
+
+@param aLib The resource library to be set.
+*/
+EXPORT_C void CFsPluginFactory::SetLibrary(RLibrary aLib)
+	{
+	iLibrary=aLib;
+	}
+
+/**
+Gets the plugin factory's resource library.
+
+@return The plugin factory's resource library.
+*/
+EXPORT_C RLibrary CFsPluginFactory::Library() const
+	{
+	return(iLibrary);
+	}
+
+/**
+
+*/
+TBool CFsPluginFactory::IsDriveSupported(TInt aDrive)
+	{
+	//If this is version 1 of the plugins, then if KPluginAutoAttach was specified at mount
+	//then it just returned ETrue! This behaviour is preserved here:
+	if(!(iSupportedDrives & KPluginVersionTwo) && (aDrive == KPluginAutoAttach))
+		{
+		return(ETrue);
+		}
+
+	//If we're version 2 plugin (or version1 && !KPluginAutoAttach) then check against what's been set in iSupportedDrives
+	return((iSupportedDrives & (1 << aDrive)) ? (TBool)ETrue : (TBool)EFalse);
+	}
+
+
+EXPORT_C CFsPlugin::CFsPlugin()
+	: iReadOnly(0)
+	{
+    Mem::FillZ(iRegisteredIntercepts, sizeof(iRegisteredIntercepts));
+	}
+
+EXPORT_C CFsPlugin::~CFsPlugin()
+	{
+	}
+
+/**
+Delivers the request to the end of plugin thread's queue. 
+In certain circumstances, where the request requires priority handling
+it adds it to the front of the queue.
+
+@param	aRequest: The request to be delivered
+@return KErrNone
+*/
+EXPORT_C TInt CFsPlugin::Deliver(TFsPluginRequest& aRequest)
+	{
+	__ASSERT_ALWAYS(iThreadP != NULL, User::Panic(_L("CFsPlugin::Dispatch"),999));
+
+	TInt function = aRequest.Function();
+
+	if(function == EFsPluginOpen)
+		{
+		// Don't dispatch open requests to the plugin thread
+		return KPluginMessageForward;
+		}
+
+	if(function == EFsPluginDoRequest ||
+	   function == EFsPluginDoControl ||
+	   function == EFsPluginDoCancel)
+		{
+		iThreadP->DeliverFront(aRequest.Request());
+		}
+	else
+		{
+		iThreadP->DeliverBack(aRequest.Request());
+		}
+
+	return KErrNone;
+	}
+
+/**
+Initialises the plugin but setting all registered intercepts to zero.
+Derived classes might wish to implement their own InitialiseL to add intercepts
+*/
+EXPORT_C void CFsPlugin::InitialiseL()
+	{
+	}
+
+/**
+Creates a new pluginconn object
+Leaves with KErrNotSupported
+
+@return NULL
+*/
+EXPORT_C CFsPluginConn* CFsPlugin::NewPluginConnL()
+	{
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+/**
+Registers a particular function with plugin to be intercepted
+
+@param	aMessage:		the message to be intercepted
+@param  aInterceptAtts:	If it is post or pre intercept
+@return KErrNone on successful completion 
+		KErrNotSupported if message is invalid
+*/
+EXPORT_C TInt CFsPlugin::RegisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
+	{
+	if(aMessage >= EMaxClientOperations)
+		{
+		return KErrNotSupported;
+		}
+
+	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
+
+    if(index >= KIntcArrSize)
+        {
+        __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
+        return KErrNotSupported;
+        }
+
+	const TUint8 msk  = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
+	iRegisteredIntercepts[index] |= msk;
+
+	return KErrNone;
+	}
+
+/**
+Unregisters a particular function with plugin 
+
+@param	aMessage:		the message which should be unregistered
+@param  aInterceptAtts:	If it is post or pre intercept
+@return KErrNone on successful completion 
+		KErrNotSupported if message is invalid
+*/
+EXPORT_C TInt CFsPlugin::UnregisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
+	{
+	if(aMessage >= EMaxClientOperations)
+		{
+		return KErrNotSupported;
+		}
+
+	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
+    if(index >= KIntcArrSize)
+        {
+        __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
+        return KErrNotSupported;
+        }
+
+	const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
+	iRegisteredIntercepts[index] &= ~msk;
+
+	return KErrNone;
+	}
+
+/**
+    @return ETrue if the message aMessage is registered with any TInterceptAtts type
+*/
+TBool CFsPlugin::IsRegistered(TInt aMessage)
+	{
+	if(IsRegistered(aMessage,(TInterceptAtts)EPreIntercept) ||
+		IsRegistered(aMessage,(TInterceptAtts)EPrePostIntercept) ||
+		IsRegistered(aMessage, (TInterceptAtts)EPostIntercept))
+		{
+		return (TBool)ETrue;
+		}
+	return (TBool)EFalse;
+	}
+
+/**
+    @return ETrue if the message aMessage is registered with the given aInterceptAtts attrubutes
+*/
+TBool CFsPlugin::IsRegistered(TInt aMessage, TInterceptAtts aInterceptAtts)
+	{
+	if(aMessage >= EMaxClientOperations)
+		{
+		return EFalse;
+		}
+
+	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
+    if(index >= KIntcArrSize)
+        {
+        __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
+        return EFalse;
+        }
+
+	const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
+
+	return((iRegisteredIntercepts[index] & msk) == msk);
+	}
+
+/**
+   Return ETrue if the calling thread is the plugin thread
+*/
+TBool CFsPlugin::IsPluginThread(CFsRequest& aRequest)
+	{
+	if(aRequest.iOwnerPlugin == this)
+		return ETrue;
+
+	if(aRequest.iClientThreadId == iThreadId)
+		return ETrue;
+
+	// Allow specific requests from the client connection...
+	if(aRequest.IsPluginSpecific())
+		return EFalse;
+
+	// Check the client connections
+	return FsPluginManager::IsPluginConnThread(aRequest.iClientThreadId, this);
+	}
+
+TBool CFsPlugin::IsMounted(TInt aDrive)
+	{
+	CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(this->Name());	
+	TInt supportedDrives = pF->SupportedDrives();
+
+	//Version1 plugins could not mount on Z Drive as KPluginAutoAttach==0x19==25==EDriveZ
+	//Drive Z is only supported for version two of the plugins.
+	//Prevent version 1 plugins here.
+	if (!(supportedDrives & KPluginVersionTwo) && (aDrive == EDriveZ))
+		return EFalse;
+	
+	//Some requests have aDrive as -1, so for those requests
+	// so long as the plugin was registered we shall say it's mounted.
+	if(aDrive > EDriveZ || aDrive < EDriveA)
+		return ETrue;
+	
+	//Otherwise Check iMountedOn
+	if(iMountedOn&(1<<aDrive))
+		{
+		return ETrue;
+		}
+
+	return EFalse;
+	}
+
+// NOTE: The following API classification might need changing
+
+/** 
+@prototype
+@deprecated
+@see RFilePlugin::Read
+ */
+EXPORT_C TInt CFsPlugin::FileRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos)
+	{
+	CFileShare* share;
+	CFileCB* file;
+	GetFileFromScratch((CFsMessageRequest*) aRequest.Request(), share, file);
+	TInt64 fileSize = file->CachedSize64();
+	if (aPos > fileSize)
+		aPos = fileSize;
+	TInt len = aDes.Length();
+	if (aPos >= fileSize)
+		len = 0;
+	if (aPos + len > fileSize)
+		// filesize - pos shall of TInt size
+		// Hence to suppress warning
+		len = (TInt)(fileSize - aPos);
+	aDes.SetLength(len);
+
+	return DispatchOperation(aRequest, aDes, aPos, EFsFileRead);
+	}
+
+/** 
+@prototype
+@deprecated
+@see RFilePlugin::Write
+*/
+EXPORT_C TInt CFsPlugin::FileWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt64 aPos)
+	{
+	return DispatchOperation(aRequest, (TDes8&) aDes, aPos, EFsFileWrite);
+	}
+
+/**
+@internalTechnology
+@prototype
+@deprecated
+
+Pushes a msgop, dispatches it and waits for it to complete
+*/
+TInt CFsPlugin::DispatchOperation(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos, TInt aFunction)
+	{
+	if (aRequest.Function() != EFsFileRead && aRequest.Function() != EFsFileWrite)
+		return KErrNotSupported;
+	if (aFunction != EFsFileRead && aFunction != EFsFileWrite)
+		return KErrNotSupported;
+
+	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
+
+
+	TInt len = aDes.Length();
+	if (len <= 0)
+		return CFsRequest::EReqActionComplete;
+
+	TUint8* ptr = (TUint8*) aDes.Ptr();
+
+	TInt r = msgRequest.PushOperation(
+		aPos, len, ptr,
+		0,			// aOffset
+		Complete,	// callback
+		0,			// next state
+		aFunction);
+	if (r != KErrNone)
+		return r;
+
+
+	CFsPlugin* plugin = this;
+	FsPluginManager::NextPlugin(plugin, &msgRequest,(TBool)ETrue);
+	msgRequest.iCurrentPlugin = plugin;
+	msgRequest.Dispatch();
+	iThreadP->OperationLockWait();
+
+	aDes.SetLength(len);
+	
+	return msgRequest.LastError();	// KErrNone;
+	}
+
+TInt CFsPlugin::WaitForRequest()
+	{
+	iLastError = KErrNone;
+	iThreadP->OperationLockWait();
+	return iLastError;
+	}
+
+
+/** @prototype */
+TInt CFsPlugin::Complete(CFsRequest* aRequest, TInt aError)
+	{
+	CFsMessageRequest& msgRequest = *(CFsMessageRequest*) aRequest;
+
+	CFsPlugin* plugin = msgRequest.iOwnerPlugin;
+	if (plugin)
+		{
+		plugin->iLastError = aError;
+		plugin->iThreadP->OperationLockSignal();
+		msgRequest.iOwnerPlugin = NULL;
+		return CFsRequest::EReqActionComplete;
+		}
+
+	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
+
+	if (currentOperation.iState == 0)	// waiting ?
+		{
+		currentOperation.iState = 1;
+		msgRequest.iCurrentPlugin->iThreadP->OperationLockSignal();
+		// DON'T dispatch message again, DON'T complete message
+		return CFsRequest::EReqActionOwnedByPlugin;	
+		}
+	else
+		{
+		return CFsRequest::EReqActionComplete;
+		}
+	}
+
+/** @prototype */
+TInt CFsPlugin::Complete(CFsRequest* aRequest)
+	{
+	return CFsPlugin::Complete(aRequest, KErrNone);
+	}
+
+/** @prototype */
+EXPORT_C TInt CFsPlugin::ClientWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt aOffset)
+	{
+	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
+	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
+	
+	TInt r = KErrNone;
+	if (currentOperation.iClientRequest)
+		{
+		r = msgRequest.Write(0, aDes, aOffset);
+		}
+	else
+		{
+		TInt len = aDes.Length();
+		if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
+			return KErrArgument;
+		memcpy(((TUint8*) currentOperation.iReadWriteArgs.iData) + aOffset, aDes.Ptr(), len);
+		currentOperation.iReadWriteArgs.iOffset = aOffset + len;
+		}
+	return r;
+	}
+
+/** @prototype */
+EXPORT_C TInt CFsPlugin::ClientRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt aOffset)
+	{
+	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
+	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
+	
+	TInt r = KErrNone;
+	if (currentOperation.iClientRequest)
+		{
+		r = msgRequest.Read(0, aDes, aOffset);
+		}
+	else
+		{
+		TInt len = aDes.Length();
+		if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
+			return KErrArgument;
+		aDes.Copy ( (TUint8*) currentOperation.iReadWriteArgs.iData + aOffset, len );
+		currentOperation.iReadWriteArgs.iOffset = aOffset + len;
+		}
+	return r;
+	}
+
+/**
+Constructs a TFsPluginRequest object
+@param	aReuqest	client's request, to be wrapped by TFsPluginRequest object
+*/
+EXPORT_C TFsPluginRequest::TFsPluginRequest(CFsRequest* aRequest)
+ : iFsRequest(aRequest)
+	{ }
+
+/**
+@return		The function of the request
+*/
+EXPORT_C TInt TFsPluginRequest::Function() const
+	{ return(iFsRequest->Operation()->Function()); }
+
+/**
+@return		The drive number of the request
+*/
+EXPORT_C TInt TFsPluginRequest::DriveNumber() const
+	{ return(iFsRequest->DriveNumber()); }
+
+/**
+@return		The source of the request (often the filename)
+*/
+EXPORT_C TParse& TFsPluginRequest::Src() const
+	{ return(iFsRequest->Src()); }
+
+/**
+@return		The destination of the request (often the filename)
+*/
+EXPORT_C TParse& TFsPluginRequest::Dest() const
+	{ return(iFsRequest->Dest()); }
+
+/**
+@return		The drive of the request
+*/
+EXPORT_C TDrive* TFsPluginRequest::Drive() const
+	{ return(iFsRequest->Drive()); }
+
+/**
+@return		The substitude drive of the request
+*/
+EXPORT_C TDrive* TFsPluginRequest::SubstedDrive() const
+	{ return(iFsRequest->SubstedDrive()); }
+
+/**
+@return		The message of the request
+*/
+EXPORT_C const RMessage2& TFsPluginRequest::Message() const
+	{ return(iFsRequest->Message()); }
+
+/**
+@return		The request itself
+*/
+EXPORT_C CFsRequest* TFsPluginRequest::Request() const
+	{
+	__ASSERT_DEBUG(iFsRequest != NULL, User::Invariant());
+	return iFsRequest; 
+	}
+
+/**
+@return		The scratch value of the request
+*/
+EXPORT_C TUint TFsPluginRequest::ScratchValue() const
+	{ return iFsRequest->ScratchValue(); }
+
+/**
+@return		The scratch value of the request
+*/
+EXPORT_C TInt64 TFsPluginRequest::ScratchValue64() const
+	{ return iFsRequest->ScratchValue64(); }
+
+/**
+@return		ETrue if the operation is in Post-Intercept
+*/
+EXPORT_C TInt TFsPluginRequest::IsPostOperation() const
+	{ return(iFsRequest->IsPostOperation()); }
+
+
+EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes8& aDes, TInt aOffset)
+	{ 
+	return(iFsRequest->Read(aType, aDes, aOffset));
+	}
+	
+EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes16& aDes, TInt aOffset)
+	{ 
+	//The following if packaged correctly will never come here
+	//but just in case someone tries something wrong with a wonky wide descriptor 
+	switch(aType)
+		{
+		case (TF32ArgType)EEntryArray:
+		case (TF32ArgType)EEntry:
+		case (TF32ArgType)EUid:
+		case (TF32ArgType)ETime:
+			return KErrBadDescriptor;
+		default:
+			break;
+		}
+	return(iFsRequest->Read(aType, aDes, aOffset));
+	}
+	
+EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt& aVal)
+	{ 
+	//
+	// Some messages require special handling...
+	//
+	if(aType == (TF32ArgType)EPosition)
+		{
+		return KErrArgument;
+		}
+	
+	return iFsRequest->Read(aType, aVal);
+	}
+	
+EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TUint& aVal)
+	{ 
+	//
+	// Some messages require special handling...
+	//
+	if(aType == (TF32ArgType)EPosition)
+		{
+		return KErrArgument;
+		}
+	
+	return iFsRequest->Read(aType, aVal);
+	}
+
+EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt64& aVal)
+	{
+	TInt err = iFsRequest->Read(aType, aVal);
+	if(err != KErrNone)
+		return err;
+
+	//
+	// Some messages require special handling...
+	//
+	if(aType == (TF32ArgType)EPosition)
+		{
+		TInt op = Function();
+		if(op == EFsFileRead || op == EFsFileWrite)
+			{	
+			if (aVal == KCurrentPosition64)
+				{
+				CFileShare* share = (CFileShare*)iFsRequest->ScratchValue();
+				if(share == NULL)
+					return KErrBadHandle;
+			
+				aVal = share->iPos;
+				}
+			}
+		}
+	
+	return KErrNone;
+	}
+	
+EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC8& aDes, TInt aOffset)
+	{ 
+	return(iFsRequest->Write(aType, aDes, aOffset));
+	}
+	
+
+EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC16& aDes, TInt aOffset)
+	{ 
+	return(iFsRequest->Write(aType, aDes, aOffset));
+	}
+	
+EXPORT_C TInt TFsPluginRequest::FileName(TDes& aName)
+	{
+	//Special handling required for directories.
+	switch(Function())
+		{
+		case EFsDirOpen:
+			{
+			aName.Copy(Request()->Src().FullName());
+			break;
+			}
+		case EFsDirReadOne:
+		case EFsDirReadPacked:
+		case EFsDirSubClose:
+			{
+			//Get the name from CDirCB::iName
+			CDirCB* dir = (CDirCB*) ScratchValue();
+			__ASSERT_ALWAYS(dir!= NULL, Fault(EPluginOpError));
+			TName name = dir->Name();
+			if(name.Size() == 0)
+				{
+				return KErrNotFound;
+				}
+			aName.Copy(name);
+			break;
+			}
+		default:
+			{
+			CFileShare* share;
+			TInt err = ShareFromClientHandle(share);
+			if(err != KErrNone || share == NULL)
+				return(err);
+			
+			NameFromShare(*share, aName);
+			}
+		}
+	return KErrNone;
+	}
+
+EXPORT_C TInt TFsPluginRequest::SetSharePos(TInt64& aPos)
+	{
+	CFileShare* share;
+	TInt err = ShareFromClientHandle(share);
+	if(err != KErrNone || share == NULL)
+		return(KErrBadHandle);
+	
+	share->File().Drive().Lock();
+	share->iPos = aPos;
+	share->File().Drive().UnLock();
+	
+	return KErrNone;
+	}
+
+TInt TFsPluginRequest::ShareFromClientHandle(CFileShare*& aShare)
+	{
+	aShare = NULL;
+	
+	TInt handle;
+	TInt err = ClientSubSessionHandle(handle);
+	if(err != KErrNone)
+		return err;
+
+	aShare = GetShareFromHandle(iFsRequest->Session(), handle);
+	
+	return aShare ? KErrNone : KErrBadHandle;
+	}
+
+TInt TFsPluginRequest::ClientSubSessionHandle(TInt& aHandle)
+	{
+	aHandle = 0;
+
+	// Subsession handle is in Arg[3] for read/write etc, but 
+	// when subsession create it's contained in client descriptor
+	if(iFsRequest->Operation()->IsOpenSubSess())
+		{
+		if(!IsPostOperation())
+			return KErrNotSupported;
+
+		TPtr8 handleDes((TUint8*)&aHandle,sizeof(TInt));
+		TInt err = iFsRequest->Read(KMsgPtr3,handleDes);
+		if(err != KErrNone)
+			return err;
+		}
+	else
+		{
+		aHandle = iFsRequest->Message().Int3(); 
+		}
+
+	return KErrNone;
+	}
+
+/**
+@publishedPartner
+
+Utility function to obtain the file name from a file share object
+
+@param	aFileShare		A pointer to the file share
+@param	aName			A reference to the descriptor to contain the file name
+*/
+void TFsPluginRequest::NameFromShare(CFileShare& aFileShare, TDes& aName)
+	{
+	CFileCB& theFile = aFileShare.File();
+	aName = _L("?:");
+	aName[0] = TText('A' + theFile.Drive().DriveNumber());
+	aName.Append(theFile.FileName());
+	}
+
+
+/**
+Constructor of plugin connection object
+*/
+EXPORT_C CFsPluginConn::CFsPluginConn()
+	{
+	}
+
+/**
+Destructor of plugin conn. object
+*/
+EXPORT_C CFsPluginConn::~CFsPluginConn()
+	{
+	}
+
+/**
+Closes the plugin conn. 
+*/
+EXPORT_C void CFsPluginConn::Close()
+	{
+	iRequestQue.DoCancelAll(KErrCancel);
+	CFsObject::Close();
+	}
+
+CFsPluginConnRequest::CFsPluginConnRequest(CFsPluginConn* aPluginConn)
+ : iPluginConn(*aPluginConn)
+	{	
+	}
+	
+TInt CFsPluginConnRequest::InitControl(CFsRequest* aRequest)
+	{
+	iMessage = aRequest->Message();
+	const RMessage2& m = aRequest->Message();
+	iFunction = m.Int0();
+	iParam1 = (TDes8*)m.Ptr1();
+	iParam2 = (TDes8*)m.Ptr2();
+	return KErrNone;
+	}
+
+TInt CFsPluginConnRequest::DoControl()
+	{	
+	return iPluginConn.DoControl(*this);
+	}
+
+TInt CFsPluginConnRequest::InitRequest(CFsRequest* aRequest)
+	{
+	InitControl(aRequest);
+	iPluginConn.iRequestQue.DoAddRequest(this);
+	return KErrNone;
+	}
+	
+void CFsPluginConnRequest::DoRequest()
+	{	
+	iPluginConn.DoRequest(*this);
+	}
+	
+TPluginConnRequestQue::TPluginConnRequestQue()
+	{
+	iHeader.SetOffset(_FOFF(CFsPluginConnRequest,iLink));
+	}
+
+TPluginConnRequestQue::~TPluginConnRequestQue()
+	{
+	}
+
+void TPluginConnRequestQue::DoAddRequest(CFsPluginConnRequest* aRequest)
+	{
+	iHeader.AddLast(*aRequest);
+	}
+
+/**
+Cancels all the requests of plugin connection
+
+@param		aCompletionCode: the code the request are completed 
+*/
+EXPORT_C void TPluginConnRequestQue::DoCancelAll(TInt aCompletionCode)
+	{
+	TDblQueIter<CFsPluginConnRequest> q(iHeader);
+	CFsPluginConnRequest* info;
+	while((info=q++)!=NULL)
+		{
+		info->Complete(aCompletionCode);
+		}
+	__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
+	}
+
+
+/**
+*/
+EXPORT_C TDes8& TRawEntryArray::Buf()
+	{ return iBuf; }
+
+/**
+*/
+EXPORT_C void TRawEntryArray::SetBuf(TDes8& aBuf)
+	{
+	iCount = KCountNeeded;
+	iBuf.Copy(aBuf);
+	}
+
+/**
+*/
+EXPORT_C TInt TRawEntryArray::EntrySize(TInt aIdx)
+	{ return Align4(::EntrySize((*this)[aIdx])); }