Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "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:
// f32\sfile\sf_fmt.cpp
//
//
#include "sf_std.h"
LOCAL_C CFormatCB* GetFormatFromHandle(TInt aHandle,CSessionFs* aSession)
//
// Get the format control block from aHandle
//
{
return((CFormatCB*)(SessionObjectFromHandle(aHandle,Formats->UniqueID(),aSession)));
}
/**
Default constructor.
*/
EXPORT_C CFormatCB::CFormatCB()
{
}
/**
Destructor.
Frees resources before destruction of the object.
*/
EXPORT_C CFormatCB::~CFormatCB()
{
if (iMount)
{
RemoveDiskAccess(*iMount);
iMount->Drive().SetChanged(ETrue);
iMount->Close();
}
}
/**
Checks that the disk media is still mounted.
@return KErrNone if the media is still mounted; KErrDisMounted otherwise.
*/
EXPORT_C TInt CFormatCB::CheckMount()
{
TDrive& d=Drive();
TInt r=d.CheckMount();
if (r!=KErrNone)
return(r);
if (&Mount()!=&d.CurrentMount())
return(KErrDisMounted);
return(KErrNone);
}
void CFormatCB::InitL(TDrive* aDrive,TFormatMode aMode)
{
DoInitL(aDrive->DriveNumber());
iDrive=aDrive;
iMount=&iDrive->CurrentMount();
iMode=aMode;
User::LeaveIfError(iMount->Open());
}
EXPORT_C TInt CFormatCB::GetInterface(TInt /*aInterfaceId*/,TAny*& /*aInterface*/,TAny* /*aInput*/)
{
return(KErrNotSupported);
}
//----------------------------------------------------------------------------
/**
set volume formatting parameters, which are provided in TLDFormatInfo structure
@param apLDFormatInfo pointer to the parameters structure. If NULL, iSpecialInfo will be initialised
*/
void CFormatCB::SetFormatParameters(const TLDFormatInfo* apLDFormatInfo)
{
TLDFormatInfo& fmtInfo = iSpecialInfo();
if(!apLDFormatInfo)
{//-- special meaning; invalidate iSpecialInfo by setting its package size as 0
iSpecialInfo.SetLength(0);
}
else
{
Mem::Copy(&fmtInfo, apLDFormatInfo, sizeof(TLDFormatInfo));
}
}
//----------------------------------------------------------------------------
/** set volume formatting parameters, which are provided in TVolFormatParam structure */
TInt CFormatCB::SetFormatParameters(const TVolFormatParam* apVolFormatParam)
{
ASSERT(apVolFormatParam);
TAny* dummy;
//-- push parameters to the particular implementation of the CFormatCB. Default behaviour: KErrNotSupported
return GetInterface(ESetFmtParameters, dummy, (TAny*)apVolFormatParam);
}
//----------------------------------------------------------------------------
#ifdef _DEBUG
#define DUMP_OPENED_OBJECTS
#endif
/**
Debug helper method. Dumps names of opened files and directories on this drive
define DUMP_OPENED_OBJECTS to have it called
*/
#ifdef DUMP_OPENED_OBJECTS
static void DumpOpenedObjects(TDrive& aDrive)
{
{//-- 1. files
const TInt nFiles = Files->Count();
for(TInt i=0; i<nFiles; ++i)
{
CFileCB* pFile=(CFileCB*)(*Files)[i];
if(pFile->Drive().DriveNumber() == aDrive.DriveNumber())
{
__PRINT1(_L("FsFormatOpen() opened file:'%S'"), &pFile->FileName());
}
}
}
{//-- 2. directories; CDirCB doesn't have associated name.
const TInt nDirs = Dirs->Count();
TInt cntDirs = 0;
for(TInt i=0; i<nDirs; ++i)
{
CDirCB* pDir = (CDirCB*)(*Dirs)[i];
if(pDir->Drive().DriveNumber() == aDrive.DriveNumber())
{
++cntDirs;
}
}
if(cntDirs)
{
__PRINT1(_L("FsFormatOpen() opened directories:%d"), cntDirs);
}
}
}
#endif //DUMP_OPENED_OBJECTS
//----------------------------------------------------------------------------
/**
Open a drive for formatting.
*/
TInt FsFormatOpen(CFsRequest* aRequest)
{
TDrive& drive = *aRequest->Drive();
__PRINT1(_L("FsFormatOpen() drv:%d"), drive.DriveNumber());
TInt nMountRes = drive.CheckMount();
//-- KErrNotReady means that there is no file system mounted on this drive
//-- KErrInUse means that there are some "disk access" objects, like RFormat or RRawDisk opened on the mount.
if(nMountRes == KErrNotReady || nMountRes == KErrInUse)
{
__PRINT1(_L("FsFormatOpen() ChkMount:%d"), nMountRes);
return nMountRes;
}
const TFormatMode fmtMode = (TFormatMode)aRequest->Message().Int1();
TName buf;
TUint32 currFsNameHash = 0; //-- current file system name hash, 0 means "not set"; used during forced FS dismounting
if((nMountRes == KErrNone) && drive.CurrentMount().LockStatus() < 0)
{//-- the mount is locked, it has normal objects (files, directories) opened on it.
//-- if someone is interested in the list of opened files and number of opened directories, compile this code in.
#ifdef DUMP_OPENED_OBJECTS
DumpOpenedObjects(drive);
#endif //DUMP_OPENED_OBJECTS
if(!(fmtMode & EForceFormat))
{
__PRINT(_L("FsFormatOpen() The mount is in use"));
return KErrInUse;
}
//-- there is a special flag that tells to force media dismounting even if it has files or dirs opened.
__PRINT(_L("FsFormatOpen() The mount is in use, forcing dismounting!"));
//-- record currently mounted FS name hash, it may be used after forced dismounting
drive.CurrentMount().FileSystemName(buf); //-- the iCurrentMount is alive
currFsNameHash = TVolFormatParam::CalcFSNameHash(buf);
//-- kill the current mount
FsThreadManager::LockDrive(drive.DriveNumber());
TInt nRes = drive.ForceUnmountFileSystemForFormatting();
FsThreadManager::UnlockDrive(drive.DriveNumber());
switch(nRes)
{
case KErrInUse:
__PRINT(_L("FsFormatOpen() The mount has clamps! Can't force dismount"));
return KErrInUse; //-- there are clamps on this drive - can't dismount
case KErrNone:
break;
default:
ASSERT(0); //-- unexpected error code
return nRes;
};
if(fmtMode & EQuickFormat)
{//-- quick format may require the normally mounted FS, make the best effrot to mount it
nMountRes = drive.CheckMount();
}
else
{//-- this will make the FS mounted by force; for full format it will be quicker
nMountRes = KErrCorrupt;
}
}
//-- if True, we will need mount (probably specific) file system by force because normal mounting has failed
TBool bNeedForceMount = (nMountRes != KErrNone);
//-- find out if we have optional data structure that describes format parameter
TUint32 newFsNameHash = 0; //-- file system name hash, may be used for selecting which file system to put onto the volume. 0 means "not specified"
const TLDFormatInfo* pLDFormatInfo = NULL;
const TVolFormatParam* pVolFormatParam = NULL;
__ASSERT_COMPILE(sizeof(TVolFormatParam) >= sizeof(TLDFormatInfo));
TBuf8<sizeof(TVolFormatParam)> paramBuf;
if(fmtMode & ESpecialFormat)
{
//-- the user has provided format parameters structure.
//-- IPC argument #2 contains a structure: <TUint32>[optional package descriptor]
//-- where 1st mandatory TUint32 is a pointer to format counter and the optional additional package is a data structure passed to the filesystem by the client of RFormat
const TInt desLen = aRequest->GetDesLength(KMsgPtr2);
ASSERT((TUint32)desLen >= sizeof(TUint32));
const TInt dataPckgLen = desLen - sizeof(TUint32);
if((TUint32)dataPckgLen > sizeof(TUint32))
{
aRequest->ReadL(KMsgPtr2, paramBuf);
}
if(dataPckgLen == sizeof(TLDFormatInfo))
{//-- the user has provided formatting parameters via TLDFormatInfo structure.
pLDFormatInfo = (const TLDFormatInfo*)(paramBuf.Ptr() + sizeof(TUint32));
}
else if(dataPckgLen == sizeof(TVolFormatParam))
{//-- it's likely to be TVolFormatParam, need to check UId to be sure.
pVolFormatParam = (const TVolFormatParam*)(const TVolFormatParam*)(paramBuf.Ptr() + sizeof(TUint32));
if(pVolFormatParam->iUId == TVolFormatParam::KUId) //-- check the class UID
{//-- this is the real TVolFormatParam object passed
newFsNameHash = pVolFormatParam->FSNameHash();
}
}
else if(dataPckgLen >0)
{//-- parameters data structure has strange length
return KErrArgument;
}
}
//-------------------
if(!newFsNameHash && currFsNameHash)
{//-- new file system name isn't specified (default formatting), but the volume had been forcedly dismounted.
//-- restore the original file system
newFsNameHash = currFsNameHash;
}
if(newFsNameHash)
{//-- check if the specified FS is already mounted on the volume
if(!bNeedForceMount)
{
drive.CurrentMount().FileSystemName(buf); //-- the iCurrentMount is alive
}
else
{ //-- the iCurrentMount can be NULL, use the iFsys - the real file system associated with this drive
buf = drive.GetFSys()->Name();
}
const TUint32 currFSNameHash = TVolFormatParam::CalcFSNameHash(buf);
if(currFSNameHash == newFsNameHash)
{//-- no need to do anything, the required FS is already mounted
newFsNameHash = 0;
}
}
if(newFsNameHash)
{
//-- the user has specified some filesystem to be mounted on the volume. Check if this FS is supported at all.
//-- if it is supported, but some other FS is currently mounted, it will be dismounted and the new one will be forced.
TInt nRes;
for(TInt cntFS=0; ;++cntFS)
{
nRes = drive.FSys().GetSupportedFileSystemName(cntFS, buf); //-- enumerate possible child file systems
if(nRes != KErrNone)
return KErrNotSupported; //-- the filesystem with the given name (fsNameHash) is not supported.
if(newFsNameHash == TVolFormatParam::CalcFSNameHash(buf))
{//-- the filesystem with the given name (fsNameHash) is supported, but some other filesystem can be already mounted
drive.Dismount();
bNeedForceMount = ETrue; //-- this will force the desired FS to be mounted
break;
}
}
}//if(fsNameHash)
//-- try force mounting the desired file system if it is required
if(bNeedForceMount)
{
const TInt KMaxRetries = 3;
for(TInt cnt=0; ; ++cnt)
{
drive.MountFileSystem(ETrue, newFsNameHash);
nMountRes = drive.GetReason();
if(nMountRes == KErrNone || nMountRes == KErrLocked)
break;
drive.Dismount(); //-- will reset mount retries counter
if(cnt >= KMaxRetries)
{
__PRINT1(_L("FsFormatOpen() can't mount FS! res:%d"), nMountRes);
return nMountRes;
}
}
}
ASSERT(nMountRes == KErrNone || nMountRes == KErrLocked);
__ASSERT_DEBUG(drive.CurrentMount().LockStatus()==0, Fault(ESvrFormatOpenFailed));
TDriveInfo dInfo;
drive.DriveInfo(dInfo);
const TInt mediaAtt = dInfo.iMediaAtt;
#if defined(_LOCKABLE_MEDIA)
if (!(fmtMode & EForceErase) && (mediaAtt & KMediaAttLocked))
{
// if attempting to format a locked drive, dismount otherwise subsequent
// requests will operate on a mount that has been forcibly mounted (a few lines above)
CMountCB* pM = &drive.CurrentMount();
if(pM)
pM->Close();
drive.MountFileSystem(EFalse); // clear iCurrentMount
return KErrLocked;
}
#endif
if (!(mediaAtt & KMediaAttFormattable) || (mediaAtt & KMediaAttWriteProtected))
{
CMountCB* pM = &drive.CurrentMount();
if(pM)
pM->Close();
drive.MountFileSystem(EFalse);
return KErrAccessDenied;
}
//-- instantinate and open CFormatCB object for this drive
CFormatCB* formatCB=NULL;
TInt fmtHandle;
TRAPD(ret, formatCB = drive.FormatOpenL(aRequest, fmtHandle, fmtMode, pLDFormatInfo, pVolFormatParam ));
if (ret!=KErrNone)
{
if(formatCB)
formatCB->Close();
return ret;
}
TPtrC8 pH((TUint8*)&fmtHandle,sizeof(TInt));
aRequest->WriteL(KMsgPtr3,pH);
TInt count=100;
TPtrC8 pCount((TUint8*)&count,sizeof(TInt));
aRequest->WriteL(KMsgPtr2,pCount);
aRequest->Session()->IncResourceCount();
return KErrNone;
}
TInt TFsFormatOpen::DoRequestL(CFsRequest* aRequest)
//
// Open a drive for formatting.
//
{
// Can not format if any files are clamped
TInt r=FsFormatOpen(aRequest);
return r;
}
TInt TFsFormatOpen::Initialise(CFsRequest* aRequest)
//
//
//
{
TInt r;
if (!KCapFsFormatOpen.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Format Open")))
return KErrPermissionDenied;
r=ParseNoWildSubstPtr0(aRequest,aRequest->Src());
if (r!=KErrNone)
return(r);
if (aRequest->Src().NameOrExtPresent())
return(KErrBadName);
if (aRequest->SubstedDrive())
return(KErrAccessDenied);
return(r);
}
TInt TFsFormatNext::DoRequestL(CFsRequest* aRequest)
//
// Format the next part of the media.
//
{
__PRINT1(_L("TFsFormatNext::DoRequestL() drv:%d"), aRequest->DriveNumber());
CFormatCB* format=(CFormatCB*)aRequest->ScratchValue();
TInt r=format->CheckMount();
if (r!=KErrNone && r!=KErrInUse)
{
__PRINT1(_L("TFsFormatNext::DoRequestL() err:%d"), r);
return r;
}
TPtr8 pStep((TUint8*)&format->CurrentStep(),sizeof(TInt));
aRequest->ReadL(KMsgPtr0,pStep);
TRACE1(UTF::EBorder, UTraceModuleFileSys::ECFormatCBDoFormatStepL, EF32TraceUidFileSys, format);
TRAP(r,format->DoFormatStepL());
TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFormatCBDoFormatStepLRet, EF32TraceUidFileSys, r, format->CurrentStep());
if (r==KErrNone)
aRequest->WriteL(KMsgPtr0,pStep);
if (r==KErrNone && format->CurrentStep()==0)
{
FsNotify::DiskChange(aRequest->DriveNumber());
}
return(r);
}
TInt TFsFormatNext::Initialise(CFsRequest* aRequest)
//
//
//
{
if (!KCapFsFormatNext.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Format Next")))
return KErrPermissionDenied;
CFormatCB* format;
format=GetFormatFromHandle(aRequest->Message().Int3(), aRequest->Session());
if(!format)
return(KErrBadHandle);
aRequest->SetDrive(&format->Drive());
aRequest->SetScratchValue((TUint)format);
return KErrNone;
}