remotestoragefw/mountmanager/src/rsfwbootmounter.cpp
branchRCL_3
changeset 20 1aa8c82cb4cb
parent 0 3ad9d5175a89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/remotestoragefw/mountmanager/src/rsfwbootmounter.cpp	Wed Sep 01 12:15:08 2010 +0100
@@ -0,0 +1,307 @@
+/*
+* Copyright (c) 2006 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:  Mounts during boot remote drives configured in CenRep
+ *
+*/
+
+
+#include <f32file.h>	// link against efsrv.lib
+#include <centralrepository.h> // link against centralrepository.lib 
+#include <f32fsys.h>
+
+// for the file server client side API   
+_LIT(KRemoteFSName, "RemoteFS");
+_LIT(KRemoteFs, "eremotefs");
+   
+   
+// for the central repository API   
+enum TMountEntryItemIndex
+    {
+    EMountEntryItemIndex, 
+    EMountEntryItemName,
+    EMountEntryItemDrive,
+    EMountEntryItemUri,
+    EMountEntryItemUserName,
+    EMountEntryItemPassword,
+    EMountEntryItemIap,
+    EMountEntryItemInactivityTimeout,
+    EMountEntryItemReserved,
+    EMountEntryItemCount
+    };
+const TUid  KCRUidRsfwCtrl = { 0x101F9775 }; // RSFW cenrep table id
+const TUint KColumnName       = EMountEntryItemName;
+const TUint KColumnMask       = 0x000000ff; 
+const TUint KRowMask          = 0xffffff00;
+const TInt KMaxFileSystemName = 256;
+const TInt KMaxDriveLetterLength = 5;
+const TInt KMaxFriendlyNameLength = 20;
+ 
+
+//  isRsfwFileSystem
+//
+//  Checks whether certain drive has rsfw file system mounted on it
+//
+//  
+LOCAL_C TBool isRsfwFileSystemL(TInt aDrive,
+                              TDriveList aDriveList,
+                              RFs aFsSession) 
+    {
+    TBool rsfwFileSystem = EFalse;
+    // check first KDriveAttRemote bit as if that is missing it is a quick way 
+    // to conclude that this is not a rsfw mount
+    if (aDriveList[aDrive] & KDriveAttRemote) 
+        {
+        TInt err;
+        HBufC* filesystemName = HBufC::NewL(KMaxFileSystemName);
+        TPtr itemPtr = filesystemName->Des();
+        err = aFsSession.FileSystemName(itemPtr, aDrive);
+        if (!err && (itemPtr.Compare(KRemoteFSName) == 0)) 
+            {
+            rsfwFileSystem = ETrue;
+            }
+        delete filesystemName;
+        }
+    return rsfwFileSystem;
+    }
+ 
+ 
+ 
+//  DoMountL
+//
+//  Do either simple mount or replace (our) existing mount
+//  by doing dismount and mount
+//
+//  
+LOCAL_C TInt DoMount(TInt aDrive, RFs aFsSession, TBool aReplaceExisting)
+
+    {
+    TInt err;
+    if (aReplaceExisting) 
+        {
+        // ignore dismount error code
+        aFsSession.DismountFileSystem(KRemoteFSName, aDrive);
+        err = aFsSession.MountFileSystem(KRemoteFSName, aDrive);
+        }
+    else 
+        {
+        err = aFsSession.MountFileSystem(KRemoteFSName, aDrive);
+        }
+    return err;
+    }
+ 
+
+//  ExecuteFileServerMountL
+//
+//  Attempts to mount our file system to the file server
+//
+// 
+LOCAL_C TInt ExecuteFileServerMountL(TInt aDrive,
+                                    TDriveList aDriveList,
+                                    RFs aFsSession)
+    {
+    TInt err;
+    if (aDriveList[aDrive]) 
+        {
+        if (isRsfwFileSystemL(aDrive, aDriveList, aFsSession)) 
+            {
+            err = DoMount(aDrive, aFsSession, ETrue);
+            }
+        else 
+            {
+            // the drive we attempt to mount contains some other file system
+            return KErrInUse;
+            }
+        }
+    else 
+        {
+        // the drive we attempt to mount does not contain an existing mount
+        err = DoMount(aDrive, aFsSession, EFalse);
+        }
+    return err;
+    }
+
+
+//  SetFriendlyNameL
+//  
+//  Sets the friendly name of the remote drive to 
+//  mounted fs drivename and volumename fields
+//  (to the volume name field first 11 chars)
+//
+//  This function assumes that we are allowed to manipulate
+//  drive aDrive, in practise that ExecuteFileServerMount()
+//  has been called succesfully
+// 
+LOCAL_C TInt SetFriendlyName(TInt aDrive,
+                             TDesC& aFriendlyName,
+                             RFs aFsSession)
+    {
+    TInt err;
+    err = aFsSession.SetDriveName(aDrive, aFriendlyName);
+    if (!err) 
+        {
+        TPtrC volumeNamePtr = aFriendlyName.Left(KMaxVolumeNameLength);
+        err = aFsSession.SetVolumeLabel(volumeNamePtr, aDrive);
+        }
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// SyncConfiguredRemoteDrivesL
+// adds RSFW File Server plug-in 
+// and synchronizes Central Repository's view of configured remote drives 
+// with File Server's view (mounts the remote drives configured in CR and
+// unmounts those remote drives that are not anymore configured)   
+// ----------------------------------------------------------------------------
+//  
+LOCAL_C void SyncConfiguredRemoteDrivesL()
+    {  
+    TInt err = 0;
+    TInt row = 0;
+    TInt driveNumber = 0;
+    RFs fs;
+    TChar paramLetter(90);
+    TBool paramSet = EFalse;
+    
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+    
+    // it is possible to manipulate only one drive letter, and give that as an argument
+    TInt clinelength = User::CommandLineLength();
+    if (clinelength > 0) 
+        {
+        HBufC* cl = HBufC::NewL(clinelength);
+        TPtr linePtr = cl->Des();
+        User::CommandLine(linePtr);
+        TLex lex(linePtr);
+        paramLetter = lex.Get();
+        paramSet = ETrue;
+        delete cl;
+        }
+    
+ 	// add our file system plugin to the file server
+    err = fs.AddFileSystem(KRemoteFs);
+    if ((err != KErrNone) && (err != KErrAlreadyExists)) 
+    	{
+    	User::Leave(err);
+    	}
+    	
+    // Get a list of drives in the File Server
+    TDriveList drives;
+    User::LeaveIfError(fs.DriveList(drives, KDriveAttAll));  
+    // 	(drives[i] & KDriveAttRemote) now tells whether i:th drive is remote
+    
+    // Get a list of remote drives in the central repository table
+    
+    // connect
+   	CRepository* cenrep;
+    cenrep = CRepository::NewL(KCRUidRsfwCtrl);
+    CleanupStack::PushL(cenrep);
+    
+     // find all entries by name
+    RArray<TUint32> nameIds;
+    CleanupClosePushL(nameIds);
+    err = cenrep->FindL(KColumnName, KColumnMask, nameIds);
+    if (!err)
+    	{
+    	// for each remote drive entry, represented by a record in central repository, do the following:
+    	// 1) get drive letter from central repository
+    	// 2) based on drive letter acquire corresponding drive number from the File Server
+    	// 3) check whether in the File Server there is already mounted a drive with given number
+    	//    3.1) if there is NOT, then mount the drive
+    	//    3.2) if there is and it appears to be remote, then do re-mounting
+    	//    3.3) if there is and it appears NOT to be remote, then this means error
+    	// 4) still for the same record from central repository, get the name of the drive
+    	// 5) use this name as the volume label in the File Server
+    	for (row = 0; row < nameIds.Count(); row++)
+        	{
+        	TUint rowId = (nameIds[row] & KRowMask);
+        	// don't touch zero row as it DOES NOT contain info about mounted drives
+        	if (rowId > 0) 
+        	    {
+        	    TInt i;
+            	// mount it to the file server
+            	
+            	// get drive number
+            	TBuf<KMaxDriveLetterLength> driveLetter;
+            	i = EMountEntryItemDrive;
+            	User::LeaveIfError(cenrep->Get(rowId | i, driveLetter));
+            	
+            	// driveNumber needed in any case, so that we can mark this as existing drive
+            	if (driveLetter.Length() > 0) 
+            	    {
+            	    User::LeaveIfError(fs.CharToDrive((driveLetter)[0], driveNumber));
+            	    }
+            	 else 
+            	    {
+            	    User::Leave(KErrBadName);
+            	    }
+            	
+            	// proceed this drive if we didn't get any drive
+            	// letter as a parameter or we got this one
+                if ((!paramSet) || (paramLetter ==  driveLetter[0]))
+                    {
+                    // get friendly name
+            	    TBuf<KMaxFriendlyNameLength> friendlyName;
+            	    i = EMountEntryItemName;
+            	    User::LeaveIfError(cenrep->Get(rowId | i, friendlyName));
+            	
+            	    if (friendlyName.Length() > 0) 
+            	        {
+            		    User::LeaveIfError(ExecuteFileServerMountL(driveNumber, drives, fs));
+            		    User::LeaveIfError(SetFriendlyName(driveNumber, friendlyName,fs));		
+            		    }
+            	
+            	    else
+            		    {
+            		    User::Leave(KErrBadName);
+            		    }
+                    }
+                    
+            	// do not unmount this drive as it is still in the CenRep table
+            	// after this loop non-zero drives are used to see 
+            	// which remote drives should be unmounted	
+            	drives[driveNumber] = 0; 
+        	    }
+            } // loop
+    	}
+    	
+    	// If drives now contain some remote drives, this means that they are not 
+    	// anymore configured in CenRep and should be unmounted. 
+       	for (int i = 0; i < EDriveZ; i++) 
+       		{
+       		if (isRsfwFileSystemL(i, drives, fs))
+       			{
+       			fs.DismountFileSystem(KRemoteFSName, i);
+       			}
+       		}
+    
+    CleanupStack::PopAndDestroy(3, &fs);   // fs, cenrep, nameIds
+    
+    }
+    
+// ----------------------------------------------------------------------------
+// E32Main
+// 
+// ----------------------------------------------------------------------------
+//   
+GLDEF_C TInt E32Main() 
+    {
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    TRAPD(err, SyncConfiguredRemoteDrivesL());
+    delete cleanupStack;
+    return err;
+    }
+
+
+// End of file