--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/remotestoragefw/remotefileengine/src/rsfwsession.cpp Thu Dec 17 09:07:59 2009 +0200
@@ -0,0 +1,946 @@
+/*
+* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Client side of Remote Storage FW API access functions.
+ *
+*/
+
+
+// INCLUDE FILES
+#include "rsfwsession.h"
+#include "rsfwinterface.h"
+
+#ifdef __WINS__
+#include <e32math.h>
+#endif
+
+// CONSTANTS
+
+// Number of message slots to reserve for this client server session.
+// Since we only communicate synchronously here, we never have any
+// outstanding asynchronous requests.
+const TUint KDefaultMessageSlots = 4;
+
+#ifdef __WINS__
+const TUint KServerMinHeapSize = 0x1000; // 4K
+const TUint KServerMaxHeapSize = 0x100000; // 64K
+#endif
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::RRsfwSession
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C RRsfwSession::RRsfwSession() : RSessionBase()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::Connect
+// Connects to the framework by starting the server if neccessary and creating
+// a session.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::Connect()
+ {
+ const TInt KTryCount = 3;
+
+ TInt err;
+ TBool retry;
+ TInt i = KTryCount;
+ do
+ {
+ err = StartServer(KRfeServerName);
+ if (err == KErrNone)
+ {
+ err = CreateSession(KRfeServerName,
+ Version(),
+ KDefaultMessageSlots);
+ }
+ retry = ((err == KErrNotFound) || (err == KErrServerTerminated));
+ } while (retry && (++i <= KTryCount));
+
+ return err;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::Close
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RRsfwSession::Close()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::Version
+// Returns the version of Remote File Engine
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TVersion RRsfwSession::Version() const
+ {
+ return(TVersion(KRfeMajorVersionNumber,
+ KRfeMinorVersionNumber,
+ KRfeBuildVersionNumber));
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::MoveFids
+// Sends the rename operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::MoveFids(
+ TFid aSourceFid,
+ const TDesC& aSourceName,
+ TFid aDestFid,
+ const TDesC& aDestName,
+ TBool aOverWrite)
+ {
+
+ TRfeRenameInArgs* renameArgs = new TRfeRenameInArgs();
+ if (!renameArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ // TRfeRenameInArgs* writePtr = static_cast<TRfeRenameInArgs*>(iWritePtr);
+ renameArgs->iOpCode = ERenameReplace;
+
+ renameArgs->iFid = aSourceFid;
+ renameArgs->iSrcName.Copy(aSourceName);
+ renameArgs->iDstFid = aDestFid;
+ renameArgs->iDstName.Copy(aDestName);
+ renameArgs->iOverWrite = aOverWrite;
+
+ TPckg<TRfeRenameInArgs> pckgInArgs(*renameArgs);
+
+ TInt result = SendRequest(ERenameReplace, aSourceFid.iVolumeId,
+ TIpcArgs(&pckgInArgs));
+ delete renameArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::SetEntry
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::SetEntry(
+ const TFid aFid,
+ const TTime& aTime,
+ TUint aSetAttMask,
+ TUint aClearAttMask)
+ {
+ TRfeSetAttrInArgs* setEntryArgs = new TRfeSetAttrInArgs();
+ if (!setEntryArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ setEntryArgs->iOpCode = ESetAttr;
+ setEntryArgs->iFid = aFid;
+
+ // default: no change
+ setEntryArgs->iAttr.iAtt = 0;
+ setEntryArgs->iMask.iAtt = 0;
+
+ if (aSetAttMask & KEntryAttReadOnly)
+ {
+ // Set read-only
+ setEntryArgs->iAttr.iAtt |= KEntryAttReadOnly;
+ setEntryArgs->iMask.iAtt |= KEntryAttReadOnly;
+ }
+ if (aClearAttMask & KEntryAttReadOnly)
+ {
+ // Reset read-only
+ setEntryArgs->iMask.iAtt |= KEntryAttReadOnly;
+ }
+
+ // Setting time
+ setEntryArgs->iAttr.iModified = aTime;
+
+ // Let's see - we will not want to do anything unless
+ // the attributes convey something significant.
+ TInt result = KErrNone;
+ if (setEntryArgs->iMask.iAtt)
+ {
+ TPckg<TRfeSetAttrInArgs> pckgInArgs(*setEntryArgs);
+ result = SendRequest(ESetAttr, aFid.iVolumeId, TIpcArgs(&pckgInArgs));
+ }
+ delete setEntryArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::FlushCache
+// Flushes the directory cache of a file or directory by putting the parameters
+// into the shared memory chunk and sending the request.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::FlushCache(
+ TFid& aFid)
+ {
+ TRfeIoctlInArgs* ioctlArgs = new TRfeIoctlInArgs();
+ if (!ioctlArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ ioctlArgs->iOpCode = EFsIoctl;
+ ioctlArgs->iFid = aFid;
+ ioctlArgs->iCmd = ERemoteFsIoctlRefresh;
+ ioctlArgs->iLen = 0;
+
+ TPckg<TRfeIoctlInArgs> pckgInArgs(*ioctlArgs);
+ TInt result = SendRequest(EFsIoctl, aFid.iVolumeId, TIpcArgs(&pckgInArgs));
+ delete ioctlArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::SetHighCachePriority
+// Sets higher cache priority for a file by putting the parameters
+// into the shared memory chunk and sending the request.
+// This feature is not supported currently.
+// Perhaps will be implemented in near future.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::SetHighCachePriority(TFid& /* aFid */)
+ {
+ return KErrNotSupported;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::GetAttributes
+// Sends GetAttr operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::GetAttributes(
+ TFid aFileFid,
+ TEntry& aAttributes)
+ {
+ TRfeGetAttrInArgs* getattrArgs = new TRfeGetAttrInArgs();
+ if (!getattrArgs)
+ {
+ return KErrNoMemory;
+ }
+ TRfeGetAttrOutArgs* getattrOutArgs = new TRfeGetAttrOutArgs();
+ if (!getattrOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ getattrArgs->iOpCode = EGetAttr;
+ getattrArgs->iFid = aFileFid;
+
+ TPckg<TRfeGetAttrInArgs> pckgInArgs(*getattrArgs);
+ TPckg<TRfeGetAttrOutArgs> pckgOutArgs(*getattrOutArgs);
+
+ TInt result = SendRequest(EGetAttr, aFileFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ // Note that aAttributes.iType (the entry UID)
+ // should only be set for a file whose
+ // size is greater than or equal to sizeof(TCheckedUid).
+ aAttributes.iAtt = getattrOutArgs->iAttr.iAtt;
+ aAttributes.iSize = getattrOutArgs->iAttr.iSize;
+ aAttributes.iModified = getattrOutArgs->iAttr.iModified;
+ aAttributes.iType = KNullUid;
+ }
+
+ delete getattrArgs;
+ delete getattrOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::OpenByPathL
+// Sends OpenByPath operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// Remote File Engine returns the path of the cache container file for this fid
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::OpenByPath(
+ TFid aFid,
+ TDes& aContainerPath,
+ TDirEntAttr* aAttributes,
+ TBool aTrueOpen)
+ {
+ TRfeOpenByPathInArgs* openbypathArgs = new TRfeOpenByPathInArgs();
+ if (!openbypathArgs)
+ {
+ return KErrNoMemory;
+ }
+ TRfeOpenByPathOutArgs* openbypathOutArgs = new TRfeOpenByPathOutArgs();
+ if (!openbypathOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ openbypathArgs->iOpCode = EOpenByPath;
+ openbypathArgs->iFid = aFid;
+
+ // Flag field is used to pass attributes,
+ // which indicate which lock should be obtained for the file
+ if (aAttributes)
+ {
+ openbypathArgs->iFlags = aAttributes->iAtt;
+ }
+ else
+ {
+ openbypathArgs->iFlags = 0;
+ }
+
+ // tells whether the file is really opened or do we need it because
+ // ReadSection() was called... (in the latter case Symbian File Server
+ // does not open the file...) */
+ openbypathArgs->iTrueOpen = aTrueOpen;
+
+ TPckg<TRfeOpenByPathInArgs> pckgInArgs(*openbypathArgs);
+ TPckg<TRfeOpenByPathOutArgs> pckgOutArgs(*openbypathOutArgs);
+
+ TInt result = SendRequest(EOpenByPath, aFid.iVolumeId, TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ if (aAttributes)
+ {
+ *aAttributes = openbypathOutArgs->iAttr;
+ }
+ // Processing the response
+ _LIT(KPathRedundancy, "\\.\\");
+ TInt j = openbypathOutArgs->iPath.Find(KPathRedundancy);
+ if (j != KErrNotFound)
+ {
+ TInt i = openbypathOutArgs->iPath.Length();
+ TInt k;
+ for (k = j; k + 2 < i; k++)
+ {
+ openbypathOutArgs->iPath[k] =
+ openbypathOutArgs->iPath[k + 2];
+ }
+ openbypathOutArgs->iPath.SetLength(i - 2);
+ }
+
+ const TInt maximumLength = aContainerPath.MaxLength();
+ if (maximumLength >= openbypathOutArgs->iPath.Length())
+ {
+ aContainerPath.Copy(openbypathOutArgs->iPath);
+ }
+ else
+ {
+ aContainerPath.Copy(
+ openbypathOutArgs->iPath.Left(maximumLength));
+ }
+ }
+ delete openbypathArgs;
+ delete openbypathOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::RfeInit
+// Gets the fid of the root of the mount for Remote File Engine by putting the
+// parameters into the shared memory chunk, sending the request and reading
+// the result.
+// This allows us to get other fids by lookup().
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::RfeInit(TFid& aRootFid)
+ {
+ TRfeRootInArgs* rootArgs = new TRfeRootInArgs();
+ if (!rootArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ TRfeRootOutArgs* rootOutArgs = new TRfeRootOutArgs();
+ if (!rootOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ rootArgs->iOpCode = EFsRoot;
+ rootArgs->iFid.iVolumeId = 0;
+ rootArgs->iFid.iNodeId = 0;
+
+ TPckg<TRfeRootInArgs> pckgInArgs(*rootArgs);
+ TPckg<TRfeRootOutArgs> pckgOutArgs(*rootOutArgs);
+
+ TInt result = SendRequest(EFsRoot, aRootFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ aRootFid = rootOutArgs->iFid;
+ }
+
+ delete rootArgs;
+ delete rootOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::MakeDirectoryL
+// Sends MkDir operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::MakeDirectory(
+ TFid aParentFid,
+ const TDesC& aDirName)
+ {
+ TRfeMkdirInArgs* mkdirArgs = new TRfeMkdirInArgs();
+ if (!mkdirArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ mkdirArgs->iOpCode = EMkDir;
+ mkdirArgs->iFid = aParentFid;
+
+ mkdirArgs->iEntry.iName.Copy(aDirName);
+ mkdirArgs->iEntry.iAttr.iAtt = 0; // not read only
+
+ TPckg<TRfeMkdirInArgs> pckgInArgs(*mkdirArgs);
+ TInt result = SendRequest(EMkDir,
+ aParentFid.iVolumeId,
+ TIpcArgs(&pckgInArgs));
+ delete mkdirArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::RemoveDirectoryL
+// Sends Remove Directory operation to Remote File Engine by putting the
+// parameters into the shared memory chunk, sending the request and reading
+// the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::RemoveDirectory(
+ TFid aParentFid,
+ const TDesC& aDirName)
+ {
+ TRfeRmdirInArgs* rmdirArgs = new TRfeRmdirInArgs();
+ if (!rmdirArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ rmdirArgs->iOpCode = ERemoveDir;
+ rmdirArgs->iFid = aParentFid;
+
+ rmdirArgs->iName.Copy(aDirName);
+
+ TPckg<TRfeRmdirInArgs> pckgInArgs(*rmdirArgs);
+ TInt result = SendRequest(ERemoveDir,
+ aParentFid.iVolumeId,
+ TIpcArgs(&pckgInArgs));
+
+ delete rmdirArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::CreateFileL
+// Sends Create File operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::CreateFile(
+ TFid aParentFid,
+ const TDesC& aFileName,
+ TUint aMode,
+ TUint aExcl,
+ TFid& aNewFid)
+ {
+ TRfeCreateInArgs* createArgs = new TRfeCreateInArgs();
+ if (!createArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ TRfeCreateOutArgs* createOutArgs = new TRfeCreateOutArgs();
+ if (!createOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ createArgs->iOpCode = ECreateFile;
+ createArgs->iFid = aParentFid;
+
+ createArgs->iEntry.iName.Copy(aFileName);
+
+ if (aMode & EFileWrite)
+ {
+ createArgs->iEntry.iAttr.iAtt = 0;
+ }
+ else
+ {
+ createArgs->iEntry.iAttr.iAtt = KEntryAttReadOnly;
+ }
+ createArgs->iEntry.iAttr.iSize = 0;
+ createArgs->iEntry.iAttr.iModified = 0;
+
+ createArgs->iExcl = aExcl;
+
+ TPckg<TRfeCreateInArgs> pckgInArgs(*createArgs);
+ TPckg<TRfeCreateOutArgs> pckgOutArgs(*createOutArgs);
+ TInt result = SendRequest(ECreateFile,
+ aParentFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ aNewFid = createOutArgs->iFid;
+ }
+
+ delete createArgs;
+ delete createOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::RemoveFileL
+// Sends Remove File operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::RemoveFile(
+ TFid aParentFid,
+ const TDesC& aFileName)
+ {
+ TRfeRemoveInArgs* removeArgs = new TRfeRemoveInArgs();
+ if (!removeArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ removeArgs->iOpCode = ERemove;
+ removeArgs->iFid = aParentFid;
+
+ removeArgs->iName.Copy(aFileName);
+
+ TPckg<TRfeRemoveInArgs> pckgInArgs(*removeArgs);
+ TInt result = SendRequest(ERemove,
+ aParentFid.iVolumeId,
+ TIpcArgs(&pckgInArgs));
+
+ delete removeArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::LookupL
+// Sends Lookup operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::Lookup(
+ TFid aParentFid,
+ const TDesC& aName,
+ TUint aNodeType,
+ TFid& aFid)
+ {
+ TBool directory = EFalse;
+
+ TPtrC peek;
+ peek.Set(aName.Right(1)); // the last char
+ if ((peek.Length() > 0) && (peek[0] == '\\'))
+ {
+ directory = ETrue;
+ }
+
+ TRfeLookupInArgs* lookupArgs = new TRfeLookupInArgs();
+ if (!lookupArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ TRfeLookupOutArgs* lookupOutArgs = new TRfeLookupOutArgs();
+ if (!lookupOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ lookupArgs->iOpCode = ELookUp;
+ lookupArgs->iFid = aParentFid;
+ lookupArgs->iNodeType = aNodeType;
+
+ lookupArgs->iName.Copy(aName);
+
+ if (directory)
+ {
+ // We don't want to copy the trailing backslash
+ TInt len = lookupArgs->iName.Length();
+ lookupArgs->iName.SetLength(len - 1);
+ }
+
+ TPckg<TRfeLookupInArgs> pckgInArgs(*lookupArgs);
+ TPckg<TRfeLookupOutArgs> pckgOutArgs(*lookupOutArgs);
+ TInt result = SendRequest(ELookUp,
+ aParentFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ aFid = lookupOutArgs->iFid;
+ }
+
+ if (result == KErrNotFound)
+ {
+ if (directory)
+ {
+ return KErrPathNotFound;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+ delete lookupArgs;
+ delete lookupOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::CloseFile
+// Sends Close operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void RRsfwSession::CloseFile(
+ const TFid aFid,
+ const TUint aFlags)
+ {
+ // close cannot be called asynchronously in the file server API
+ // and cannot return an error code
+ // so we make a blind request to the server
+ SendReceive(EClose, TIpcArgs(aFid.iVolumeId, aFid.iNodeId, aFlags));
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::FlushL
+// This "abuses" close operation code.
+// The file is not really closed by the File Server,
+// and Remote File Engine only writes the (changed) file back to the
+// remote server, but does not release a possible write lock.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::Flush(
+ const TFid aFid,
+ TInt aFirstByte,
+ TInt aDataLength,
+ TInt aTotalSize)
+ {
+ TRfeFlushInArgs* flushArgs = new TRfeFlushInArgs();
+ if (!flushArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ flushArgs->iOpCode = EFlush;
+ flushArgs->iFid = aFid;
+ flushArgs->iFirstByte = aFirstByte;
+ flushArgs->iDataLength = aDataLength;
+ flushArgs->iTotalSize = aTotalSize;
+
+ TPckg<TRfeFlushInArgs> pckgInArgs(*flushArgs);
+
+ TInt result = SendRequest(EFlush, aFid.iVolumeId,
+ TIpcArgs(&pckgInArgs));
+
+ delete flushArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::Fetch
+// Sends Fetch operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// Remote File Engine will write data into cache file, which path it knows by
+// the fid.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::Fetch(
+ TFid aFileFid,
+ TInt aFirstByte,
+ TInt aLastByte,
+ TInt& aCachedBytes)
+ {
+ TRfeFetchInArgs* fetchArgs = new TRfeFetchInArgs();
+ if (!fetchArgs)
+ {
+ return KErrNoMemory;
+ }
+ TRfeFetchOutArgs* fetchOutArgs = new TRfeFetchOutArgs();
+ if (!fetchOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ fetchArgs->iOpCode = EFetch;
+ fetchArgs->iFid = aFileFid;
+ fetchArgs->iFirstByte = aFirstByte;
+ fetchArgs->iLastByte = aLastByte;
+
+ TPckg<TRfeFetchInArgs> pckgInArgs(*fetchArgs);
+ TPckg<TRfeFetchOutArgs> pckgOutArgs(*fetchOutArgs);
+ TInt result = SendRequest(EFetch, aFileFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ aCachedBytes = fetchOutArgs->iLastByte;
+ }
+
+ delete fetchArgs;
+ delete fetchOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::FetchData
+// Sends Fetch operation to Remote File Engine by putting the parameters
+// into the shared memory chunk, sending the request and reading the result.
+// Remote File Engine will write data into a temporary cache file,
+// valid only for the duration of this request.
+// Note that in this case Remote File Engine will read exactly the requested
+// amount, so aLastByte is not reset.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::FetchData(
+ TFid aFileFid,
+ TInt aFirstByte,
+ TInt aLastByte,
+ TDes& aTempFileName,
+ TBool& aUseTempPath)
+ {
+ TRfeFetchDataInArgs* fetchDataArgs = new TRfeFetchDataInArgs();
+ if (!fetchDataArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ TRfeFetchDataOutArgs* fetchDataOutArgs = new TRfeFetchDataOutArgs();
+ if (!fetchDataOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ fetchDataArgs->iOpCode = EFetchData;
+ fetchDataArgs->iFid = aFileFid;
+ fetchDataArgs->iFirstByte = aFirstByte;
+ fetchDataArgs->iLastByte = aLastByte;
+
+ TPckg<TRfeFetchDataInArgs> pckgInArgs(*fetchDataArgs);
+ TPckg<TRfeFetchDataOutArgs> pckgOutArgs(*fetchDataOutArgs);
+ TInt result = SendRequest(EFetchData, aFileFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ // Processing the response
+ _LIT(KPathRedundancy, "\\.\\");
+ TInt j = fetchDataOutArgs->iTempPath.Find(KPathRedundancy);
+ if (j != KErrNotFound)
+ {
+ TInt i = fetchDataOutArgs->iTempPath.Length();
+ TInt k;
+ for (k = j; k + 2 < i; k++)
+ {
+ fetchDataOutArgs->iTempPath[k] =
+ fetchDataOutArgs->iTempPath[k + 2];
+ }
+ fetchDataOutArgs->iTempPath.SetLength(i - 2);
+ }
+
+ const TInt maximumLength = aTempFileName.MaxLength();
+ if (maximumLength >= fetchDataOutArgs->iTempPath.Length())
+ {
+ aTempFileName.Copy(fetchDataOutArgs->iTempPath);
+ }
+ else
+ {
+ aTempFileName.Copy(
+ fetchDataOutArgs->iTempPath.Left(maximumLength));
+ }
+ aUseTempPath = fetchDataOutArgs->iUseTempPath;
+ }
+ delete fetchDataArgs;
+ delete fetchDataOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::OkToWriteL
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt RRsfwSession::OkToWrite(
+ TFid aFid,
+ TUint aBytes,
+ TBool& aOkToWrite)
+ {
+ TRfeWriteDataInArgs* writedataArgs = new TRfeWriteDataInArgs();
+ if (!writedataArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ TRfeWriteDataOutArgs* writedataOutArgs = new TRfeWriteDataOutArgs();
+ if (!writedataOutArgs)
+ {
+ return KErrNoMemory;
+ }
+
+ writedataArgs->iOpCode = EOkToWrite;
+ writedataArgs->iFid = aFid;
+ writedataArgs->iBytes = aBytes;
+
+ TPckg<TRfeWriteDataInArgs> pckgInArgs(*writedataArgs);
+ TPckg<TRfeWriteDataOutArgs> pckgOutArgs(*writedataOutArgs);
+ TInt result = SendRequest(EOkToWrite, aFid.iVolumeId,
+ TIpcArgs(&pckgInArgs, &pckgOutArgs));
+
+ if (result == KErrNone)
+ {
+ aOkToWrite = writedataOutArgs->iOkToWrite;
+ }
+
+ delete writedataArgs;
+ delete writedataOutArgs;
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::StartServer
+// Starts the Remote File Engine if it is not running, uses semaphore to
+// synchronize startup.
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+TInt RRsfwSession::StartServer(const TDesC& aServerName)
+ {
+ TFindServer findRfe(aServerName);
+ TFullName name;
+
+ TInt result = findRfe.Next(name);
+ if (result == KErrNone)
+ {
+ // Server already running
+ return KErrNone;
+ }
+
+ RSemaphore semaphore;
+ result = semaphore.CreateGlobal(KRfeSemaphoreName, 0);
+ if (result != KErrNone)
+ {
+ return result;
+ }
+
+ result = CreateServerProcess(aServerName);
+ if (result != KErrNone)
+ {
+ semaphore.Close();
+ return result;
+ }
+ semaphore.Wait();
+ semaphore.Close();
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::CreateServerProcess
+// Starts the Remote File Engine using name to find the binary
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+TInt RRsfwSession::CreateServerProcess(const TDesC& aServerName)
+ {
+ // Just load anything that matches with the name
+ const TUidType serverUid(KNullUid, KNullUid, KNullUid);
+
+ RProcess server;
+
+ _LIT(KStartCommand, "");
+ TInt result = server.Create(aServerName, KStartCommand, serverUid);
+ if (result != KErrNone)
+ {
+ return result;
+ }
+ server.Resume();
+ server.Close();
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// RRsfwSession::SendRequest
+// ----------------------------------------------------------------------------
+//
+TInt RRsfwSession::SendRequest(TInt aOpCode, TInt aDrive, TIpcArgs aArgs)
+ {
+ TInt result = SendReceive(aOpCode, aArgs);
+ if (result == KErrServerTerminated)
+ {
+ // try to restart the server
+ result = Connect();
+ if (result == KErrNone)
+ {
+ result = SendReceive(aOpCode, aArgs);
+ }
+ }
+
+ // Disable following codes will fix auto connection of rsfw
+ /*
+ if (result == KErrNotReady)
+ {
+ // try to restore the mount
+ result = SendReceive(EMountByDriveLetter, TIpcArgs(aDrive));
+ if (result == KErrNone)
+ {
+ result = SendReceive(aOpCode, aArgs);
+ }
+ }
+ */
+
+ return result;
+ }
+
+// End of File