remotestoragefw/mountmanager/src/rsfwbootmounter.cpp
changeset 13 6b4fc789785b
parent 2 c32dc0be5eb4
equal deleted inserted replaced
2:c32dc0be5eb4 13:6b4fc789785b
     1 /*
       
     2 * Copyright (c) 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:  Mounts during boot remote drives configured in CenRep
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include <f32file.h>	// link against efsrv.lib
       
    20 #include <centralrepository.h> // link against centralrepository.lib 
       
    21 #include <f32fsys.h>
       
    22 
       
    23 // for the file server client side API   
       
    24 _LIT(KRemoteFSName, "RemoteFS");
       
    25 _LIT(KRemoteFs, "eremotefs");
       
    26    
       
    27    
       
    28 // for the central repository API   
       
    29 enum TMountEntryItemIndex
       
    30     {
       
    31     EMountEntryItemIndex, 
       
    32     EMountEntryItemName,
       
    33     EMountEntryItemDrive,
       
    34     EMountEntryItemUri,
       
    35     EMountEntryItemUserName,
       
    36     EMountEntryItemPassword,
       
    37     EMountEntryItemIap,
       
    38     EMountEntryItemInactivityTimeout,
       
    39     EMountEntryItemReserved,
       
    40     EMountEntryItemCount
       
    41     };
       
    42 const TUid  KCRUidRsfwCtrl = { 0x101F9775 }; // RSFW cenrep table id
       
    43 const TUint KColumnName       = EMountEntryItemName;
       
    44 const TUint KColumnMask       = 0x000000ff; 
       
    45 const TUint KRowMask          = 0xffffff00;
       
    46 const TInt KMaxFileSystemName = 256;
       
    47 const TInt KMaxDriveLetterLength = 5;
       
    48 const TInt KMaxFriendlyNameLength = 20;
       
    49  
       
    50 
       
    51 //  isRsfwFileSystem
       
    52 //
       
    53 //  Checks whether certain drive has rsfw file system mounted on it
       
    54 //
       
    55 //  
       
    56 LOCAL_C TBool isRsfwFileSystemL(TInt aDrive,
       
    57                               TDriveList aDriveList,
       
    58                               RFs aFsSession) 
       
    59     {
       
    60     TBool rsfwFileSystem = EFalse;
       
    61     // check first KDriveAttRemote bit as if that is missing it is a quick way 
       
    62     // to conclude that this is not a rsfw mount
       
    63     if (aDriveList[aDrive] & KDriveAttRemote) 
       
    64         {
       
    65         TInt err;
       
    66         HBufC* filesystemName = HBufC::NewL(KMaxFileSystemName);
       
    67         TPtr itemPtr = filesystemName->Des();
       
    68         err = aFsSession.FileSystemName(itemPtr, aDrive);
       
    69         if (!err && (itemPtr.Compare(KRemoteFSName) == 0)) 
       
    70             {
       
    71             rsfwFileSystem = ETrue;
       
    72             }
       
    73         delete filesystemName;
       
    74         }
       
    75     return rsfwFileSystem;
       
    76     }
       
    77  
       
    78  
       
    79  
       
    80 //  DoMountL
       
    81 //
       
    82 //  Do either simple mount or replace (our) existing mount
       
    83 //  by doing dismount and mount
       
    84 //
       
    85 //  
       
    86 LOCAL_C TInt DoMount(TInt aDrive, RFs aFsSession, TBool aReplaceExisting)
       
    87 
       
    88     {
       
    89     TInt err;
       
    90     if (aReplaceExisting) 
       
    91         {
       
    92         // ignore dismount error code
       
    93         aFsSession.DismountFileSystem(KRemoteFSName, aDrive);
       
    94         err = aFsSession.MountFileSystem(KRemoteFSName, aDrive);
       
    95         }
       
    96     else 
       
    97         {
       
    98         err = aFsSession.MountFileSystem(KRemoteFSName, aDrive);
       
    99         }
       
   100     return err;
       
   101     }
       
   102  
       
   103 
       
   104 //  ExecuteFileServerMountL
       
   105 //
       
   106 //  Attempts to mount our file system to the file server
       
   107 //
       
   108 // 
       
   109 LOCAL_C TInt ExecuteFileServerMountL(TInt aDrive,
       
   110                                     TDriveList aDriveList,
       
   111                                     RFs aFsSession)
       
   112     {
       
   113     TInt err;
       
   114     if (aDriveList[aDrive]) 
       
   115         {
       
   116         if (isRsfwFileSystemL(aDrive, aDriveList, aFsSession)) 
       
   117             {
       
   118             err = DoMount(aDrive, aFsSession, ETrue);
       
   119             }
       
   120         else 
       
   121             {
       
   122             // the drive we attempt to mount contains some other file system
       
   123             return KErrInUse;
       
   124             }
       
   125         }
       
   126     else 
       
   127         {
       
   128         // the drive we attempt to mount does not contain an existing mount
       
   129         err = DoMount(aDrive, aFsSession, EFalse);
       
   130         }
       
   131     return err;
       
   132     }
       
   133 
       
   134 
       
   135 //  SetFriendlyNameL
       
   136 //  
       
   137 //  Sets the friendly name of the remote drive to 
       
   138 //  mounted fs drivename and volumename fields
       
   139 //  (to the volume name field first 11 chars)
       
   140 //
       
   141 //  This function assumes that we are allowed to manipulate
       
   142 //  drive aDrive, in practise that ExecuteFileServerMount()
       
   143 //  has been called succesfully
       
   144 // 
       
   145 LOCAL_C TInt SetFriendlyName(TInt aDrive,
       
   146                              TDesC& aFriendlyName,
       
   147                              RFs aFsSession)
       
   148     {
       
   149     TInt err;
       
   150     err = aFsSession.SetDriveName(aDrive, aFriendlyName);
       
   151     if (!err) 
       
   152         {
       
   153         TPtrC volumeNamePtr = aFriendlyName.Left(KMaxVolumeNameLength);
       
   154         err = aFsSession.SetVolumeLabel(volumeNamePtr, aDrive);
       
   155         }
       
   156     return err;
       
   157     }
       
   158 
       
   159 // ----------------------------------------------------------------------------
       
   160 // SyncConfiguredRemoteDrivesL
       
   161 // adds RSFW File Server plug-in 
       
   162 // and synchronizes Central Repository's view of configured remote drives 
       
   163 // with File Server's view (mounts the remote drives configured in CR and
       
   164 // unmounts those remote drives that are not anymore configured)   
       
   165 // ----------------------------------------------------------------------------
       
   166 //  
       
   167 LOCAL_C void SyncConfiguredRemoteDrivesL()
       
   168     {  
       
   169     TInt err = 0;
       
   170     TInt row = 0;
       
   171     TInt driveNumber = 0;
       
   172     RFs fs;
       
   173     TChar paramLetter(90);
       
   174     TBool paramSet = EFalse;
       
   175     
       
   176     User::LeaveIfError(fs.Connect());
       
   177     CleanupClosePushL(fs);
       
   178     
       
   179     // it is possible to manipulate only one drive letter, and give that as an argument
       
   180     TInt clinelength = User::CommandLineLength();
       
   181     if (clinelength > 0) 
       
   182         {
       
   183         HBufC* cl = HBufC::NewL(clinelength);
       
   184         TPtr linePtr = cl->Des();
       
   185         User::CommandLine(linePtr);
       
   186         TLex lex(linePtr);
       
   187         paramLetter = lex.Get();
       
   188         paramSet = ETrue;
       
   189         delete cl;
       
   190         }
       
   191     
       
   192  	// add our file system plugin to the file server
       
   193     err = fs.AddFileSystem(KRemoteFs);
       
   194     if ((err != KErrNone) && (err != KErrAlreadyExists)) 
       
   195     	{
       
   196     	User::Leave(err);
       
   197     	}
       
   198     	
       
   199     // Get a list of drives in the File Server
       
   200     TDriveList drives;
       
   201     User::LeaveIfError(fs.DriveList(drives, KDriveAttAll));  
       
   202     // 	(drives[i] & KDriveAttRemote) now tells whether i:th drive is remote
       
   203     
       
   204     // Get a list of remote drives in the central repository table
       
   205     
       
   206     // connect
       
   207    	CRepository* cenrep;
       
   208     cenrep = CRepository::NewL(KCRUidRsfwCtrl);
       
   209     CleanupStack::PushL(cenrep);
       
   210     
       
   211      // find all entries by name
       
   212     RArray<TUint32> nameIds;
       
   213     CleanupClosePushL(nameIds);
       
   214     err = cenrep->FindL(KColumnName, KColumnMask, nameIds);
       
   215     if (!err)
       
   216     	{
       
   217     	// for each remote drive entry, represented by a record in central repository, do the following:
       
   218     	// 1) get drive letter from central repository
       
   219     	// 2) based on drive letter acquire corresponding drive number from the File Server
       
   220     	// 3) check whether in the File Server there is already mounted a drive with given number
       
   221     	//    3.1) if there is NOT, then mount the drive
       
   222     	//    3.2) if there is and it appears to be remote, then do re-mounting
       
   223     	//    3.3) if there is and it appears NOT to be remote, then this means error
       
   224     	// 4) still for the same record from central repository, get the name of the drive
       
   225     	// 5) use this name as the volume label in the File Server
       
   226     	for (row = 0; row < nameIds.Count(); row++)
       
   227         	{
       
   228         	TUint rowId = (nameIds[row] & KRowMask);
       
   229         	// don't touch zero row as it DOES NOT contain info about mounted drives
       
   230         	if (rowId > 0) 
       
   231         	    {
       
   232         	    TInt i;
       
   233             	// mount it to the file server
       
   234             	
       
   235             	// get drive number
       
   236             	TBuf<KMaxDriveLetterLength> driveLetter;
       
   237             	i = EMountEntryItemDrive;
       
   238             	User::LeaveIfError(cenrep->Get(rowId | i, driveLetter));
       
   239             	
       
   240             	// driveNumber needed in any case, so that we can mark this as existing drive
       
   241             	if (driveLetter.Length() > 0) 
       
   242             	    {
       
   243             	    User::LeaveIfError(fs.CharToDrive((driveLetter)[0], driveNumber));
       
   244             	    }
       
   245             	 else 
       
   246             	    {
       
   247             	    User::Leave(KErrBadName);
       
   248             	    }
       
   249             	
       
   250             	// proceed this drive if we didn't get any drive
       
   251             	// letter as a parameter or we got this one
       
   252                 if ((!paramSet) || (paramLetter ==  driveLetter[0]))
       
   253                     {
       
   254                     // get friendly name
       
   255             	    TBuf<KMaxFriendlyNameLength> friendlyName;
       
   256             	    i = EMountEntryItemName;
       
   257             	    User::LeaveIfError(cenrep->Get(rowId | i, friendlyName));
       
   258             	
       
   259             	    if (friendlyName.Length() > 0) 
       
   260             	        {
       
   261             		    User::LeaveIfError(ExecuteFileServerMountL(driveNumber, drives, fs));
       
   262             		    User::LeaveIfError(SetFriendlyName(driveNumber, friendlyName,fs));		
       
   263             		    }
       
   264             	
       
   265             	    else
       
   266             		    {
       
   267             		    User::Leave(KErrBadName);
       
   268             		    }
       
   269                     }
       
   270                     
       
   271             	// do not unmount this drive as it is still in the CenRep table
       
   272             	// after this loop non-zero drives are used to see 
       
   273             	// which remote drives should be unmounted	
       
   274             	drives[driveNumber] = 0; 
       
   275         	    }
       
   276             } // loop
       
   277     	}
       
   278     	
       
   279     	// If drives now contain some remote drives, this means that they are not 
       
   280     	// anymore configured in CenRep and should be unmounted. 
       
   281        	for (int i = 0; i < EDriveZ; i++) 
       
   282        		{
       
   283        		if (isRsfwFileSystemL(i, drives, fs))
       
   284        			{
       
   285        			fs.DismountFileSystem(KRemoteFSName, i);
       
   286        			}
       
   287        		}
       
   288     
       
   289     CleanupStack::PopAndDestroy(3, &fs);   // fs, cenrep, nameIds
       
   290     
       
   291     }
       
   292     
       
   293 // ----------------------------------------------------------------------------
       
   294 // E32Main
       
   295 // 
       
   296 // ----------------------------------------------------------------------------
       
   297 //   
       
   298 GLDEF_C TInt E32Main() 
       
   299     {
       
   300     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   301     TRAPD(err, SyncConfiguredRemoteDrivesL());
       
   302     delete cleanupStack;
       
   303     return err;
       
   304     }
       
   305 
       
   306 
       
   307 // End of file