os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_plugin_shim.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-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_shim.cpp
    15 // 
    16 //
    17 
    18 #include "cl_std.h"
    19 #include "sf_std.h"
    20 
    21 /*******************************************************
    22 *						RFsPlugin					   *
    23 *******************************************************/
    24 
    25 EXPORT_C RFsPlugin::RFsPlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
    26   : iSessionHelper(&aRequest, aDirectToDrive)
    27 	{
    28 	SetReturnedHandle(KNullHandle);
    29 	}
    30 
    31 EXPORT_C RFsPlugin::~RFsPlugin()
    32 	{
    33 	Close();
    34 	}
    35 
    36 EXPORT_C TInt RFsPlugin::Connect()
    37 /**
    38 Connects a file server plugin to the file server.
    39 
    40 To end the file server session, use Close().
    41 
    42 @return KErrNone, if successful, otherwise one of the other system-wide error codes.
    43 */
    44 	{
    45 	return KErrNone;
    46 	}
    47 
    48 EXPORT_C void RFsPlugin::Close()
    49 /**
    50 Closes a file server plugin session.
    51 */
    52 	{
    53 	SetReturnedHandle(KNullHandle);
    54 	}
    55 
    56 EXPORT_C TInt RFsPlugin::Delete(const TDesC& aName)
    57 /**
    58 Deletes a single file.
    59 
    60 @see RFs::Delete
    61 */
    62 	{
    63 	return(RFs::Delete(aName));
    64 	}
    65 
    66 EXPORT_C TInt RFsPlugin::Rename(const TDesC& aOldName,const TDesC& aNewName)
    67 /**
    68 Renames a single file or directory.
    69 
    70 @see RFs::Rename
    71 */
    72 	{
    73 	return(RFs::Rename(aOldName, aNewName));
    74 	}
    75 
    76 EXPORT_C TInt RFsPlugin::Replace(const TDesC& aOldName,const TDesC& aNewName)
    77 /**
    78 Replaces a single file with another.
    79 
    80 @see RFs::Replace
    81 */
    82 	{
    83 	return(RFs::Replace(aOldName, aNewName));
    84 	}
    85 
    86 EXPORT_C TInt RFsPlugin::Entry(const TDesC& aName,TEntry& aEntry) const
    87 /**
    88 Gets the entry details for a file or directory.
    89 
    90 @see RFs::Entry
    91 */
    92 	{
    93 	return(RFs::Entry(aName, aEntry));
    94 	}
    95 
    96 EXPORT_C TInt RFsPlugin::SetEntry(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
    97 /**
    98 Sets both the attributes and the last modified date and time for a file or directory.
    99 
   100 @see RFs::SetEntry
   101 */
   102 	{
   103 	return(RFs::SetEntry(aName,aTime,aSetAttMask,aClearAttMask));
   104 	}
   105 
   106 EXPORT_C TInt RFsPlugin::ReadFileSection(const TDesC& aName,TInt64 aPos,TDes8& aDes,TInt aLength) const
   107 /**
   108 Reads data from a file without opening it.
   109 
   110 The contents of the	file can be accessed regardless of the file's lock state.
   111 
   112 @see RFs::ReadFileSection
   113 */
   114 	{
   115 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   116 	return(RFs::ReadFileSection(aName,I64LOW(aPos),aDes,aLength));
   117 #else
   118 	return(RFs::ReadFileSection(aName,aPos,aDes,aLength));
   119 #endif
   120 	}
   121 
   122 EXPORT_C TInt RFsPlugin::Volume(TVolumeInfo &aVol, TInt aDrive) const
   123 /**
   124 Gets volume information for a formatted device.
   125 
   126 @see RFs::Volume
   127 */
   128 	{
   129 	return (RFs::Volume(aVol, aDrive));
   130 	}
   131 
   132 TInt RFsPlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   133 	{
   134 	return iSessionHelper.SendReceive(aFunction, aArgs);
   135 	}
   136 
   137 TInt RFs::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   138 	{
   139 	if(Handle())
   140 		return RSessionBase::SendReceive(aFunction, aArgs);
   141 
   142 	return ((RFsPlugin*) this)->SendReceive(aFunction, aArgs);
   143 	}
   144 
   145 
   146 /*******************************************************
   147 *						RFilePlugin					   *
   148 *******************************************************/
   149 
   150 EXPORT_C RFilePlugin::RFilePlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
   151   : iSessionHelper(&aRequest, aDirectToDrive)
   152 	{
   153 	SetHandle(KErrBadHandle);
   154 	SetSubSessionHandle(KErrBadHandle);
   155 	}
   156 
   157 EXPORT_C RFilePlugin::~RFilePlugin()
   158 	{
   159 	Close();
   160 	}
   161 
   162 EXPORT_C TInt RFilePlugin::Open(const TDesC& aName,TUint aMode)
   163 /**
   164 Opens an existing file for reading or writing.
   165 
   166 If the file does not already exist, an error is returned.
   167 
   168 @see RFile::Open
   169 */
   170 	{
   171 	RFs fs;
   172 	fs.SetHandle(Session().Handle());
   173 	return(CreateSubSession(fs,EFsFileOpen,TIpcArgs(&aName,aMode)));
   174 	}
   175 
   176 EXPORT_C void RFilePlugin::Close()
   177 /**
   178 Closes the file.
   179 
   180 @see RFile::Close
   181 */
   182 	{
   183 	CloseSubSession(EFsFileSubClose);
   184 	SetSubSessionHandle(KErrBadHandle);
   185 	}
   186 
   187 EXPORT_C TInt RFilePlugin::Create(const TDesC& aName,TUint aFileMode)
   188 /**
   189 Closes the file.
   190 
   191 @see RFile::Create
   192 */
   193 	{
   194 	RFs fs;
   195 	fs.SetHandle(Session().Handle());
   196 	return(CreateSubSession(fs,EFsFileCreate,TIpcArgs(&aName,aFileMode)));
   197 	}
   198 
   199 EXPORT_C TInt RFilePlugin::Replace(const TDesC& aName,TUint aFileMode)
   200 /**
   201 Closes the file.
   202 
   203 @see RFile::Replace
   204 */
   205 	{
   206 	RFs fs;
   207 	fs.SetHandle(Session().Handle());
   208 	return(CreateSubSession(fs,EFsFileReplace,TIpcArgs(&aName,aFileMode)));
   209 	}
   210 
   211 EXPORT_C TInt RFilePlugin::Temp(const TDesC& aPath,TFileName& aName,TUint aFileMode)
   212 /**
   213 Closes the file.
   214 
   215 @see RFile::Temp
   216 */
   217 	{
   218 	RFs fs;
   219 	fs.SetHandle(Session().Handle());
   220 	return(CreateSubSession(fs,EFsFileTemp,TIpcArgs(&aPath,aFileMode,&aName)));
   221 	}
   222 
   223 EXPORT_C TInt RFilePlugin::AdoptFromClient()
   224 /**
   225 Closes the file.
   226 
   227 @see RFile::AdoptFromClient
   228 */
   229 	{
   230 	TFsPluginRequest* request = iSessionHelper.Request();
   231 	if(request == NULL)
   232 		return KErrBadHandle;
   233 
   234 	TInt clientSubSessionHandle;
   235 	TInt err = request->ClientSubSessionHandle(clientSubSessionHandle);
   236 	if (err != KErrNone)
   237 		return err;
   238 
   239 	RFs fs;
   240 	fs.SetHandle(Session().Handle());
   241 	err = CreateSubSession(fs,EFsFileDuplicate, TIpcArgs(clientSubSessionHandle, ETrue));
   242 	if (err != KErrNone)
   243 		return err;
   244 
   245 	SetSubSessionHandle(SubSessionHandle() ^ KSubSessionMangleBit);
   246 
   247 	return err;
   248 	}
   249 
   250 EXPORT_C TInt RFilePlugin::TransferToClient()
   251 /**
   252 Closes the file.
   253 
   254 @see RFile::TransferToClient
   255 */
   256 	{
   257 	TFsPluginRequest* request = iSessionHelper.Request();
   258 	if(request == NULL)
   259 		return KErrBadHandle;
   260 
   261 	// This doesn't behave like a standard duplicate as we're running in the context of the
   262 	// client's session.  Instead, we can simply return our subsession handle to the client.
   263 	TRAPD(err, request->Request()->WriteL(KMsgPtr3, TPckgC<TInt>(SubSessionHandle())));
   264 
   265 	// Next we have to free up the close request reserved for our internal subsession
   266 	// otherwise two messages will be reserved for the client...
   267 	RequestAllocator::OpenSubFailed(request->Request()->Session());
   268 
   269 	// And now we're done - we don't bother closing, as the client now completely owns the handle
   270 	SetSubSessionHandle(KErrBadHandle);
   271 
   272 	return err;
   273 	}
   274 
   275 EXPORT_C TInt RFilePlugin::Write(TInt64 aPos, const TDesC8& aDes)
   276 /**
   277 Writes to the file at the specified offset within the file
   278 
   279 @see RFile::Write
   280 */
   281 	{
   282 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   283 	return RFile::Write(I64LOW(aPos), aDes);
   284 #else
   285 	return RFile64::Write(aPos, aDes);
   286 #endif
   287 	}
   288 
   289 EXPORT_C TInt RFilePlugin::Write(TInt64 aPos,const TDesC8& aDes,TInt aLen)
   290 /**
   291 Writes the specified number of bytes to the file at the specified offset within the file.
   292 
   293 @see RFile::Write
   294 */
   295 	{
   296 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   297 	return RFile::Write(I64LOW(aPos), aDes, aLen);
   298 #else
   299 	return RFile64::Write(aPos, aDes, aLen);
   300 #endif
   301 	}
   302 
   303 EXPORT_C TInt RFilePlugin::Read(TInt64 aPos,TDes8& aDes) const
   304 /**
   305 Reads from the file at the specified offset within the file
   306 
   307 @see RFile::Read
   308 */
   309 	{
   310 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   311 	return RFile::Read(I64LOW(aPos), aDes);
   312 #else
   313 	return RFile64::Read(aPos, aDes);
   314 #endif
   315 	}
   316 
   317 EXPORT_C TInt RFilePlugin::Read(TInt64 aPos,TDes8& aDes,TInt aLen) const
   318 /**
   319 Reads the specified number of bytes of binary data from the file at a specified
   320 offset within the file.
   321 
   322 @see RFile::Read
   323 */
   324 	{
   325 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   326 	return RFile::Read(I64LOW(aPos), aDes, aLen);
   327 #else
   328 	return RFile64::Read(aPos, aDes, aLen);
   329 #endif
   330 	}
   331 
   332 EXPORT_C TInt RFilePlugin::Size(TInt64& aSize) const
   333 /**
   334 Gets the current file size.
   335 
   336 @see RFile::Size
   337 */
   338 	{
   339 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   340 	TInt size = I64LOW(aSize);
   341 	TInt err = RFile::Size(size);
   342 	aSize = size;
   343 	return err;
   344 #else
   345 	return RFile64::Size(aSize);
   346 #endif
   347 	}
   348 
   349 EXPORT_C TInt RFilePlugin::SetSize(TInt64 aSize)
   350 /**
   351 Sets the file size.
   352 
   353 @see RFile::SetSize
   354 */
   355 	{
   356 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   357 	return RFile::SetSize(I64LOW(aSize));
   358 #else
   359 	return RFile64::SetSize(aSize);
   360 #endif
   361 	}
   362 
   363 EXPORT_C TInt RFilePlugin::Lock(TInt64 aPos, TInt64 aLength) const
   364 /**
   365 Locks a region within the file as defined by a range of bytes.
   366 
   367 @see RFile::Lock
   368 */
   369 	{
   370 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   371 	return RFile::Lock(I64LOW(aPos), I64LOW(aLength));
   372 #else
   373 	return RFile64::Lock(aPos, aLength);
   374 #endif
   375 	}
   376 
   377 EXPORT_C TInt RFilePlugin::UnLock(TInt64 aPos, TInt64 aLength) const
   378 /**
   379 Unlocks a region within the file as defined by a range of bytes.
   380 
   381 @see RFile::UnLock
   382 */
   383 	{
   384 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   385 	return RFile::UnLock(I64LOW(aPos), I64LOW(aLength));
   386 #else
   387 	return RFile64::UnLock(aPos, aLength);
   388 #endif
   389 	}
   390 
   391 EXPORT_C TInt RFilePlugin::Seek(TSeek aMode,TInt64& aPos) const
   392 /**
   393 Sets the the current file position.
   394 
   395 @see RFile::Seek
   396 */
   397 	{
   398 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
   399 	TInt position = I64LOW(aPos);
   400 	TInt err = RFile::Seek(aMode, position);
   401 	if(err != KErrNone)
   402 		return err;
   403 	aPos = position;
   404 	return KErrNone;
   405 #else
   406 	return RFile64::Seek(aMode, aPos);
   407 #endif
   408 	}
   409 
   410 EXPORT_C TInt RFilePlugin::Flush()
   411 /**
   412 Commits data to the storage device and flushes internal buffers without closing
   413 the file.
   414 
   415 @see RFile::Flush
   416 */
   417 	{
   418 	return RFile::Flush();
   419 	}
   420 
   421 EXPORT_C TInt RFilePlugin::Att(TUint& aVal) const
   422 /**
   423 Gets the file's attributes.
   424 
   425 @see RFile::Att
   426 */
   427 	{
   428 	return RFile::Att(aVal);
   429 	}
   430 
   431 EXPORT_C TInt RFilePlugin::SetAtt(TUint aSetAttMask,TUint aClearAttMask)
   432 /**
   433 Sets or clears file attributes using two bitmasks.
   434 
   435 @see RFile::SetAtt
   436 */
   437 	{
   438 	return RFile::SetAtt(aSetAttMask, aClearAttMask);
   439 	}
   440 
   441 EXPORT_C TInt RFilePlugin::Modified(TTime& aTime) const
   442 /**
   443 Gets local date and time the file was last modified, in universal time.
   444 
   445 @see RFile::Modified
   446 */
   447 	{
   448 	return RFile::Modified(aTime);
   449 	}
   450 
   451 EXPORT_C TInt RFilePlugin::SetModified(const TTime& aTime)
   452 /**
   453 Sets the date and time the file was last modified. UTC date and time should be used.
   454 
   455 @see RFile::SetModified
   456 */
   457 	{
   458 	return RFile::SetModified(aTime);
   459 	}
   460 
   461 EXPORT_C TInt RFilePlugin::Set(const TTime& aTime,TUint aMask,TUint aVal)
   462 /**
   463 Sets the file’s attributes, and the date and time it was last modified.
   464 
   465 @see RFile::Set
   466 */
   467 	{
   468 	return RFile::Set(aTime, aMask, aVal);
   469 	}
   470 
   471 EXPORT_C TInt RFilePlugin::ChangeMode(TFileMode aNewMode)
   472 /**
   473 Switches an open file's access mode between EFileShareExclusive and EFileShareReadersOnly.
   474 
   475 @see RFile::ChangeMode
   476 */
   477 	{
   478 	return RFile::ChangeMode(aNewMode);
   479 	}
   480 
   481 EXPORT_C TInt RFilePlugin::Rename(const TDesC& aNewName)
   482 /**
   483 Renames a file.
   484 
   485 @see RFile::Rename
   486 */
   487 	{
   488 	return RFile::Rename(aNewName);
   489 	}
   490 
   491 void RFilePlugin::SetHandle(TInt aHandle)
   492 	{
   493 	*(((TInt*) this) + 0) = aHandle;
   494 	}
   495 
   496 void RFilePlugin::SetSubSessionHandle(TInt aHandle)
   497 	{
   498 	*(((TInt*) this) + 1) = aHandle;
   499 	}
   500 
   501 TInt RFilePlugin::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs)
   502 	{
   503 	TInt reply;
   504 	TInt err = iSessionHelper.CreateSubSession(aSession, aFunction, aArgs, &reply);
   505 	if(err == KErrNone)
   506 		SetSubSessionHandle(reply);
   507 	return(err);
   508 	}
   509 
   510 void RFilePlugin::CloseSubSession(TInt aFunction)
   511 	{
   512 	if (SubSessionHandle())
   513 		{
   514 		SendReceive(aFunction,TIpcArgs(TIpcArgs::ENothing,TIpcArgs::ENothing,TIpcArgs::ENothing,SubSessionHandle()));
   515 		}
   516 
   517 	SetHandle(KErrBadHandle);
   518 	SetSubSessionHandle(KErrBadHandle);
   519 	}
   520 
   521 TInt RFilePlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   522 	{
   523 	return iSessionHelper.SendReceive(aFunction, aArgs, ((RFilePlugin*) this)->SubSessionHandle());
   524 	}
   525 
   526 TInt RFile::CreateSubSession(const RSessionBase& aSession,TInt aFunction,const TIpcArgs& aArgs)
   527 	{
   528 	if(SubSessionHandle() == KErrBadHandle)
   529 		return ((RFilePlugin*) this)->CreateSubSession(aSession, aFunction, aArgs);
   530 
   531 	return RSubSessionBase::CreateSubSession(aSession, aFunction, aArgs);
   532 	}
   533 
   534 void RFile::CloseSubSession(TInt aFunction)
   535 	{
   536 	if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
   537 		RSubSessionBase::CloseSubSession(aFunction);
   538 	else
   539 		((RFilePlugin*) this)->CloseSubSession(aFunction);
   540 	}
   541 
   542 TInt RFile::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   543 	{
   544 	if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
   545 		return RSubSessionBase::SendReceive(aFunction, aArgs);
   546 
   547 	return ((RFilePlugin*) this)->SendReceive(aFunction, aArgs);
   548 	}
   549 
   550 
   551 /*******************************************************
   552 *						RDirPlugin					   *
   553 *******************************************************/
   554 
   555 EXPORT_C RDirPlugin::RDirPlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
   556   : iSessionHelper(&aRequest, aDirectToDrive)
   557 	{
   558 	SetHandle(KErrBadHandle);
   559 	SetSubSessionHandle(KErrBadHandle);
   560 	}
   561 
   562 EXPORT_C RDirPlugin::~RDirPlugin()
   563 	{
   564 	Close();
   565 	}
   566 
   567 EXPORT_C TInt RDirPlugin::Open(const TDesC& aMatchName,const TUidType& aUidType)
   568 /**
   569 Opens a directory using the specified UID type to filter the
   570 directory entry types that will subsequently be read.
   571 
   572 @see RDir::Open
   573 */
   574 	{
   575 	RFs fs;
   576 	fs.SetHandle(Session().Handle());
   577 
   578 	TPckgC<TUidType> pckgUid(aUidType);
   579 	return(CreateSubSession(fs,EFsDirOpen,TIpcArgs(&aMatchName,KEntryAttAllowUid,&pckgUid)));
   580 	}
   581 
   582 EXPORT_C TInt RDirPlugin::Open(const TDesC& aMatchName,TUint anAttMask)
   583 /**
   584 Opens a directory using an attribute bitmask to filter the directory entry
   585 types that will subsequently be read.
   586 
   587 @see RDir::Open
   588 */
   589 	{
   590 	RFs fs;
   591 	fs.SetHandle(Session().Handle());
   592 
   593 	TUidType uidType(TUid::Null(),TUid::Null(),TUid::Null());
   594 	TPckgC<TUidType> pckgUid(uidType);
   595 	return(CreateSubSession(fs,EFsDirOpen,TIpcArgs(&aMatchName,anAttMask,&pckgUid)));
   596 	}
   597 
   598 EXPORT_C void RDirPlugin::Close()
   599 /**
   600 Closes the the directory.
   601 
   602 @see RDir::Close
   603 */
   604 	{
   605 	CloseSubSession(EFsDirSubClose);
   606 	SetSubSessionHandle(KErrBadHandle);
   607 	}
   608 
   609 EXPORT_C TInt RDirPlugin::Read(TEntryArray& aArray)
   610 /**
   611 Reads all filtered directory entries into the specified array.
   612 
   613 @see RDir::Read
   614 */
   615 	{
   616 	return RDir::Read(aArray);
   617 	}
   618 
   619 EXPORT_C TInt RDirPlugin::Read(TEntry& aEntry)
   620 /**
   621 Reads all filtered directory entries into the specified array.
   622 
   623 @see RDir::Read
   624 */
   625 	{
   626 	return RDir::Read(aEntry);
   627 	}
   628 
   629 void RDirPlugin::SetHandle(TInt aHandle)
   630 	{
   631 	*(((TInt*) this) + 0) = aHandle;
   632 	}
   633 
   634 void RDirPlugin::SetSubSessionHandle(TInt aHandle)
   635 	{
   636 	*(((TInt*) this) + 1) = aHandle;
   637 	}
   638 
   639 TInt RDirPlugin::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs)
   640 	{
   641 	TInt reply;
   642 	TInt err = iSessionHelper.CreateSubSession(aSession, aFunction, aArgs, &reply);
   643 	if(err == KErrNone)
   644 		SetSubSessionHandle(reply);
   645 	return(err);
   646 	}
   647 
   648 void RDirPlugin::CloseSubSession(TInt aFunction)
   649 	{
   650 	if (SubSessionHandle())
   651 		{
   652 		SendReceive(aFunction,TIpcArgs(TIpcArgs::ENothing,TIpcArgs::ENothing,TIpcArgs::ENothing,SubSessionHandle()));
   653 		}
   654 
   655 	SetHandle(KErrBadHandle);
   656 	SetSubSessionHandle(KErrBadHandle);
   657 	}
   658 
   659 TInt RDirPlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   660 	{
   661 	return iSessionHelper.SendReceive(aFunction, aArgs, ((RDirPlugin*) this)->SubSessionHandle());
   662 	}
   663 
   664 TInt RDir::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
   665 	{
   666 	if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
   667 		return RSubSessionBase::SendReceive(aFunction, aArgs);
   668 
   669 	return ((RDirPlugin*) this)->SendReceive(aFunction, aArgs);
   670 	}
   671 
   672 
   673 /*******************************************************
   674 *				TFsPluginSessionHelper				   *
   675 *******************************************************/
   676 
   677 TPluginSessionHelper::TPluginSessionHelper()
   678 	{ memclr(this, sizeof(TPluginSessionHelper)); }
   679 
   680 TPluginSessionHelper::TPluginSessionHelper(TFsPluginRequest* aRequest, TBool aDirectToDrive)
   681   : iPlugin(aRequest->Request()->iCurrentPlugin),
   682 	iSession(aRequest->Request()->Session()),
   683 	iDirectToDrive(aDirectToDrive),
   684     iRequest(aRequest)
   685 	{
   686 	// need to initialise RLocalMessage with client session
   687 	*((RMessage2*) &iMessage) = aRequest->Message();
   688 	iMessage.InitHandle();	// set handle to KLocalMessageHandle
   689 	memclr(iSpare, sizeof(iSpare));
   690 	}
   691 
   692 TInt TPluginSessionHelper::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs, TInt* aReply)
   693 	{
   694 	(void)aSession;
   695 
   696 	// Init message
   697 	TIpcArgs args;
   698 	args.iArgs[0] = aArgs.iArgs[0];
   699 	args.iArgs[1] = aArgs.iArgs[1];
   700 	args.iArgs[2] = aArgs.iArgs[2];
   701 	args.iFlags = aArgs.iFlags&((1<<(3*TIpcArgs::KBitsPerType))-1);
   702 
   703 	TPckgBuf<TInt> reply;
   704 	args.Set(3,&reply);
   705 
   706 	// copy session pointer
   707 	RLocalMessage message = iMessage;
   708 	message.SetFunction(aFunction);
   709 	message.SetArgs(args);
   710 
   711 	TInt err = Dispatch(aFunction, args);
   712 	if (err == KErrNone)
   713 		*aReply = reply();
   714 
   715 	return err;
   716 	}
   717 
   718 TInt TPluginSessionHelper::Dispatch(TInt aFunction, TIpcArgs& aArgs) const
   719 	{
   720 	// copy session pointer
   721 	RLocalMessage message = iMessage;
   722 	message.SetFunction(aFunction);
   723 	message.SetArgs(aArgs);
   724 
   725 	// allocate request
   726 	CFsClientMessageRequest* newRequest;
   727 	const TOperation& oP = OperationArray[aFunction & KIpcFunctionMask];
   728 	TInt err = RequestAllocator::GetMessageRequest(oP, message, newRequest);
   729 	if (err != KErrNone)
   730 		return err;
   731 
   732 	newRequest->Set(message, oP, iSession);
   733 	
   734 	//This is wrong. drive number is set in TFsXxx::initialise
   735 	//newRequest->SetDrive(&TheDrives[iPlugin->Drive()]);
   736 
   737 	newRequest->iCurrentPlugin = iPlugin;
   738 	newRequest->iOwnerPlugin   = iPlugin;
   739 	newRequest->iDirectToDrive = iDirectToDrive;
   740 
   741 	newRequest->Dispatch();
   742 
   743 	// NOTE : newRequest will be free'd by the File Server before completing the
   744 	//        request so it's not safe to touch the request from now on...
   745 	
   746 	return(iPlugin->WaitForRequest());
   747 	}
   748 
   749 TInt TPluginSessionHelper::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TInt aSubSessionHandle) const
   750 	{
   751 	// Init message
   752 	TIpcArgs args;
   753 	args.iArgs[0] = aArgs.iArgs[0];
   754 	args.iArgs[1] = aArgs.iArgs[1];
   755 	args.iArgs[2] = aArgs.iArgs[2];
   756 	args.iFlags   = aArgs.iFlags&((1<<(3*TIpcArgs::KBitsPerType))-1);
   757 	args.iArgs[3] = aSubSessionHandle;
   758 
   759 	return Dispatch(aFunction, args);
   760 	}
   761 
   762 TInt TPluginSessionHelper::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const
   763 	{
   764 	// Init message
   765 	TIpcArgs args;
   766 	args.iArgs[0] = aArgs.iArgs[0];
   767 	args.iArgs[1] = aArgs.iArgs[1];
   768 	args.iArgs[2] = aArgs.iArgs[2];
   769 	args.iArgs[3] = aArgs.iArgs[3];
   770 	args.iFlags = aArgs.iFlags&((1<<(3*TIpcArgs::KBitsPerType))-1);
   771 
   772 	return Dispatch(aFunction, args);
   773 	}
   774 
   775 GLDEF_C void Panic(TClientPanic aPanic)
   776 //
   777 // Panic the current client with a file server client side panic.
   778 //
   779 	{
   780 	User::Panic(_L("FS_PLUGIN_CLIENT panic"),aPanic);
   781 	}
   782