/*
* 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