remotestoragefw/remotefilesystemplugin/src/rsfwfsmountcb.cpp
changeset 0 3ad9d5175a89
equal deleted inserted replaced
-1:000000000000 0:3ad9d5175a89
       
     1 /*
       
     2 * Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  File server interface class representing a mount.
       
    15 *                An instance of this object is referred to as
       
    16 *                a mount control block.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 #include "rsfwfsmountcb.h"
       
    24 #include "rsfwfsfilecb.h"
       
    25 #include "rsfwfsdircb.h"
       
    26 
       
    27 
       
    28 // there is no good way to give remote storage size so just put some big numbers here
       
    29 const TInt KMountReportedSize         = 999999999;
       
    30 const TInt KMountReportedFreeSize     = 999999999;
       
    31 
       
    32 // ============================ MEMBER FUNCTIONS ===============================
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // CRsfwFsMountCB::NewL
       
    36 // C++ default constructor can NOT contain any code, that
       
    37 // might leave.
       
    38 // -----------------------------------------------------------------------------
       
    39 //
       
    40 CRsfwFsMountCB* CRsfwFsMountCB::NewL()
       
    41     {
       
    42     CRsfwFsMountCB* remoteFsMntCB = new(ELeave) CRsfwFsMountCB();
       
    43     return remoteFsMntCB;
       
    44     }
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 // CRsfwFsMountCB::CRsfwFsMountCB
       
    48 // C++ default constructor can NOT contain any code, that
       
    49 // might leave.
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CRsfwFsMountCB::CRsfwFsMountCB()
       
    53     {
       
    54    
       
    55     }
       
    56 
       
    57 // Destructor
       
    58 CRsfwFsMountCB::~CRsfwFsMountCB()
       
    59     {   
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CRsfwFsMountCB::MountL
       
    64 // The function should set the volume name (iVolumeName), the unique ID 
       
    65 // (iUniqueID) and the volume size (iSize) by reading and processing the current 
       
    66 // mount. The function should leave, on error detection, with an appropriate error 
       
    67 // code. When aForceMount is set to ETrue, the properties of a corrupt volume 
       
    68 // should be forcibly stored. The classic case of when this is desirable is when a 
       
    69 // corrupt volume needs to be formatted.
       
    70 //
       
    71 // We set the values (iSize to a fixed size). We also create a
       
    72 // File Server session (needed to access the local cache) and put the handle into 
       
    73 // the TLS for future access. aForceMount is ignored.
       
    74 // Note that this operation does not attempt to connect to remote server.
       
    75 //
       
    76 // (other items were commented in a header).
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 void CRsfwFsMountCB::MountL(
       
    80     TBool /* aForceMount */)
       
    81     {
       
    82     
       
    83     iServerName = HBufC::NewL( KMaxVolumeNameLength);
       
    84     TPtr serverName (iServerName->Des());
       
    85     serverName.Append(KRemoteVolumeName);
       
    86     SetVolumeName(iServerName); 
       
    87        
       
    88     TTime timeID;
       
    89     timeID.HomeTime();
       
    90     iUniqueID = I64LOW(timeID.Int64());
       
    91     iSize = KMountReportedSize;
       
    92     
       
    93     User::LeaveIfError(iFsSession.Connect());
       
    94     User::LeaveIfError(Dll::SetTls(&iFsSession));
       
    95     
       
    96     iRootFid.iVolumeId = Drive().DriveNumber();
       
    97     iRootFid.iNodeId = 1;
       
    98     }
       
    99 
       
   100 
       
   101 // -----------------------------------------------------------------------------
       
   102 // CRsfwFsMountCB::ReMount
       
   103 // The function should check whether the mount control block represents the 
       
   104 // current mount on the associated drive. The function should read mount 
       
   105 // information from the current volume, and check it against the mount 
       
   106 // information from this mount - typically iVolumeName and iUniqueID. If the mount 
       
   107 // information matches, the function should return KErrNone, otherwise it should 
       
   108 // return KErrGeneral.
       
   109 // (other items were commented in a header).
       
   110 // -----------------------------------------------------------------------------
       
   111 //
       
   112 int CRsfwFsMountCB::ReMount()
       
   113     {
       
   114     // we assume that this operation - if called on remote drive
       
   115     // - can be succesfull
       
   116     return KErrNone;
       
   117     
       
   118     }
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 // CRsfwFsMountCB::Dismounted
       
   122 // Carries out clean-up necessary for a volume dismount:
       
   123 // Closing the session to the File Server used for local cache.
       
   124 // Closing the session to Remote File Engine.
       
   125 // Dismounting a volume will always succeed, so the function does not need to 
       
   126 // return an error value. 
       
   127 // (other items were commented in a header).
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 void CRsfwFsMountCB::Dismounted()
       
   131     {
       
   132       
       
   133     iSession->Close();  
       
   134     iFsSession.Close();
       
   135     
       
   136     }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // CRsfwFsMountCB::VolumeL
       
   140 // Gets volume information. The only information that the function has to supply 
       
   141 // is the free space, TVolumeInfo::iFree, since the remaining members have already 
       
   142 // been set by the calling function. The function should leave, on error detection, 
       
   143 // with an appropriate error code.
       
   144 // (other items were commented in a header).
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 void CRsfwFsMountCB::VolumeL(
       
   148     TVolumeInfo& aVolume) const
       
   149     {
       
   150       
       
   151     // : we should return info about free storage
       
   152     // at the remote server, if possible...
       
   153     aVolume.iFree = KMountReportedFreeSize;
       
   154     
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CRsfwFsMountCB::SetVolumeL
       
   159 // Sets the volume name for the mount, thus writing the new volume name to the 
       
   160 // corresponding volume.
       
   161 // (other items were commented in a header).
       
   162 // -----------------------------------------------------------------------------
       
   163 //
       
   164 void CRsfwFsMountCB::SetVolumeL(
       
   165     TDes& aName)
       
   166     {   
       
   167       
       
   168     if (aName.Length() >  KMaxVolumeNameLength) 
       
   169         {
       
   170         User::Leave(KErrBadName);
       
   171         }
       
   172     if (iServerName) 
       
   173         {
       
   174         delete iServerName;
       
   175         iServerName = NULL;
       
   176         }
       
   177     iServerName = HBufC::NewL( KMaxVolumeNameLength);
       
   178     TPtr serverName (iServerName->Des());
       
   179     serverName.Append(aName);
       
   180     SetVolumeName(iServerName);
       
   181     
       
   182     }
       
   183     
       
   184 // -----------------------------------------------------------------------------
       
   185 // CRsfwFsMountCB::MkDirL
       
   186 // Creates a new directory on the mount by figuring out the FID of the parent
       
   187 // directory and the name of the child to be created.
       
   188 //
       
   189 // The full name in aName is in the form:
       
   190 //    \\dirA\\dirB\\dirC\\dirD  
       
   191 // where dirD is the new directory to be created in \\dirA\\dirB\\dirC\\.
       
   192 // This means that dirC is the leaf directory in which dirD will be created.
       
   193 //    
       
   194 // (other items were commented in a header).
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 void CRsfwFsMountCB::MkDirL(
       
   198     const TDesC& aName)
       
   199     {
       
   200       
       
   201     TInt delimiterPos;
       
   202     TPtrC directory, path;
       
   203     TFid theFid;
       
   204   
       
   205     delimiterPos = aName.LocateReverse(KPathDelimiter);
       
   206     directory.Set(aName.Right(aName.Length() - (delimiterPos + 1)));
       
   207     path.Set(aName.Left(delimiterPos + 1)); 
       
   208     theFid = FetchFidL(path, KNodeTypeDir);
       
   209     User::LeaveIfError(RSessionL()->MakeDirectory(theFid, directory));
       
   210        
       
   211     }
       
   212 
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // CRsfwFsMountCB::RmDirL
       
   216 // Removes the directory specified by aName by figuring out the FID of the parent
       
   217 // directory and the name of the child to be created. The function can assume 
       
   218 // that the directory exists and is not read-only. 
       
   219 //
       
   220 // The directory specified by aName is in the form:
       
   221 //    \\dirA\\dirB\\dirC\\dirD  
       
   222 // where dirD is the directory to be removed from \\dirA\\dirB\\dirC\\.
       
   223 // This means that dirC is the leaf directory from which dirD should be removed.
       
   224 //
       
   225 // (other items were commented in a header).
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 void CRsfwFsMountCB::RmDirL(
       
   229     const TDesC& aName)
       
   230     {
       
   231      
       
   232     TInt delimiterPos;
       
   233     TPtrC directory, path;
       
   234     TFid parentFid;
       
   235         
       
   236     delimiterPos = aName.LocateReverse(KPathDelimiter);
       
   237     directory.Set(aName.Right(aName.Length() - (delimiterPos + 1)));
       
   238     path.Set(aName.Left(delimiterPos + 1)); 
       
   239     parentFid = FetchFidL(path, KNodeTypeDir);
       
   240     User::LeaveIfError(RSessionL()->RemoveDirectory(parentFid, directory));
       
   241         
       
   242     }
       
   243 
       
   244 // -----------------------------------------------------------------------------
       
   245 // CRsfwFsMountCB::DeleteL
       
   246 // Deletes the specified file from the mount by figuring out the FID of the parent
       
   247 // directory and the name of the child to be created. The function can assume that 
       
   248 // the file is closed.
       
   249 //
       
   250 //  The file name specified by aName is of the form:
       
   251 //    \\dirA\\dirB\\dirC\\file.ext    
       
   252 //  The extension is optional.
       
   253 //
       
   254 // (other items were commented in a header).
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 
       
   258 void CRsfwFsMountCB::DeleteL(
       
   259     const TDesC& aName)
       
   260     {  
       
   261  
       
   262     TInt delimiterPos;
       
   263     TPtrC file, path;
       
   264     TFid parentFid;
       
   265     
       
   266     delimiterPos = aName.LocateReverse(KPathDelimiter);
       
   267     file.Set(aName.Right(aName.Length() - (delimiterPos + 1)));
       
   268     path.Set(aName.Left(delimiterPos + 1)); 
       
   269     parentFid = FetchFidL(path, KNodeTypeDir);
       
   270     User::LeaveIfError(RSessionL()->RemoveFile(parentFid, file));      
       
   271     
       
   272     }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CRsfwFsMountCB::RenameL
       
   276 // Renames or moves a single file or directory on the mount by figuring out
       
   277 // the FIDs of the parent directories and child names for both anOldName and 
       
   278 // anNewName.  If oldEntryName is a file, it can be assumed that it is closed.
       
   279 // If oldEntryName is a directory, it can be assumed that there are no
       
   280 // open files in this directory. Furthermore, if newEntryName specifies
       
   281 // a directory, it can be assumed that it is not a subdirectory of oldEntryName.
       
   282 //
       
   283 // anOldName and anNewName specify the respective entries with full names; 
       
   284 // for example,
       
   285 // \\dirA\\dirB\\dirC\\oldEntryName
       
   286 // and
       
   287 // \\dirE\\dirF\\dirG\\newEntryName
       
   288 //   
       
   289 // (other items were commented in a header).
       
   290 // -----------------------------------------------------------------------------
       
   291 //
       
   292 void CRsfwFsMountCB::RenameL(
       
   293     const TDesC& anOldName, 
       
   294     const TDesC& aNewName)
       
   295     {
       
   296       
       
   297     TInt delimiterPos;
       
   298     TPtrC sourcepath, destpath;
       
   299     TPtrC srcname, destname;
       
   300     TFid sourceFid, destFid;
       
   301 
       
   302     delimiterPos = anOldName.LocateReverse(KPathDelimiter);
       
   303     srcname.Set(anOldName.Right(anOldName.Length() - (delimiterPos + 1)));  
       
   304     sourcepath.Set(anOldName.Left(delimiterPos + 1));   
       
   305     sourceFid = FetchFidL(sourcepath, KNodeTypeDir);
       
   306 
       
   307     delimiterPos = aNewName.LocateReverse(KPathDelimiter);
       
   308     destname.Set(aNewName.Right(aNewName.Length() - (delimiterPos + 1)));
       
   309     destpath.Set(aNewName.Left(delimiterPos + 1));  
       
   310     destFid = FetchFidL(destpath, KNodeTypeDir);
       
   311 
       
   312     User::LeaveIfError(RSessionL()->MoveFids(sourceFid, 
       
   313         										  srcname, 
       
   314         										  destFid, 
       
   315         										  destname, 
       
   316         										  EFalse));    
       
   317         
       
   318  
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CRsfwFsMountCB::ReplaceL
       
   323 // Replaces one file on the mount with another. The file anOldName should have 
       
   324 // its contents, attributes, and the universal date and time of its last 
       
   325 // modification, copied to the file aNewName, overwriting any existing contents 
       
   326 // and attribute details. If the file aNewName does not exist it should be created.
       
   327 // The function can assume that both anOldName and, if it exists, anNewName
       
   328 // contain the full file names of files, and that these files are not open.
       
   329 // (other items were commented in a header).
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CRsfwFsMountCB::ReplaceL(
       
   333     const TDesC&  anOldName, 
       
   334     const TDesC& aNewName )
       
   335     {
       
   336    
       
   337     TInt delimiterPos;
       
   338     TPtrC sourcepath, destpath;
       
   339     TPtrC srcname, destname;
       
   340     TFid sourceFid, destFid;
       
   341 
       
   342     delimiterPos = anOldName.LocateReverse(KPathDelimiter);
       
   343     srcname.Set(anOldName.Right(anOldName.Length() - (delimiterPos + 1)));
       
   344     sourcepath.Set(anOldName.Left(delimiterPos + 1));   
       
   345     sourceFid = FetchFidL(sourcepath, KNodeTypeDir);
       
   346 
       
   347     delimiterPos = aNewName.LocateReverse(KPathDelimiter);
       
   348     destname.Set(aNewName.Right(aNewName.Length() - (delimiterPos + 1)));
       
   349     destpath.Set(aNewName.Left(delimiterPos + 1));  
       
   350     destFid = FetchFidL(destpath, KNodeTypeDir);
       
   351         
       
   352     User::LeaveIfError(RSessionL()->MoveFids(sourceFid, 
       
   353         										  srcname, 
       
   354         										  destFid, 
       
   355         										  destname, 
       
   356         										  ETrue)); 
       
   357     
       
   358    
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CRsfwFsMountCB::EntryL
       
   363 // Gets the entry details for the specified file or directory.
       
   364 // This function is defined as a const function in the base class CMountCB.
       
   365 // However, we need to modify the shared memory chunks used in the parameter 
       
   366 // passing. That's why we need  to cast away const.
       
   367 //
       
   368 // Always returns KErrPathNotFoud for certain Symbian system directories. The 
       
   369 // reason for this is that scanning all drives for some system directory does
       
   370 // not always skip remote drives, but it is not feasible to start to look
       
   371 // for some library, recognizer etc. from a remote drive.
       
   372 //
       
   373 // (other items were commented in a header).
       
   374 // -----------------------------------------------------------------------------
       
   375 //
       
   376 void CRsfwFsMountCB::EntryL(
       
   377     const TDesC& aName, 
       
   378     TEntry& anEntry) const
       
   379     {
       
   380     
       
   381     if (aName.Length() > KMaxPath) 
       
   382     	{
       
   383     	User::Leave(KErrBadName);
       
   384     	}
       
   385         
       
   386     CONST_CAST(CRsfwFsMountCB*, this)->RemoteFsEntryL(aName, anEntry);
       
   387     
       
   388     }
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // CRsfwFsMountCB::RemoteFsEntryL
       
   392 // Gets the entry details for the specified file or directory by figuring out
       
   393 // the fid of the entry.
       
   394 // (other items were commented in a header).
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 void CRsfwFsMountCB::RemoteFsEntryL(const TDesC& aName, TEntry& anEntry)
       
   398     {
       
   399       
       
   400     anEntry.iName = aName;
       
   401     TFid fileFid = FetchFidL(aName, KNodeTypeUnknown); 
       
   402     User::LeaveIfError(RSessionL()->GetAttributes(fileFid, anEntry));
       
   403       
       
   404     }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CRsfwFsMountCB::SetEntryL
       
   408 // Sets entry details for a specified file or directory. 
       
   409 // The entry identified by the full name descriptor aName should have
       
   410 // its modification time and its attributes mask updated as required.
       
   411 // We also use this function to control (using new attributes bits) the file 
       
   412 // caching state (KEntryAttCachePriorityHigh)
       
   413 // 
       
   414 // The entry receives a new universal modified time from aTime.
       
   415 // The entry attributes are set with aSetAttMask and cleared with aClearAttMask:
       
   416 // the bits that are set in aSetAttMask should be set in the entry attribute mask;
       
   417 // the bits that are set in aClearAttMask should be cleared from the entry 
       
   418 // attribute mask.
       
   419 //
       
   420 // The function can assume that aSetAttMask and aClearAttMask do not change
       
   421 // the type of attribute (i.e. volume or directory). Furthermore, if aName
       
   422 // specifies a file, it can be assumed that this file is closed.
       
   423 //
       
   424 // (other items were commented in a header).
       
   425 // -----------------------------------------------------------------------------
       
   426 //
       
   427 void CRsfwFsMountCB::SetEntryL(
       
   428     const TDesC& aName,
       
   429     const TTime& aTime,
       
   430     TUint aSetAttMask,
       
   431     TUint aClearAttMask)
       
   432     {
       
   433         
       
   434     TFid thisFid;
       
   435     thisFid = FetchFidL(aName, KNodeTypeUnknown);
       
   436     
       
   437     TInt result = RSessionL()->SetEntry(thisFid, aTime, aSetAttMask, aClearAttMask);
       
   438     
       
   439     // KErrNotSupported is dismissed currently
       
   440     // The reason for this is CFileMan::Copy
       
   441     // CFileMan::Copy is a composite operation which as a last step
       
   442     // calls RFs::SetAtt() for the target file.
       
   443     // If we honestly return KErrNotSupported CFileMan::Copy will now
       
   444     // return KErrNotSupported also, although it already copied the file on the server.
       
   445     // We rather have a working copy and return false information about the success of 
       
   446     // SetAtt().
       
   447     if ((result != KErrNone) && (result != KErrNotSupported))
       
   448         {
       
   449         User::Leave(result);
       
   450         }
       
   451     
       
   452     }
       
   453 
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CRsfwFsMountCB::FileOpenL
       
   457 // If needed creates a new file by figuring out the FID of the parent directory 
       
   458 // and the name of the new file. After that opens the file. After successful 
       
   459 // completion of the function, the file control block pointer will be added to the 
       
   460 // file server's global files container.  Adds information to the file control 
       
   461 // block (e.g. path of the local cache file and pointer to this mount control block)
       
   462 //
       
   463 // If anOpen specifies EFileReplace (rather than EFileCreate or EFileOpen) then
       
   464 // the data contained in the file should be discarded, the archive attribute 
       
   465 // should be set, and the size of the file should be set to zero. Note that it can 
       
   466 // be assumed that if anOpen specifies EFileReplace then the file already exists.
       
   467 //
       
   468 // (other items were commented in a header).
       
   469 // -----------------------------------------------------------------------------
       
   470 //
       
   471 void CRsfwFsMountCB::FileOpenL(
       
   472     const TDesC& aName,
       
   473     TUint aMode,
       
   474     TFileOpen anOpen,
       
   475     CFileCB* aFile)
       
   476     {
       
   477 
       
   478     TFid parentFid;
       
   479     TFid thisFid;
       
   480     TInt delimiterPos;
       
   481     TPtrC filename, path;
       
   482     delimiterPos = aName.LocateReverse(KPathDelimiter);
       
   483     filename.Set(aName.Right(aName.Length() - (delimiterPos + 1)));
       
   484     path.Set(aName.Left(delimiterPos + 1)); 
       
   485     parentFid = FetchFidL(path, KNodeTypeDir);
       
   486        
       
   487     switch (anOpen)
       
   488         {
       
   489     case EFileCreate:
       
   490         // exclusive = 1 
       
   491         User::LeaveIfError(RSessionL()->
       
   492       		CreateFile(parentFid, filename, aMode, TRUE, thisFid));
       
   493         break;
       
   494     case EFileReplace: 
       
   495         // exclusive = 0 
       
   496         User::LeaveIfError(RSessionL()->
       
   497         	CreateFile(parentFid, filename, aMode, FALSE, thisFid));
       
   498         break;
       
   499     case EFileOpen: // the file must exist
       
   500     default:
       
   501         User::LeaveIfError(RSessionL()->
       
   502 			Lookup(parentFid, filename, KNodeTypeFile, thisFid));
       
   503         break;
       
   504         } 
       
   505     
       
   506     TDirEntAttr attributes;
       
   507     HBufC* unicodepath = HBufC::NewMaxLC(KMaxPath);
       
   508     TPtr unicodepathptr(unicodepath->Des());
       
   509     attributes.iAtt = aMode;
       
   510     User::LeaveIfError(RSessionL()->
       
   511     				   OpenByPath(thisFid, unicodepathptr, &attributes, ETrue));
       
   512     unicodepathptr.SetLength(unicodepath->Length());
       
   513     
       
   514     ((CRsfwFsFileCB*)aFile)->iLastFlushFailed = EFalse;
       
   515     ((CRsfwFsFileCB*)aFile)->iThisFid = thisFid;
       
   516     ((CRsfwFsFileCB*)aFile)->iParentFid = parentFid;
       
   517     ((CRsfwFsFileCB*)aFile)->SetContainerFileL(unicodepathptr);
       
   518   	// set size, att, modified for the file
       
   519   	((CRsfwFsFileCB*)aFile)->SetSize(attributes.iSize);
       
   520   	((CRsfwFsFileCB*)aFile)->SetAtt(attributes.iAtt);
       
   521   	((CRsfwFsFileCB*)aFile)->SetModified(attributes.iModified);
       
   522     aFile->SetMount(this);
       
   523     CleanupStack::PopAndDestroy(unicodepath); // unicodepath
       
   524     
       
   525     }
       
   526  
       
   527 // -----------------------------------------------------------------------------
       
   528 // CRsfwFsMountCB::DirOpenL
       
   529 // Opens a directory on the mount by figuring out the FID of the parent 
       
   530 // directory and the name of the directory. 
       
   531 // Note that aName is of the form
       
   532 //  \\dirA\\dirB\\dirC\\file.ext
       
   533 // where \\dirA\\dirB\\dirC\\ is the directory to be opened and file.ext is
       
   534 // an optional entry name and extension. The name and extension (e.g. "*" or 
       
   535 // "*.txt") limit entries that reading the directory should return.
       
   536 // 
       
   537 // Always returns KErrPathNotFoud for certain Symbian system directories. The 
       
   538 // reason for this is that scanning all drives for some system directory does
       
   539 // not always skip remote drives, but it is not feasible to start to look
       
   540 // for some library, recognizer etc. from a remote drive.
       
   541 //
       
   542 // After successful completion of the function, the directory control block
       
   543 // pointer will be added to the file server global directories container. Adds 
       
   544 // information to the directory control block (e.g. path of the local cache file 
       
   545 // and possible name and extension)
       
   546 // (other items were commented in a header).
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 void CRsfwFsMountCB::DirOpenL(
       
   550     const TDesC& aName, 
       
   551     CDirCB* aDir)
       
   552     {
       
   553             
       
   554     TFid fileFid;
       
   555     TInt namePos;
       
   556     namePos = aName.LocateReverse(KPathDelimiter);
       
   557     TPtrC directoryPathName(aName.Left(namePos + 1));
       
   558     TPtrC matchName(aName.Mid(namePos + 1));
       
   559     if (matchName.Length() == 0)
       
   560         {
       
   561         matchName.Set(KDirReadAllMask);
       
   562         }
       
   563     if (directoryPathName.Length() == 0)
       
   564         {
       
   565         fileFid = iRootFid;
       
   566         }
       
   567     else
       
   568         {
       
   569         fileFid = FetchFidL(directoryPathName, KNodeTypeDir);
       
   570         }   
       
   571 
       
   572     HBufC* unicodepath = HBufC::NewMaxLC(KMaxPath);
       
   573     TPtr unicodepathptr(unicodepath->Des());
       
   574     User::LeaveIfError(RSessionL()->
       
   575     				   OpenByPath(fileFid, unicodepathptr, NULL, EFalse));
       
   576     ((CRsfwFsDirCB*)aDir)->SetDirL(unicodepathptr, matchName);    
       
   577     ((CRsfwFsDirCB*)aDir)->iThisFid = fileFid;
       
   578     ((CRsfwFsDirCB*)aDir)->SetMount(this);
       
   579     CleanupStack::PopAndDestroy(unicodepath); // unicopath
       
   580    
       
   581     }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // CRsfwFsMountCB::RawReadL
       
   585 // Should read the specified length of data from the specified position on
       
   586 // the volume directly into the client thread. It can be assumed that if this 
       
   587 // function is called, then there has been  a successful mount.
       
   588 // Not supported, as "position in a volume" without files is meaningless to 
       
   589 // us.
       
   590 // (other items were commented in a header).
       
   591 // -----------------------------------------------------------------------------
       
   592 //
       
   593 void CRsfwFsMountCB::RawReadL(
       
   594     TInt64 /* aPos */, 
       
   595     TInt /* aLength */ , 
       
   596     const TAny* /* aTrg */, 
       
   597     TInt /* anOffset */ ,
       
   598     const RMessagePtr2& /* aMessage */) const 
       
   599     {
       
   600       
       
   601     User::Leave(KErrNotSupported);
       
   602     
       
   603     }
       
   604 
       
   605 // -----------------------------------------------------------------------------
       
   606 // CRsfwFsMountCB::RawWriteL
       
   607 // Should write a specified length of data from the client thread to the volume
       
   608 // at the specified position. It can be assumed that if this 
       
   609 // function is called, then there has been  a successful mount.
       
   610 // Not supported, as "position in a volume" without files is meaningless to 
       
   611 // us.
       
   612 // (other items were commented in a header).
       
   613 // -----------------------------------------------------------------------------
       
   614 //
       
   615 void CRsfwFsMountCB::RawWriteL(
       
   616     TInt64 /* aPos */, 
       
   617     TInt /* aLength */, 
       
   618     const TAny* /* aSrc */, 
       
   619     TInt /* anOffset */,
       
   620     const RMessagePtr2& /* aMessage */)
       
   621     {
       
   622       
       
   623     User::Leave(KErrNotSupported);
       
   624     
       
   625     }
       
   626     
       
   627 // -----------------------------------------------------------------------------
       
   628 // CRsfwFsMountCB::GetShortNameL
       
   629 // Should get the short name of the file or directory with the given full name.
       
   630 // This function is used in circumstances where a file system mangles
       
   631 // Symbian OS natural names, in order to be able to store them on
       
   632 // a file system that is not entirely compatible.
       
   633 // (other items were commented in a header).
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 void CRsfwFsMountCB::GetShortNameL(
       
   637     const TDesC& /* aLongName */,
       
   638     TDes& /* aShortName */)
       
   639     {
       
   640          
       
   641     User::Leave(KErrNotSupported);
       
   642     
       
   643     }
       
   644 
       
   645 // -----------------------------------------------------------------------------
       
   646 // CRsfwFsMountCB::GetLongNameL
       
   647 // Should get the long name of the file or directory associated with the given 
       
   648 // short name. This function is used in circumstances where a file system mangles
       
   649 // Symbian OS natural names in order to be able to store them on
       
   650 // a file system that is not entirely compatible. 
       
   651 // (other items were commented in a header).
       
   652 // -----------------------------------------------------------------------------
       
   653 //
       
   654 void CRsfwFsMountCB::GetLongNameL(
       
   655     const TDesC& /* aShortName */,
       
   656     TDes& /* aLongName */)
       
   657     {
       
   658       
       
   659     User::Leave(KErrNotSupported);
       
   660     
       
   661     }
       
   662 
       
   663 // -----------------------------------------------------------------------------
       
   664 // CRsfwFsMountCB::ReadSectionL
       
   665 // Reads a specified section of the file, regardless of the file's lock state.
       
   666 // This function basically does what the chain of opening a file, creating 
       
   667 // the file control block, and reading file data using CRsfwFsFile::Read()
       
   668 // does, but without creating the file control block. For us file's lock state 
       
   669 // does not have meaning.
       
   670 // (other items were commented in a header).
       
   671 // -----------------------------------------------------------------------------
       
   672 //
       
   673 void CRsfwFsMountCB::ReadSectionL(
       
   674     const TDesC& aName,
       
   675     TInt aPos,
       
   676     TAny* /*aTrg */,
       
   677     TInt aLength,
       
   678     const RMessagePtr2& aMessage)
       
   679 
       
   680     {
       
   681 
       
   682     HBufC8* data = HBufC8::NewMaxLC(aLength);
       
   683     TPtr8 buf(data->Des());   
       
   684   
       
   685     TFid parentFid;
       
   686     TFid newFid;
       
   687     TInt delimiterPos;
       
   688     TPtrC filename, path;
       
   689     HBufC* unicodepath = HBufC::NewMaxLC(KMaxPath);
       
   690     TPtr unicodepathptr(unicodepath->Des());
       
   691     
       
   692     delimiterPos = aName.LocateReverse(KPathDelimiter);
       
   693     filename.Set(aName.Right(aName.Length() - (delimiterPos + 1)));
       
   694     path.Set(aName.Left(delimiterPos + 1));
       
   695     parentFid = FetchFidL(path, KNodeTypeDir);
       
   696     User::LeaveIfError(RSessionL()->
       
   697     		Lookup(parentFid, filename, KNodeTypeFile, newFid));
       
   698     User::LeaveIfError(RSessionL()->
       
   699    			OpenByPath(newFid, unicodepathptr, NULL, EFalse));
       
   700    			
       
   701    	// get the size of the container file	
       
   702    	TEntry tentry;
       
   703    	User::LeaveIfError((*(RFs* )Dll::Tls()).Entry(unicodepathptr, tentry));
       
   704     if (aPos > tentry.iSize) 
       
   705         {
       
   706         // non-sequential read 
       
   707         // i.e. if 128 bytes have been cached 
       
   708         // starting read from pos 128 continues to fill the cache file
       
   709         // but starting read from pos 129- is "random access"
       
   710         // that by-passes the cache */
       
   711         RFile tempFile;
       
   712         TBool usetempCache = EFalse;
       
   713         HBufC* tmpcacheFile = HBufC::NewLC(KMaxPath);
       
   714         TPtr tmpCache(tmpcacheFile->Des());
       
   715         User::LeaveIfError(RSessionL()->FetchData(newFid, 
       
   716         										  aPos, 
       
   717         										  aPos + aLength - 1, 
       
   718         										  tmpCache, 
       
   719         										  usetempCache));
       
   720         // if caching mode is "Whole File Caching" this operation may fetch
       
   721         // the whole file into normal cache anyway. "tmpCache" contains
       
   722         // the right path in this case too, so in this function (where the file
       
   723         // is not open), we don't have to check "usetempCache" boolean.									  
       
   724         User::LeaveIfError(tempFile.Open(*(RFs* )Dll::Tls(), tmpCache, EFileRead));
       
   725         CleanupClosePushL(tempFile);
       
   726         User::LeaveIfError(tempFile.Read(buf, aLength));
       
   727         CleanupStack::PopAndDestroy(2, tmpcacheFile); // tempfile, tempcacheFile
       
   728         }
       
   729     else 
       
   730         {
       
   731         TInt lastByte;
       
   732         User::LeaveIfError(RSessionL()->Fetch(newFid, aPos, aPos + aLength-1, lastByte));
       
   733         User::LeaveIfError((*(RFs* )Dll::Tls()).ReadFileSection(*unicodepath,
       
   734                                                                 aPos,
       
   735                                                                 buf,
       
   736                                                                 aLength));
       
   737         }
       
   738     CleanupStack::PopAndDestroy(unicodepath); // unicodepath
       
   739    
       
   740     // we have read the data into buf
       
   741     aMessage.WriteL(0, buf, 0);
       
   742     CleanupStack::PopAndDestroy(data); //  data 
       
   743     
       
   744     }
       
   745 
       
   746 
       
   747    
       
   748 // -----------------------------------------------------------------------------
       
   749 // CRsfwFsMountCB::FetchFidL
       
   750 // Fetches fid for an entry.
       
   751 // aPath is of the form \\dirA\\dirB\\dirC\\entry
       
   752 // Goes through the path recursively. I.e. first gets the fid of dirA by
       
   753 // fid_dirA = lookup(iRootFid, dirA), then does lookup(fid_dirA, dirB) etc. 
       
   754 // (other items were commented in a header).
       
   755 // -----------------------------------------------------------------------------
       
   756 //
       
   757 TFid CRsfwFsMountCB::FetchFidL(
       
   758     const TDesC& aPath, 
       
   759     TUint aNodeType)
       
   760     {
       
   761     TFid newFid;  
       
   762     TInt pathlength = aPath.Length();
       
   763 
       
   764     if (pathlength <= 1)
       
   765         {
       
   766         // '\'
       
   767         // In some rare cases called with zero length aPath,
       
   768         // it seems to be ok to return rootFid
       
   769         return iRootFid;
       
   770         }
       
   771     else
       
   772         {
       
   773         TInt delimiterPos = aPath.LocateReverse(KPathDelimiter);
       
   774         if (delimiterPos == (pathlength - 1))
       
   775             {
       
   776             // The path ends with a slash,
       
   777             //i.e. this is a directory - continue parsing
       
   778             TPtrC nextdelimiter;
       
   779             nextdelimiter.Set(aPath.Left(delimiterPos));
       
   780             delimiterPos = nextdelimiter.LocateReverse(KPathDelimiter);
       
   781             }
       
   782         TPtrC entry(aPath.Right(aPath.Length() - (delimiterPos + 1)));
       
   783         TPtrC path(aPath.Left(delimiterPos + 1));
       
   784         // fetch recursively TFid of path 
       
   785         User::LeaveIfError(RSessionL()->
       
   786 				Lookup(FetchFidL(path, KNodeTypeDir), entry, aNodeType, newFid));
       
   787         return newFid;
       
   788         }
       
   789         
       
   790     }
       
   791 
       
   792 // -----------------------------------------------------------------------------
       
   793 // CRsfwFsMountCB::RenameFidL
       
   794 // Renames a file
       
   795 // (other items were commented in a header).
       
   796 // -----------------------------------------------------------------------------
       
   797 //
       
   798 void CRsfwFsMountCB::RenameFidL( 
       
   799     TFid aDirFid, 
       
   800     const TDesC& aSourceName,
       
   801     const TDesC& aNewName )
       
   802     {
       
   803 
       
   804     TInt delimiterPos;
       
   805     TPtrC destpath, srcname, destname;
       
   806     TFid destFid;
       
   807 
       
   808     delimiterPos = aSourceName.LocateReverse(KPathDelimiter);
       
   809     srcname.Set(aSourceName.Right(aSourceName.Length() - (delimiterPos + 1)));
       
   810 
       
   811     delimiterPos = aNewName.LocateReverse(KPathDelimiter);
       
   812     destname.Set(aNewName.Right(aNewName.Length() - (delimiterPos + 1)));
       
   813     destpath.Set(aNewName.Left(delimiterPos + 1));  
       
   814     destFid = FetchFidL(destpath, KNodeTypeDir);
       
   815 
       
   816     User::LeaveIfError(RSessionL()->MoveFids(aDirFid, 
       
   817     										  srcname, 
       
   818     										  destFid, 
       
   819     										  destname, 
       
   820     										  EFalse));     
       
   821 
       
   822     }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CRsfwFsMountCB::CheckDisk
       
   826 // Checks the integrity of the disk on the specified drive
       
   827 // temporarily return KErrNone as a workaround for CommonDialogs 
       
   828 // should return KErrNotSupported for remote drives
       
   829 // (other items were commented in a header).
       
   830 // -----------------------------------------------------------------------------
       
   831 //
       
   832 TInt CRsfwFsMountCB::CheckDisk()
       
   833     {
       
   834     return KErrNone;
       
   835     }
       
   836 
       
   837 
       
   838 // -----------------------------------------------------------------------------
       
   839 // CRsfwFsMountCB::RSessionL
       
   840 // Singleton-function that creates a session to Remote File Engine once.
       
   841 // (other items were commented in a header).
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 RRsfwSession* CRsfwFsMountCB::RSessionL()
       
   845     { 
       
   846       
       
   847     if (!iSession)
       
   848         {
       
   849         iSession = new (ELeave) RRsfwSession();
       
   850         User::LeaveIfError(iSession->Connect());
       
   851         }     
       
   852     return iSession;
       
   853     
       
   854     }
       
   855 
       
   856 
       
   857 // End of File