First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_drv.cpp
19 #include "sf_file_cache.h"
22 //const TInt KMaxNotifierAttempts=4; // not used anywhere
24 static TPtrC StripBackSlash(const TDesC& aName)
26 // If aName ends in a backslash, strip it.
30 __ASSERT_DEBUG(aName.Length(),Fault(EStripBackSlashBadName));
31 if (aName[aName.Length()-1]==KPathDelimiter)
32 return(aName.Left(aName.Length()-1));
36 static void CheckSubClose(CFsObject* anObj,TInt aHandle, CSessionFs* aSession)
38 // Close anObj if its not NULL.
41 __PRINT1(_L("CheckSubClose() session 0x0%x"),aSession);
42 __PRINT1(_L("CheckSubClose() anObj 0x0%x"),anObj);
49 // can't have been added to the object index
50 __ASSERT_DEBUG(KErrNotFound==aSession->Handles().At(anObj,ETrue),Fault(ESubOpenBadHandle));
54 aSession->Handles().Remove(aHandle,ETrue);
57 TInt ValidateDrive(TInt aDriveNumber,CFsRequest* aRequest)
59 // Validate a drive number and set iTheDrive.
62 if (aDriveNumber==KDefaultDrive)
63 aDriveNumber=aRequest->Session()->CurrentDrive();
64 if (!RFs::IsValidDrive(aDriveNumber))
66 aRequest->SetDrive(&TheDrives[aDriveNumber]);
70 TInt ValidateDriveDoSubst(TInt aDriveNumber,CFsRequest* aRequest)
72 // Validate a drive number and set iTheDrive.
76 TInt r=ValidateDrive(aDriveNumber,aRequest);
79 if (aRequest->Drive()->IsSubsted())
81 aRequest->SetSubstedDrive(aRequest->Drive());
82 aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
87 void ValidateAtts(TUint /*anEntryAtts*/,TUint& aSetAttMask,TUint& aClearAttMask)
89 // Do not allow the entry type to be changed
92 const TUint KReadOnlySetAtts = KEntryAttVolume |
96 const TUint KReadOnlyClrAtts = KEntryAttVolume |
101 aSetAttMask &= ~KReadOnlySetAtts;
102 aClearAttMask &= ~KReadOnlyClrAtts;
105 void CheckForLeaveAfterOpenL(TInt leaveError, CFsRequest* aRequest, TInt aHandle)
107 // Tidy up in the event of a leave after opening a file or directory
111 CFsObject* anObj=(CFsObject* )aRequest->ScratchValue();
112 CheckSubClose(anObj,aHandle,aRequest->Session());
113 User::Leave(leaveError);
121 : iDriveNumber(0),iAtt(0),iChanged(EFalse),
122 iFSys(NULL),iCurrentMount(NULL),iSubstedDrive(NULL),iSubst(NULL),
123 iMount(NULL),iDriveFlags(0),iMountFailures(0)
126 void TDrive::CreateL(TInt aDriveNumber)
128 // Allocate the drive number and any resources.
131 __PRINT1(_L("TDrive::CreateL(%d)"),aDriveNumber);
132 iDriveNumber=aDriveNumber;
133 iMount=TheContainer->CreateL();
134 TInt r=iLock.CreateLocal();
135 User::LeaveIfError(r);
138 TInt TDrive::CheckMountAndEntryName(const TDesC& aName)
140 // Check drive is mounted then check aName is legal
144 __PRINT1(_L("TDrive::CheckMountAndEntryName Drive%d"),DriveNumber());
146 if (r==KErrNone && IsIllegalFullName(aName))
151 void TDrive::MultiSlotDriveCheck()
153 // Check whether the current drive is a dual-slot/multi-slot
154 // if so, we need to check which drive is connected now and
155 // swap the mapping in LocalDrives::iMapping such that the
156 // mapping of driveNumber to localDriveNumber is correct.
159 //Is this a multislot drive?
160 if(LocalDrives::iIsMultiSlotDrive[iDriveNumber])
162 for(TInt localDrvNum=0; localDrvNum<KMaxLocalDrives; localDrvNum++)
164 // ensure that this local drive is a multi-slot choice for this drive number..
165 if(LocalDrives::iReverseMapping[localDrvNum]==iDriveNumber)
167 // Caps - find out which one is connected
168 TLocalDriveCapsBuf capsInfo;
169 TInt r = LocalDrives::iLocalDrives[localDrvNum].Caps(capsInfo);
172 continue; //go to next localdrive
174 //found a connected drive
177 RDebug::Print(_L("Multislot drive mapping update: DriveNum %d to LocDrv %d"),iDriveNumber,localDrvNum);
180 LocalDrives::iMapping[iDriveNumber] = localDrvNum;
181 break; // Swap complete - don't look any further
188 TInt TDrive::CheckMount()
190 // Check the drive and try to mount a media if not already mounted.
193 __PRINT2(_L("TDrive::CheckMount Drive%d, changed:%d"),DriveNumber(), iChanged);
194 __CHECK_DRIVETHREAD(iDriveNumber);
199 if (iChanged) // If a media change has occurred
202 iChanged=EFalse; // Reset the flag
203 if (IsMounted()) // Dismount the mount if it is still marked as mounted
207 //If we have a dual/multi removable media slot then we may need to
209 MultiSlotDriveCheck();
212 if (!IsMounted()) // Checks that iCurrentMount!=NULL
214 __PRINT(_L("TDrive::CheckMount() Not Mounted"));
215 const TInt KMaxMountFailures = 3;
216 // if we've repeatedly failed to mount, give up until a media change
217 if (iMountFailures >= KMaxMountFailures)
219 __PRINT1(_L("TDrive::CheckMount() retries exceeded, last Err:%d"), iLastMountError);
220 return iLastMountError;
223 if (!ReMount()) // Have we just remounted a mount we have previously encountered?
225 MountFileSystem(EFalse); // If not, mount it for the first time now
227 else if(IsWriteProtected() && IsWriteableResource())
230 return KErrAccessDenied;
234 if (iReason==KErrNone && CurrentMount().LockStatus() > 0)
236 //-- this meand that the mount has drive access objetcs opened (RFormat or RRawDisk)
237 __PRINT1(_L("TDrive::CheckMount() Mount is locked! LockStaus:%d"), CurrentMount().LockStatus());
241 __PRINT1(_L("TDrive::CheckMount returned %d "),iReason);
246 //----------------------------------------------------------------------------
248 Try and re-mount any of the pending media
250 @return ETrue if the mount matching media found and been attached back (set as iCurrentMount)
252 TBool TDrive::ReMount()
254 const TInt mCount=Mount().Count();
255 __PRINT1(_L("TDrive::ReMount() MountCnt:%d"), mCount);
257 const TInt u=(Mount().UniqueID()<<16);
260 //-- try every instance of CMountCB that is associated with this object of TDrive.
261 //-- mounts are stored in the container of mCount elements.
262 //-- if some CMountCB recognises the media it belongs, it means that "remount succeded"
263 for(TInt i=0; i<mCount; i++)
265 CMountCB* pM=(CMountCB*)Mount().At(u|i);
274 //----------------------------------------------------------------------------
276 Try and re-mount the specified media.
278 @return ETrue if remounting succeeded - i.e. the CMountCB instance that matches the media is found in the
279 mounts container (Mount()) and bound to the media.
281 TBool TDrive::ReMount(CMountCB& aMount)
283 __PRINT1(_L("TDrive::ReMount(0x%x)"), &aMount);
286 if (!aMount.IsDismounted() && !aMount.ProxyDriveDismounted())
288 aMount.SetDrive(this);
289 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMount, EF32TraceUidFileSys, DriveNumber());
291 //-- actually, this is asking CMountCB to see if it belongs to the current media.
292 iReason = aMount.ReMount();
294 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMountRet, EF32TraceUidFileSys, iReason);
296 if (iReason == KErrNone) // ReMount succeeded
299 iCurrentMount = &aMount;
300 __PRINT1(_L("TDrive::ReMount for Mount:0x%x OK!"), &aMount);
304 __PRINT2(_L("TDrive::ReMount for Mount:0x%x failed iReason=%d"),&aMount,iReason);
308 __PRINT1(_L("TDrive::ReMount() failed - Mount:0x%x is dismounted"), &aMount);
316 //----------------------------------------------------------------------------
318 Mount the media on the drive. Optionally force a bad media to be mounted.
320 @param apMount out: pointer to the produced CMountCB object; NULL if the CMountCB is not constructed
321 @param aForceMount if ETrue, the filesystem will be forcedly mounted on the drive, disregarding what it contains.
322 @param aFsNameHash file system name hash; see TDrive::MountFileSystem()
324 void TDrive::DoMountFileSystemL(CMountCB*& apMount, TBool aForceMount, TUint32 aFsNameHash)
326 CFileSystem* pMountsFs = NULL; //-- reference to the filesystem that will be producing CMountCB
330 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
332 //-- construct a new CmountCB object.
333 //-- on return pMountsFs will be the pointer to the factory object of CFileSystem that produced this mount
334 apMount = FSys().NewMountExL(this, &pMountsFs, aForceMount, aFsNameHash);
336 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, KErrNone, apMount);
337 __PRINT2(_L("TDrive::MountMediaL created mount:0x%x FileSys:0x%x"), apMount, pMountsFs);
339 ASSERT(pMountsFs && apMount);
341 apMount->SetMountNumber(iMountNumber++);
342 apMount->InitL(*this, pMountsFs); //-- initialise Mount
343 apMount->MountL(aForceMount); //-- mount the file system
344 Mount().AddL(apMount,EFalse); //-- add mount object to the mounts container.
346 iCurrentMount=apMount;
350 //----------------------------------------------------------------------------
352 Mount file system on the drive.
353 @param aForceMount if EFalse, will try to mount the file system normally, the file system implementation will decide if it can work on this drive or not.
354 if ETrue, will mount the file suystem by force, this is used mostly for formatting unrecognisable media.
356 @param aFsNameHash optional parameter. Can specify the concrete file system name (hash). It can be used to force mounting some specific
357 file system. Default value '0' means "not specified / not used"
360 TDrive::iReason on return contains the operation result code.
362 void TDrive::MountFileSystem(TBool aForceMount, TUint32 aFsNameHash /*=0*/ )
364 __PRINT2(_L("TDrive::MountFileSystem aForceMount=%d, FSNameHash:0x%x"),aForceMount, aFsNameHash);
365 __CHECK_DRIVETHREAD(iDriveNumber);
370 iReason=KErrNotReady;
375 TRAP(iReason, DoMountFileSystemL(pM, aForceMount, aFsNameHash));
376 if (iReason == KErrNone)
379 ASSERT(iCurrentMount);
383 iLastMountError = iReason;
385 __PRINT2(_L("TDrive::MountFileSystem 0x%x failed iReason=%d"),pM,iReason);
389 ASSERT(!iCurrentMount);
394 //----------------------------------------------------------------------------
396 Generic mount control method.
397 @param aLevel specifies the operation to perfrom on the mount
398 @param aOption specific option for the given operation
399 @param aParam pointer to generic parameter, its meaning depends on aLevel and aOption
401 @return standard error code.
403 TInt TDrive::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
405 TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControl, EF32TraceUidFileSys, DriveNumber(), aLevel, aOption, aParam);
406 TInt r = CurrentMount().MountControl(aLevel, aOption, aParam);
407 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControlRet, EF32TraceUidFileSys, r);
412 //----------------------------------------------------------------------------
414 Request aFreeSpaceRequired free bytes from the mount associated with this drive.
415 The volume free space on for some filesystems can be changing (usually increasing) after it has been mounted.
416 If the mount supports this functionality, it can block this call until certain number of free bytes encounted if its free
417 space calculation activity hasn't finished yet.
419 @param aFreeSpaceRequired required free space, bytes.
421 @return KErrNone on success and if there is at least aFreeSpaceRequired bytes on the volume
422 KErrDiskFull on success and if there is no aFreeSpaceRequired bytes on the volume
423 system-wide error code otherwise
425 TInt TDrive::RequestFreeSpaceOnMount(TUint64 aFreeSpaceRequired)
433 //-- 1. Try mount-specific request first. If the mount is still performing free space calculations,
434 //-- the caller will be suspended until aFreeSpaceRequired bytes is available or scanning process finishes
436 TUint64 freeSpaceReq = aFreeSpaceRequired;
437 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpace, EF32TraceUidFileSys, DriveNumber());
438 nRes = CurrentMount().RequestFreeSpace(freeSpaceReq);
439 TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(freeSpaceReq), I64HIGH(freeSpaceReq));
442 return (freeSpaceReq >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
446 //-- given Mount doesn't support this functionality, use legacy method
448 nRes = Volume(volInfo);
452 return ((TUint64)volInfo.iFree >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
455 //----------------------------------------------------------------------------
457 Get size of the mounted volume. It can be less than physical volume size because FileSystem data may occupy some space.
459 @param aSize on success mounted volume size in bytes will be returned there
460 @return KErrNone on success, standard error code otherwise
462 TInt TDrive::MountedVolumeSize(TUint64& aSize)
470 //-- 1. Try mount-specific request first. It won't block this call as CMountCB::VolumeL() can do if some background activity is going on the mount
471 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, DriveNumber());
472 nRes = CurrentMount().MountedVolumeSize(aSize);
473 TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, nRes, I64LOW(aSize), I64HIGH(aSize));
477 //-- given Mount doesn't support this functionality, use legacy method
479 nRes = Volume(volInfo);
482 aSize = volInfo.iSize;
488 //----------------------------------------------------------------------------
490 Get _current_ amount of free space on the volume. Some mounts implementations can be updating the amount of free space
493 @param aFreeDiskSpace on success will contain a current amount of free space
494 @return KErrNone on success, standard error code otherwise
497 TInt TDrive::FreeDiskSpace(TInt64& aFreeDiskSpace)
505 //-- 1. Try mount-specific request first. It won't block this call as CMountCB::VolumeL() can do
506 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpace, EF32TraceUidFileSys, DriveNumber());
507 nRes = CurrentMount().GetCurrentFreeSpaceAvailable(aFreeDiskSpace);
508 TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(aFreeDiskSpace), I64HIGH(aFreeDiskSpace));
512 //-- given Mount doesn't support this functionality, use legacy method
514 nRes = Volume(volInfo);
517 aFreeDiskSpace = volInfo.iFree;
523 //----------------------------------------------------------------------------
525 Finalise drive (the mount).
527 @param aOperation describes finalisation operation ,see RFs::TFinaliseDrvMode
528 @param aParam1 not used, for future expansion
529 @param aParam2 not used, for future expansion
531 @return Standard error code
533 TInt TDrive::FinaliseMount(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
539 r = FlushCachedFileInfo();
543 if(IsWriteProtected())
544 return(KErrAccessDenied);
546 TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
547 TRAP(r,CurrentMount().FinaliseMountL(aOperation, aParam1, aParam2));
548 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2Ret, EF32TraceUidFileSys, r);
553 //----------------------------------------------------------------------------
554 /** old implementation */
555 TInt TDrive::FinaliseMount()
561 r = FlushCachedFileInfo();
565 if(IsWriteProtected())
566 return(KErrAccessDenied);
568 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1, EF32TraceUidFileSys, DriveNumber());
569 TRAP(r,CurrentMount().FinaliseMountL());
570 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1Ret, EF32TraceUidFileSys, r);
577 CFileCB* TDrive::LocateFile(const TDesC& aName)
579 // Locate a file of the same name already open on the drive.
582 TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
584 // early out for normal case, list is empty
588 // strip off trailing dots
589 TInt length= aName.Length();
590 while((length !=0) && (aName[length-1]==KExtDelimiter))
595 TPtrC temp(aName.Ptr(),length);
598 tempName.CopyF(temp);
599 TUint32 nameHash=CalcNameHash(tempName);
601 while ((pF=q++)!=NULL)
603 if(nameHash==pF->NameHash())
605 if (pF->FileNameF().Match(tempName)==KErrNone)
613 CFileCache* TDrive::LocateClosedFile(const TDesC& aName, TBool aResurrect)
615 // Locate a recently closed file of the same name on the drive.
618 // strip off trailing dots
619 TInt length= aName.Length();
620 while((length !=0) && (aName[length-1]==KExtDelimiter))
625 TPtrC temp(aName.Ptr(),length);
628 tempName.CopyF(temp);
629 TUint32 nameHash=CalcNameHash(tempName);
631 CFileCache* pF = NULL;
632 CMountCB* currentMount = &CurrentMount();
635 TClosedFileUtils::Lock();
637 TInt count = TClosedFileUtils::Count();
640 CFileCache* fileCache = TClosedFileUtils::At(count);
641 if (&fileCache->Drive() == this &&
642 fileCache->NameHash()== nameHash &&
643 fileCache->FileNameF().Match(tempName)==KErrNone &&
644 &fileCache->Mount() == currentMount)
646 __ASSERT_DEBUG(TClosedFileUtils::IsClosed(fileCache), Fault(EObjRemoveContainerNotFound));
647 __CACHE_PRINT2(_L("CLOSEDFILES: LocateClosedFile(%S, %d\n"), &fileCache->FileNameF(), aResurrect);
650 TClosedFileUtils::ReOpen(fileCache, EFalse);
657 TClosedFileUtils::Unlock();
659 if (pF != NULL && !aResurrect)
669 static TBool IsSubDir(const TDesC& aFullName,const TDesC& aParent)
671 // Returns ETrue if aFullName is a subdirectory of aParent
672 // Assumes aParent is a path name with the trailing backslash removed
676 __ASSERT_DEBUG(aParent.Length() && aParent[aParent.Length()-1]!=KPathDelimiter,Fault(EIsSubDirBadDes));
677 TPtrC entryFullName(NULL,0);
678 TPtrC entryParent(NULL,0);
684 NextInPath(aParent,entryParent,posParent);
685 if (entryParent.Length()==0)
687 NextInPath(aFullName,entryFullName,posFullName);
688 if (entryParent!=entryFullName)
692 if (aFullName.Length()<=posFullName)
694 if (aFullName[posFullName]!=KPathDelimiter)
699 CFileCB* TDrive::LocateFileByPath(const TDesC& aPath)
701 // Locate a file opened in a subdirectory of aPath
705 TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
707 while ((pF=q++)!=NULL)
709 if (IsSubDir(pF->FileName(),aPath))
715 void TDrive::FlushCachedFileInfoL()
717 // Flush data stored in the file control blocks
720 __CHECK_DRIVETHREAD(iDriveNumber);
721 TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
723 while ((pF=q++)!=NULL)
725 if (pF->iAtt&KEntryAttModified)
731 Flushes (asynchronously) all dirty data on this drive and optionally
732 purges non-dirty data
734 aPurgeCache - purges all file caches on this drive AFTER dirty data has ben flushed
736 returns KErrNone if complete
737 CFsRequest::EReqActionBusy if flushing is in progress
738 otherwise one of the other system-wide error codes.
740 TInt TDrive::FlushCachedFileInfo(TBool aPurgeCache)
742 if (iCurrentMount == NULL)
745 TBool driveThread = FsThreadManager::IsDriveThread(iDriveNumber,EFalse);
752 TDblQueIter<CFileCB> q(iCurrentMount->iMountQ);
754 while ((pF=q++)!=NULL)
756 CFileCache* fileCache = pF->FileCache();
758 // Write dirty data if there is a file cache
759 TInt flushDirtyRetCode = CFsRequest::EReqActionComplete;
762 flushDirtyRetCode = fileCache->FlushDirty();
763 if (flushDirtyRetCode == CFsRequest::EReqActionComplete) // nothing to flush
766 fileCache->Purge(EFalse);
768 else if (flushDirtyRetCode == CFsRequest::EReqActionBusy) // flushing
770 ret = flushDirtyRetCode;
774 ret = flushDirtyRetCode;
778 // if no file cache or no dirty data left, update the file entry & attributes
779 if (driveThread && (pF->iAtt&KEntryAttModified) && flushDirtyRetCode == CFsRequest::EReqActionComplete )
781 TRAP(ret, pF->FlushAllL());
793 //----------------------------------------------------------------------------
795 Purge dirty cache data associated with all files on a given mount
797 void TDrive::PurgeDirty(CMountCB& aMount)
799 TDblQueIter<CFileCB> q(aMount.iMountQ);
801 while ((pF=q++)!=NULL)
803 CFileCache* fileCache = pF->FileCache();
806 fileCache->Purge(ETrue);
807 fileCache->MarkFileClean();
812 //----------------------------------------------------------------------------
813 TInt TDrive::ValidateShare(CFileCB& aFile, TShare aReqShare)
815 // Check that the sharing rules are obeyed.
821 case EFileShareExclusive:
822 case EFileShareReadersOnly:
824 case EFileShareReadersOrWriters:
827 return(KErrArgument);
829 switch (aFile.iShare)
831 case EFileShareExclusive:
834 case EFileShareReadersOnly:
836 if (aReqShare != aFile.iShare && aReqShare != EFileShareReadersOrWriters)
840 case EFileShareReadersOrWriters:
841 if (aReqShare==EFileShareExclusive)
844 // If the file is currently open as EFileShareReadersOrWriters then
845 // promote the share to the requested share mode.
847 // If the requested share is EFileShareReadersOnly, verfiy that no
848 // other share has the file open for writing.
851 if (aReqShare == EFileShareReadersOnly)
854 TInt count = FileShares->Count();
857 CFileShare* share = (CFileShare*)(*FileShares)[count];
858 if (&share->File() == &aFile)
860 if(share->iMode & EFileWrite)
862 FileShares->Unlock();
867 FileShares->Unlock();
872 Fault(EDrvIllegalShareValue);
878 void TDrive::DriveInfo(TDriveInfo& anInfo)
880 // Get the drive info.
883 anInfo.iType=EMediaNotPresent;
885 anInfo.iBattery=EBatNotSupported;
886 anInfo.iConnectionBusType=EConnectionBusInternal;
890 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfo, EF32TraceUidFileSys, &FSys(), DriveNumber());
891 FSys().DriveInfo(anInfo,DriveNumber());
892 TRACE3(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfoRet, EF32TraceUidFileSys,
893 anInfo.iType, anInfo.iDriveAtt, anInfo.iMediaAtt);
896 anInfo.iDriveAtt=Att();
899 TInt TDrive::Volume(TVolumeInfo& aVolume)
901 // Get the drive volume info.
907 DriveInfo(aVolume.iDrive);
908 CMountCB& m=CurrentMount();
909 aVolume.iName=m.VolumeName();
910 aVolume.iUniqueID=m.iUniqueID;
911 aVolume.iSize=m.iSize;
913 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeL, EF32TraceUidFileSys, DriveNumber());
914 TRAP(r,m.VolumeL(aVolume))
915 TRACE7(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeLRet, EF32TraceUidFileSys,
916 r, aVolume.iUniqueID, I64LOW(aVolume.iSize), I64HIGH(aVolume.iSize),
917 I64LOW(aVolume.iFree), I64HIGH(aVolume.iFree), aVolume.iFileCacheFlags);
924 void TDrive::SetVolumeL(const TDesC& aName,HBufC*& aBuf)
926 // Set the volume name.
929 __CHECK_DRIVETHREAD(iDriveNumber);
931 TPtr volumeName=aBuf->Des();
933 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeL, EF32TraceUidFileSys, DriveNumber(), aName);
934 CurrentMount().SetVolumeL(volumeName);
935 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeLRet, EF32TraceUidFileSys, KErrNone);
938 delete &CurrentMount().VolumeName();
939 CurrentMount().SetVolumeName(aBuf);
942 TInt TDrive::SetVolume(const TDesC& aName)
944 // Set the volume name.
951 if(IsWriteProtected())
952 return(KErrAccessDenied);
953 TRAP(r,SetVolumeL(aName,pV))
960 TInt TDrive::MkDir(const TDesC& aName)
968 if(IsWriteProtected())
969 return(KErrAccessDenied);
971 newDirName.Set(aName,NULL,NULL);
973 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirL, EF32TraceUidFileSys, DriveNumber(), aName);
974 TRAP(r,CurrentMount().MkDirL(newDirName.FullName()))
975 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirLRet, EF32TraceUidFileSys, r);
980 TInt TDrive::RmDir(const TDesC& aName)
982 // Remove a directory.
989 r=Entry(aName,entry);
992 if (entry.IsDir()==EFalse)
993 return(KErrPathNotFound);
994 if ((entry.iAtt&KEntryAttReadOnly) || IsWriteProtected())
995 return(KErrAccessDenied);
997 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirL, EF32TraceUidFileSys, DriveNumber(), aName);
998 TRAP(r,CurrentMount().RmDirL(aName))
999 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirLRet, EF32TraceUidFileSys, r);
1005 Delete files allowing wild cards.
1007 TInt TDrive::Delete(const TDesC& aName)
1009 TInt r=CheckMountAndEntryName(aName);
1013 if(LocateFile(aName))
1014 return KErrInUse; //-- the file is already opened by someone
1016 // remove from closed queue - NB this isn't strictly necessary if file is read-only or write-protected...
1017 LocateClosedFile(aName, EFalse);
1019 if (IsWriteProtected())
1020 return(KErrAccessDenied);
1022 //-- filesystems' CMountCB::DeleteL() implementations shall check the entry attributes themeselves.
1023 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteL, EF32TraceUidFileSys, DriveNumber(), aName);
1024 TRAP(r,CurrentMount().DeleteL(aName))
1025 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteLRet, EF32TraceUidFileSys, r);
1030 TInt TDrive::CheckMountAndEntryNames(const TDesC& anOldName,const TDesC& aNewName)
1032 // Check mount, that neither is open, and that both names are legal.
1036 TInt r=CheckMountAndEntryName(anOldName);
1039 if (IsIllegalFullName(aNewName))
1040 return(KErrBadName);
1044 TInt TDrive::CheckDirectories(const TDesC& anOldName,const TDesC& aNewName)
1046 // Return KErrAlreadyExists if aNewName exists and
1047 // KErrAccessDenied if anOldName is a directory being moved to a subdirectory of itself
1052 TInt r=Entry(anOldName,entry);
1057 //-- check the length of the destination directory name. It shall not exceed 253 characters.
1058 //-- aNewName looks like "\\dir1" i.e. drive letter and ':' is removed from the name and there is no trailing '\\' in this case.
1060 const TInt maxDirNameLength = KMaxFileName - 3;
1061 if(aNewName.Length() > maxDirNameLength)
1063 if(IsSubDir(aNewName,anOldName))
1064 return(KErrInUse); // rename into a subdir of itself
1065 if (LocateFileByPath(anOldName))
1066 return(KErrInUse); // a file inside anOldName is open
1068 else if (LocateFile(anOldName))
1071 r=Entry(aNewName,entry);
1072 if (r!=KErrNone && r!=KErrNotFound)
1077 TInt TDrive::Rename(const TDesC& anOldName,const TDesC& aNewName)
1079 // Rename files or directories. No wild cards.
1082 __CHECK_DRIVETHREAD(iDriveNumber);
1083 TInt r=CheckMountAndEntryNames(anOldName,aNewName);
1086 TPtrC oldEntryName(StripBackSlash(anOldName));
1087 TPtrC newEntryName(StripBackSlash(aNewName));
1088 r=CheckDirectories(oldEntryName,newEntryName);
1091 if(IsWriteProtected())
1092 return(KErrAccessDenied);
1094 // remove from closed queue
1095 LocateClosedFile(anOldName, EFalse);
1096 LocateClosedFile(aNewName, EFalse);
1098 TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameL, EF32TraceUidFileSys, DriveNumber(), oldEntryName,newEntryName);
1099 TRAP(r,CurrentMount().RenameL(oldEntryName,newEntryName))
1100 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameLRet, EF32TraceUidFileSys, r);
1105 TInt TDrive::Replace(const TDesC& anOldName,const TDesC& aNewName)
1107 // Replace anOldName with aNewName atomically. No wild cards. No directories
1110 TInt r=CheckMountAndEntryNames(anOldName,aNewName);
1114 r=Entry(aNewName,entry);
1115 if (r!=KErrNotFound)
1119 if (entry.IsDir() || entry.IsReadOnly())
1120 return(KErrAccessDenied);
1121 if (LocateFile(aNewName))
1124 r=Entry(anOldName,entry);
1127 if (entry.IsDir() || IsWriteProtected())
1128 return(KErrAccessDenied);
1129 if (LocateFile(anOldName))
1132 // remove from closed queue
1133 LocateClosedFile(anOldName, EFalse);
1134 LocateClosedFile(aNewName, EFalse);
1136 TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceL, EF32TraceUidFileSys, DriveNumber(), anOldName, aNewName);
1137 TRAP(r,CurrentMount().ReplaceL(anOldName,aNewName))
1138 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceLRet, EF32TraceUidFileSys, r);
1143 TInt TDrive::Entry(const TDesC& aName,TEntry& anEntry)
1145 // Get the entry details.
1148 __CHECK_DRIVETHREAD(iDriveNumber);
1149 TInt r=CheckMountAndEntryName(aName);
1152 TPtrC entryName(StripBackSlash(aName));
1153 TRAP(r,DoEntryL(entryName,anEntry));
1157 else if (r==KErrPathHidden)
1163 void TDrive::DoEntryL(const TDesC& aName, TEntry& anEntry)
1165 // Get entry details
1168 FlushCachedFileInfoL();
1170 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryL, EF32TraceUidFileSys, DriveNumber(), aName);
1171 CurrentMount().EntryL(aName,anEntry);
1172 TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryLRet, EF32TraceUidFileSys,
1173 KErrNone, anEntry.iAtt,
1174 I64LOW(anEntry.iModified.Int64()), I64HIGH(anEntry.iModified.Int64()),
1179 TInt TDrive::CheckAttributes(const TDesC& aName,TUint& aSetAttMask,TUint& aClearAttMask)
1181 // Validate the changes against the current entry attributes
1186 TRAPD(r,DoEntryL(aName,entry));
1189 ValidateAtts(entry.iAtt,aSetAttMask,aClearAttMask);
1193 TInt TDrive::SetEntry(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
1195 // Set the entry details.
1198 __CHECK_DRIVETHREAD(iDriveNumber);
1199 TInt r=CheckMountAndEntryName(aName);
1202 TPtrC entryName(StripBackSlash(aName));
1203 CFileCB* pF=LocateFile(entryName);
1206 r=CheckAttributes(entryName,aSetAttMask,aClearAttMask);
1209 if (IsWriteProtected())
1210 return(KErrAccessDenied);
1212 if (aTime!=nullTime)
1213 aSetAttMask|=KEntryAttModified;
1215 TRACEMULT6(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryL, EF32TraceUidFileSys,
1216 DriveNumber(), aName, I64LOW(aTime.Int64()), I64HIGH(aTime.Int64()), aSetAttMask, aClearAttMask);
1217 TRAP(r,CurrentMount().SetEntryL(entryName,aTime,aSetAttMask,aClearAttMask))
1218 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryLRet, EF32TraceUidFileSys, r);
1223 TInt TDrive::FileTemp(CFsRequest* aRequest,TInt& aHandle,const TDesC& aPath,TDes& aName,TUint aMode)
1225 // Create a temporary file and return the file name.
1228 __CHECK_DRIVETHREAD(iDriveNumber);
1230 TInt len=aName.Length();
1231 TInt t=User::TickCount()&0xfffff;
1233 for (TInt retry=0;retry<KMaxTempNameAttempts;retry++)
1235 aName.SetLength(len);
1236 aName.AppendFormat(_L("TMP%05x.$$$"),t);
1238 TInt r=Entry(aName,e);
1241 if (r!=KErrNotFound)
1243 return(FileOpen(aRequest,aHandle,aName,aMode,EFileCreate));
1245 t=((t|1)*13)&0xfffff;
1247 return(KErrGeneral);
1250 LOCAL_C HBufC* CreateFileNameL(const TDesC& aName)
1252 // Create a HBufC from aName
1253 // Converts _L("\\F32.\\GROUP\\release.") to _L("\\F32\\GROUP\\release")
1257 TParsePtrC name(aName);
1259 fileName.Append(KPathDelimiter);
1261 if (name.Path().Length())
1264 TPtrC entry(NULL,0);
1267 NextInPath(name.Path(),entry,pos);
1268 if (entry.Length()==0)
1270 fileName.Append(entry);
1271 fileName.Append(KPathDelimiter);
1275 fileName.Append(name.Name());
1276 if (name.Ext().Length()>1)
1277 fileName.Append(name.Ext());
1278 return(fileName.AllocL());
1281 void TDrive::FileOpenL(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB*& aFileCB,CFileShare*& aFileShare)
1283 // Open/Create/Replace a file.
1288 TInt r = CheckMount();
1292 if (IsIllegalFullName(aRequest->Src()))
1293 User::Leave(KErrBadName);
1295 if (CurrentMount().Locked())
1296 User::Leave(KErrInUse);
1298 if ((aMode & EFileWrite) != 0)
1300 TDriveInfo driveInfo;
1301 DriveInfo(driveInfo);
1302 if (driveInfo.iType==EMediaRom || (driveInfo.iMediaAtt&KMediaAttWriteProtected)!=0)
1303 User::Leave(KErrAccessDenied);
1306 TShare share=(TShare)(aMode&KFileShareMask);
1307 if (share==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
1308 User::Leave(KErrArgument);
1310 if (aMode & EFileReadAsyncAll)
1312 // Async read all mode is not compatible with EFileShareExclusive or EFileShareReadersOnly,
1313 // as these modes prevent a writer from accessing the file and completing the request.
1314 if(share == EFileShareExclusive || share == EFileShareReadersOnly)
1315 User::Leave(KErrArgument);
1318 // check for silly cache on / off combinations
1319 const TUint KBadWriteMode = EFileWriteBuffered | EFileWriteDirectIO;
1320 const TUint KBadReadMode = EFileReadBuffered | EFileReadDirectIO;
1321 const TUint KBadReadAheadMode = EFileReadAheadOn | EFileReadAheadOff;
1322 const TUint KBadReadAheadMode2 = EFileReadDirectIO | EFileReadAheadOn;
1323 if (((aMode & KBadWriteMode) == KBadWriteMode) ||
1324 ((aMode & KBadReadMode) == KBadReadMode) ||
1325 ((aMode & KBadReadAheadMode) == KBadReadAheadMode) ||
1326 ((aMode & KBadReadAheadMode2) == KBadReadAheadMode2))
1328 User::Leave(KErrArgument);
1331 // Only allow delete on close for a newly created file.
1332 if ((aMode & EDeleteOnClose) && (anOpen!=EFileCreate))
1333 User::Leave(KErrArgument);
1335 CFileCB* pF=LocateFile(aName);
1336 CFileCache* pFileCache = NULL;
1337 TBool openFile=EFalse;
1340 if (pF->iShare==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
1341 User::Leave(KErrInUse);
1342 if (anOpen==EFileCreate)
1343 User::Leave(KErrAlreadyExists);
1344 TInt r=ValidateShare(*pF,share);
1347 if ((r=pF->Open())!=KErrNone)
1350 pFileCache = pF->FileCache();
1354 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1356 //-- construct CFileCB object, belonging to the corresponding mount
1357 pF = aFileCB = CurrentMount().NewFileL();
1359 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileLRet, EF32TraceUidFileSys, r, pF);
1360 TDrive* createdDrive=!aRequest->SubstedDrive() ? this : aRequest->SubstedDrive();
1362 HBufC* fileName = CreateFileNameL(aName);
1364 pF->InitL(this, createdDrive, fileName);
1369 CurrentMount().iMountQ.AddLast(*pF);
1370 Files->AddL(pF,ETrue);
1373 CFileShare* pS=aFileShare=new(ELeave) CFileShare(pF);
1375 // We need to call CFileCB::PromoteShare immediately after the CFileShare
1376 // instance is created since the destructor calls CFileCB::DemoteShare()
1377 // which checks the share count is non-zero
1379 pF->PromoteShare(pS);
1383 FileShares->AddL(pS,ETrue);
1384 aHandle=aRequest->Session()->Handles().AddL(pS,ETrue);
1389 TRACEMULT5(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenL, EF32TraceUidFileSys, DriveNumber(), aName, aMode, (TUint) anOpen, (TUint) pF);
1390 CurrentMount().FileOpenL(aName,aMode,anOpen,pF);
1391 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenLRet, EF32TraceUidFileSys, KErrNone);
1393 // Delete on close may now be safely flagged if required.
1394 // The file did not exist on the media prior to the
1395 // CMountCB::FileOpenL() call for the case of a create.
1396 if ((aMode & EDeleteOnClose) && (anOpen==EFileCreate))
1397 pF->SetDeleteOnClose();
1399 TBool localBufferSuppport = (CurrentMount().LocalBufferSupport(pF) == KErrNone)?(TBool)ETrue:(TBool)EFalse;
1400 pF->SetLocalBufferSupport(localBufferSuppport);
1401 if (localBufferSuppport)
1403 // if file exists on closed queue resurrect it or discard it,
1404 // depending on the file open mode
1405 pFileCache = LocateClosedFile(aName, anOpen == EFileOpen?(TBool)ETrue:(TBool)EFalse);
1408 pFileCache = pFileCache->ReNewL(*pS); // NB may return NULL if caching not enabled
1412 pFileCache = CFileCache::NewL(*pS); // NB may return NULL if caching not enabled
1415 // set the cached size to be the same as the uncached size
1416 pF->SetCachedSize64(pF->Size64());
1420 __CACHE_PRINT(_L("TDrive::FileOpenL(), Local buffers not supported"));
1424 // initialize share mode flags
1425 if (pFileCache != NULL)
1426 pFileCache->Init(*pS);
1429 TInt TDrive::FileOpen(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen)
1431 // Open/Create/Replace a file.
1434 __CHECK_DRIVETHREAD(iDriveNumber);
1436 CFileShare* pS=NULL;
1438 TRAPD(r,FileOpenL(aRequest,aHandle,aName,aMode,anOpen,pF,pS))
1440 // Allow files > 2GB-1 to be opened only if EFileBigFile is specified in iMode
1441 if (r == KErrNone && pS && ((TUint64)pS->File().Size64() > KMaxLegacyFileSize) && (!(pS->IsFileModeBig())))
1448 else if (r==KErrPathHidden)
1453 CheckSubClose(pS,aHandle,aRequest->Session());
1458 void TDrive::DirOpenL(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType,CDirCB*& aDir)
1460 // Open a directory listing. Leave on error.
1463 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1465 CDirCB* pD = aDir = CurrentMount().NewDirL(); //-- construct CDirCB object, belonging to the corresponding mount
1467 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirLRet, EF32TraceUidFileSys, KErrNone, pD);
1469 // modify resource counter after initialisation to ensure correct cleanup
1470 AddResource(CurrentMount());
1472 pD->iUidType=aUidType;
1473 Dirs->AddL(pD,ETrue);
1474 aHandle=aSession->Handles().AddL(pD,ETrue);
1476 TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenL, EF32TraceUidFileSys, DriveNumber(), aName, (TUint) pD);
1477 CurrentMount().DirOpenL(aName,pD);
1478 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenLRet, EF32TraceUidFileSys, KErrNone);
1481 TInt TDrive::DirOpen(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType)
1483 // Open a directory listing.
1486 TInt r=CheckMountAndEntryName(aName);
1489 if (CurrentMount().Locked())
1493 TRAP(r,DirOpenL(aSession,aHandle,aName,anAtt,aUidType,pD));
1497 else if (r==KErrPathHidden)
1501 CheckSubClose(pD,aHandle,aSession);
1506 TInt TDrive::ReadFileSection(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1508 // Starting from aPos, read aLength bytes of a file into a Trg,
1509 // regardless of lock state
1512 return ReadFileSection64(aName, aPos, aTrg, aLength, aMessage);
1516 TInt TDrive::ReadFileSection64(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1518 // Starting from aPos, read aLength bytes of a file into a Trg,
1519 // regardless of lock state
1523 // flush dirty data if already open
1525 IsFileOpen(aName, file);
1526 if (file && file->FileCache())
1528 if (file->FileCache()->FlushDirty() == CFsRequest::EReqActionBusy)
1529 return CFsRequest::EReqActionBusy;
1532 __PRINT(_L("TDrive::ReadSection"));
1533 TInt r=CheckMountAndEntryName(aName);
1536 TPtrC entryName(StripBackSlash(aName));
1538 TRACETHREADID(aMessage);
1539 TRACEMULT7(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionL, EF32TraceUidFileSys,
1540 DriveNumber(), aName, I64LOW(aPos), I64HIGH(aPos), (TUint) aTrg, aLength, I64LOW(threadId));
1541 TRAP(r,ReadSectionL(entryName,aPos,aTrg,aLength,aMessage));
1542 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionLRet, EF32TraceUidFileSys, r);
1546 else if (r==KErrPathHidden)
1553 void TDrive::ReadSectionL(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1555 // Starting from aPos, read aLength bytes of a file into a Trg,
1556 // regardless of lock state
1559 __PRINT(_L("TDrive::ReadSectionL"));
1561 FlushCachedFileInfoL();
1562 CurrentMount().ReadSection64L(aName,aPos,aTrg,aLength,aMessage);
1566 Check the disk's integrity
1568 TInt TDrive::CheckDisk()
1570 TInt r=CheckMount();
1572 TRAP(r,FlushCachedFileInfoL());
1575 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1, EF32TraceUidFileSys, DriveNumber());
1576 r=CurrentMount().CheckDisk();
1577 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1Ret, EF32TraceUidFileSys, r);
1585 TInt TDrive::CheckDisk(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
1587 TInt r=CheckMount();
1589 TRAP(r,FlushCachedFileInfoL());
1592 TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
1593 r=CurrentMount().CheckDisk(aOperation, aParam1, aParam2);
1594 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2Ret, EF32TraceUidFileSys, r);
1600 TInt TDrive::ScanDrive()
1602 __CHECK_DRIVETHREAD(iDriveNumber);
1603 TInt r=CheckMount();
1606 if(IsWriteProtected())
1607 return(KErrAccessDenied);
1608 TRAP(r,FlushCachedFileInfoL());
1613 // Empty closed file queue
1614 TClosedFileUtils::Remove(DriveNumber());
1616 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1, EF32TraceUidFileSys, DriveNumber());
1617 r = CurrentMount().ScanDrive();
1618 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1Ret, EF32TraceUidFileSys, r);
1627 TInt TDrive::ScanDrive(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
1629 __CHECK_DRIVETHREAD(iDriveNumber);
1630 TInt r=CheckMount();
1633 if(IsWriteProtected())
1634 return(KErrAccessDenied);
1635 TRAP(r,FlushCachedFileInfoL());
1640 // Empty closed file queue
1641 TClosedFileUtils::Remove(DriveNumber());
1643 TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
1644 r = CurrentMount().ScanDrive(aOperation, aParam1, aParam2);
1645 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2Ret, EF32TraceUidFileSys, r);
1651 TInt TDrive::GetShortName(const TDesC& aName,TDes& aShortName)
1653 // Get the short name associated with a long file name
1656 TInt r=CheckMountAndEntryName(aName);
1659 TPtrC entryName(StripBackSlash(aName));
1661 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
1662 TRAP(r,CurrentMount().GetShortNameL(entryName,aShortName));
1663 TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameLRet, EF32TraceUidFileSys, r, aShortName);
1668 TInt TDrive::GetLongName(const TDesC& aShortName,TDes& aLongName)
1670 // Get the long name associated with a short file name
1673 TInt r=CheckMountAndEntryName(aShortName);
1676 TPtrC entryName(StripBackSlash(aShortName));
1678 TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
1679 TRAP(r,CurrentMount().GetLongNameL(entryName,aLongName));
1680 TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameLRet, EF32TraceUidFileSys, r, aLongName);
1687 Query whether the file is open or not.
1689 TInt TDrive::IsFileOpen(const TDesC& aFileName,CFileCB*& aFileCB)
1691 __CHECK_DRIVETHREAD(iDriveNumber);
1695 TInt r=CheckMountAndEntryName(aFileName);
1700 TInt count=Files->Count();
1702 // create a hash to speed up the search
1704 TFileName foldedName;
1708 foldedName.CopyF(aFileName);
1709 nameHash=CalcNameHash(foldedName);
1714 CFileCB* file=(CFileCB*)(*Files)[count];
1716 if ((&file->Drive()==this) && nameHash == file->NameHash() && file->FileNameF().Match(foldedName)!=KErrNotFound)
1726 TInt TDrive::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
1728 // Return the start of the file if it is in rom
1731 TInt r=CheckMount();
1733 CurrentMount().IsFileInRom(aFileName,aFileStart);
1737 TBool TDrive::IsWriteProtected()
1739 // return true if the media is write protected
1742 // __CHECK_DRIVETHREAD(iDriveNumber);
1744 drvInfo.iMediaAtt=0;
1746 FSys().DriveInfo(drvInfo,DriveNumber());
1747 return((drvInfo.iMediaAtt&KMediaAttWriteProtected)!=0);
1754 Checks whether any resource that could write to disk is open on
1757 @return True, if a resource that could write to disk is open on
1758 the current mount, false otherwise.
1760 EXPORT_C TBool TDrive::IsWriteableResource() const
1762 // __CHECK_DRIVETHREAD(iDriveNumber);
1763 if(iCurrentMount==NULL)
1765 if(iCurrentMount->LockStatus()>0)
1767 // check format subsessions
1769 TInt count=Formats->Count();
1772 CFormatCB* format=(CFormatCB*)(*Formats)[count];
1773 if(&format->Mount()==iCurrentMount)
1780 // check raw disk subsessions
1782 count=RawDisks->Count();
1785 CRawDiskCB* rawDisk=(CRawDiskCB*)(*RawDisks)[count];
1786 if(&rawDisk->Mount()==iCurrentMount && !rawDisk->IsWriteProtected())
1794 else if(iCurrentMount->LockStatus()<0)
1796 // check file share subsessions
1798 TInt count=FileShares->Count();
1801 CFileShare* fileShare=(CFileShare*)(*FileShares)[count];
1802 if (&fileShare->File().Mount()==iCurrentMount && ((fileShare->iMode&EFileWrite)!=0))
1804 FileShares->Unlock();
1808 FileShares->Unlock();
1817 Tests whether the current function can cause a write to disk.
1819 @return True, if the current function can cause a write to disk,
1822 EXPORT_C TBool TDrive::IsCurrentWriteFunction() const
1824 // __CHECK_DRIVETHREAD(iDriveNumber);
1825 CDriveThread* pT=NULL;
1826 TInt r=FsThreadManager::GetDriveThread(iDriveNumber, &pT);
1827 __ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveCurrentWriteFunction));
1828 return(pT->IsRequestWriteable());
1834 TInt TDrive::ForceRemountDrive(const TDesC8* aMountInfo,TInt aMountInfoMessageHandle,TUint aFlags)
1836 // Force a remount of the drive
1839 __PRINT(_L("TDrive::ForceRemountDrive"));
1840 __CHECK_DRIVETHREAD(iDriveNumber);
1842 return(KErrNotReady);
1845 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1846 TRAP(r,pM=FSys().NewMountL());
1847 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1852 TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDrive, EF32TraceUidFileSys,
1853 DriveNumber(), aMountInfo, aMountInfoMessageHandle, aFlags);
1854 r=pM->ForceRemountDrive(aMountInfo,aMountInfoMessageHandle,aFlags);
1855 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDriveRet, EF32TraceUidFileSys, r);
1861 TBool TDrive::IsExtensionMounted(CProxyDriveFactory* aFactory)
1863 // return ETrue if extension mounted on the drive
1866 for(TInt i=0;i<iExtInfo.iCount;++i)
1868 if(iExtInfo.iInfo[i].iFactory==aFactory)
1874 TInt TDrive::MountExtension(CProxyDriveFactory* aFactory,TBool aIsPrimary)
1876 // Mount an extension
1879 __PRINT1(_L("TDrive::MountExtension aIsPrimary=%d"),aIsPrimary);
1882 __CHECK_MAINTHREAD();
1883 // primary extension mounted before file system since it must be present
1884 // for successful mount
1885 __ASSERT_ALWAYS(!iFSys,Fault(EMountExtensionFSys));
1886 if(iExtInfo.iCount!=0)
1887 return(KErrAccessDenied);
1888 iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
1889 iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=ETrue;
1892 __CHECK_DRIVETHREAD(iDriveNumber);
1893 // must be a secondary extension
1895 return(KErrNotReady);
1896 TBool extSupported = iFSys->IsExtensionSupported();
1897 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECFileSystemIsExtensionSupported, EF32TraceUidFileSys, extSupported);
1899 return(KErrNotSupported);
1900 if(IsExtensionMounted(aFactory))
1901 return(KErrAlreadyExists);
1902 if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
1904 if(iExtInfo.iCount>=KMaxExtensionCount)
1905 return(KErrAccessDenied);
1906 iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
1907 iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=EFalse;
1908 // now dismount and mount so that the extension incorporated
1910 TInt r=CheckMount();
1911 // if mount fails then remove the secondary extension
1915 __ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount0));
1920 TInt TDrive::DismountExtension(CProxyDriveFactory* aFactory, TBool /*aIsPrimary*/)
1922 // Dismount an extension
1925 __PRINT(_L("TDrive::DismountExtension"));
1926 __CHECK_DRIVETHREAD(iDriveNumber);
1928 // Empty closed file queue
1929 TClosedFileUtils::Remove(DriveNumber());
1931 if(iExtInfo.iCount==0)
1932 return(KErrNotFound);
1933 if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
1935 for(TInt i=0;i<iExtInfo.iCount;++i)
1937 if(iExtInfo.iInfo[i].iFactory==aFactory)
1939 // cannot dismount a primary extension without dismounting the file system
1940 if(i==0 && iExtInfo.iInfo[i].iIsPrimary)
1941 return(KErrAccessDenied);
1942 // slide any remaining extensions down
1943 for(TInt j=i+1;j<iExtInfo.iCount;++j)
1944 iExtInfo.iInfo[j-1].iFactory=iExtInfo.iInfo[j].iFactory;
1946 __ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount1));
1951 return(KErrNotFound);
1954 TInt TDrive::ExtensionName(TDes& aExtensionName,TInt aPos)
1956 // Return the extension name
1959 __CHECK_DRIVETHREAD(iDriveNumber);
1962 return(KErrNotReady);
1964 if(aPos<iExtInfo.iCount)
1966 aExtensionName=iExtInfo.iInfo[aPos].iFactory->Name();
1969 return(KErrNotFound);
1972 #if defined(_LOCKABLE_MEDIA)
1974 TInt TDrive::LockDevice(TMediaPassword& aOld,TMediaPassword& aNew,TBool aStore)
1976 // Lock media device
1979 __PRINT(_L("TDrive::LockDevice"));
1980 __CHECK_DRIVETHREAD(iDriveNumber);
1982 return(KErrNotReady);
1985 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1986 TRAP(r,pM=FSys().NewMountL());
1987 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1992 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBLock, EF32TraceUidFileSys, DriveNumber(), aStore);
1993 r=pM->Lock(aOld,aNew,aStore);
1994 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBLockRet, EF32TraceUidFileSys, r);
2000 TInt TDrive::UnlockDevice(TMediaPassword& aPassword,TBool aStore)
2002 // Unlock media device
2005 __PRINT(_L("TDrive::UnlockDevice"));
2006 __CHECK_DRIVETHREAD(iDriveNumber);
2008 return(KErrNotReady);
2011 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
2012 TRAP(r,pM=FSys().NewMountL());
2013 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
2017 // reset mount failure count - which is likely to be non-zero if drive is locked
2022 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlock, EF32TraceUidFileSys, DriveNumber(), aStore);
2023 r=pM->Unlock(aPassword,aStore);
2024 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlockRet, EF32TraceUidFileSys, r);
2030 TInt TDrive::ClearDevicePassword(TMediaPassword& aPassword)
2032 // Clear password of media device
2035 __PRINT(_L("TDrive::ClearDevicePassword"));
2036 __CHECK_DRIVETHREAD(iDriveNumber);
2038 return(KErrNotReady);
2041 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
2042 TRAP(r,pM=FSys().NewMountL());
2043 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
2048 // ClearPassword() will only work if the card is already unlocked.
2049 // If the stack powers down, the card will become locked, so now that TBusLocalDrive::Caps()
2050 // no longer powers up ths stack, we need to unlock the card first - but ignore the error as
2051 // the stack may unlock from the password store.
2054 if (info.iMediaAtt & KMediaAttLocked)
2055 UnlockDevice(aPassword, EFalse);
2057 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPassword, EF32TraceUidFileSys, DriveNumber());
2058 r=pM->ClearPassword(aPassword);
2059 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPasswordRet, EF32TraceUidFileSys, r);
2065 TInt TDrive::EraseDevicePassword()
2067 // Erase password from the media device
2070 __PRINT(_L("TDrive::EraseDevicePassword"));
2071 __CHECK_DRIVETHREAD(iDriveNumber);
2073 return(KErrNotReady);
2076 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
2077 TRAP(r,pM=FSys().NewMountL());
2078 TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
2083 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePassword, EF32TraceUidFileSys, DriveNumber());
2084 r=pM->ErasePassword();
2085 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePasswordRet, EF32TraceUidFileSys, r);
2093 TInt TDrive::LockDevice(TMediaPassword& /*aOld*/,TMediaPassword& /*aNew*/,TBool /*aStore*/)
2095 // Lock media device
2098 return(KErrNotSupported);
2101 TInt TDrive::UnlockDevice(TMediaPassword& /*aPassword*/,TBool /*aStore*/)
2103 // Unlock media device
2106 return(KErrNotSupported);
2109 TInt TDrive::ClearDevicePassword(TMediaPassword& /*aPassword*/)
2111 // Clear password of media device
2114 return(KErrNotSupported);
2117 TInt TDrive::EraseDevicePassword(TMediaPassword& /*aPassword*/)
2119 // Clear password of media device
2122 return(KErrNotSupported);
2131 Gets the current notification state, which indicates whether the client
2132 is notified of any read or write failures.
2134 The notification status is a property of the current session with
2135 the file server, the value of which is stored in CSessionFs::iNotifyUser.
2136 If set to ETrue, the client will receive notifications from the file system.
2138 Called by CMountCB::GetNotifyUser().
2140 @return True, if the client receives notifications from the file system,
2145 EXPORT_C TBool TDrive::GetNotifyUser()
2147 __CHECK_DRIVETHREAD(iDriveNumber);
2148 if(iDriveFlags & ENotifyOff)
2152 CDriveThread* pT=NULL;
2154 const TInt r=FsThreadManager::GetDriveThread(iDriveNumber,&pT);
2156 //-- if this drive is synchronous, i.e. all requests are processed in the main FS thread,
2157 //-- pretend that user notifications are turned off to avoid panic in the assert below.
2158 //-- for synch. drives pT will always be NULL and it's not possible to obtain CSessionFs by drive number.
2159 if(r == KErrAccessDenied)
2162 __ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveGetNotifyUser));
2163 return(pT->IsSessionNotifyUser());
2171 Dismounts the current mount. This is method is called from outside, so do some finalisation work on mount.
2172 After calling this function there is no current mount on the drive.
2174 EXPORT_C void TDrive::Dismount()
2176 __PRINT1(_L("TDrive::Dismount() iCurrentMount:0x%x"),iCurrentMount);
2182 TRAP_IGNORE(FlushCachedFileInfoL());
2184 //-- try our best to finalise the mount (the mount can decide to do some job during finalisation, e.g. write some data)
2185 TRAP_IGNORE(iCurrentMount->FinaliseMountL());
2194 Forcibly dismounts the current mount and prevents it being remounted.
2195 After calling this function there is no current mount on the drive.
2197 void TDrive::ForceDismount()
2199 __PRINT1(_L("TDrive::ForceDismount() iCurrentMount:0x%x"),iCurrentMount);
2206 TRAP_IGNORE(FlushCachedFileInfoL());
2207 iCurrentMount->SetDismounted(); //! this affects TDrive::ReMount()
2212 An internal method. Dismounts and closes a current mount.
2213 This method must not involve writing data to the media, because it could have beeen physically changed before.
2214 Called only from TDrive::CheckMount().
2216 void TDrive::DoDismount()
2218 __PRINT1(_L("TDrive::DoDismount() iCurrentMount:0x%x"),iCurrentMount);
2225 TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismounted, EF32TraceUidFileSys, DriveNumber());
2226 iCurrentMount->Dismounted();
2227 TRACE0(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismountedRet, EF32TraceUidFileSys);
2229 iCurrentMount->Close();
2235 Return the number of active mounts associated with this drive.
2236 (inactive mounts are those that have been forcibly dismounted)
2238 TInt TDrive::ActiveMounts() const
2240 TInt activeMounts = 0;
2242 TInt idx = Mount().Count();
2245 if(((CMountCB*)Mount()[idx])->IsDismounted())
2251 __PRINT1(_L("TDrive::ActiveMounts = %d"), activeMounts);
2252 return activeMounts;
2259 Reactivate any disactive mounts on the drive following a dismount.
2260 (inactive mounts are those that have been foribly dismounted)
2262 void TDrive::ReactivateMounts()
2264 __PRINT(_L("TDrive::ReactivateMounts"));
2266 TInt idx = Mount().Count();
2269 ((CMountCB*)Mount()[idx])->SetDismounted(EFalse);
2277 Increments the drive dismount lock. This defers dismount
2278 of a file system until all clients have notified that it
2281 @see RFs::NotifyDismount
2283 void TDrive::DismountLock()
2284 { iDismountLock++; }
2290 Decrements the drive dismount lock. When the lock count
2291 reaches zero, the file system may be unmounted
2293 @see RFs::AllowDismount
2294 @return The new lock count
2296 TInt TDrive::DismountUnlock()
2298 return(--iDismountLock);
2305 Return the state of the dismount lock.
2307 TBool TDrive::DismountLocked() const
2308 { return(iDismountLock); }
2314 Pending flag - set while waiting for clients to accept the dismount
2316 void TDrive::SetDismountDeferred(TBool aPending)
2319 iDriveFlags |= EDismountDeferred;
2321 iDriveFlags &= ~EDismountDeferred;
2326 TInt TDrive::ControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2)
2328 // General purpose test interface - .FSY specific.
2331 TInt r=CheckMount();
2332 if(r==KErrNone || (r==KErrInUse && iReason==KErrNone))
2334 TRACETHREADID(aMessage);
2335 TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIO, EF32TraceUidFileSys,
2336 DriveNumber(), aCommand, aParam1, aParam2, I64LOW(threadId));
2337 r=CurrentMount().ControlIO(aMessage,aCommand,aParam1,aParam2);
2338 TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIORet, EF32TraceUidFileSys, r);
2347 Gets the drive attributes
2349 @return The drive attributes.
2351 EXPORT_C TUint TDrive::Att()
2357 void TDrive::SetAtt(TUint aValue)
2359 // set drive attributes
2365 EXPORT_C TBool TDrive::IsDriveThread() const
2367 // Return ETrue if the current thread id is the same as that of the drive's drive thread
2370 return(FsThreadManager::IsDriveThread(iDriveNumber,ETrue));
2373 EXPORT_C TBool TDrive::IsMainThread() const
2375 // Reture ETrue if the current thread id is the same as that of the main file server thread
2378 return(FsThreadManager::IsMainThread());
2381 EXPORT_C void TDrive::DriveFault(TBool aDriveError) const
2387 ::Fault(EFsDriveThreadError);
2389 ::Fault(EFsMainThreadError);
2392 TInt TDrive::ClampFile(const TDesC& aName, TAny* aHandle)
2394 // Attempt to clamp file
2397 CMountCB* mount = (CMountCB*)&(CurrentMount());
2398 TInt driveNo = DriveNumber();
2399 return(mount->ClampFile(driveNo,aName,aHandle));
2403 TInt TDrive::UnclampFile(CMountCB* aMount, RFileClamp* aHandle)
2405 // Attempt to unclamp file
2408 return(aMount->UnclampFile(aHandle));
2412 TInt TDrive::ClampsOnDrive()
2414 // Returns the number of clamps on this drive
2418 TInt clamps = IsMounted()?((CMountCB*)&(CurrentMount()))->NoOfClamps():0;
2425 void TDrive::SetClampFlag(TBool aClamped)
2427 // Indicate if any files are clamped
2431 iDriveFlags |= EClampPresent;
2433 iDriveFlags &= ~EClampPresent;
2437 TBool TDrive::ClampFlag()
2439 // Report if any files are clamped
2441 { return(iDriveFlags & EClampPresent); }
2445 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
2446 TInt TDrive::ClearDeferredDismount()
2447 // debug-only function for testing
2450 FsNotify::HandleDismount(EFsDismountRegisterClient, DriveNumber(), ETrue, KErrNone);
2451 SetDismountDeferred(EFalse);
2458 TInt TDrive::DismountProxyDrive()
2460 // Dismount a proxy drive
2463 __PRINT(_L("TDrive::DismountProxyDrive"));
2464 __CHECK_DRIVETHREAD(iDriveNumber);
2466 if (!IsProxyDrive(iDriveNumber) || LocalDrives::DriveNumberToLocalDriveNumber(iDriveNumber) == KDriveInvalid)
2467 return KErrArgument;
2473 // Prevent ALL inactive mounts from EVER being remounted as they MAY (& probably do) point to
2474 // this proxy-drive which we are about to delete....
2475 // NB We could try to find out which mounts actually use this particular proxy-drive, but that's
2476 // a bit tricky to determine if there are extensions present as CMountCB::ProxyDrive() will only
2477 // return the first proxy drive in the chain.
2478 TInt mCount=Mount().Count();
2479 TInt u=(Mount().UniqueID()<<16);
2480 for (TInt i=0;i<mCount;i++)
2482 CMountCB* pM=(CMountCB*)Mount().At(u|i);
2483 pM->SetProxyDriveDismounted();
2486 FsThreadManager::LockDrive(iDriveNumber);
2487 // Proxy drives are responsible for managing the drive threads...
2488 FsThreadManager::CloseDrive(iDriveNumber);
2489 LocalDrives::ClearProxyDriveMapping(iDriveNumber);
2490 FsThreadManager::UnlockDrive(iDriveNumber);
2495 //----------------------------------------------------------------------------
2497 Complete, remove and delete notification requests
2498 @param aCompletionCode completion code for some notifications
2500 void TDrive::DoCompleteDismountNotify(TInt aCompletionCode)
2502 FsNotify::HandleDismount(EFsDismountRegisterClient, iDriveNumber, ETrue, KErrNone);
2503 FsNotify::HandleDismount(EFsDismountNotifyClients, iDriveNumber, ETrue, aCompletionCode);
2504 FsNotify::HandleDismount(EFsDismountForceDismount, iDriveNumber, ETrue, aCompletionCode);
2507 //----------------------------------------------------------------------------
2509 a helper method that allows forced dismounting current mount for volume formatting.
2511 TInt TDrive::ForceUnmountFileSystemForFormatting()
2515 //-- check if there are any clamps on this drive
2516 nRes = ClampsOnDrive();
2520 //-- purge all dirty data in the files associated with this drive's mount
2521 CDriveThread* pT=NULL;
2522 nRes = FsThreadManager::GetDriveThread(DriveNumber(), &pT);
2523 if(nRes == KErrNone && pT)
2525 pT->CompleteReadWriteRequests();
2528 PurgeDirty(CurrentMount());
2534 DoCompleteDismountNotify(KErrDisMounted); //-- complete all dismount notifications
2539 //-----------------------------------------------------------------------------
2541 Instantiate CFormatCB object for formatting the file ssytem on the given TDrive.
2543 @param aRequest file server request object
2544 @param aFmtHandle out: format handle
2545 @param aFmtMode format mode
2546 @param apLDFormatInfo pointer to legacy parameters structure; NULL means "not used"
2547 @param apVolFormatParam pointer to the newparameters structure; NULL means "not used"
2549 @return pointer to the instantiated CFormatCB object.
2551 CFormatCB* TDrive::FormatOpenL(CFsRequest* aRequest, TInt& aFmtHandle, TFormatMode aFmtMode, const TLDFormatInfo* apLDFormatInfo, const TVolFormatParam* apVolFormatParam)
2553 ASSERT(!(apLDFormatInfo && apVolFormatParam)); //-- these parameters are mutually exclusive
2555 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatL, EF32TraceUidFileSys, &FSys(), DriveNumber());
2557 CFormatCB* pFormat = CurrentMount().NewFormatL();
2559 TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatLRet, EF32TraceUidFileSys, KErrNone, pFormat);
2561 Formats->AddL(pFormat, ETrue);
2562 pFormat->InitL(this, aFmtMode);
2564 if(aFmtMode & ESpecialFormat)
2567 {//-- the user has specified formatting parameters as TLDFormatInfo
2568 pFormat->SetFormatParameters(apLDFormatInfo);
2570 else if(apVolFormatParam && apVolFormatParam->SomeParamsSet())
2571 {//-- the user has specified formatting parameters as TVolFormatParam
2572 TInt nRes = pFormat->SetFormatParameters(apVolFormatParam);
2573 User::LeaveIfError(nRes); //-- the particular file system might not support this feature
2576 {//-- this is a special case, ESpecialFormat is set, but no parameters provided at all;
2577 //-- invalidate CFormatCB::iSpecialInfo to make filesystem not to use it
2578 pFormat->SetFormatParameters((TLDFormatInfo*)NULL);
2583 // modify resource counter after initialised to ensure correct cleanup
2584 AddDiskAccess(CurrentMount());
2585 aFmtHandle = aRequest->Session()->Handles().AddL(pFormat, ETrue);
2594 EXPORT_C void UNUSED1() {}
2595 EXPORT_C void UNUSED2() {}
2596 EXPORT_C void UNUSED3() {}