userlibandfileserver/fileserver/sfile/sf_plugin.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 			{
       
   633 			aName.Copy(Request()->Src().FullName());
       
   634 			break;
       
   635 			}
       
   636 		case EFsDirReadOne:
       
   637 		case EFsDirReadPacked:
       
   638 		case EFsDirSubClose:
       
   639 			{
       
   640 			//Get the name from CDirCB::iName
       
   641 			CDirCB* dir = (CDirCB*) ScratchValue();
       
   642 			__ASSERT_ALWAYS(dir!= NULL, Fault(EPluginOpError));
       
   643 			TName name = dir->Name();
       
   644 			if(name.Size() == 0)
       
   645 				{
       
   646 				return KErrNotFound;
       
   647 				}
       
   648 			aName.Copy(name);
       
   649 			break;
       
   650 			}
       
   651 		default:
       
   652 			{
       
   653 			CFileShare* share;
       
   654 			TInt err = ShareFromClientHandle(share);
       
   655 			if(err != KErrNone || share == NULL)
       
   656 				return(err);
       
   657 			
       
   658 			NameFromShare(*share, aName);
       
   659 			}
       
   660 		}
       
   661 	return KErrNone;
       
   662 	}
       
   663 
       
   664 EXPORT_C TInt TFsPluginRequest::SetSharePos(TInt64& aPos)
       
   665 	{
       
   666 	CFileShare* share;
       
   667 	TInt err = ShareFromClientHandle(share);
       
   668 	if(err != KErrNone || share == NULL)
       
   669 		return(KErrBadHandle);
       
   670 	
       
   671 	share->File().Drive().Lock();
       
   672 	share->iPos = aPos;
       
   673 	share->File().Drive().UnLock();
       
   674 	
       
   675 	return KErrNone;
       
   676 	}
       
   677 
       
   678 TInt TFsPluginRequest::ShareFromClientHandle(CFileShare*& aShare)
       
   679 	{
       
   680 	aShare = NULL;
       
   681 	
       
   682 	TInt handle;
       
   683 	TInt err = ClientSubSessionHandle(handle);
       
   684 	if(err != KErrNone)
       
   685 		return err;
       
   686 
       
   687 	aShare = GetShareFromHandle(iFsRequest->Session(), handle);
       
   688 	
       
   689 	return aShare ? KErrNone : KErrBadHandle;
       
   690 	}
       
   691 
       
   692 TInt TFsPluginRequest::ClientSubSessionHandle(TInt& aHandle)
       
   693 	{
       
   694 	aHandle = 0;
       
   695 
       
   696 	// Subsession handle is in Arg[3] for read/write etc, but 
       
   697 	// when subsession create it's contained in client descriptor
       
   698 	if(iFsRequest->Operation()->IsOpenSubSess())
       
   699 		{
       
   700 		if(!IsPostOperation())
       
   701 			return KErrNotSupported;
       
   702 
       
   703 		TPtr8 handleDes((TUint8*)&aHandle,sizeof(TInt));
       
   704 		TInt err = iFsRequest->Read(KMsgPtr3,handleDes);
       
   705 		if(err != KErrNone)
       
   706 			return err;
       
   707 		}
       
   708 	else
       
   709 		{
       
   710 		aHandle = iFsRequest->Message().Int3(); 
       
   711 		}
       
   712 
       
   713 	return KErrNone;
       
   714 	}
       
   715 
       
   716 /**
       
   717 @publishedPartner
       
   718 
       
   719 Utility function to obtain the file name from a file share object
       
   720 
       
   721 @param	aFileShare		A pointer to the file share
       
   722 @param	aName			A reference to the descriptor to contain the file name
       
   723 */
       
   724 void TFsPluginRequest::NameFromShare(CFileShare& aFileShare, TDes& aName)
       
   725 	{
       
   726 	CFileCB& theFile = aFileShare.File();
       
   727 	aName = _L("?:");
       
   728 	aName[0] = TText('A' + theFile.Drive().DriveNumber());
       
   729 	aName.Append(theFile.FileName());
       
   730 	}
       
   731 
       
   732 
       
   733 /**
       
   734 Constructor of plugin connection object
       
   735 */
       
   736 EXPORT_C CFsPluginConn::CFsPluginConn()
       
   737 	{
       
   738 	}
       
   739 
       
   740 /**
       
   741 Destructor of plugin conn. object
       
   742 */
       
   743 EXPORT_C CFsPluginConn::~CFsPluginConn()
       
   744 	{
       
   745 	}
       
   746 
       
   747 /**
       
   748 Closes the plugin conn. 
       
   749 */
       
   750 EXPORT_C void CFsPluginConn::Close()
       
   751 	{
       
   752 	iRequestQue.DoCancelAll(KErrCancel);
       
   753 	CFsObject::Close();
       
   754 	}
       
   755 
       
   756 CFsPluginConnRequest::CFsPluginConnRequest(CFsPluginConn* aPluginConn)
       
   757  : iPluginConn(*aPluginConn)
       
   758 	{	
       
   759 	}
       
   760 	
       
   761 TInt CFsPluginConnRequest::InitControl(CFsRequest* aRequest)
       
   762 	{
       
   763 	iMessage = aRequest->Message();
       
   764 	const RMessage2& m = aRequest->Message();
       
   765 	iFunction = m.Int0();
       
   766 	iParam1 = (TDes8*)m.Ptr1();
       
   767 	iParam2 = (TDes8*)m.Ptr2();
       
   768 	return KErrNone;
       
   769 	}
       
   770 
       
   771 TInt CFsPluginConnRequest::DoControl()
       
   772 	{	
       
   773 	return iPluginConn.DoControl(*this);
       
   774 	}
       
   775 
       
   776 TInt CFsPluginConnRequest::InitRequest(CFsRequest* aRequest)
       
   777 	{
       
   778 	InitControl(aRequest);
       
   779 	iPluginConn.iRequestQue.DoAddRequest(this);
       
   780 	return KErrNone;
       
   781 	}
       
   782 	
       
   783 void CFsPluginConnRequest::DoRequest()
       
   784 	{	
       
   785 	iPluginConn.DoRequest(*this);
       
   786 	}
       
   787 	
       
   788 TPluginConnRequestQue::TPluginConnRequestQue()
       
   789 	{
       
   790 	iHeader.SetOffset(_FOFF(CFsPluginConnRequest,iLink));
       
   791 	}
       
   792 
       
   793 TPluginConnRequestQue::~TPluginConnRequestQue()
       
   794 	{
       
   795 	}
       
   796 
       
   797 void TPluginConnRequestQue::DoAddRequest(CFsPluginConnRequest* aRequest)
       
   798 	{
       
   799 	iHeader.AddLast(*aRequest);
       
   800 	}
       
   801 
       
   802 /**
       
   803 Cancels all the requests of plugin connection
       
   804 
       
   805 @param		aCompletionCode: the code the request are completed 
       
   806 */
       
   807 EXPORT_C void TPluginConnRequestQue::DoCancelAll(TInt aCompletionCode)
       
   808 	{
       
   809 	TDblQueIter<CFsPluginConnRequest> q(iHeader);
       
   810 	CFsPluginConnRequest* info;
       
   811 	while((info=q++)!=NULL)
       
   812 		{
       
   813 		info->Complete(aCompletionCode);
       
   814 		}
       
   815 	__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
       
   816 	}
       
   817 
       
   818 
       
   819 /**
       
   820 */
       
   821 EXPORT_C TDes8& TRawEntryArray::Buf()
       
   822 	{ return iBuf; }
       
   823 
       
   824 /**
       
   825 */
       
   826 EXPORT_C void TRawEntryArray::SetBuf(TDes8& aBuf)
       
   827 	{
       
   828 	iCount = KCountNeeded;
       
   829 	iBuf.Copy(aBuf);
       
   830 	}
       
   831 
       
   832 /**
       
   833 */
       
   834 EXPORT_C TInt TRawEntryArray::EntrySize(TInt aIdx)
       
   835 	{ return Align4(::EntrySize((*this)[aIdx])); }