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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_plugin_shim.cpp
21 /*******************************************************
23 *******************************************************/
25 EXPORT_C RFsPlugin::RFsPlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
26 : iSessionHelper(&aRequest, aDirectToDrive)
28 SetReturnedHandle(KNullHandle);
31 EXPORT_C RFsPlugin::~RFsPlugin()
36 EXPORT_C TInt RFsPlugin::Connect()
38 Connects a file server plugin to the file server.
40 To end the file server session, use Close().
42 @return KErrNone, if successful, otherwise one of the other system-wide error codes.
48 EXPORT_C void RFsPlugin::Close()
50 Closes a file server plugin session.
53 SetReturnedHandle(KNullHandle);
56 EXPORT_C TInt RFsPlugin::Delete(const TDesC& aName)
58 Deletes a single file.
63 return(RFs::Delete(aName));
66 EXPORT_C TInt RFsPlugin::Rename(const TDesC& aOldName,const TDesC& aNewName)
68 Renames a single file or directory.
73 return(RFs::Rename(aOldName, aNewName));
76 EXPORT_C TInt RFsPlugin::Replace(const TDesC& aOldName,const TDesC& aNewName)
78 Replaces a single file with another.
83 return(RFs::Replace(aOldName, aNewName));
86 EXPORT_C TInt RFsPlugin::Entry(const TDesC& aName,TEntry& aEntry) const
88 Gets the entry details for a file or directory.
93 return(RFs::Entry(aName, aEntry));
96 EXPORT_C TInt RFsPlugin::SetEntry(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
98 Sets both the attributes and the last modified date and time for a file or directory.
103 return(RFs::SetEntry(aName,aTime,aSetAttMask,aClearAttMask));
106 EXPORT_C TInt RFsPlugin::ReadFileSection(const TDesC& aName,TInt64 aPos,TDes8& aDes,TInt aLength) const
108 Reads data from a file without opening it.
110 The contents of the file can be accessed regardless of the file's lock state.
112 @see RFs::ReadFileSection
115 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
116 return(RFs::ReadFileSection(aName,I64LOW(aPos),aDes,aLength));
118 return(RFs::ReadFileSection(aName,aPos,aDes,aLength));
122 EXPORT_C TInt RFsPlugin::Volume(TVolumeInfo &aVol, TInt aDrive) const
124 Gets volume information for a formatted device.
129 return (RFs::Volume(aVol, aDrive));
132 TInt RFsPlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
134 return iSessionHelper.SendReceive(aFunction, aArgs);
137 TInt RFs::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
140 return RSessionBase::SendReceive(aFunction, aArgs);
142 return ((RFsPlugin*) this)->SendReceive(aFunction, aArgs);
146 /*******************************************************
148 *******************************************************/
150 EXPORT_C RFilePlugin::RFilePlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
151 : iSessionHelper(&aRequest, aDirectToDrive)
153 SetHandle(KErrBadHandle);
154 SetSubSessionHandle(KErrBadHandle);
157 EXPORT_C RFilePlugin::~RFilePlugin()
162 EXPORT_C TInt RFilePlugin::Open(const TDesC& aName,TUint aMode)
164 Opens an existing file for reading or writing.
166 If the file does not already exist, an error is returned.
172 fs.SetHandle(Session().Handle());
173 return(CreateSubSession(fs,EFsFileOpen,TIpcArgs(&aName,aMode)));
176 EXPORT_C void RFilePlugin::Close()
183 CloseSubSession(EFsFileSubClose);
184 SetSubSessionHandle(KErrBadHandle);
187 EXPORT_C TInt RFilePlugin::Create(const TDesC& aName,TUint aFileMode)
195 fs.SetHandle(Session().Handle());
196 return(CreateSubSession(fs,EFsFileCreate,TIpcArgs(&aName,aFileMode)));
199 EXPORT_C TInt RFilePlugin::Replace(const TDesC& aName,TUint aFileMode)
207 fs.SetHandle(Session().Handle());
208 return(CreateSubSession(fs,EFsFileReplace,TIpcArgs(&aName,aFileMode)));
211 EXPORT_C TInt RFilePlugin::Temp(const TDesC& aPath,TFileName& aName,TUint aFileMode)
219 fs.SetHandle(Session().Handle());
220 return(CreateSubSession(fs,EFsFileTemp,TIpcArgs(&aPath,aFileMode,&aName)));
223 EXPORT_C TInt RFilePlugin::AdoptFromClient()
227 @see RFile::AdoptFromClient
230 TFsPluginRequest* request = iSessionHelper.Request();
232 return KErrBadHandle;
234 TInt clientSubSessionHandle;
235 TInt err = request->ClientSubSessionHandle(clientSubSessionHandle);
240 fs.SetHandle(Session().Handle());
241 err = CreateSubSession(fs,EFsFileDuplicate, TIpcArgs(clientSubSessionHandle, ETrue));
245 SetSubSessionHandle(SubSessionHandle() ^ KSubSessionMangleBit);
250 EXPORT_C TInt RFilePlugin::TransferToClient()
254 @see RFile::TransferToClient
257 TFsPluginRequest* request = iSessionHelper.Request();
259 return KErrBadHandle;
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())));
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());
269 // And now we're done - we don't bother closing, as the client now completely owns the handle
270 SetSubSessionHandle(KErrBadHandle);
275 EXPORT_C TInt RFilePlugin::Write(TInt64 aPos, const TDesC8& aDes)
277 Writes to the file at the specified offset within the file
282 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
283 return RFile::Write(I64LOW(aPos), aDes);
285 return RFile64::Write(aPos, aDes);
289 EXPORT_C TInt RFilePlugin::Write(TInt64 aPos,const TDesC8& aDes,TInt aLen)
291 Writes the specified number of bytes to the file at the specified offset within the file.
296 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
297 return RFile::Write(I64LOW(aPos), aDes, aLen);
299 return RFile64::Write(aPos, aDes, aLen);
303 EXPORT_C TInt RFilePlugin::Read(TInt64 aPos,TDes8& aDes) const
305 Reads from the file at the specified offset within the file
310 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
311 return RFile::Read(I64LOW(aPos), aDes);
313 return RFile64::Read(aPos, aDes);
317 EXPORT_C TInt RFilePlugin::Read(TInt64 aPos,TDes8& aDes,TInt aLen) const
319 Reads the specified number of bytes of binary data from the file at a specified
320 offset within the file.
325 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
326 return RFile::Read(I64LOW(aPos), aDes, aLen);
328 return RFile64::Read(aPos, aDes, aLen);
332 EXPORT_C TInt RFilePlugin::Size(TInt64& aSize) const
334 Gets the current file size.
339 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
340 TInt size = I64LOW(aSize);
341 TInt err = RFile::Size(size);
345 return RFile64::Size(aSize);
349 EXPORT_C TInt RFilePlugin::SetSize(TInt64 aSize)
356 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
357 return RFile::SetSize(I64LOW(aSize));
359 return RFile64::SetSize(aSize);
363 EXPORT_C TInt RFilePlugin::Lock(TInt64 aPos, TInt64 aLength) const
365 Locks a region within the file as defined by a range of bytes.
370 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
371 return RFile::Lock(I64LOW(aPos), I64LOW(aLength));
373 return RFile64::Lock(aPos, aLength);
377 EXPORT_C TInt RFilePlugin::UnLock(TInt64 aPos, TInt64 aLength) const
379 Unlocks a region within the file as defined by a range of bytes.
384 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
385 return RFile::UnLock(I64LOW(aPos), I64LOW(aLength));
387 return RFile64::UnLock(aPos, aLength);
391 EXPORT_C TInt RFilePlugin::Seek(TSeek aMode,TInt64& aPos) const
393 Sets the the current file position.
398 #ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
399 TInt position = I64LOW(aPos);
400 TInt err = RFile::Seek(aMode, position);
406 return RFile64::Seek(aMode, aPos);
410 EXPORT_C TInt RFilePlugin::Flush()
412 Commits data to the storage device and flushes internal buffers without closing
418 return RFile::Flush();
421 EXPORT_C TInt RFilePlugin::Att(TUint& aVal) const
423 Gets the file's attributes.
428 return RFile::Att(aVal);
431 EXPORT_C TInt RFilePlugin::SetAtt(TUint aSetAttMask,TUint aClearAttMask)
433 Sets or clears file attributes using two bitmasks.
438 return RFile::SetAtt(aSetAttMask, aClearAttMask);
441 EXPORT_C TInt RFilePlugin::Modified(TTime& aTime) const
443 Gets local date and time the file was last modified, in universal time.
448 return RFile::Modified(aTime);
451 EXPORT_C TInt RFilePlugin::SetModified(const TTime& aTime)
453 Sets the date and time the file was last modified. UTC date and time should be used.
455 @see RFile::SetModified
458 return RFile::SetModified(aTime);
461 EXPORT_C TInt RFilePlugin::Set(const TTime& aTime,TUint aMask,TUint aVal)
463 Sets the file’s attributes, and the date and time it was last modified.
468 return RFile::Set(aTime, aMask, aVal);
471 EXPORT_C TInt RFilePlugin::ChangeMode(TFileMode aNewMode)
473 Switches an open file's access mode between EFileShareExclusive and EFileShareReadersOnly.
475 @see RFile::ChangeMode
478 return RFile::ChangeMode(aNewMode);
481 EXPORT_C TInt RFilePlugin::Rename(const TDesC& aNewName)
488 return RFile::Rename(aNewName);
491 void RFilePlugin::SetHandle(TInt aHandle)
493 *(((TInt*) this) + 0) = aHandle;
496 void RFilePlugin::SetSubSessionHandle(TInt aHandle)
498 *(((TInt*) this) + 1) = aHandle;
501 TInt RFilePlugin::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs)
504 TInt err = iSessionHelper.CreateSubSession(aSession, aFunction, aArgs, &reply);
506 SetSubSessionHandle(reply);
510 void RFilePlugin::CloseSubSession(TInt aFunction)
512 if (SubSessionHandle())
514 SendReceive(aFunction,TIpcArgs(TIpcArgs::ENothing,TIpcArgs::ENothing,TIpcArgs::ENothing,SubSessionHandle()));
517 SetHandle(KErrBadHandle);
518 SetSubSessionHandle(KErrBadHandle);
521 TInt RFilePlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
523 return iSessionHelper.SendReceive(aFunction, aArgs, ((RFilePlugin*) this)->SubSessionHandle());
526 TInt RFile::CreateSubSession(const RSessionBase& aSession,TInt aFunction,const TIpcArgs& aArgs)
528 if(SubSessionHandle() == KErrBadHandle)
529 return ((RFilePlugin*) this)->CreateSubSession(aSession, aFunction, aArgs);
531 return RSubSessionBase::CreateSubSession(aSession, aFunction, aArgs);
534 void RFile::CloseSubSession(TInt aFunction)
536 if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
537 RSubSessionBase::CloseSubSession(aFunction);
539 ((RFilePlugin*) this)->CloseSubSession(aFunction);
542 TInt RFile::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
544 if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
545 return RSubSessionBase::SendReceive(aFunction, aArgs);
547 return ((RFilePlugin*) this)->SendReceive(aFunction, aArgs);
551 /*******************************************************
553 *******************************************************/
555 EXPORT_C RDirPlugin::RDirPlugin(TFsPluginRequest& aRequest, TBool aDirectToDrive)
556 : iSessionHelper(&aRequest, aDirectToDrive)
558 SetHandle(KErrBadHandle);
559 SetSubSessionHandle(KErrBadHandle);
562 EXPORT_C RDirPlugin::~RDirPlugin()
567 EXPORT_C TInt RDirPlugin::Open(const TDesC& aMatchName,const TUidType& aUidType)
569 Opens a directory using the specified UID type to filter the
570 directory entry types that will subsequently be read.
576 fs.SetHandle(Session().Handle());
578 TPckgC<TUidType> pckgUid(aUidType);
579 return(CreateSubSession(fs,EFsDirOpen,TIpcArgs(&aMatchName,KEntryAttAllowUid,&pckgUid)));
582 EXPORT_C TInt RDirPlugin::Open(const TDesC& aMatchName,TUint anAttMask)
584 Opens a directory using an attribute bitmask to filter the directory entry
585 types that will subsequently be read.
591 fs.SetHandle(Session().Handle());
593 TUidType uidType(TUid::Null(),TUid::Null(),TUid::Null());
594 TPckgC<TUidType> pckgUid(uidType);
595 return(CreateSubSession(fs,EFsDirOpen,TIpcArgs(&aMatchName,anAttMask,&pckgUid)));
598 EXPORT_C void RDirPlugin::Close()
600 Closes the the directory.
605 CloseSubSession(EFsDirSubClose);
606 SetSubSessionHandle(KErrBadHandle);
609 EXPORT_C TInt RDirPlugin::Read(TEntryArray& aArray)
611 Reads all filtered directory entries into the specified array.
616 return RDir::Read(aArray);
619 EXPORT_C TInt RDirPlugin::Read(TEntry& aEntry)
621 Reads all filtered directory entries into the specified array.
626 return RDir::Read(aEntry);
629 void RDirPlugin::SetHandle(TInt aHandle)
631 *(((TInt*) this) + 0) = aHandle;
634 void RDirPlugin::SetSubSessionHandle(TInt aHandle)
636 *(((TInt*) this) + 1) = aHandle;
639 TInt RDirPlugin::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs)
642 TInt err = iSessionHelper.CreateSubSession(aSession, aFunction, aArgs, &reply);
644 SetSubSessionHandle(reply);
648 void RDirPlugin::CloseSubSession(TInt aFunction)
650 if (SubSessionHandle())
652 SendReceive(aFunction,TIpcArgs(TIpcArgs::ENothing,TIpcArgs::ENothing,TIpcArgs::ENothing,SubSessionHandle()));
655 SetHandle(KErrBadHandle);
656 SetSubSessionHandle(KErrBadHandle);
659 TInt RDirPlugin::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
661 return iSessionHelper.SendReceive(aFunction, aArgs, ((RDirPlugin*) this)->SubSessionHandle());
664 TInt RDir::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const
666 if((Session().Handle() ^ CObjectIx::ENoClose) != KErrBadHandle)
667 return RSubSessionBase::SendReceive(aFunction, aArgs);
669 return ((RDirPlugin*) this)->SendReceive(aFunction, aArgs);
673 /*******************************************************
674 * TFsPluginSessionHelper *
675 *******************************************************/
677 TPluginSessionHelper::TPluginSessionHelper()
678 { memclr(this, sizeof(TPluginSessionHelper)); }
680 TPluginSessionHelper::TPluginSessionHelper(TFsPluginRequest* aRequest, TBool aDirectToDrive)
681 : iPlugin(aRequest->Request()->iCurrentPlugin),
682 iSession(aRequest->Request()->Session()),
683 iDirectToDrive(aDirectToDrive),
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));
692 TInt TPluginSessionHelper::CreateSubSession(const RSessionBase& aSession, TInt aFunction, const TIpcArgs& aArgs, TInt* aReply)
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);
703 TPckgBuf<TInt> reply;
706 // copy session pointer
707 RLocalMessage message = iMessage;
708 message.SetFunction(aFunction);
709 message.SetArgs(args);
711 TInt err = Dispatch(aFunction, args);
718 TInt TPluginSessionHelper::Dispatch(TInt aFunction, TIpcArgs& aArgs) const
720 // copy session pointer
721 RLocalMessage message = iMessage;
722 message.SetFunction(aFunction);
723 message.SetArgs(aArgs);
726 CFsClientMessageRequest* newRequest;
727 const TOperation& oP = OperationArray[aFunction & KIpcFunctionMask];
728 TInt err = RequestAllocator::GetMessageRequest(oP, message, newRequest);
732 newRequest->Set(message, oP, iSession);
734 //This is wrong. drive number is set in TFsXxx::initialise
735 //newRequest->SetDrive(&TheDrives[iPlugin->Drive()]);
737 newRequest->iCurrentPlugin = iPlugin;
738 newRequest->iOwnerPlugin = iPlugin;
739 newRequest->iDirectToDrive = iDirectToDrive;
741 newRequest->Dispatch();
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...
746 return(iPlugin->WaitForRequest());
749 TInt TPluginSessionHelper::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TInt aSubSessionHandle) const
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;
759 return Dispatch(aFunction, args);
762 TInt TPluginSessionHelper::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const
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);
772 return Dispatch(aFunction, args);
775 GLDEF_C void Panic(TClientPanic aPanic)
777 // Panic the current client with a file server client side panic.
780 User::Panic(_L("FS_PLUGIN_CLIENT panic"),aPanic);