--- a/userlibandfileserver/fileserver/sfile/sf_sys.cpp Tue Aug 24 14:49:21 2010 +0100
+++ b/userlibandfileserver/fileserver/sfile/sf_sys.cpp Tue Aug 31 11:31:15 2010 +0100
@@ -32,11 +32,7 @@
extern TBool gInitCacheCheckDrivesAndAddNotifications;
#endif
-struct TFatUtilityFunctions;
GLREF_D TCodePageUtils TheCodePage;
-const TInt KMaxLengthShortNameWithDot = 12;
-const TUint8 KLeadingE5Replacement = 0x05;
-const TUint8 KEntryErasedMarker=0xE5; ///< Erased entry marker for a directory entry
/**
Default constructor.
@@ -353,6 +349,7 @@
TSecurityPolicy policy(RProcess().SecureId(), ECapabilityTCB);
if (!policy.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Add File System")))
return KErrPermissionDenied;
+
return KErrNone;
}
@@ -398,12 +395,15 @@
}
TInt TFsRemoveFileSystem::Initialise(CFsRequest* aRequest)
-//
-//
-//
{
if (!KCapFsRemoveFileSystem.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Remove File System")))
return KErrPermissionDenied;
+
+ //-- check file system name length. It should not exceed KMaxFSNameLength (32 characters)
+ TInt r = aRequest->GetDesLength(KMsgPtr0);
+ if(r <=0 || r >KMaxFSNameLength)
+ return KErrArgument;
+
return KErrNone;
}
@@ -419,11 +419,160 @@
return(aRequest->Drive()->CheckMount());
}
+//-----------------------------------------------------------------------------
+/**
+ Read optional drive setting from estart.txt that may contain additional drive attributes, like KDRIVEATTLOGICALLYREMOVABLE, KDRIVEATTHIDDEN
+ and process them.
+ This may lead to addding/removing some attributes to the existing drive's ones.
+ N.B Implementation of this is quite strange, it knows only about 2 specific additional attributes..
-LOCAL_C TInt DoMountFsInitialise(CFsRequest* aRequest,TDesC& aFsName,TBool aIsExtension,TBool aIsSync)
-//
-//
-//
+ @param aDrvNum drive number
+ @param aDrvAtt in: original drive attributes, out: altered drive attributes.
+
+
+*/
+static void DoProcessAdditionalDriveAttributes(TInt aDrvNum, TUint& aDrvAtt)
+{
+ TUint add_Att= 0; //-- additional drive attributes to be added
+ TUint remove_Att = 0; //-- additional drive attributes to be removed
+
+ _LIT8( KAddAtt, "AddDriveAttributes");
+ _LIT8( KRemoveAtt, "RemoveDriveAttributes");
+ _LIT8( KLogicallyRemovableAtt, "KDRIVEATTLOGICALLYREMOVABLE");
+ _LIT8( KHiddenAtt, "KDRIVEATTHIDDEN");
+ _LIT8( KLogicallyRemovableAttHex, "0X200");
+ _LIT8( KHiddenAttHex, "0X400");
+
+ TBuf8<0x100> buf;
+ TBuf8<8> sectionName;
+ F32Properties::GetDriveSection(aDrvNum, sectionName);
+
+ //-- read and parse "AddDriveAttributes" string
+ buf.Zero();
+ TBool bSectFound = F32Properties::GetString(sectionName, KAddAtt, buf);
+
+ if(bSectFound && buf.Length() > 0)
+ {
+ TInt pos = 0;
+ TInt length = 0;
+ TPtrC8 ptr;
+ TBool endOfFlag=EFalse;
+
+ while(!endOfFlag)
+ {
+ ptr.Set(buf.Mid(pos));
+ length = ptr.Locate(',');
+
+ if(length == KErrNotFound)
+ {
+ endOfFlag = ETrue;
+ }
+ else{
+ ptr.Set(ptr.Left(length));
+ pos += (length +1);
+ }
+
+ if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound))
+ add_Att |= KDriveAttLogicallyRemovable;
+
+ if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound))
+ add_Att |= KDriveAttHidden;
+
+ }//while(!endOfFlag)
+ }
+
+ //-- read and parse "RemoveDriveAttributes" string
+ buf.Zero();
+ bSectFound = F32Properties::GetString(sectionName, KRemoveAtt, buf); //oldAtt now contains value of the attributes to be removed from iDriveAtt.
+
+ if(bSectFound && buf.Length() > 0)
+ {
+ TInt pos = 0;
+ TInt length = 0;
+ TPtrC8 ptr;
+ TBool endOfFlag=EFalse;
+
+ while(!endOfFlag)
+ {
+ ptr.Set(buf.Mid(pos));
+ length = ptr.Locate(',');
+
+ if(length == KErrNotFound)
+ {
+ endOfFlag = ETrue;
+ }
+ else
+ {
+ ptr.Set(ptr.Left(length));
+ pos += (length +1);
+ }
+
+ if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound))
+ remove_Att |= KDriveAttLogicallyRemovable;
+
+ if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound))
+ remove_Att |= KDriveAttHidden;
+
+ }//while(!endOfFlag)
+
+ }
+
+ if ((add_Att & KDriveAttLogicallyRemovable))
+ {
+ add_Att |= KDriveAttRemovable; //KDriveAttLogicallyRemovale should always set KDriveAttRemovale
+ }
+
+ if ((remove_Att & KDriveAttRemovable))
+ {
+ remove_Att |= KDriveAttLogicallyRemovable;
+ }
+
+
+ aDrvAtt |= add_Att; //-- add new attributes to drive's ones
+ aDrvAtt &= ~remove_Att; //-- remove drive attributes if there are soem indicated
+}
+
+//-----------------------------------------------------------------------------
+/**
+ Try to find and process "ForceRugged" key in the drive section. It looks like:
+ [DriveX]
+ ForceRugged N
+
+ where when N==0, the drive forced to be non-rugged, when N==1, the drive forced to be rugged,
+ otherwise the original value is not overridden.
+
+ @param aDrvNum drive number
+ @param aRugged out: true/false if the setting is found, not changed if there is no such a key in the config file
+*/
+static void DoProcessForceRuggedSetting(TInt aDrvNum, TBool& aRugged)
+{
+ _LIT8(KKeyname, "ForceRugged");
+ TBuf8<8> sectionName;
+ F32Properties::GetDriveSection(aDrvNum, sectionName);
+
+ TInt32 val=-1;
+ if(F32Properties::GetInt(sectionName, KKeyname, val))
+ {
+ if(val == 0)
+ aRugged = EFalse;
+ else if(val == 1)
+ aRugged = ETrue;
+ //else the value is considered to be invalid and nothing changed
+ }
+}
+
+//-----------------------------------------------------------------------------
+/**
+ A helper function that binds a file system to the drive along with the optional primary extension etc.
+
+ @param aRequest FS request object
+ @param aFsName file system name to be bound to the drive
+ @param aIsExtension if true, this means that it's necessary to mount aprimary extension as well
+ @param aIsSync specifies if this drive is synchronous one or not
+
+ @return standard error code
+*/
+static TInt DoMountFsInitialise(CFsRequest* aRequest, TDesC& aFsName, TBool aIsExtension, TBool aIsSync)
{
if (!KCapFsMountFileSystem.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount File System")))
return KErrPermissionDenied;
@@ -432,12 +581,14 @@
if(r!=KErrNone)
return(r);
- TBool driveThreadExists = FsThreadManager::IsDriveAvailable(aRequest->DriveNumber(), ETrue);
+ const TBool driveThreadExists = FsThreadManager::IsDriveAvailable(aRequest->DriveNumber(), ETrue);
+ TDrive& drive = *aRequest->Drive();
+
if(driveThreadExists)
{
// A drive thread already exists for this drive.This could be because a filesystem
// is already mounted, or a proxy drive is loaded. Check the mount to be sure...
- if(aRequest->Drive()->GetFSys())
+ if(drive.GetFSys())
{
// Yes, a mount already exists so we can't mount another one!
return(KErrAccessDenied);
@@ -447,18 +598,18 @@
}
// ...therefore no drive thread can be present
- __ASSERT_DEBUG(!&aRequest->Drive()->FSys(),Fault(EMountFileSystemFSys));
+ __ASSERT_DEBUG(! &drive.FSys(),Fault(EMountFileSystemFSys));
- if(aRequest->Drive()->IsSubsted())
+ if(drive.IsSubsted())
return(KErrAccessDenied);
CFileSystem* pF = GetFileSystem(aFsName);
-
- if (pF == NULL)
+ if(!pF)
return(KErrNotFound);
+
// Check that if the drive is a proxy drive (not using TBusLocalDrive) then the filesystem supports these...
- TInt driveNumber = aRequest->DriveNumber();
+ const TInt driveNumber = aRequest->DriveNumber();
if(IsProxyDrive(driveNumber))
{
if(!pF->IsProxyDriveSupported())
@@ -467,15 +618,16 @@
r = LocalDrives::SetupMediaChange(driveNumber);
}
+
+ //-- get drive information from the file system
TDriveInfo driveInfo;
driveInfo.iDriveAtt=0;
- pF->DriveInfo(driveInfo, driveNumber);
+ pF->DriveInfo(driveInfo, driveNumber); //-- the file system can override some driveInfo properties
if(!driveInfo.iDriveAtt)
r = KErrArgument;
if(r == KErrNone && !driveThreadExists)
- {
- // determine whether file system synchronous or not not by flag passed in
+ {// determine whether file system synchronous or not not by flag passed in
r=FsThreadManager::InitDrive(driveNumber, aIsSync);
}
@@ -483,129 +635,66 @@
return(r);
- //-- let TDrive object know if the drive is synchronous
- aRequest->Drive()->SetSynchronous(aIsSync);
-
+ //-- add a primary drive extension if it is specified
if(aIsExtension && aRequest->Message().Ptr2()!=NULL)
{
- TFullName extName;
+ //-- check extension name length. It should not exceed KMaxFSNameLength (32 characters)
+ r = aRequest->GetDesLength(KMsgPtr2);
+ if(r <=0 || r >KMaxFSNameLength)
+ return KErrArgument;
+
+ TFSName extName;
+
r = aRequest->Read(KMsgPtr2,extName);
if (r!=KErrNone)
return r;
+
CProxyDriveFactory* pE=GetExtension(extName);
if(pE==NULL)
return(KErrNotFound);
- r=aRequest->Drive()->MountExtension(pE,ETrue);
+
+ r=drive.MountExtension(pE,ETrue);
if(r!=KErrNone)
return(r);
}
- TInt32 newAtt = 0;
- TInt32 oldAtt = 0;
- _LIT8( KAddAtt, "AddDriveAttributes");
- _LIT8( KRemoveAtt, "RemoveDriveAttributes");
- _LIT8( KLogicallyRemovableAtt, "KDRIVEATTLOGICALLYREMOVABLE");
- _LIT8( KHiddenAtt, "KDRIVEATTHIDDEN");
- _LIT8( KLogicallyRemovableAttHex, "0X200");
- _LIT8( KHiddenAttHex, "0X400");
- TBuf8<0x1000> addbuf;
- addbuf.FillZ();
- TBuf8<0x1000> removebuf;
- removebuf.FillZ();
- TInt drive = aRequest->Message().Int1();
- _LIT8(KLitSectionNameDrive,"Drive%C");
- TBuf8<8> sectionName;
- sectionName.Format(KLitSectionNameDrive, 'A' + drive);
- F32Properties::GetString(sectionName, KAddAtt, addbuf);
- F32Properties::GetString(sectionName, KRemoveAtt, removebuf); //oldAtt now contains value of the attributes to be removed from iDriveAtt.
-
- if(addbuf.Length() != 0)
- {
- TInt pos = 0;
- TInt length = 0;
- TPtrC8 ptr;
- TBool endOfFlag=EFalse;
+ //-- process optional additional drive attributes that can be specified in estart.txt
+ DoProcessAdditionalDriveAttributes(driveNumber, driveInfo.iDriveAtt);
- while(!endOfFlag)
- {
- ptr.Set(addbuf.Mid(pos));
- length = ptr.Locate(',');
-
- if(length == KErrNotFound)
- {
- endOfFlag = ETrue;
- }
- else{
- ptr.Set(ptr.Left(length));
- pos += (length +1);
- }
-
- if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound))
- newAtt |= KDriveAttLogicallyRemovable;
- if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound))
- newAtt |= KDriveAttHidden;
-
- }
- }
+ if(driveInfo.iDriveAtt & KDriveAttLogicallyRemovable)
+ {
+ ASSERT(driveInfo.iDriveAtt & KDriveAttRemovable);
+ }
- if(removebuf.Length() != 0)
- {
- TInt pos = 0;
- TInt length = 0;
- TPtrC8 ptr;
- TBool endOfFlag=EFalse;
+
+ //-- process 'rugged drive' property
+ TBool bRuggedDrive = drive.IsRugged();
+
+ //-- reset 'Rugged drive' attribute if this drive is removable. Having 'rugged' file system on a removable drive
+ //-- doesn't make any sense and leads only to the performance degradation
+ if(bRuggedDrive && (driveInfo.iDriveAtt & KDriveAttRemovable))
+ {
+ __PRINT1(_L("DoMountFsInitialise() drv:%d is removable. resetting 'Rugged' flag!"), driveNumber);
+ bRuggedDrive = EFalse;
+ }
- while(!endOfFlag)
- {
- ptr.Set(removebuf.Mid(pos));
- length = ptr.Locate(',');
+ DoProcessForceRuggedSetting(driveNumber, bRuggedDrive); //-- setting in estart.txt can override this flag
+ drive.SetRugged(bRuggedDrive);
+
+
+ //-- let TDrive object know if the drive is synchronous
+ drive.SetSynchronous(aIsSync);
+
+ drive.SetAtt(driveInfo.iDriveAtt); //-- finally set drive attributes
+ drive.GetFSys()=pF; //-- bind a file system to the drive
+
- if(length == KErrNotFound)
- {
- endOfFlag = ETrue;
- }
- else{
- ptr.Set(ptr.Left(length));
- pos += (length +1);
- }
-
- if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound))
- oldAtt |= KDriveAttLogicallyRemovable;
- if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound))
- oldAtt |= KDriveAttHidden;
-
- }
- }
-
- if ((newAtt & KDriveAttLogicallyRemovable) && (!(driveInfo.iDriveAtt & KDriveAttRemovable)) && (!(newAtt & KDriveAttRemovable)))
- {
- newAtt |= KDriveAttRemovable; //KDriveAttLogicallyRemovale should always set KDriveAttRemovale
- }
- if ((oldAtt & KDriveAttRemovable) && (!(oldAtt & KDriveAttLogicallyRemovable)))
- {
- oldAtt |= KDriveAttLogicallyRemovable;
- }
- if(newAtt)
- {
- driveInfo.iDriveAtt |= newAtt;
- }
- if(oldAtt)
- {
- if(oldAtt & driveInfo.iDriveAtt)
- {
- driveInfo.iDriveAtt ^= oldAtt;
- }
- }
- aRequest->Drive()->SetAtt(driveInfo.iDriveAtt);
- aRequest->Drive()->GetFSys()=pF;
+ TClosedFileUtils::Remove(driveNumber); // empty the closed file queue
- // empty the closed file queue
- TClosedFileUtils::Remove(aRequest->DriveNumber());
-
- return(KErrNone);
+ return KErrNone;
}
-
+//-----------------------------------------------------------------------------
TInt TFsMountFileSystem::DoRequestL(CFsRequest* aRequest)
//
// Mount a filesystem on a drive.
@@ -625,19 +714,26 @@
return r;
}
-
+//-----------------------------------------------------------------------------
TInt TFsMountFileSystem::Initialise(CFsRequest* aRequest)
-//
-//
-//
{
- TFullName name;
- TInt r = aRequest->Read(KMsgPtr0,name);
+ TInt r;
+
+ //-- check file system name length. It should not exceed KMaxFSNameLength (32 characters)
+ r = aRequest->GetDesLength(KMsgPtr0);
+ if(r <=0 || r >KMaxFSNameLength)
+ return KErrArgument;
+
+ TFSName name;
+ r = aRequest->Read(KMsgPtr0, name);
+
if (r == KErrNone)
r = DoMountFsInitialise(aRequest,name,ETrue,aRequest->Message().Int3());
+
return r;
}
+//-----------------------------------------------------------------------------
TInt TFsMountFileSystemScan::DoRequestL(CFsRequest* aRequest)
//
// mount file system and then call scandrive
@@ -651,25 +747,33 @@
r=aRequest->Drive()->ScanDrive();
FsNotify::DiskChange(aRequest->DriveNumber());
}
+
TPtrC8 pMS((TUint8*)&isMountSuccess,sizeof(TBool));
aRequest->WriteL(KMsgPtr3,pMS);
return(r);
}
+//-----------------------------------------------------------------------------
TInt TFsMountFileSystemScan::Initialise(CFsRequest* aRequest)
-//
-//
-//
{
- TFullName name;
- TInt r = aRequest->Read(KMsgPtr0,name);
+ TInt r;
+
+ //-- check file system name length. It should not exceed KMaxFSNameLength (32 characters)
+ r = aRequest->GetDesLength(KMsgPtr0);
+ if(r <=0 || r >KMaxFSNameLength)
+ return KErrArgument;
+
+ TFSName name;
+ r = aRequest->Read(KMsgPtr0,name);
if (r == KErrNone)
r = DoMountFsInitialise(aRequest,name,ETrue,EFalse);
+
return r;
}
-LOCAL_C TInt DoDismountFileSystem(const TDesC& aName, TDrive* aDrive, TBool aAllowRom, TBool aForceDismount)
+//-----------------------------------------------------------------------------
+static TInt DoDismountFileSystem(const TDesC& aName, TDrive* aDrive, TBool aAllowRom, TBool aForceDismount)
//
// Do file system dismount
//
@@ -747,6 +851,7 @@
return(KErrNone);
}
+//-----------------------------------------------------------------------------
TInt TFsDismountFileSystem::DoRequestL(CFsRequest* aRequest)
//
// Dismount a filesystem from a drive.
@@ -754,7 +859,8 @@
{
TDrive* drive=aRequest->Drive();
__ASSERT_DEBUG(&aRequest->Drive()->FSys() && !drive->IsSubsted(),Fault(EDisMountFileSystemFSys));
- TFullName name;
+
+ TFSName name;
aRequest->ReadL(KMsgPtr0,name);
if(drive->DismountDeferred())
@@ -763,14 +869,24 @@
return DoDismountFileSystem(name, drive, EFalse, EFalse);
}
+//-----------------------------------------------------------------------------
TInt TFsDismountFileSystem::Initialise(CFsRequest* aRequest)
//
//
//
{
+ TInt r;
+
if (!KCapFsDismountFileSystem.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Dismount File System")))
return KErrPermissionDenied;
- TInt r = ValidateDrive(aRequest->Message().Int1(),aRequest);
+
+ //-- check file system name length. It should not exceed KMaxFSNameLength (32 characters)
+ r = aRequest->GetDesLength(KMsgPtr0);
+ if(r <=0 || r >KMaxFSNameLength)
+ return KErrArgument;
+
+
+ r = ValidateDrive(aRequest->Message().Int1(),aRequest);
if(r == KErrNone)
{
TInt driveNumber = aRequest->DriveNumber();
@@ -873,12 +989,13 @@
// Should always leave a filesystem mounted on the drive
//
{
- TFileName newName;
+ TFSName newName;
aRequest->ReadL(KMsgPtr0,newName);
CFileSystem* pF=GetFileSystem(newName);
if (pF==NULL)
return(KErrNotFound);
- TFileName oldName;
+
+ TFSName oldName;
aRequest->ReadL(KMsgPtr2,oldName);
TInt drvNumber=aRequest->Message().Int1();
TBool newFsIsComposite = (newName.CompareF(KCompositeFsName) == 0);
@@ -946,11 +1063,19 @@
return(r);
}
-TInt TFsSwapFileSystem::Initialise(CFsRequest* /*aRequest*/)
-//
-//
-//
+TInt TFsSwapFileSystem::Initialise(CFsRequest* aRequest)
{
+ TInt len;
+
+ //-- check file system name length. It should not exceed KMaxFSNameLength (32 characters)
+ len = aRequest->GetDesLength(KMsgPtr0); //-- new name
+ if(len <=0 || len >KMaxFSNameLength)
+ return KErrArgument;
+
+ len = aRequest->GetDesLength(KMsgPtr2); //-- old name
+ if(len <=0 || len >KMaxFSNameLength)
+ return KErrArgument;
+
return KErrNone;
}
@@ -1569,6 +1694,10 @@
@return False if and only if aUnicode has not enough space remaining.
*/
{
+ const TInt KMaxLengthShortNameWithDot = 12;
+ const TUint8 KLeadingE5Replacement = 0x05;
+ const TUint8 KEntryErasedMarker=0xE5; ///< Erased entry marker for a directory entry
+
// A workaround to handle leading 'E5' byte in short file names
TBuf8<KMaxLengthShortNameWithDot> shortFileNameWithLeadingE5;
TBool convertedLeading05toE5 = EFalse;