os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_plugin.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32\sfile\sf_plugin.cpp
    15 // 
    16 //
    17 
    18 /**
    19  @file
    20  @internalTechnology
    21 */
    22 
    23 
    24 #include "sf_std.h"
    25 #include "sf_plugin_priv.h"
    26 
    27 
    28 EXPORT_C CFsPluginFactory::CFsPluginFactory()
    29 	{}
    30 
    31 EXPORT_C CFsPluginFactory::~CFsPluginFactory()
    32 	{}
    33 
    34 /**
    35 
    36 Uninstalls the plugin factory.
    37 
    38 This is called just before the plugin factory object is destroyed, and allows
    39 any clean up to be carried out.
    40 
    41 The default implementation does nothing except return KErrNone.
    42 Implementations should return an error code on error detection.
    43 
    44 @return KErrNone if successful, otherwise one of the other system wide error
    45         codes.
    46 */
    47 EXPORT_C TInt CFsPluginFactory::Remove()
    48 	{
    49 	return(KErrNone);
    50 	}
    51 
    52 /**
    53 
    54 Sets the plugin factory's resource library.
    55 This library represents the loaded plugin factory.
    56 This is called internally by InstallPluginFactory().
    57 
    58 @param aLib The resource library to be set.
    59 */
    60 EXPORT_C void CFsPluginFactory::SetLibrary(RLibrary aLib)
    61 	{
    62 	iLibrary=aLib;
    63 	}
    64 
    65 /**
    66 Gets the plugin factory's resource library.
    67 
    68 @return The plugin factory's resource library.
    69 */
    70 EXPORT_C RLibrary CFsPluginFactory::Library() const
    71 	{
    72 	return(iLibrary);
    73 	}
    74 
    75 /**
    76 
    77 */
    78 TBool CFsPluginFactory::IsDriveSupported(TInt aDrive)
    79 	{
    80 	//If this is version 1 of the plugins, then if KPluginAutoAttach was specified at mount
    81 	//then it just returned ETrue! This behaviour is preserved here:
    82 	if(!(iSupportedDrives & KPluginVersionTwo) && (aDrive == KPluginAutoAttach))
    83 		{
    84 		return(ETrue);
    85 		}
    86 
    87 	//If we're version 2 plugin (or version1 && !KPluginAutoAttach) then check against what's been set in iSupportedDrives
    88 	return((iSupportedDrives & (1 << aDrive)) ? (TBool)ETrue : (TBool)EFalse);
    89 	}
    90 
    91 
    92 EXPORT_C CFsPlugin::CFsPlugin()
    93 	: iReadOnly(0)
    94 	{
    95     Mem::FillZ(iRegisteredIntercepts, sizeof(iRegisteredIntercepts));
    96 	}
    97 
    98 EXPORT_C CFsPlugin::~CFsPlugin()
    99 	{
   100 	}
   101 
   102 /**
   103 Delivers the request to the end of plugin thread's queue. 
   104 In certain circumstances, where the request requires priority handling
   105 it adds it to the front of the queue.
   106 
   107 @param	aRequest: The request to be delivered
   108 @return KErrNone
   109 */
   110 EXPORT_C TInt CFsPlugin::Deliver(TFsPluginRequest& aRequest)
   111 	{
   112 	__ASSERT_ALWAYS(iThreadP != NULL, User::Panic(_L("CFsPlugin::Dispatch"),999));
   113 
   114 	TInt function = aRequest.Function();
   115 
   116 	if(function == EFsPluginOpen)
   117 		{
   118 		// Don't dispatch open requests to the plugin thread
   119 		return KPluginMessageForward;
   120 		}
   121 
   122 	if(function == EFsPluginDoRequest ||
   123 	   function == EFsPluginDoControl ||
   124 	   function == EFsPluginDoCancel)
   125 		{
   126 		iThreadP->DeliverFront(aRequest.Request());
   127 		}
   128 	else
   129 		{
   130 		iThreadP->DeliverBack(aRequest.Request());
   131 		}
   132 
   133 	return KErrNone;
   134 	}
   135 
   136 /**
   137 Initialises the plugin but setting all registered intercepts to zero.
   138 Derived classes might wish to implement their own InitialiseL to add intercepts
   139 */
   140 EXPORT_C void CFsPlugin::InitialiseL()
   141 	{
   142 	}
   143 
   144 /**
   145 Creates a new pluginconn object
   146 Leaves with KErrNotSupported
   147 
   148 @return NULL
   149 */
   150 EXPORT_C CFsPluginConn* CFsPlugin::NewPluginConnL()
   151 	{
   152 	User::Leave(KErrNotSupported);
   153 	return NULL;
   154 	}
   155 
   156 /**
   157 Registers a particular function with plugin to be intercepted
   158 
   159 @param	aMessage:		the message to be intercepted
   160 @param  aInterceptAtts:	If it is post or pre intercept
   161 @return KErrNone on successful completion 
   162 		KErrNotSupported if message is invalid
   163 */
   164 EXPORT_C TInt CFsPlugin::RegisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
   165 	{
   166 	if(aMessage >= EMaxClientOperations)
   167 		{
   168 		return KErrNotSupported;
   169 		}
   170 
   171 	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
   172 
   173     if(index >= KIntcArrSize)
   174         {
   175         __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
   176         return KErrNotSupported;
   177         }
   178 
   179 	const TUint8 msk  = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
   180 	iRegisteredIntercepts[index] |= msk;
   181 
   182 	return KErrNone;
   183 	}
   184 
   185 /**
   186 Unregisters a particular function with plugin 
   187 
   188 @param	aMessage:		the message which should be unregistered
   189 @param  aInterceptAtts:	If it is post or pre intercept
   190 @return KErrNone on successful completion 
   191 		KErrNotSupported if message is invalid
   192 */
   193 EXPORT_C TInt CFsPlugin::UnregisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
   194 	{
   195 	if(aMessage >= EMaxClientOperations)
   196 		{
   197 		return KErrNotSupported;
   198 		}
   199 
   200 	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
   201     if(index >= KIntcArrSize)
   202         {
   203         __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
   204         return KErrNotSupported;
   205         }
   206 
   207 	const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
   208 	iRegisteredIntercepts[index] &= ~msk;
   209 
   210 	return KErrNone;
   211 	}
   212 
   213 /**
   214     @return ETrue if the message aMessage is registered with any TInterceptAtts type
   215 */
   216 TBool CFsPlugin::IsRegistered(TInt aMessage)
   217 	{
   218 	if(IsRegistered(aMessage,(TInterceptAtts)EPreIntercept) ||
   219 		IsRegistered(aMessage,(TInterceptAtts)EPrePostIntercept) ||
   220 		IsRegistered(aMessage, (TInterceptAtts)EPostIntercept))
   221 		{
   222 		return (TBool)ETrue;
   223 		}
   224 	return (TBool)EFalse;
   225 	}
   226 
   227 /**
   228     @return ETrue if the message aMessage is registered with the given aInterceptAtts attrubutes
   229 */
   230 TBool CFsPlugin::IsRegistered(TInt aMessage, TInterceptAtts aInterceptAtts)
   231 	{
   232 	if(aMessage >= EMaxClientOperations)
   233 		{
   234 		return EFalse;
   235 		}
   236 
   237 	const TUint32 index = aMessage >> 2; //-- index in the intercepts array
   238     if(index >= KIntcArrSize)
   239         {
   240         __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
   241         return EFalse;
   242         }
   243 
   244 	const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
   245 
   246 	return((iRegisteredIntercepts[index] & msk) == msk);
   247 	}
   248 
   249 /**
   250    Return ETrue if the calling thread is the plugin thread
   251 */
   252 TBool CFsPlugin::IsPluginThread(CFsRequest& aRequest)
   253 	{
   254 	if(aRequest.iOwnerPlugin == this)
   255 		return ETrue;
   256 
   257 	if(aRequest.iClientThreadId == iThreadId)
   258 		return ETrue;
   259 
   260 	// Allow specific requests from the client connection...
   261 	if(aRequest.IsPluginSpecific())
   262 		return EFalse;
   263 
   264 	// Check the client connections
   265 	return FsPluginManager::IsPluginConnThread(aRequest.iClientThreadId, this);
   266 	}
   267 
   268 TBool CFsPlugin::IsMounted(TInt aDrive)
   269 	{
   270 	CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(this->Name());	
   271 	TInt supportedDrives = pF->SupportedDrives();
   272 
   273 	//Version1 plugins could not mount on Z Drive as KPluginAutoAttach==0x19==25==EDriveZ
   274 	//Drive Z is only supported for version two of the plugins.
   275 	//Prevent version 1 plugins here.
   276 	if (!(supportedDrives & KPluginVersionTwo) && (aDrive == EDriveZ))
   277 		return EFalse;
   278 	
   279 	//Some requests have aDrive as -1, so for those requests
   280 	// so long as the plugin was registered we shall say it's mounted.
   281 	if(aDrive > EDriveZ || aDrive < EDriveA)
   282 		return ETrue;
   283 	
   284 	//Otherwise Check iMountedOn
   285 	if(iMountedOn&(1<<aDrive))
   286 		{
   287 		return ETrue;
   288 		}
   289 
   290 	return EFalse;
   291 	}
   292 
   293 // NOTE: The following API classification might need changing
   294 
   295 /** 
   296 @prototype
   297 @deprecated
   298 @see RFilePlugin::Read
   299  */
   300 EXPORT_C TInt CFsPlugin::FileRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos)
   301 	{
   302 	CFileShare* share;
   303 	CFileCB* file;
   304 	GetFileFromScratch((CFsMessageRequest*) aRequest.Request(), share, file);
   305 	TInt64 fileSize = file->CachedSize64();
   306 	if (aPos > fileSize)
   307 		aPos = fileSize;
   308 	TInt len = aDes.Length();
   309 	if (aPos >= fileSize)
   310 		len = 0;
   311 	if (aPos + len > fileSize)
   312 		// filesize - pos shall of TInt size
   313 		// Hence to suppress warning
   314 		len = (TInt)(fileSize - aPos);
   315 	aDes.SetLength(len);
   316 
   317 	return DispatchOperation(aRequest, aDes, aPos, EFsFileRead);
   318 	}
   319 
   320 /** 
   321 @prototype
   322 @deprecated
   323 @see RFilePlugin::Write
   324 */
   325 EXPORT_C TInt CFsPlugin::FileWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt64 aPos)
   326 	{
   327 	return DispatchOperation(aRequest, (TDes8&) aDes, aPos, EFsFileWrite);
   328 	}
   329 
   330 /**
   331 @internalTechnology
   332 @prototype
   333 @deprecated
   334 
   335 Pushes a msgop, dispatches it and waits for it to complete
   336 */
   337 TInt CFsPlugin::DispatchOperation(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos, TInt aFunction)
   338 	{
   339 	if (aRequest.Function() != EFsFileRead && aRequest.Function() != EFsFileWrite)
   340 		return KErrNotSupported;
   341 	if (aFunction != EFsFileRead && aFunction != EFsFileWrite)
   342 		return KErrNotSupported;
   343 
   344 	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
   345 
   346 
   347 	TInt len = aDes.Length();
   348 	if (len <= 0)
   349 		return CFsRequest::EReqActionComplete;
   350 
   351 	TUint8* ptr = (TUint8*) aDes.Ptr();
   352 
   353 	TInt r = msgRequest.PushOperation(
   354 		aPos, len, ptr,
   355 		0,			// aOffset
   356 		Complete,	// callback
   357 		0,			// next state
   358 		aFunction);
   359 	if (r != KErrNone)
   360 		return r;
   361 
   362 
   363 	CFsPlugin* plugin = this;
   364 	FsPluginManager::NextPlugin(plugin, &msgRequest,(TBool)ETrue);
   365 	msgRequest.iCurrentPlugin = plugin;
   366 	msgRequest.Dispatch();
   367 	iThreadP->OperationLockWait();
   368 
   369 	aDes.SetLength(len);
   370 	
   371 	return msgRequest.LastError();	// KErrNone;
   372 	}
   373 
   374 TInt CFsPlugin::WaitForRequest()
   375 	{
   376 	iLastError = KErrNone;
   377 	iThreadP->OperationLockWait();
   378 	return iLastError;
   379 	}
   380 
   381 
   382 /** @prototype */
   383 TInt CFsPlugin::Complete(CFsRequest* aRequest, TInt aError)
   384 	{
   385 	CFsMessageRequest& msgRequest = *(CFsMessageRequest*) aRequest;
   386 
   387 	CFsPlugin* plugin = msgRequest.iOwnerPlugin;
   388 	if (plugin)
   389 		{
   390 		plugin->iLastError = aError;
   391 		plugin->iThreadP->OperationLockSignal();
   392 		msgRequest.iOwnerPlugin = NULL;
   393 		return CFsRequest::EReqActionComplete;
   394 		}
   395 
   396 	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
   397 
   398 	if (currentOperation.iState == 0)	// waiting ?
   399 		{
   400 		currentOperation.iState = 1;
   401 		msgRequest.iCurrentPlugin->iThreadP->OperationLockSignal();
   402 		// DON'T dispatch message again, DON'T complete message
   403 		return CFsRequest::EReqActionOwnedByPlugin;	
   404 		}
   405 	else
   406 		{
   407 		return CFsRequest::EReqActionComplete;
   408 		}
   409 	}
   410 
   411 /** @prototype */
   412 TInt CFsPlugin::Complete(CFsRequest* aRequest)
   413 	{
   414 	return CFsPlugin::Complete(aRequest, KErrNone);
   415 	}
   416 
   417 /** @prototype */
   418 EXPORT_C TInt CFsPlugin::ClientWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt aOffset)
   419 	{
   420 	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
   421 	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
   422 	
   423 	TInt r = KErrNone;
   424 	if (currentOperation.iClientRequest)
   425 		{
   426 		r = msgRequest.Write(0, aDes, aOffset);
   427 		}
   428 	else
   429 		{
   430 		TInt len = aDes.Length();
   431 		if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
   432 			return KErrArgument;
   433 		memcpy(((TUint8*) currentOperation.iReadWriteArgs.iData) + aOffset, aDes.Ptr(), len);
   434 		currentOperation.iReadWriteArgs.iOffset = aOffset + len;
   435 		}
   436 	return r;
   437 	}
   438 
   439 /** @prototype */
   440 EXPORT_C TInt CFsPlugin::ClientRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt aOffset)
   441 	{
   442 	CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
   443 	TMsgOperation& currentOperation = msgRequest.CurrentOperation();
   444 	
   445 	TInt r = KErrNone;
   446 	if (currentOperation.iClientRequest)
   447 		{
   448 		r = msgRequest.Read(0, aDes, aOffset);
   449 		}
   450 	else
   451 		{
   452 		TInt len = aDes.Length();
   453 		if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
   454 			return KErrArgument;
   455 		aDes.Copy ( (TUint8*) currentOperation.iReadWriteArgs.iData + aOffset, len );
   456 		currentOperation.iReadWriteArgs.iOffset = aOffset + len;
   457 		}
   458 	return r;
   459 	}
   460 
   461 /**
   462 Constructs a TFsPluginRequest object
   463 @param	aReuqest	client's request, to be wrapped by TFsPluginRequest object
   464 */
   465 EXPORT_C TFsPluginRequest::TFsPluginRequest(CFsRequest* aRequest)
   466  : iFsRequest(aRequest)
   467 	{ }
   468 
   469 /**
   470 @return		The function of the request
   471 */
   472 EXPORT_C TInt TFsPluginRequest::Function() const
   473 	{ return(iFsRequest->Operation()->Function()); }
   474 
   475 /**
   476 @return		The drive number of the request
   477 */
   478 EXPORT_C TInt TFsPluginRequest::DriveNumber() const
   479 	{ return(iFsRequest->DriveNumber()); }
   480 
   481 /**
   482 @return		The source of the request (often the filename)
   483 */
   484 EXPORT_C TParse& TFsPluginRequest::Src() const
   485 	{ return(iFsRequest->Src()); }
   486 
   487 /**
   488 @return		The destination of the request (often the filename)
   489 */
   490 EXPORT_C TParse& TFsPluginRequest::Dest() const
   491 	{ return(iFsRequest->Dest()); }
   492 
   493 /**
   494 @return		The drive of the request
   495 */
   496 EXPORT_C TDrive* TFsPluginRequest::Drive() const
   497 	{ return(iFsRequest->Drive()); }
   498 
   499 /**
   500 @return		The substitude drive of the request
   501 */
   502 EXPORT_C TDrive* TFsPluginRequest::SubstedDrive() const
   503 	{ return(iFsRequest->SubstedDrive()); }
   504 
   505 /**
   506 @return		The message of the request
   507 */
   508 EXPORT_C const RMessage2& TFsPluginRequest::Message() const
   509 	{ return(iFsRequest->Message()); }
   510 
   511 /**
   512 @return		The request itself
   513 */
   514 EXPORT_C CFsRequest* TFsPluginRequest::Request() const
   515 	{
   516 	__ASSERT_DEBUG(iFsRequest != NULL, User::Invariant());
   517 	return iFsRequest; 
   518 	}
   519 
   520 /**
   521 @return		The scratch value of the request
   522 */
   523 EXPORT_C TUint TFsPluginRequest::ScratchValue() const
   524 	{ return iFsRequest->ScratchValue(); }
   525 
   526 /**
   527 @return		The scratch value of the request
   528 */
   529 EXPORT_C TInt64 TFsPluginRequest::ScratchValue64() const
   530 	{ return iFsRequest->ScratchValue64(); }
   531 
   532 /**
   533 @return		ETrue if the operation is in Post-Intercept
   534 */
   535 EXPORT_C TInt TFsPluginRequest::IsPostOperation() const
   536 	{ return(iFsRequest->IsPostOperation()); }
   537 
   538 
   539 EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes8& aDes, TInt aOffset)
   540 	{ 
   541 	return(iFsRequest->Read(aType, aDes, aOffset));
   542 	}
   543 	
   544 EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes16& aDes, TInt aOffset)
   545 	{ 
   546 	//The following if packaged correctly will never come here
   547 	//but just in case someone tries something wrong with a wonky wide descriptor 
   548 	switch(aType)
   549 		{
   550 		case (TF32ArgType)EEntryArray:
   551 		case (TF32ArgType)EEntry:
   552 		case (TF32ArgType)EUid:
   553 		case (TF32ArgType)ETime:
   554 			return KErrBadDescriptor;
   555 		default:
   556 			break;
   557 		}
   558 	return(iFsRequest->Read(aType, aDes, aOffset));
   559 	}
   560 	
   561 EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt& aVal)
   562 	{ 
   563 	//
   564 	// Some messages require special handling...
   565 	//
   566 	if(aType == (TF32ArgType)EPosition)
   567 		{
   568 		return KErrArgument;
   569 		}
   570 	
   571 	return iFsRequest->Read(aType, aVal);
   572 	}
   573 	
   574 EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TUint& aVal)
   575 	{ 
   576 	//
   577 	// Some messages require special handling...
   578 	//
   579 	if(aType == (TF32ArgType)EPosition)
   580 		{
   581 		return KErrArgument;
   582 		}
   583 	
   584 	return iFsRequest->Read(aType, aVal);
   585 	}
   586 
   587 EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt64& aVal)
   588 	{
   589 	TInt err = iFsRequest->Read(aType, aVal);
   590 	if(err != KErrNone)
   591 		return err;
   592 
   593 	//
   594 	// Some messages require special handling...
   595 	//
   596 	if(aType == (TF32ArgType)EPosition)
   597 		{
   598 		TInt op = Function();
   599 		if(op == EFsFileRead || op == EFsFileWrite)
   600 			{	
   601 			if (aVal == KCurrentPosition64)
   602 				{
   603 				CFileShare* share = (CFileShare*)iFsRequest->ScratchValue();
   604 				if(share == NULL)
   605 					return KErrBadHandle;
   606 			
   607 				aVal = share->iPos;
   608 				}
   609 			}
   610 		}
   611 	
   612 	return KErrNone;
   613 	}
   614 	
   615 EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC8& aDes, TInt aOffset)
   616 	{ 
   617 	return(iFsRequest->Write(aType, aDes, aOffset));
   618 	}
   619 	
   620 
   621 EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC16& aDes, TInt aOffset)
   622 	{ 
   623 	return(iFsRequest->Write(aType, aDes, aOffset));
   624 	}
   625 	
   626 EXPORT_C TInt TFsPluginRequest::FileName(TDes& aName)
   627 	{
   628 	//Special handling required for directories.
   629 	switch(Function())
   630 		{
   631 		case EFsDirOpen:
   632 		case EFsSetEntry:
   633 			{
   634 			aName.Copy(Request()->Src().FullName());
   635 			break;
   636 			}
   637 		case EFsDirReadOne:
   638 		case EFsDirReadPacked:
   639 		case EFsDirSubClose:
   640 			{
   641 			//Get the name from CDirCB::iName
   642 			CDirCB* dir = (CDirCB*) ScratchValue();
   643 			__ASSERT_ALWAYS(dir!= NULL, Fault(EPluginOpError));
   644 			TName name = dir->Name();
   645 			if(name.Size() == 0)
   646 				{
   647 				return KErrNotFound;
   648 				}
   649 			aName.Copy(name);
   650 			break;
   651 			}
   652 		default:
   653 			{
   654 			CFileShare* share;
   655 			TInt err = ShareFromClientHandle(share);
   656 			if(err != KErrNone || share == NULL)
   657 				return(err);
   658 			
   659 			NameFromShare(*share, aName);
   660 			}
   661 		}
   662 	return KErrNone;
   663 	}
   664 
   665 EXPORT_C TInt TFsPluginRequest::SetSharePos(TInt64& aPos)
   666 	{
   667 	CFileShare* share;
   668 	TInt err = ShareFromClientHandle(share);
   669 	if(err != KErrNone || share == NULL)
   670 		return(KErrBadHandle);
   671 	
   672 	share->File().Drive().Lock();
   673 	share->iPos = aPos;
   674 	share->File().Drive().UnLock();
   675 	
   676 	return KErrNone;
   677 	}
   678 
   679 TInt TFsPluginRequest::ShareFromClientHandle(CFileShare*& aShare)
   680 	{
   681 	aShare = NULL;
   682 	
   683 	TInt handle;
   684 	TInt err = ClientSubSessionHandle(handle);
   685 	if(err != KErrNone)
   686 		return err;
   687 
   688 	aShare = GetShareFromHandle(iFsRequest->Session(), handle);
   689 	
   690 	return aShare ? KErrNone : KErrBadHandle;
   691 	}
   692 
   693 TInt TFsPluginRequest::ClientSubSessionHandle(TInt& aHandle)
   694 	{
   695 	aHandle = 0;
   696 
   697 	// Subsession handle is in Arg[3] for read/write etc, but 
   698 	// when subsession create it's contained in client descriptor
   699 	if(iFsRequest->Operation()->IsOpenSubSess())
   700 		{
   701 		if(!IsPostOperation())
   702 			return KErrNotSupported;
   703 
   704 		TPtr8 handleDes((TUint8*)&aHandle,sizeof(TInt));
   705 		TInt err = iFsRequest->Read(KMsgPtr3,handleDes);
   706 		if(err != KErrNone)
   707 			return err;
   708 		}
   709 	else
   710 		{
   711 		aHandle = iFsRequest->Message().Int3(); 
   712 		}
   713 
   714 	return KErrNone;
   715 	}
   716 
   717 /**
   718 @publishedPartner
   719 
   720 Utility function to obtain the file name from a file share object
   721 
   722 @param	aFileShare		A pointer to the file share
   723 @param	aName			A reference to the descriptor to contain the file name
   724 */
   725 void TFsPluginRequest::NameFromShare(CFileShare& aFileShare, TDes& aName)
   726 	{
   727 	CFileCB& theFile = aFileShare.File();
   728 	aName = _L("?:");
   729 	aName[0] = TText('A' + theFile.Drive().DriveNumber());
   730 	aName.Append(theFile.FileName());
   731 	}
   732 
   733 
   734 /**
   735 Constructor of plugin connection object
   736 */
   737 EXPORT_C CFsPluginConn::CFsPluginConn()
   738 	{
   739 	}
   740 
   741 /**
   742 Destructor of plugin conn. object
   743 */
   744 EXPORT_C CFsPluginConn::~CFsPluginConn()
   745 	{
   746 	}
   747 
   748 /**
   749 Closes the plugin conn. 
   750 */
   751 EXPORT_C void CFsPluginConn::Close()
   752 	{
   753 	iRequestQue.DoCancelAll(KErrCancel);
   754 	CFsObject::Close();
   755 	}
   756 
   757 CFsPluginConnRequest::CFsPluginConnRequest(CFsPluginConn* aPluginConn)
   758  : iPluginConn(*aPluginConn)
   759 	{	
   760 	}
   761 	
   762 TInt CFsPluginConnRequest::InitControl(CFsRequest* aRequest)
   763 	{
   764 	iMessage = aRequest->Message();
   765 	const RMessage2& m = aRequest->Message();
   766 	iFunction = m.Int0();
   767 	iParam1 = (TDes8*)m.Ptr1();
   768 	iParam2 = (TDes8*)m.Ptr2();
   769 	return KErrNone;
   770 	}
   771 
   772 TInt CFsPluginConnRequest::DoControl()
   773 	{	
   774 	return iPluginConn.DoControl(*this);
   775 	}
   776 
   777 TInt CFsPluginConnRequest::InitRequest(CFsRequest* aRequest)
   778 	{
   779 	InitControl(aRequest);
   780 	iPluginConn.iRequestQue.DoAddRequest(this);
   781 	return KErrNone;
   782 	}
   783 	
   784 void CFsPluginConnRequest::DoRequest()
   785 	{	
   786 	iPluginConn.DoRequest(*this);
   787 	}
   788 	
   789 TPluginConnRequestQue::TPluginConnRequestQue()
   790 	{
   791 	iHeader.SetOffset(_FOFF(CFsPluginConnRequest,iLink));
   792 	}
   793 
   794 TPluginConnRequestQue::~TPluginConnRequestQue()
   795 	{
   796 	}
   797 
   798 void TPluginConnRequestQue::DoAddRequest(CFsPluginConnRequest* aRequest)
   799 	{
   800 	iHeader.AddLast(*aRequest);
   801 	}
   802 
   803 /**
   804 Cancels all the requests of plugin connection
   805 
   806 @param		aCompletionCode: the code the request are completed 
   807 */
   808 EXPORT_C void TPluginConnRequestQue::DoCancelAll(TInt aCompletionCode)
   809 	{
   810 	TDblQueIter<CFsPluginConnRequest> q(iHeader);
   811 	CFsPluginConnRequest* info;
   812 	while((info=q++)!=NULL)
   813 		{
   814 		info->Complete(aCompletionCode);
   815 		}
   816 	__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
   817 	}
   818 
   819 
   820 /**
   821 */
   822 EXPORT_C TDes8& TRawEntryArray::Buf()
   823 	{ return iBuf; }
   824 
   825 /**
   826 */
   827 EXPORT_C void TRawEntryArray::SetBuf(TDes8& aBuf)
   828 	{
   829 	iCount = KCountNeeded;
   830 	iBuf.Copy(aBuf);
   831 	}
   832 
   833 /**
   834 */
   835 EXPORT_C TInt TRawEntryArray::EntrySize(TInt aIdx)
   836 	{ return Align4(::EntrySize((*this)[aIdx])); }