diff -r 88ee4cf65e19 -r 1aa8c82cb4cb remotestoragefw/mountmanager/src/rsfwbootmounter.cpp --- /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 // link against efsrv.lib +#include // link against centralrepository.lib +#include + +// 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 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 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 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