1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_drv.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2605 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\sfile\sf_drv.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "sf_std.h"
1.22 +#include "sf_file_cache.h"
1.23 +
1.24 +
1.25 +//const TInt KMaxNotifierAttempts=4; // not used anywhere
1.26 +
1.27 +static TPtrC StripBackSlash(const TDesC& aName)
1.28 +//
1.29 +// If aName ends in a backslash, strip it.
1.30 +//
1.31 + {
1.32 +
1.33 + __ASSERT_DEBUG(aName.Length(),Fault(EStripBackSlashBadName));
1.34 + if (aName[aName.Length()-1]==KPathDelimiter)
1.35 + return(aName.Left(aName.Length()-1));
1.36 + return(aName);
1.37 + }
1.38 +
1.39 +static void CheckSubClose(CFsObject* anObj,TInt aHandle, CSessionFs* aSession)
1.40 +//
1.41 +// Close anObj if its not NULL.
1.42 +//
1.43 + {
1.44 + __PRINT1(_L("CheckSubClose() session 0x0%x"),aSession);
1.45 + __PRINT1(_L("CheckSubClose() anObj 0x0%x"),anObj);
1.46 +
1.47 + if(!anObj)
1.48 + return;
1.49 +
1.50 + if(aHandle==0)
1.51 + {
1.52 + // can't have been added to the object index
1.53 + __ASSERT_DEBUG(KErrNotFound==aSession->Handles().At(anObj,ETrue),Fault(ESubOpenBadHandle));
1.54 + anObj->Close();
1.55 + }
1.56 + else
1.57 + aSession->Handles().Remove(aHandle,ETrue);
1.58 + }
1.59 +
1.60 +TInt ValidateDrive(TInt aDriveNumber,CFsRequest* aRequest)
1.61 +//
1.62 +// Validate a drive number and set iTheDrive.
1.63 +//
1.64 + {
1.65 + if (aDriveNumber==KDefaultDrive)
1.66 + aDriveNumber=aRequest->Session()->CurrentDrive();
1.67 + if (!RFs::IsValidDrive(aDriveNumber))
1.68 + return(KErrBadName);
1.69 + aRequest->SetDrive(&TheDrives[aDriveNumber]);
1.70 + return(KErrNone);
1.71 + }
1.72 +
1.73 +TInt ValidateDriveDoSubst(TInt aDriveNumber,CFsRequest* aRequest)
1.74 +//
1.75 +// Validate a drive number and set iTheDrive.
1.76 +//
1.77 + {
1.78 +
1.79 + TInt r=ValidateDrive(aDriveNumber,aRequest);
1.80 + if (r!=KErrNone)
1.81 + return(r);
1.82 + if (aRequest->Drive()->IsSubsted())
1.83 + {
1.84 + aRequest->SetSubstedDrive(aRequest->Drive());
1.85 + aRequest->SetDrive(&aRequest->Drive()->SubstedDrive());
1.86 + }
1.87 + return(KErrNone);
1.88 + }
1.89 +
1.90 +void ValidateAtts(TUint /*anEntryAtts*/,TUint& aSetAttMask,TUint& aClearAttMask)
1.91 +//
1.92 +// Do not allow the entry type to be changed
1.93 +//
1.94 + {
1.95 + const TUint KReadOnlySetAtts = KEntryAttVolume |
1.96 + KEntryAttDir |
1.97 + KEntryAttRemote;
1.98 +
1.99 + const TUint KReadOnlyClrAtts = KEntryAttVolume |
1.100 + KEntryAttDir |
1.101 + KEntryAttRemote |
1.102 + KEntryAttModified;
1.103 +
1.104 + aSetAttMask &= ~KReadOnlySetAtts;
1.105 + aClearAttMask &= ~KReadOnlyClrAtts;
1.106 + }
1.107 +
1.108 +void CheckForLeaveAfterOpenL(TInt leaveError, CFsRequest* aRequest, TInt aHandle)
1.109 +//
1.110 +// Tidy up in the event of a leave after opening a file or directory
1.111 + {
1.112 + if (leaveError)
1.113 + {
1.114 + CFsObject* anObj=(CFsObject* )aRequest->ScratchValue();
1.115 + CheckSubClose(anObj,aHandle,aRequest->Session());
1.116 + User::Leave(leaveError);
1.117 + }
1.118 + }
1.119 +
1.120 +TDrive::TDrive()
1.121 +//
1.122 +// Constructor.
1.123 +//
1.124 + : iDriveNumber(0),iAtt(0),iChanged(EFalse),
1.125 + iFSys(NULL),iCurrentMount(NULL),iSubstedDrive(NULL),iSubst(NULL),
1.126 + iMount(NULL),iDriveFlags(0),iMountFailures(0)
1.127 + {}
1.128 +
1.129 +void TDrive::CreateL(TInt aDriveNumber)
1.130 +//
1.131 +// Allocate the drive number and any resources.
1.132 +//
1.133 + {
1.134 + __PRINT1(_L("TDrive::CreateL(%d)"),aDriveNumber);
1.135 + iDriveNumber=aDriveNumber;
1.136 + iMount=TheContainer->CreateL();
1.137 + TInt r=iLock.CreateLocal();
1.138 + User::LeaveIfError(r);
1.139 + }
1.140 +
1.141 +TInt TDrive::CheckMountAndEntryName(const TDesC& aName)
1.142 +//
1.143 +// Check drive is mounted then check aName is legal
1.144 +//
1.145 + {
1.146 +
1.147 + __PRINT1(_L("TDrive::CheckMountAndEntryName Drive%d"),DriveNumber());
1.148 + TInt r=CheckMount();
1.149 + if (r==KErrNone && IsIllegalFullName(aName))
1.150 + return(KErrBadName);
1.151 + return(r);
1.152 + }
1.153 +
1.154 +void TDrive::MultiSlotDriveCheck()
1.155 + {
1.156 + // Check whether the current drive is a dual-slot/multi-slot
1.157 + // if so, we need to check which drive is connected now and
1.158 + // swap the mapping in LocalDrives::iMapping such that the
1.159 + // mapping of driveNumber to localDriveNumber is correct.
1.160 +
1.161 + Lock();
1.162 + //Is this a multislot drive?
1.163 + if(LocalDrives::iIsMultiSlotDrive[iDriveNumber])
1.164 + {
1.165 + for(TInt localDrvNum=0; localDrvNum<KMaxLocalDrives; localDrvNum++)
1.166 + {
1.167 + // ensure that this local drive is a multi-slot choice for this drive number..
1.168 + if(LocalDrives::iReverseMapping[localDrvNum]==iDriveNumber)
1.169 + {
1.170 + // Caps - find out which one is connected
1.171 + TLocalDriveCapsBuf capsInfo;
1.172 + TInt r = LocalDrives::iLocalDrives[localDrvNum].Caps(capsInfo);
1.173 + if(r==KErrNotReady)
1.174 + {
1.175 + continue; //go to next localdrive
1.176 + }
1.177 + //found a connected drive
1.178 + //Update mapping
1.179 + #ifdef _DEBUG
1.180 + RDebug::Print(_L("Multislot drive mapping update: DriveNum %d to LocDrv %d"),iDriveNumber,localDrvNum);
1.181 + #endif
1.182 +
1.183 + LocalDrives::iMapping[iDriveNumber] = localDrvNum;
1.184 + break; // Swap complete - don't look any further
1.185 + }
1.186 + }
1.187 + }
1.188 + UnLock();
1.189 + }
1.190 +
1.191 +TInt TDrive::CheckMount()
1.192 +//
1.193 +// Check the drive and try to mount a media if not already mounted.
1.194 +//
1.195 + {
1.196 + __PRINT2(_L("TDrive::CheckMount Drive%d, changed:%d"),DriveNumber(), iChanged);
1.197 + __CHECK_DRIVETHREAD(iDriveNumber);
1.198 +
1.199 + if (!iFSys)
1.200 + return KErrNotReady;
1.201 +
1.202 + if (iChanged) // If a media change has occurred
1.203 + {
1.204 + iMountFailures = 0;
1.205 + iChanged=EFalse; // Reset the flag
1.206 + if (IsMounted()) // Dismount the mount if it is still marked as mounted
1.207 + {
1.208 + DoDismount();
1.209 + }
1.210 + //If we have a dual/multi removable media slot then we may need to
1.211 + //swop the mappings.
1.212 + MultiSlotDriveCheck();
1.213 + }
1.214 +
1.215 + if (!IsMounted()) // Checks that iCurrentMount!=NULL
1.216 + {
1.217 + __PRINT(_L("TDrive::CheckMount() Not Mounted"));
1.218 + const TInt KMaxMountFailures = 3;
1.219 + // if we've repeatedly failed to mount, give up until a media change
1.220 + if (iMountFailures >= KMaxMountFailures)
1.221 + {
1.222 + __PRINT1(_L("TDrive::CheckMount() retries exceeded, last Err:%d"), iLastMountError);
1.223 + return iLastMountError;
1.224 + }
1.225 +
1.226 + if (!ReMount()) // Have we just remounted a mount we have previously encountered?
1.227 + {
1.228 + MountFileSystem(EFalse); // If not, mount it for the first time now
1.229 + }
1.230 + else if(IsWriteProtected() && IsWriteableResource())
1.231 + {
1.232 + DoDismount();
1.233 + return KErrAccessDenied;
1.234 + }
1.235 + }
1.236 +
1.237 + if (iReason==KErrNone && CurrentMount().LockStatus() > 0)
1.238 + {
1.239 + //-- this meand that the mount has drive access objetcs opened (RFormat or RRawDisk)
1.240 + __PRINT1(_L("TDrive::CheckMount() Mount is locked! LockStaus:%d"), CurrentMount().LockStatus());
1.241 + return KErrInUse;
1.242 + }
1.243 +
1.244 + __PRINT1(_L("TDrive::CheckMount returned %d "),iReason);
1.245 +
1.246 + return(iReason);
1.247 + }
1.248 +
1.249 +//----------------------------------------------------------------------------
1.250 +/**
1.251 + Try and re-mount any of the pending media
1.252 +
1.253 + @return ETrue if the mount matching media found and been attached back (set as iCurrentMount)
1.254 +*/
1.255 +TBool TDrive::ReMount()
1.256 + {
1.257 + const TInt mCount=Mount().Count();
1.258 + __PRINT1(_L("TDrive::ReMount() MountCnt:%d"), mCount);
1.259 +
1.260 + const TInt u=(Mount().UniqueID()<<16);
1.261 + iReason=KErrNone;
1.262 +
1.263 + //-- try every instance of CMountCB that is associated with this object of TDrive.
1.264 + //-- mounts are stored in the container of mCount elements.
1.265 + //-- if some CMountCB recognises the media it belongs, it means that "remount succeded"
1.266 + for(TInt i=0; i<mCount; i++)
1.267 + {
1.268 + CMountCB* pM=(CMountCB*)Mount().At(u|i);
1.269 +
1.270 + if (ReMount(*pM))
1.271 + return ETrue;
1.272 + }
1.273 +
1.274 + return EFalse;
1.275 + }
1.276 +
1.277 +//----------------------------------------------------------------------------
1.278 +/**
1.279 + Try and re-mount the specified media.
1.280 +
1.281 + @return ETrue if remounting succeeded - i.e. the CMountCB instance that matches the media is found in the
1.282 + mounts container (Mount()) and bound to the media.
1.283 +*/
1.284 +TBool TDrive::ReMount(CMountCB& aMount)
1.285 + {
1.286 + __PRINT1(_L("TDrive::ReMount(0x%x)"), &aMount);
1.287 + iReason=KErrNone;
1.288 +
1.289 + if (!aMount.IsDismounted() && !aMount.ProxyDriveDismounted())
1.290 + {
1.291 + aMount.SetDrive(this);
1.292 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMount, EF32TraceUidFileSys, DriveNumber());
1.293 +
1.294 + //-- actually, this is asking CMountCB to see if it belongs to the current media.
1.295 + iReason = aMount.ReMount();
1.296 +
1.297 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMountRet, EF32TraceUidFileSys, iReason);
1.298 +
1.299 + if (iReason == KErrNone) // ReMount succeeded
1.300 + {
1.301 + aMount.Open();
1.302 + iCurrentMount = &aMount;
1.303 + __PRINT1(_L("TDrive::ReMount for Mount:0x%x OK!"), &aMount);
1.304 + return ETrue;
1.305 + }
1.306 +
1.307 + __PRINT2(_L("TDrive::ReMount for Mount:0x%x failed iReason=%d"),&aMount,iReason);
1.308 + }
1.309 + else
1.310 + {
1.311 + __PRINT1(_L("TDrive::ReMount() failed - Mount:0x%x is dismounted"), &aMount);
1.312 + }
1.313 +
1.314 + return EFalse;
1.315 + }
1.316 +
1.317 +
1.318 +
1.319 +//----------------------------------------------------------------------------
1.320 +/**
1.321 + Mount the media on the drive. Optionally force a bad media to be mounted.
1.322 +
1.323 + @param apMount out: pointer to the produced CMountCB object; NULL if the CMountCB is not constructed
1.324 + @param aForceMount if ETrue, the filesystem will be forcedly mounted on the drive, disregarding what it contains.
1.325 + @param aFsNameHash file system name hash; see TDrive::MountFileSystem()
1.326 +*/
1.327 +void TDrive::DoMountFileSystemL(CMountCB*& apMount, TBool aForceMount, TUint32 aFsNameHash)
1.328 + {
1.329 + CFileSystem* pMountsFs = NULL; //-- reference to the filesystem that will be producing CMountCB
1.330 +
1.331 + apMount = NULL;
1.332 +
1.333 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.334 +
1.335 + //-- construct a new CmountCB object.
1.336 + //-- on return pMountsFs will be the pointer to the factory object of CFileSystem that produced this mount
1.337 + apMount = FSys().NewMountExL(this, &pMountsFs, aForceMount, aFsNameHash);
1.338 +
1.339 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, KErrNone, apMount);
1.340 + __PRINT2(_L("TDrive::MountMediaL created mount:0x%x FileSys:0x%x"), apMount, pMountsFs);
1.341 +
1.342 + ASSERT(pMountsFs && apMount);
1.343 +
1.344 + apMount->SetMountNumber(iMountNumber++);
1.345 + apMount->InitL(*this, pMountsFs); //-- initialise Mount
1.346 + apMount->MountL(aForceMount); //-- mount the file system
1.347 + Mount().AddL(apMount,EFalse); //-- add mount object to the mounts container.
1.348 +
1.349 + iCurrentMount=apMount;
1.350 + }
1.351 +
1.352 +
1.353 +//----------------------------------------------------------------------------
1.354 +/*
1.355 + Mount file system on the drive.
1.356 + @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.
1.357 + if ETrue, will mount the file suystem by force, this is used mostly for formatting unrecognisable media.
1.358 +
1.359 + @param aFsNameHash optional parameter. Can specify the concrete file system name (hash). It can be used to force mounting some specific
1.360 + file system. Default value '0' means "not specified / not used"
1.361 +
1.362 +
1.363 + TDrive::iReason on return contains the operation result code.
1.364 +*/
1.365 +void TDrive::MountFileSystem(TBool aForceMount, TUint32 aFsNameHash /*=0*/ )
1.366 + {
1.367 + __PRINT2(_L("TDrive::MountFileSystem aForceMount=%d, FSNameHash:0x%x"),aForceMount, aFsNameHash);
1.368 + __CHECK_DRIVETHREAD(iDriveNumber);
1.369 +
1.370 + iCurrentMount=NULL;
1.371 + if(!iFSys)
1.372 + {
1.373 + iReason=KErrNotReady;
1.374 + return;
1.375 + }
1.376 +
1.377 + CMountCB* pM=NULL;
1.378 + TRAP(iReason, DoMountFileSystemL(pM, aForceMount, aFsNameHash));
1.379 + if (iReason == KErrNone)
1.380 + {
1.381 + iMountFailures = 0;
1.382 + ASSERT(iCurrentMount);
1.383 + }
1.384 + else
1.385 + {
1.386 + iLastMountError = iReason;
1.387 + iMountFailures++;
1.388 + __PRINT2(_L("TDrive::MountFileSystem 0x%x failed iReason=%d"),pM,iReason);
1.389 + if(pM)
1.390 + pM->Close();
1.391 +
1.392 + ASSERT(!iCurrentMount);
1.393 + }
1.394 + }
1.395 +
1.396 +
1.397 +//----------------------------------------------------------------------------
1.398 +/**
1.399 + Generic mount control method.
1.400 + @param aLevel specifies the operation to perfrom on the mount
1.401 + @param aOption specific option for the given operation
1.402 + @param aParam pointer to generic parameter, its meaning depends on aLevel and aOption
1.403 +
1.404 + @return standard error code.
1.405 +*/
1.406 +TInt TDrive::MountControl(TInt aLevel, TInt aOption, TAny* aParam)
1.407 + {
1.408 + TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControl, EF32TraceUidFileSys, DriveNumber(), aLevel, aOption, aParam);
1.409 + TInt r = CurrentMount().MountControl(aLevel, aOption, aParam);
1.410 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMountControlRet, EF32TraceUidFileSys, r);
1.411 +
1.412 + return r;
1.413 + }
1.414 +
1.415 +//----------------------------------------------------------------------------
1.416 +/**
1.417 + Request aFreeSpaceRequired free bytes from the mount associated with this drive.
1.418 + The volume free space on for some filesystems can be changing (usually increasing) after it has been mounted.
1.419 + If the mount supports this functionality, it can block this call until certain number of free bytes encounted if its free
1.420 + space calculation activity hasn't finished yet.
1.421 +
1.422 + @param aFreeSpaceRequired required free space, bytes.
1.423 +
1.424 + @return KErrNone on success and if there is at least aFreeSpaceRequired bytes on the volume
1.425 + KErrDiskFull on success and if there is no aFreeSpaceRequired bytes on the volume
1.426 + system-wide error code otherwise
1.427 +*/
1.428 +TInt TDrive::RequestFreeSpaceOnMount(TUint64 aFreeSpaceRequired)
1.429 + {
1.430 + TInt nRes;
1.431 +
1.432 + nRes = CheckMount();
1.433 + if(nRes != KErrNone)
1.434 + return nRes;
1.435 +
1.436 + //-- 1. Try mount-specific request first. If the mount is still performing free space calculations,
1.437 + //-- the caller will be suspended until aFreeSpaceRequired bytes is available or scanning process finishes
1.438 + {
1.439 + TUint64 freeSpaceReq = aFreeSpaceRequired;
1.440 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpace, EF32TraceUidFileSys, DriveNumber());
1.441 + nRes = CurrentMount().RequestFreeSpace(freeSpaceReq);
1.442 + TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(freeSpaceReq), I64HIGH(freeSpaceReq));
1.443 + if(nRes == KErrNone)
1.444 + {
1.445 + return (freeSpaceReq >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
1.446 + }
1.447 + }
1.448 +
1.449 + //-- given Mount doesn't support this functionality, use legacy method
1.450 + TVolumeInfo volInfo;
1.451 + nRes = Volume(volInfo);
1.452 + if(nRes !=KErrNone)
1.453 + return nRes;
1.454 +
1.455 + return ((TUint64)volInfo.iFree >= aFreeSpaceRequired) ? KErrNone : KErrDiskFull;
1.456 + }
1.457 +
1.458 +//----------------------------------------------------------------------------
1.459 +/**
1.460 + Get size of the mounted volume. It can be less than physical volume size because FileSystem data may occupy some space.
1.461 +
1.462 + @param aSize on success mounted volume size in bytes will be returned there
1.463 + @return KErrNone on success, standard error code otherwise
1.464 +*/
1.465 +TInt TDrive::MountedVolumeSize(TUint64& aSize)
1.466 + {
1.467 + TInt nRes;
1.468 +
1.469 + nRes = CheckMount();
1.470 + if(nRes != KErrNone)
1.471 + return nRes;
1.472 +
1.473 + //-- 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
1.474 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, DriveNumber());
1.475 + nRes = CurrentMount().MountedVolumeSize(aSize);
1.476 + TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeSize, EF32TraceUidFileSys, nRes, I64LOW(aSize), I64HIGH(aSize));
1.477 + if(nRes == KErrNone)
1.478 + return nRes;
1.479 +
1.480 + //-- given Mount doesn't support this functionality, use legacy method
1.481 + TVolumeInfo volInfo;
1.482 + nRes = Volume(volInfo);
1.483 + if(nRes == KErrNone)
1.484 + {
1.485 + aSize = volInfo.iSize;
1.486 + }
1.487 +
1.488 + return nRes;
1.489 + }
1.490 +
1.491 +//----------------------------------------------------------------------------
1.492 +/**
1.493 + Get _current_ amount of free space on the volume. Some mounts implementations can be updating the amount of free space
1.494 + in background.
1.495 +
1.496 + @param aFreeDiskSpace on success will contain a current amount of free space
1.497 + @return KErrNone on success, standard error code otherwise
1.498 +
1.499 +*/
1.500 +TInt TDrive::FreeDiskSpace(TInt64& aFreeDiskSpace)
1.501 + {
1.502 + TInt nRes;
1.503 +
1.504 + nRes = CheckMount();
1.505 + if(nRes != KErrNone)
1.506 + return nRes;
1.507 +
1.508 + //-- 1. Try mount-specific request first. It won't block this call as CMountCB::VolumeL() can do
1.509 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpace, EF32TraceUidFileSys, DriveNumber());
1.510 + nRes = CurrentMount().GetCurrentFreeSpaceAvailable(aFreeDiskSpace);
1.511 + TRACERET3(UTF::EBorder, UTraceModuleFileSys::ECMountCBCurrentFreeSpaceRet, EF32TraceUidFileSys, nRes, I64LOW(aFreeDiskSpace), I64HIGH(aFreeDiskSpace));
1.512 + if(nRes == KErrNone)
1.513 + return nRes;
1.514 +
1.515 + //-- given Mount doesn't support this functionality, use legacy method
1.516 + TVolumeInfo volInfo;
1.517 + nRes = Volume(volInfo);
1.518 + if(nRes == KErrNone)
1.519 + {
1.520 + aFreeDiskSpace = volInfo.iFree;
1.521 + }
1.522 +
1.523 + return nRes;
1.524 + }
1.525 +
1.526 +//----------------------------------------------------------------------------
1.527 +/**
1.528 + Finalise drive (the mount).
1.529 +
1.530 + @param aOperation describes finalisation operation ,see RFs::TFinaliseDrvMode
1.531 + @param aParam1 not used, for future expansion
1.532 + @param aParam2 not used, for future expansion
1.533 +
1.534 + @return Standard error code
1.535 +*/
1.536 +TInt TDrive::FinaliseMount(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
1.537 + {
1.538 + TInt r=CheckMount();
1.539 + if (r!=KErrNone)
1.540 + return(r);
1.541 +
1.542 + r = FlushCachedFileInfo();
1.543 + if (r!=KErrNone)
1.544 + return(r);
1.545 +
1.546 + if(IsWriteProtected())
1.547 + return(KErrAccessDenied);
1.548 +
1.549 + TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
1.550 + TRAP(r,CurrentMount().FinaliseMountL(aOperation, aParam1, aParam2));
1.551 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2Ret, EF32TraceUidFileSys, r);
1.552 +
1.553 + return r;
1.554 + }
1.555 +
1.556 +//----------------------------------------------------------------------------
1.557 +/** old implementation */
1.558 +TInt TDrive::FinaliseMount()
1.559 + {
1.560 + TInt r=CheckMount();
1.561 + if (r!=KErrNone)
1.562 + return(r);
1.563 +
1.564 + r = FlushCachedFileInfo();
1.565 + if (r!=KErrNone)
1.566 + return(r);
1.567 +
1.568 + if(IsWriteProtected())
1.569 + return(KErrAccessDenied);
1.570 +
1.571 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1, EF32TraceUidFileSys, DriveNumber());
1.572 + TRAP(r,CurrentMount().FinaliseMountL());
1.573 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount1Ret, EF32TraceUidFileSys, r);
1.574 +
1.575 + return r;
1.576 + }
1.577 +
1.578 +
1.579 +
1.580 +CFileCB* TDrive::LocateFile(const TDesC& aName)
1.581 +//
1.582 +// Locate a file of the same name already open on the drive.
1.583 +//
1.584 + {
1.585 + TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
1.586 + CFileCB* pF;
1.587 + // early out for normal case, list is empty
1.588 + if(q==NULL)
1.589 + return NULL;
1.590 +
1.591 + // strip off trailing dots
1.592 + TInt length= aName.Length();
1.593 + while((length !=0) && (aName[length-1]==KExtDelimiter))
1.594 + {
1.595 + length--;
1.596 + }
1.597 +
1.598 + TPtrC temp(aName.Ptr(),length);
1.599 +
1.600 + TFileName tempName;
1.601 + tempName.CopyF(temp);
1.602 + TUint32 nameHash=CalcNameHash(tempName);
1.603 +
1.604 + while ((pF=q++)!=NULL)
1.605 + {
1.606 + if(nameHash==pF->NameHash())
1.607 + {
1.608 + if (pF->FileNameF().Match(tempName)==KErrNone)
1.609 + return(pF);
1.610 + }
1.611 + }
1.612 + return(NULL);
1.613 + }
1.614 +
1.615 +
1.616 +CFileCache* TDrive::LocateClosedFile(const TDesC& aName, TBool aResurrect)
1.617 +//
1.618 +// Locate a recently closed file of the same name on the drive.
1.619 +//
1.620 + {
1.621 + // strip off trailing dots
1.622 + TInt length= aName.Length();
1.623 + while((length !=0) && (aName[length-1]==KExtDelimiter))
1.624 + {
1.625 + length--;
1.626 + }
1.627 +
1.628 + TPtrC temp(aName.Ptr(),length);
1.629 +
1.630 + TFileName tempName;
1.631 + tempName.CopyF(temp);
1.632 + TUint32 nameHash=CalcNameHash(tempName);
1.633 +
1.634 + CFileCache* pF = NULL;
1.635 + CMountCB* currentMount = &CurrentMount();
1.636 +
1.637 +
1.638 + TClosedFileUtils::Lock();
1.639 +
1.640 + TInt count = TClosedFileUtils::Count();
1.641 + while(count--)
1.642 + {
1.643 + CFileCache* fileCache = TClosedFileUtils::At(count);
1.644 + if (&fileCache->Drive() == this &&
1.645 + fileCache->NameHash()== nameHash &&
1.646 + fileCache->FileNameF().Match(tempName)==KErrNone &&
1.647 + &fileCache->Mount() == currentMount)
1.648 + {
1.649 + __ASSERT_DEBUG(TClosedFileUtils::IsClosed(fileCache), Fault(EObjRemoveContainerNotFound));
1.650 + __CACHE_PRINT2(_L("CLOSEDFILES: LocateClosedFile(%S, %d\n"), &fileCache->FileNameF(), aResurrect);
1.651 + if (aResurrect)
1.652 + {
1.653 + TClosedFileUtils::ReOpen(fileCache, EFalse);
1.654 + }
1.655 + pF = fileCache;
1.656 + break;
1.657 + }
1.658 +
1.659 + }
1.660 + TClosedFileUtils::Unlock();
1.661 +
1.662 + if (pF != NULL && !aResurrect)
1.663 + {
1.664 + pF->Close();
1.665 + pF = NULL;
1.666 + }
1.667 +
1.668 + return(pF);
1.669 + }
1.670 +
1.671 +
1.672 +static TBool IsSubDir(const TDesC& aFullName,const TDesC& aParent)
1.673 +//
1.674 +// Returns ETrue if aFullName is a subdirectory of aParent
1.675 +// Assumes aParent is a path name with the trailing backslash removed
1.676 +//
1.677 + {
1.678 +
1.679 + __ASSERT_DEBUG(aParent.Length() && aParent[aParent.Length()-1]!=KPathDelimiter,Fault(EIsSubDirBadDes));
1.680 + TPtrC entryFullName(NULL,0);
1.681 + TPtrC entryParent(NULL,0);
1.682 + TInt posFullName=0;
1.683 + TInt posParent=0;
1.684 +
1.685 + FOREVER
1.686 + {
1.687 + NextInPath(aParent,entryParent,posParent);
1.688 + if (entryParent.Length()==0)
1.689 + break;
1.690 + NextInPath(aFullName,entryFullName,posFullName);
1.691 + if (entryParent!=entryFullName)
1.692 + return(EFalse);
1.693 + }
1.694 +
1.695 + if (aFullName.Length()<=posFullName)
1.696 + return(EFalse);
1.697 + if (aFullName[posFullName]!=KPathDelimiter)
1.698 + return(EFalse);
1.699 + return(ETrue);
1.700 + }
1.701 +
1.702 +CFileCB* TDrive::LocateFileByPath(const TDesC& aPath)
1.703 +//
1.704 +// Locate a file opened in a subdirectory of aPath
1.705 +//
1.706 + {
1.707 +
1.708 + TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
1.709 + CFileCB* pF;
1.710 + while ((pF=q++)!=NULL)
1.711 + {
1.712 + if (IsSubDir(pF->FileName(),aPath))
1.713 + return(pF);
1.714 + }
1.715 + return(NULL);
1.716 + }
1.717 +
1.718 +void TDrive::FlushCachedFileInfoL()
1.719 +//
1.720 +// Flush data stored in the file control blocks
1.721 +//
1.722 + {
1.723 + __CHECK_DRIVETHREAD(iDriveNumber);
1.724 + TDblQueIter<CFileCB> q(CurrentMount().iMountQ);
1.725 + CFileCB* pF;
1.726 + while ((pF=q++)!=NULL)
1.727 + {
1.728 + if (pF->iAtt&KEntryAttModified)
1.729 + pF->FlushAllL();
1.730 + }
1.731 + }
1.732 +
1.733 +/**
1.734 +Flushes (asynchronously) all dirty data on this drive and optionally
1.735 +purges non-dirty data
1.736 +
1.737 +aPurgeCache - purges all file caches on this drive AFTER dirty data has ben flushed
1.738 +
1.739 +returns KErrNone if complete
1.740 + CFsRequest::EReqActionBusy if flushing is in progress
1.741 + otherwise one of the other system-wide error codes.
1.742 +*/
1.743 +TInt TDrive::FlushCachedFileInfo(TBool aPurgeCache)
1.744 + {
1.745 + if (iCurrentMount == NULL)
1.746 + return KErrNone;
1.747 +
1.748 + TBool driveThread = FsThreadManager::IsDriveThread(iDriveNumber,EFalse);
1.749 +
1.750 + Lock();
1.751 +
1.752 +
1.753 + TInt ret = KErrNone;
1.754 +
1.755 + TDblQueIter<CFileCB> q(iCurrentMount->iMountQ);
1.756 + CFileCB* pF;
1.757 + while ((pF=q++)!=NULL)
1.758 + {
1.759 + CFileCache* fileCache = pF->FileCache();
1.760 +
1.761 + // Write dirty data if there is a file cache
1.762 + TInt flushDirtyRetCode = CFsRequest::EReqActionComplete;
1.763 + if (fileCache)
1.764 + {
1.765 + flushDirtyRetCode = fileCache->FlushDirty();
1.766 + if (flushDirtyRetCode == CFsRequest::EReqActionComplete) // nothing to flush
1.767 + {
1.768 + if (aPurgeCache)
1.769 + fileCache->Purge(EFalse);
1.770 + }
1.771 + else if (flushDirtyRetCode == CFsRequest::EReqActionBusy) // flushing
1.772 + {
1.773 + ret = flushDirtyRetCode;
1.774 + }
1.775 + else // error
1.776 + {
1.777 + ret = flushDirtyRetCode;
1.778 + break;
1.779 + }
1.780 + }
1.781 + // if no file cache or no dirty data left, update the file entry & attributes
1.782 + if (driveThread && (pF->iAtt&KEntryAttModified) && flushDirtyRetCode == CFsRequest::EReqActionComplete )
1.783 + {
1.784 + TRAP(ret, pF->FlushAllL());
1.785 + if (ret != KErrNone)
1.786 + break;
1.787 + }
1.788 + }
1.789 +
1.790 + UnLock();
1.791 +
1.792 +
1.793 + return ret;
1.794 + }
1.795 +
1.796 +//----------------------------------------------------------------------------
1.797 +/**
1.798 + Purge dirty cache data associated with all files on a given mount
1.799 +*/
1.800 +void TDrive::PurgeDirty(CMountCB& aMount)
1.801 + {
1.802 + TDblQueIter<CFileCB> q(aMount.iMountQ);
1.803 + CFileCB* pF;
1.804 + while ((pF=q++)!=NULL)
1.805 + {
1.806 + CFileCache* fileCache = pF->FileCache();
1.807 + if (fileCache)
1.808 + {
1.809 + fileCache->Purge(ETrue);
1.810 + fileCache->MarkFileClean();
1.811 + }
1.812 + }
1.813 + }
1.814 +
1.815 +//----------------------------------------------------------------------------
1.816 +TInt TDrive::ValidateShare(CFileCB& aFile, TShare aReqShare)
1.817 +//
1.818 +// Check that the sharing rules are obeyed.
1.819 +//
1.820 + {
1.821 +
1.822 + switch (aReqShare)
1.823 + {
1.824 + case EFileShareExclusive:
1.825 + case EFileShareReadersOnly:
1.826 + case EFileShareAny:
1.827 + case EFileShareReadersOrWriters:
1.828 + break;
1.829 + default:
1.830 + return(KErrArgument);
1.831 + }
1.832 + switch (aFile.iShare)
1.833 + {
1.834 + case EFileShareExclusive:
1.835 + return(KErrInUse);
1.836 +
1.837 + case EFileShareReadersOnly:
1.838 + case EFileShareAny:
1.839 + if (aReqShare != aFile.iShare && aReqShare != EFileShareReadersOrWriters)
1.840 + return(KErrInUse);
1.841 + break;
1.842 +
1.843 + case EFileShareReadersOrWriters:
1.844 + if (aReqShare==EFileShareExclusive)
1.845 + return(KErrInUse);
1.846 + //
1.847 + // If the file is currently open as EFileShareReadersOrWriters then
1.848 + // promote the share to the requested share mode.
1.849 + //
1.850 + // If the requested share is EFileShareReadersOnly, verfiy that no
1.851 + // other share has the file open for writing.
1.852 + //
1.853 +
1.854 + if (aReqShare == EFileShareReadersOnly)
1.855 + {
1.856 + FileShares->Lock();
1.857 + TInt count = FileShares->Count();
1.858 + while(count--)
1.859 + {
1.860 + CFileShare* share = (CFileShare*)(*FileShares)[count];
1.861 + if (&share->File() == &aFile)
1.862 + {
1.863 + if(share->iMode & EFileWrite)
1.864 + {
1.865 + FileShares->Unlock();
1.866 + return KErrInUse;
1.867 + }
1.868 + }
1.869 + }
1.870 + FileShares->Unlock();
1.871 + }
1.872 + break;
1.873 +
1.874 + default:
1.875 + Fault(EDrvIllegalShareValue);
1.876 + break;
1.877 + }
1.878 + return(KErrNone);
1.879 + }
1.880 +
1.881 +void TDrive::DriveInfo(TDriveInfo& anInfo)
1.882 +//
1.883 +// Get the drive info.
1.884 +//
1.885 + {
1.886 + anInfo.iType=EMediaNotPresent;
1.887 + anInfo.iMediaAtt=0;
1.888 + anInfo.iBattery=EBatNotSupported;
1.889 + anInfo.iConnectionBusType=EConnectionBusInternal;
1.890 +
1.891 + if(iFSys)
1.892 + {
1.893 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfo, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.894 + FSys().DriveInfo(anInfo,DriveNumber());
1.895 + TRACE3(UTF::EBorder, UTraceModuleFileSys::ECFileSystemDriveInfoRet, EF32TraceUidFileSys,
1.896 + anInfo.iType, anInfo.iDriveAtt, anInfo.iMediaAtt);
1.897 + }
1.898 +
1.899 + anInfo.iDriveAtt=Att();
1.900 + }
1.901 +
1.902 +TInt TDrive::Volume(TVolumeInfo& aVolume)
1.903 +//
1.904 +// Get the drive volume info.
1.905 +//
1.906 + {
1.907 + TInt r=CheckMount();
1.908 + if (r==KErrNone)
1.909 + {
1.910 + DriveInfo(aVolume.iDrive);
1.911 + CMountCB& m=CurrentMount();
1.912 + aVolume.iName=m.VolumeName();
1.913 + aVolume.iUniqueID=m.iUniqueID;
1.914 + aVolume.iSize=m.iSize;
1.915 +
1.916 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeL, EF32TraceUidFileSys, DriveNumber());
1.917 + TRAP(r,m.VolumeL(aVolume))
1.918 + TRACE7(UTF::EBorder, UTraceModuleFileSys::ECMountCBVolumeLRet, EF32TraceUidFileSys,
1.919 + r, aVolume.iUniqueID, I64LOW(aVolume.iSize), I64HIGH(aVolume.iSize),
1.920 + I64LOW(aVolume.iFree), I64HIGH(aVolume.iFree), aVolume.iFileCacheFlags);
1.921 +
1.922 + }
1.923 + return(r);
1.924 + }
1.925 +
1.926 +
1.927 +void TDrive::SetVolumeL(const TDesC& aName,HBufC*& aBuf)
1.928 +//
1.929 +// Set the volume name.
1.930 +//
1.931 + {
1.932 + __CHECK_DRIVETHREAD(iDriveNumber);
1.933 + aBuf=aName.AllocL();
1.934 + TPtr volumeName=aBuf->Des();
1.935 +
1.936 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeL, EF32TraceUidFileSys, DriveNumber(), aName);
1.937 + CurrentMount().SetVolumeL(volumeName);
1.938 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetVolumeLRet, EF32TraceUidFileSys, KErrNone);
1.939 +
1.940 +
1.941 + delete &CurrentMount().VolumeName();
1.942 + CurrentMount().SetVolumeName(aBuf);
1.943 + }
1.944 +
1.945 +TInt TDrive::SetVolume(const TDesC& aName)
1.946 +//
1.947 +// Set the volume name.
1.948 +//
1.949 + {
1.950 + TInt r=CheckMount();
1.951 + HBufC* pV=NULL;
1.952 + if (r==KErrNone)
1.953 + {
1.954 + if(IsWriteProtected())
1.955 + return(KErrAccessDenied);
1.956 + TRAP(r,SetVolumeL(aName,pV))
1.957 + if (r!=KErrNone)
1.958 + delete pV;
1.959 + }
1.960 + return(r);
1.961 + }
1.962 +
1.963 +TInt TDrive::MkDir(const TDesC& aName)
1.964 +//
1.965 +// Make a directory.
1.966 +//
1.967 + {
1.968 + TInt r=CheckMount();
1.969 + if (r!=KErrNone)
1.970 + return(r);
1.971 + if(IsWriteProtected())
1.972 + return(KErrAccessDenied);
1.973 + TParse newDirName;
1.974 + newDirName.Set(aName,NULL,NULL);
1.975 +
1.976 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirL, EF32TraceUidFileSys, DriveNumber(), aName);
1.977 + TRAP(r,CurrentMount().MkDirL(newDirName.FullName()))
1.978 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBMkDirLRet, EF32TraceUidFileSys, r);
1.979 +
1.980 + return(r);
1.981 + }
1.982 +
1.983 +TInt TDrive::RmDir(const TDesC& aName)
1.984 +//
1.985 +// Remove a directory.
1.986 +//
1.987 + {
1.988 + TInt r=CheckMount();
1.989 + if (r!=KErrNone)
1.990 + return(r);
1.991 + TEntry entry;
1.992 + r=Entry(aName,entry);
1.993 + if (r!=KErrNone)
1.994 + return(r);
1.995 + if (entry.IsDir()==EFalse)
1.996 + return(KErrPathNotFound);
1.997 + if ((entry.iAtt&KEntryAttReadOnly) || IsWriteProtected())
1.998 + return(KErrAccessDenied);
1.999 +
1.1000 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirL, EF32TraceUidFileSys, DriveNumber(), aName);
1.1001 + TRAP(r,CurrentMount().RmDirL(aName))
1.1002 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRmDirLRet, EF32TraceUidFileSys, r);
1.1003 +
1.1004 + return(r);
1.1005 + }
1.1006 +
1.1007 +/*
1.1008 + Delete files allowing wild cards.
1.1009 +*/
1.1010 +TInt TDrive::Delete(const TDesC& aName)
1.1011 + {
1.1012 + TInt r=CheckMountAndEntryName(aName);
1.1013 + if(r!=KErrNone)
1.1014 + return r;
1.1015 +
1.1016 + if(LocateFile(aName))
1.1017 + return KErrInUse; //-- the file is already opened by someone
1.1018 +
1.1019 + // remove from closed queue - NB this isn't strictly necessary if file is read-only or write-protected...
1.1020 + LocateClosedFile(aName, EFalse);
1.1021 +
1.1022 + if (IsWriteProtected())
1.1023 + return(KErrAccessDenied);
1.1024 +
1.1025 + //-- filesystems' CMountCB::DeleteL() implementations shall check the entry attributes themeselves.
1.1026 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteL, EF32TraceUidFileSys, DriveNumber(), aName);
1.1027 + TRAP(r,CurrentMount().DeleteL(aName))
1.1028 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDeleteLRet, EF32TraceUidFileSys, r);
1.1029 +
1.1030 + return r;
1.1031 + }
1.1032 +
1.1033 +TInt TDrive::CheckMountAndEntryNames(const TDesC& anOldName,const TDesC& aNewName)
1.1034 +//
1.1035 +// Check mount, that neither is open, and that both names are legal.
1.1036 +//
1.1037 + {
1.1038 +
1.1039 + TInt r=CheckMountAndEntryName(anOldName);
1.1040 + if (r!=KErrNone)
1.1041 + return(r);
1.1042 + if (IsIllegalFullName(aNewName))
1.1043 + return(KErrBadName);
1.1044 + return(KErrNone);
1.1045 + }
1.1046 +
1.1047 +TInt TDrive::CheckDirectories(const TDesC& anOldName,const TDesC& aNewName)
1.1048 +//
1.1049 +// Return KErrAlreadyExists if aNewName exists and
1.1050 +// KErrAccessDenied if anOldName is a directory being moved to a subdirectory of itself
1.1051 +//
1.1052 + {
1.1053 +
1.1054 + TEntry entry;
1.1055 + TInt r=Entry(anOldName,entry);
1.1056 + if (r!=KErrNone)
1.1057 + return(r);
1.1058 + if (entry.IsDir())
1.1059 + {
1.1060 + //-- check the length of the destination directory name. It shall not exceed 253 characters.
1.1061 + //-- aNewName looks like "\\dir1" i.e. drive letter and ':' is removed from the name and there is no trailing '\\' in this case.
1.1062 +
1.1063 + const TInt maxDirNameLength = KMaxFileName - 3;
1.1064 + if(aNewName.Length() > maxDirNameLength)
1.1065 + return KErrBadName;
1.1066 + if(IsSubDir(aNewName,anOldName))
1.1067 + return(KErrInUse); // rename into a subdir of itself
1.1068 + if (LocateFileByPath(anOldName))
1.1069 + return(KErrInUse); // a file inside anOldName is open
1.1070 + }
1.1071 + else if (LocateFile(anOldName))
1.1072 + return(KErrInUse);
1.1073 +
1.1074 + r=Entry(aNewName,entry);
1.1075 + if (r!=KErrNone && r!=KErrNotFound)
1.1076 + return(r);
1.1077 + return(KErrNone);
1.1078 + }
1.1079 +
1.1080 +TInt TDrive::Rename(const TDesC& anOldName,const TDesC& aNewName)
1.1081 +//
1.1082 +// Rename files or directories. No wild cards.
1.1083 +//
1.1084 + {
1.1085 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1086 + TInt r=CheckMountAndEntryNames(anOldName,aNewName);
1.1087 + if (r!=KErrNone)
1.1088 + return(r);
1.1089 + TPtrC oldEntryName(StripBackSlash(anOldName));
1.1090 + TPtrC newEntryName(StripBackSlash(aNewName));
1.1091 + r=CheckDirectories(oldEntryName,newEntryName);
1.1092 + if (r!=KErrNone)
1.1093 + return(r);
1.1094 + if(IsWriteProtected())
1.1095 + return(KErrAccessDenied);
1.1096 +
1.1097 + // remove from closed queue
1.1098 + LocateClosedFile(anOldName, EFalse);
1.1099 + LocateClosedFile(aNewName, EFalse);
1.1100 +
1.1101 + TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameL, EF32TraceUidFileSys, DriveNumber(), oldEntryName,newEntryName);
1.1102 + TRAP(r,CurrentMount().RenameL(oldEntryName,newEntryName))
1.1103 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBRenameLRet, EF32TraceUidFileSys, r);
1.1104 +
1.1105 + return(r);
1.1106 + }
1.1107 +
1.1108 +TInt TDrive::Replace(const TDesC& anOldName,const TDesC& aNewName)
1.1109 +//
1.1110 +// Replace anOldName with aNewName atomically. No wild cards. No directories
1.1111 +//
1.1112 + {
1.1113 + TInt r=CheckMountAndEntryNames(anOldName,aNewName);
1.1114 + if (r!=KErrNone)
1.1115 + return(r);
1.1116 + TEntry entry;
1.1117 + r=Entry(aNewName,entry);
1.1118 + if (r!=KErrNotFound)
1.1119 + {
1.1120 + if (r!=KErrNone)
1.1121 + return(r);
1.1122 + if (entry.IsDir() || entry.IsReadOnly())
1.1123 + return(KErrAccessDenied);
1.1124 + if (LocateFile(aNewName))
1.1125 + return(KErrInUse);
1.1126 + }
1.1127 + r=Entry(anOldName,entry);
1.1128 + if (r!=KErrNone)
1.1129 + return(r);
1.1130 + if (entry.IsDir() || IsWriteProtected())
1.1131 + return(KErrAccessDenied);
1.1132 + if (LocateFile(anOldName))
1.1133 + return(KErrInUse);
1.1134 +
1.1135 + // remove from closed queue
1.1136 + LocateClosedFile(anOldName, EFalse);
1.1137 + LocateClosedFile(aNewName, EFalse);
1.1138 +
1.1139 + TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceL, EF32TraceUidFileSys, DriveNumber(), anOldName, aNewName);
1.1140 + TRAP(r,CurrentMount().ReplaceL(anOldName,aNewName))
1.1141 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReplaceLRet, EF32TraceUidFileSys, r);
1.1142 +
1.1143 + return(r);
1.1144 + }
1.1145 +
1.1146 +TInt TDrive::Entry(const TDesC& aName,TEntry& anEntry)
1.1147 +//
1.1148 +// Get the entry details.
1.1149 +//
1.1150 + {
1.1151 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1152 + TInt r=CheckMountAndEntryName(aName);
1.1153 + if (r!=KErrNone)
1.1154 + return(r);
1.1155 + TPtrC entryName(StripBackSlash(aName));
1.1156 + TRAP(r,DoEntryL(entryName,anEntry));
1.1157 +
1.1158 + if (r==KErrHidden)
1.1159 + r=KErrNotFound;
1.1160 + else if (r==KErrPathHidden)
1.1161 + r=KErrPathNotFound;
1.1162 +
1.1163 + return(r);
1.1164 + }
1.1165 +
1.1166 +void TDrive::DoEntryL(const TDesC& aName, TEntry& anEntry)
1.1167 +//
1.1168 +// Get entry details
1.1169 +//
1.1170 + {
1.1171 + FlushCachedFileInfoL();
1.1172 +
1.1173 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryL, EF32TraceUidFileSys, DriveNumber(), aName);
1.1174 + CurrentMount().EntryL(aName,anEntry);
1.1175 + TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBEntryLRet, EF32TraceUidFileSys,
1.1176 + KErrNone, anEntry.iAtt,
1.1177 + I64LOW(anEntry.iModified.Int64()), I64HIGH(anEntry.iModified.Int64()),
1.1178 + anEntry.iSize);
1.1179 +
1.1180 + }
1.1181 +
1.1182 +TInt TDrive::CheckAttributes(const TDesC& aName,TUint& aSetAttMask,TUint& aClearAttMask)
1.1183 +//
1.1184 +// Validate the changes against the current entry attributes
1.1185 +//
1.1186 + {
1.1187 +
1.1188 + TEntry entry;
1.1189 + TRAPD(r,DoEntryL(aName,entry));
1.1190 + if (r!=KErrNone)
1.1191 + return(r);
1.1192 + ValidateAtts(entry.iAtt,aSetAttMask,aClearAttMask);
1.1193 + return(KErrNone);
1.1194 + }
1.1195 +
1.1196 +TInt TDrive::SetEntry(const TDesC& aName,const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
1.1197 +//
1.1198 +// Set the entry details.
1.1199 +//
1.1200 + {
1.1201 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1202 + TInt r=CheckMountAndEntryName(aName);
1.1203 + if (r!=KErrNone)
1.1204 + return(r);
1.1205 + TPtrC entryName(StripBackSlash(aName));
1.1206 + CFileCB* pF=LocateFile(entryName);
1.1207 + if (pF!=NULL)
1.1208 + return(KErrInUse);
1.1209 + r=CheckAttributes(entryName,aSetAttMask,aClearAttMask);
1.1210 + if (r!=KErrNone)
1.1211 + return(r);
1.1212 + if (IsWriteProtected())
1.1213 + return(KErrAccessDenied);
1.1214 + TTime nullTime(0);
1.1215 + if (aTime!=nullTime)
1.1216 + aSetAttMask|=KEntryAttModified;
1.1217 +
1.1218 + TRACEMULT6(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryL, EF32TraceUidFileSys,
1.1219 + DriveNumber(), aName, I64LOW(aTime.Int64()), I64HIGH(aTime.Int64()), aSetAttMask, aClearAttMask);
1.1220 + TRAP(r,CurrentMount().SetEntryL(entryName,aTime,aSetAttMask,aClearAttMask))
1.1221 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBSetEntryLRet, EF32TraceUidFileSys, r);
1.1222 +
1.1223 + return(r);
1.1224 + }
1.1225 +
1.1226 +TInt TDrive::FileTemp(CFsRequest* aRequest,TInt& aHandle,const TDesC& aPath,TDes& aName,TUint aMode)
1.1227 +//
1.1228 +// Create a temporary file and return the file name.
1.1229 +//
1.1230 + {
1.1231 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1232 + aName=aPath;
1.1233 + TInt len=aName.Length();
1.1234 + TInt t=User::TickCount()&0xfffff;
1.1235 + aMode|=EFileWrite;
1.1236 + for (TInt retry=0;retry<KMaxTempNameAttempts;retry++)
1.1237 + {
1.1238 + aName.SetLength(len);
1.1239 + aName.AppendFormat(_L("TMP%05x.$$$"),t);
1.1240 + TEntry e;
1.1241 + TInt r=Entry(aName,e);
1.1242 + if (r!=KErrNone)
1.1243 + {
1.1244 + if (r!=KErrNotFound)
1.1245 + return(r);
1.1246 + return(FileOpen(aRequest,aHandle,aName,aMode,EFileCreate));
1.1247 + }
1.1248 + t=((t|1)*13)&0xfffff;
1.1249 + }
1.1250 + return(KErrGeneral);
1.1251 + }
1.1252 +
1.1253 +LOCAL_C HBufC* CreateFileNameL(const TDesC& aName)
1.1254 +//
1.1255 +// Create a HBufC from aName
1.1256 +// Converts _L("\\F32.\\GROUP\\release.") to _L("\\F32\\GROUP\\release")
1.1257 +//
1.1258 + {
1.1259 +
1.1260 + TParsePtrC name(aName);
1.1261 + TFileName fileName;
1.1262 + fileName.Append(KPathDelimiter);
1.1263 +
1.1264 + if (name.Path().Length())
1.1265 + {
1.1266 + TInt pos=0;
1.1267 + TPtrC entry(NULL,0);
1.1268 + FOREVER
1.1269 + {
1.1270 + NextInPath(name.Path(),entry,pos);
1.1271 + if (entry.Length()==0)
1.1272 + break;
1.1273 + fileName.Append(entry);
1.1274 + fileName.Append(KPathDelimiter);
1.1275 + }
1.1276 + }
1.1277 +
1.1278 + fileName.Append(name.Name());
1.1279 + if (name.Ext().Length()>1)
1.1280 + fileName.Append(name.Ext());
1.1281 + return(fileName.AllocL());
1.1282 + }
1.1283 +
1.1284 +void TDrive::FileOpenL(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB*& aFileCB,CFileShare*& aFileShare)
1.1285 +//
1.1286 +// Open/Create/Replace a file.
1.1287 +//
1.1288 + {
1.1289 + aFileCB=NULL;
1.1290 + aFileShare=NULL;
1.1291 + TInt r = CheckMount();
1.1292 + if (r!=KErrNone)
1.1293 + User::Leave(r);
1.1294 +
1.1295 + if (IsIllegalFullName(aRequest->Src()))
1.1296 + User::Leave(KErrBadName);
1.1297 +
1.1298 + if (CurrentMount().Locked())
1.1299 + User::Leave(KErrInUse);
1.1300 +
1.1301 + if ((aMode & EFileWrite) != 0)
1.1302 + {
1.1303 + TDriveInfo driveInfo;
1.1304 + DriveInfo(driveInfo);
1.1305 + if (driveInfo.iType==EMediaRom || (driveInfo.iMediaAtt&KMediaAttWriteProtected)!=0)
1.1306 + User::Leave(KErrAccessDenied);
1.1307 + }
1.1308 +
1.1309 + TShare share=(TShare)(aMode&KFileShareMask);
1.1310 + if (share==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
1.1311 + User::Leave(KErrArgument);
1.1312 +
1.1313 + if (aMode & EFileReadAsyncAll)
1.1314 + {
1.1315 + // Async read all mode is not compatible with EFileShareExclusive or EFileShareReadersOnly,
1.1316 + // as these modes prevent a writer from accessing the file and completing the request.
1.1317 + if(share == EFileShareExclusive || share == EFileShareReadersOnly)
1.1318 + User::Leave(KErrArgument);
1.1319 + }
1.1320 +
1.1321 + // check for silly cache on / off combinations
1.1322 + const TUint KBadWriteMode = EFileWriteBuffered | EFileWriteDirectIO;
1.1323 + const TUint KBadReadMode = EFileReadBuffered | EFileReadDirectIO;
1.1324 + const TUint KBadReadAheadMode = EFileReadAheadOn | EFileReadAheadOff;
1.1325 + const TUint KBadReadAheadMode2 = EFileReadDirectIO | EFileReadAheadOn;
1.1326 + if (((aMode & KBadWriteMode) == KBadWriteMode) ||
1.1327 + ((aMode & KBadReadMode) == KBadReadMode) ||
1.1328 + ((aMode & KBadReadAheadMode) == KBadReadAheadMode) ||
1.1329 + ((aMode & KBadReadAheadMode2) == KBadReadAheadMode2))
1.1330 + {
1.1331 + User::Leave(KErrArgument);
1.1332 + }
1.1333 +
1.1334 + // Only allow delete on close for a newly created file.
1.1335 + if ((aMode & EDeleteOnClose) && (anOpen!=EFileCreate))
1.1336 + User::Leave(KErrArgument);
1.1337 +
1.1338 + CFileCB* pF=LocateFile(aName);
1.1339 + CFileCache* pFileCache = NULL;
1.1340 + TBool openFile=EFalse;
1.1341 + if (pF!=NULL)
1.1342 + {
1.1343 + if (pF->iShare==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
1.1344 + User::Leave(KErrInUse);
1.1345 + if (anOpen==EFileCreate)
1.1346 + User::Leave(KErrAlreadyExists);
1.1347 + TInt r=ValidateShare(*pF,share);
1.1348 + if (r!=KErrNone)
1.1349 + User::Leave(r);
1.1350 + if ((r=pF->Open())!=KErrNone)
1.1351 + User::Leave(r);
1.1352 + aFileCB=pF;
1.1353 + pFileCache = pF->FileCache();
1.1354 + }
1.1355 + else
1.1356 + {
1.1357 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.1358 +
1.1359 + //-- construct CFileCB object, belonging to the corresponding mount
1.1360 + pF = aFileCB = CurrentMount().NewFileL();
1.1361 +
1.1362 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileLRet, EF32TraceUidFileSys, r, pF);
1.1363 + TDrive* createdDrive=!aRequest->SubstedDrive() ? this : aRequest->SubstedDrive();
1.1364 +
1.1365 + HBufC* fileName = CreateFileNameL(aName);
1.1366 +
1.1367 + pF->InitL(this, createdDrive, fileName);
1.1368 +
1.1369 +
1.1370 + pF->iShare = share;
1.1371 + openFile=ETrue;
1.1372 + CurrentMount().iMountQ.AddLast(*pF);
1.1373 + Files->AddL(pF,ETrue);
1.1374 + }
1.1375 +
1.1376 + CFileShare* pS=aFileShare=new(ELeave) CFileShare(pF);
1.1377 +
1.1378 + // We need to call CFileCB::PromoteShare immediately after the CFileShare
1.1379 + // instance is created since the destructor calls CFileCB::DemoteShare()
1.1380 + // which checks the share count is non-zero
1.1381 + pS->iMode=aMode;
1.1382 + pF->PromoteShare(pS);
1.1383 +
1.1384 + pS->InitL();
1.1385 + aFileCB=NULL;
1.1386 + FileShares->AddL(pS,ETrue);
1.1387 + aHandle=aRequest->Session()->Handles().AddL(pS,ETrue);
1.1388 +
1.1389 +
1.1390 + if (openFile)
1.1391 + {
1.1392 + TRACEMULT5(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenL, EF32TraceUidFileSys, DriveNumber(), aName, aMode, (TUint) anOpen, (TUint) pF);
1.1393 + CurrentMount().FileOpenL(aName,aMode,anOpen,pF);
1.1394 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenLRet, EF32TraceUidFileSys, KErrNone);
1.1395 +
1.1396 + // Delete on close may now be safely flagged if required.
1.1397 + // The file did not exist on the media prior to the
1.1398 + // CMountCB::FileOpenL() call for the case of a create.
1.1399 + if ((aMode & EDeleteOnClose) && (anOpen==EFileCreate))
1.1400 + pF->SetDeleteOnClose();
1.1401 +
1.1402 + TBool localBufferSuppport = (CurrentMount().LocalBufferSupport(pF) == KErrNone)?(TBool)ETrue:(TBool)EFalse;
1.1403 + pF->SetLocalBufferSupport(localBufferSuppport);
1.1404 + if (localBufferSuppport)
1.1405 + {
1.1406 + // if file exists on closed queue resurrect it or discard it,
1.1407 + // depending on the file open mode
1.1408 + pFileCache = LocateClosedFile(aName, anOpen == EFileOpen?(TBool)ETrue:(TBool)EFalse);
1.1409 + if (pFileCache)
1.1410 + {
1.1411 + pFileCache = pFileCache->ReNewL(*pS); // NB may return NULL if caching not enabled
1.1412 + }
1.1413 + else
1.1414 + {
1.1415 + pFileCache = CFileCache::NewL(*pS); // NB may return NULL if caching not enabled
1.1416 + }
1.1417 + if (pFileCache)
1.1418 + // set the cached size to be the same as the uncached size
1.1419 + pF->SetCachedSize64(pF->Size64());
1.1420 + }
1.1421 + else
1.1422 + {
1.1423 + __CACHE_PRINT(_L("TDrive::FileOpenL(), Local buffers not supported"));
1.1424 + }
1.1425 + }
1.1426 +
1.1427 + // initialize share mode flags
1.1428 + if (pFileCache != NULL)
1.1429 + pFileCache->Init(*pS);
1.1430 + }
1.1431 +
1.1432 +TInt TDrive::FileOpen(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen)
1.1433 +//
1.1434 +// Open/Create/Replace a file.
1.1435 +//
1.1436 + {
1.1437 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1438 + CFileCB* pF=NULL;
1.1439 + CFileShare* pS=NULL;
1.1440 + aHandle=0;
1.1441 + TRAPD(r,FileOpenL(aRequest,aHandle,aName,aMode,anOpen,pF,pS))
1.1442 +
1.1443 + // Allow files > 2GB-1 to be opened only if EFileBigFile is specified in iMode
1.1444 + if (r == KErrNone && pS && ((TUint64)pS->File().Size64() > KMaxLegacyFileSize) && (!(pS->IsFileModeBig())))
1.1445 + r = KErrTooBig;
1.1446 +
1.1447 + if (r!=KErrNone)
1.1448 + {
1.1449 + if (r==KErrHidden)
1.1450 + r=KErrNotFound;
1.1451 + else if (r==KErrPathHidden)
1.1452 + r=KErrPathNotFound;
1.1453 +
1.1454 + if(pF && !pS)
1.1455 + pF->Close();
1.1456 + CheckSubClose(pS,aHandle,aRequest->Session());
1.1457 + }
1.1458 + return(r);
1.1459 + }
1.1460 +
1.1461 +void TDrive::DirOpenL(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType,CDirCB*& aDir)
1.1462 +//
1.1463 +// Open a directory listing. Leave on error.
1.1464 +//
1.1465 + {
1.1466 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.1467 +
1.1468 + CDirCB* pD = aDir = CurrentMount().NewDirL(); //-- construct CDirCB object, belonging to the corresponding mount
1.1469 +
1.1470 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewDirLRet, EF32TraceUidFileSys, KErrNone, pD);
1.1471 + pD->InitL(this);
1.1472 + // modify resource counter after initialisation to ensure correct cleanup
1.1473 + AddResource(CurrentMount());
1.1474 + pD->iAtt=anAtt;
1.1475 + pD->iUidType=aUidType;
1.1476 + Dirs->AddL(pD,ETrue);
1.1477 + aHandle=aSession->Handles().AddL(pD,ETrue);
1.1478 +
1.1479 + TRACEMULT3(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenL, EF32TraceUidFileSys, DriveNumber(), aName, (TUint) pD);
1.1480 + CurrentMount().DirOpenL(aName,pD);
1.1481 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDirOpenLRet, EF32TraceUidFileSys, KErrNone);
1.1482 + }
1.1483 +
1.1484 +TInt TDrive::DirOpen(CSessionFs* aSession,TInt& aHandle,const TDesC& aName,TUint anAtt,const TUidType& aUidType)
1.1485 +//
1.1486 +// Open a directory listing.
1.1487 +//
1.1488 + {
1.1489 + TInt r=CheckMountAndEntryName(aName);
1.1490 + if (r!=KErrNone)
1.1491 + return(r);
1.1492 + if (CurrentMount().Locked())
1.1493 + return(KErrInUse);
1.1494 + CDirCB* pD=NULL;
1.1495 + aHandle=0;
1.1496 + TRAP(r,DirOpenL(aSession,aHandle,aName,anAtt,aUidType,pD));
1.1497 +
1.1498 + if (r==KErrHidden)
1.1499 + r=KErrNotFound;
1.1500 + else if (r==KErrPathHidden)
1.1501 + r=KErrPathNotFound;
1.1502 +
1.1503 + if (r!=KErrNone)
1.1504 + CheckSubClose(pD,aHandle,aSession);
1.1505 + return(r);
1.1506 + }
1.1507 +
1.1508 +
1.1509 +TInt TDrive::ReadFileSection(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1.1510 +//
1.1511 +// Starting from aPos, read aLength bytes of a file into a Trg,
1.1512 +// regardless of lock state
1.1513 +//
1.1514 + {
1.1515 + return ReadFileSection64(aName, aPos, aTrg, aLength, aMessage);
1.1516 + }
1.1517 +
1.1518 +
1.1519 +TInt TDrive::ReadFileSection64(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1.1520 +//
1.1521 +// Starting from aPos, read aLength bytes of a file into a Trg,
1.1522 +// regardless of lock state
1.1523 +//
1.1524 + {
1.1525 +
1.1526 + // flush dirty data if already open
1.1527 + CFileCB* file;
1.1528 + IsFileOpen(aName, file);
1.1529 + if (file && file->FileCache())
1.1530 + {
1.1531 + if (file->FileCache()->FlushDirty() == CFsRequest::EReqActionBusy)
1.1532 + return CFsRequest::EReqActionBusy;
1.1533 + }
1.1534 +
1.1535 + __PRINT(_L("TDrive::ReadSection"));
1.1536 + TInt r=CheckMountAndEntryName(aName);
1.1537 + if (r!=KErrNone)
1.1538 + return(r);
1.1539 + TPtrC entryName(StripBackSlash(aName));
1.1540 +
1.1541 + TRACETHREADID(aMessage);
1.1542 + TRACEMULT7(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionL, EF32TraceUidFileSys,
1.1543 + DriveNumber(), aName, I64LOW(aPos), I64HIGH(aPos), (TUint) aTrg, aLength, I64LOW(threadId));
1.1544 + TRAP(r,ReadSectionL(entryName,aPos,aTrg,aLength,aMessage));
1.1545 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReadFileSectionLRet, EF32TraceUidFileSys, r);
1.1546 +
1.1547 + if (r==KErrHidden)
1.1548 + r=KErrNotFound;
1.1549 + else if (r==KErrPathHidden)
1.1550 + r=KErrPathNotFound;
1.1551 +
1.1552 + return(r);
1.1553 + }
1.1554 +
1.1555 +
1.1556 +void TDrive::ReadSectionL(const TDesC& aName,TInt64 aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage)
1.1557 +//
1.1558 +// Starting from aPos, read aLength bytes of a file into a Trg,
1.1559 +// regardless of lock state
1.1560 +//
1.1561 + {
1.1562 + __PRINT(_L("TDrive::ReadSectionL"));
1.1563 +
1.1564 + FlushCachedFileInfoL();
1.1565 + CurrentMount().ReadSection64L(aName,aPos,aTrg,aLength,aMessage);
1.1566 + }
1.1567 +
1.1568 +/**
1.1569 + Check the disk's integrity
1.1570 +*/
1.1571 +TInt TDrive::CheckDisk()
1.1572 + {
1.1573 + TInt r=CheckMount();
1.1574 + if (r==KErrNone)
1.1575 + TRAP(r,FlushCachedFileInfoL());
1.1576 + if (r==KErrNone)
1.1577 + {
1.1578 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1, EF32TraceUidFileSys, DriveNumber());
1.1579 + r=CurrentMount().CheckDisk();
1.1580 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk1Ret, EF32TraceUidFileSys, r);
1.1581 + }
1.1582 + return(r);
1.1583 + }
1.1584 +
1.1585 +/**
1.1586 + @prototype
1.1587 +*/
1.1588 +TInt TDrive::CheckDisk(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
1.1589 + {
1.1590 + TInt r=CheckMount();
1.1591 + if (r==KErrNone)
1.1592 + TRAP(r,FlushCachedFileInfoL());
1.1593 + if (r==KErrNone)
1.1594 + {
1.1595 + TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
1.1596 + r=CurrentMount().CheckDisk(aOperation, aParam1, aParam2);
1.1597 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBCheckDisk2Ret, EF32TraceUidFileSys, r);
1.1598 + }
1.1599 +
1.1600 + return(r);
1.1601 + }
1.1602 +
1.1603 +TInt TDrive::ScanDrive()
1.1604 + {
1.1605 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1606 + TInt r=CheckMount();
1.1607 + if(r==KErrNone)
1.1608 + {
1.1609 + if(IsWriteProtected())
1.1610 + return(KErrAccessDenied);
1.1611 + TRAP(r,FlushCachedFileInfoL());
1.1612 + }
1.1613 + if(r!=KErrNone)
1.1614 + return r;
1.1615 +
1.1616 + // Empty closed file queue
1.1617 + TClosedFileUtils::Remove(DriveNumber());
1.1618 +
1.1619 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1, EF32TraceUidFileSys, DriveNumber());
1.1620 + r = CurrentMount().ScanDrive();
1.1621 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive1Ret, EF32TraceUidFileSys, r);
1.1622 +
1.1623 + return r;
1.1624 + }
1.1625 +
1.1626 +
1.1627 +/**
1.1628 + @prototype
1.1629 +*/
1.1630 +TInt TDrive::ScanDrive(TInt aOperation, TAny* aParam1/*=NULL*/, TAny* aParam2/*=NULL*/)
1.1631 + {
1.1632 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1633 + TInt r=CheckMount();
1.1634 + if(r==KErrNone)
1.1635 + {
1.1636 + if(IsWriteProtected())
1.1637 + return(KErrAccessDenied);
1.1638 + TRAP(r,FlushCachedFileInfoL());
1.1639 + }
1.1640 + if(r!=KErrNone)
1.1641 + return r;
1.1642 +
1.1643 + // Empty closed file queue
1.1644 + TClosedFileUtils::Remove(DriveNumber());
1.1645 +
1.1646 + TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2, EF32TraceUidFileSys, DriveNumber(), aOperation, aParam1, aParam2);
1.1647 + r = CurrentMount().ScanDrive(aOperation, aParam1, aParam2);
1.1648 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBScanDrive2Ret, EF32TraceUidFileSys, r);
1.1649 +
1.1650 + return r;
1.1651 + }
1.1652 +
1.1653 +
1.1654 +TInt TDrive::GetShortName(const TDesC& aName,TDes& aShortName)
1.1655 +//
1.1656 +// Get the short name associated with a long file name
1.1657 +//
1.1658 + {
1.1659 + TInt r=CheckMountAndEntryName(aName);
1.1660 + if (r!=KErrNone)
1.1661 + return(r);
1.1662 + TPtrC entryName(StripBackSlash(aName));
1.1663 +
1.1664 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
1.1665 + TRAP(r,CurrentMount().GetShortNameL(entryName,aShortName));
1.1666 + TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetShortNameLRet, EF32TraceUidFileSys, r, aShortName);
1.1667 +
1.1668 + return(r);
1.1669 + }
1.1670 +
1.1671 +TInt TDrive::GetLongName(const TDesC& aShortName,TDes& aLongName)
1.1672 +//
1.1673 +// Get the long name associated with a short file name
1.1674 +//
1.1675 + {
1.1676 + TInt r=CheckMountAndEntryName(aShortName);
1.1677 + if (r!=KErrNone)
1.1678 + return(r);
1.1679 + TPtrC entryName(StripBackSlash(aShortName));
1.1680 +
1.1681 + TRACEMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameL, EF32TraceUidFileSys, DriveNumber(), entryName);
1.1682 + TRAP(r,CurrentMount().GetLongNameL(entryName,aLongName));
1.1683 + TRACERETMULT2(UTF::EBorder, UTraceModuleFileSys::ECMountCBGetLongNameLRet, EF32TraceUidFileSys, r, aLongName);
1.1684 +
1.1685 + return(r);
1.1686 + }
1.1687 +
1.1688 +
1.1689 +/**
1.1690 + Query whether the file is open or not.
1.1691 +*/
1.1692 +TInt TDrive::IsFileOpen(const TDesC& aFileName,CFileCB*& aFileCB)
1.1693 + {
1.1694 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1695 +
1.1696 + aFileCB = NULL;
1.1697 +
1.1698 + TInt r=CheckMountAndEntryName(aFileName);
1.1699 + if (r!=KErrNone)
1.1700 + return(r);
1.1701 +
1.1702 + Files->Lock();
1.1703 + TInt count=Files->Count();
1.1704 +
1.1705 + // create a hash to speed up the search
1.1706 +
1.1707 + TFileName foldedName;
1.1708 + TUint32 nameHash=0;
1.1709 + if (count > 0)
1.1710 + {
1.1711 + foldedName.CopyF(aFileName);
1.1712 + nameHash=CalcNameHash(foldedName);
1.1713 + }
1.1714 +
1.1715 + while(count--)
1.1716 + {
1.1717 + CFileCB* file=(CFileCB*)(*Files)[count];
1.1718 +
1.1719 + if ((&file->Drive()==this) && nameHash == file->NameHash() && file->FileNameF().Match(foldedName)!=KErrNotFound)
1.1720 + {
1.1721 + aFileCB = file;
1.1722 + break;
1.1723 + }
1.1724 + }
1.1725 + Files->Unlock();
1.1726 + return(KErrNone);
1.1727 + }
1.1728 +
1.1729 +TInt TDrive::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart)
1.1730 +//
1.1731 +// Return the start of the file if it is in rom
1.1732 +//
1.1733 + {
1.1734 + TInt r=CheckMount();
1.1735 + if (r==KErrNone)
1.1736 + CurrentMount().IsFileInRom(aFileName,aFileStart);
1.1737 + return(r);
1.1738 + }
1.1739 +
1.1740 +TBool TDrive::IsWriteProtected()
1.1741 +//
1.1742 +// return true if the media is write protected
1.1743 +//
1.1744 + {
1.1745 +// __CHECK_DRIVETHREAD(iDriveNumber);
1.1746 + TDriveInfo drvInfo;
1.1747 + drvInfo.iMediaAtt=0;
1.1748 + if(Att() && iFSys)
1.1749 + FSys().DriveInfo(drvInfo,DriveNumber());
1.1750 + return((drvInfo.iMediaAtt&KMediaAttWriteProtected)!=0);
1.1751 + }
1.1752 +
1.1753 +
1.1754 +
1.1755 +
1.1756 +/**
1.1757 +Checks whether any resource that could write to disk is open on
1.1758 +the current mount.
1.1759 +
1.1760 +@return True, if a resource that could write to disk is open on
1.1761 + the current mount, false otherwise.
1.1762 +*/
1.1763 +EXPORT_C TBool TDrive::IsWriteableResource() const
1.1764 + {
1.1765 +// __CHECK_DRIVETHREAD(iDriveNumber);
1.1766 + if(iCurrentMount==NULL)
1.1767 + return(EFalse);
1.1768 + if(iCurrentMount->LockStatus()>0)
1.1769 + {
1.1770 + // check format subsessions
1.1771 + Formats->Lock();
1.1772 + TInt count=Formats->Count();
1.1773 + while(count--)
1.1774 + {
1.1775 + CFormatCB* format=(CFormatCB*)(*Formats)[count];
1.1776 + if(&format->Mount()==iCurrentMount)
1.1777 + {
1.1778 + Formats->Unlock();
1.1779 + return(ETrue);
1.1780 + }
1.1781 + }
1.1782 + Formats->Unlock();
1.1783 + // check raw disk subsessions
1.1784 + RawDisks->Lock();
1.1785 + count=RawDisks->Count();
1.1786 + while(count--)
1.1787 + {
1.1788 + CRawDiskCB* rawDisk=(CRawDiskCB*)(*RawDisks)[count];
1.1789 + if(&rawDisk->Mount()==iCurrentMount && !rawDisk->IsWriteProtected())
1.1790 + {
1.1791 + Formats->Unlock();
1.1792 + return(ETrue);
1.1793 + }
1.1794 + }
1.1795 + Formats->Unlock();
1.1796 + }
1.1797 + else if(iCurrentMount->LockStatus()<0)
1.1798 + {
1.1799 + // check file share subsessions
1.1800 + FileShares->Lock();
1.1801 + TInt count=FileShares->Count();
1.1802 + while(count--)
1.1803 + {
1.1804 + CFileShare* fileShare=(CFileShare*)(*FileShares)[count];
1.1805 + if (&fileShare->File().Mount()==iCurrentMount && ((fileShare->iMode&EFileWrite)!=0))
1.1806 + {
1.1807 + FileShares->Unlock();
1.1808 + return(ETrue);
1.1809 + }
1.1810 + }
1.1811 + FileShares->Unlock();
1.1812 + }
1.1813 + return(EFalse);
1.1814 + }
1.1815 +
1.1816 +
1.1817 +
1.1818 +
1.1819 +/**
1.1820 +Tests whether the current function can cause a write to disk.
1.1821 +
1.1822 +@return True, if the current function can cause a write to disk,
1.1823 + false otherwise.
1.1824 +*/
1.1825 +EXPORT_C TBool TDrive::IsCurrentWriteFunction() const
1.1826 + {
1.1827 +// __CHECK_DRIVETHREAD(iDriveNumber);
1.1828 + CDriveThread* pT=NULL;
1.1829 + TInt r=FsThreadManager::GetDriveThread(iDriveNumber, &pT);
1.1830 + __ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveCurrentWriteFunction));
1.1831 + return(pT->IsRequestWriteable());
1.1832 + }
1.1833 +
1.1834 +
1.1835 +
1.1836 +
1.1837 +TInt TDrive::ForceRemountDrive(const TDesC8* aMountInfo,TInt aMountInfoMessageHandle,TUint aFlags)
1.1838 +//
1.1839 +// Force a remount of the drive
1.1840 +//
1.1841 + {
1.1842 + __PRINT(_L("TDrive::ForceRemountDrive"));
1.1843 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1844 + if(iFSys==NULL)
1.1845 + return(KErrNotReady);
1.1846 + TInt r;
1.1847 + CMountCB* pM=NULL;
1.1848 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.1849 + TRAP(r,pM=FSys().NewMountL());
1.1850 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1.1851 + if(r!=KErrNone)
1.1852 + return(r);
1.1853 + pM->SetDrive(this);
1.1854 +
1.1855 + TRACE4(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDrive, EF32TraceUidFileSys,
1.1856 + DriveNumber(), aMountInfo, aMountInfoMessageHandle, aFlags);
1.1857 + r=pM->ForceRemountDrive(aMountInfo,aMountInfoMessageHandle,aFlags);
1.1858 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBForceRemountDriveRet, EF32TraceUidFileSys, r);
1.1859 +
1.1860 + pM->Close();
1.1861 + return(r);
1.1862 + }
1.1863 +
1.1864 +TBool TDrive::IsExtensionMounted(CProxyDriveFactory* aFactory)
1.1865 +//
1.1866 +// return ETrue if extension mounted on the drive
1.1867 +//
1.1868 + {
1.1869 + for(TInt i=0;i<iExtInfo.iCount;++i)
1.1870 + {
1.1871 + if(iExtInfo.iInfo[i].iFactory==aFactory)
1.1872 + return(ETrue);
1.1873 + }
1.1874 + return(EFalse);
1.1875 + }
1.1876 +
1.1877 +TInt TDrive::MountExtension(CProxyDriveFactory* aFactory,TBool aIsPrimary)
1.1878 +//
1.1879 +// Mount an extension
1.1880 +//
1.1881 + {
1.1882 + __PRINT1(_L("TDrive::MountExtension aIsPrimary=%d"),aIsPrimary);
1.1883 + if(aIsPrimary)
1.1884 + {
1.1885 + __CHECK_MAINTHREAD();
1.1886 + // primary extension mounted before file system since it must be present
1.1887 + // for successful mount
1.1888 + __ASSERT_ALWAYS(!iFSys,Fault(EMountExtensionFSys));
1.1889 + if(iExtInfo.iCount!=0)
1.1890 + return(KErrAccessDenied);
1.1891 + iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
1.1892 + iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=ETrue;
1.1893 + return(KErrNone);
1.1894 + }
1.1895 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1896 + // must be a secondary extension
1.1897 + if(iFSys==NULL)
1.1898 + return(KErrNotReady);
1.1899 + TBool extSupported = iFSys->IsExtensionSupported();
1.1900 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECFileSystemIsExtensionSupported, EF32TraceUidFileSys, extSupported);
1.1901 + if(!extSupported)
1.1902 + return(KErrNotSupported);
1.1903 + if(IsExtensionMounted(aFactory))
1.1904 + return(KErrAlreadyExists);
1.1905 + if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
1.1906 + return(KErrInUse);
1.1907 + if(iExtInfo.iCount>=KMaxExtensionCount)
1.1908 + return(KErrAccessDenied);
1.1909 + iExtInfo.iInfo[iExtInfo.iCount].iFactory=aFactory;
1.1910 + iExtInfo.iInfo[iExtInfo.iCount++].iIsPrimary=EFalse;
1.1911 + // now dismount and mount so that the extension incorporated
1.1912 + Dismount();
1.1913 + TInt r=CheckMount();
1.1914 + // if mount fails then remove the secondary extension
1.1915 + if(r!=KErrNone)
1.1916 + {
1.1917 + --iExtInfo.iCount;
1.1918 + __ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount0));
1.1919 + }
1.1920 + return(r);
1.1921 + }
1.1922 +
1.1923 +TInt TDrive::DismountExtension(CProxyDriveFactory* aFactory, TBool /*aIsPrimary*/)
1.1924 +//
1.1925 +// Dismount an extension
1.1926 +//
1.1927 + {
1.1928 + __PRINT(_L("TDrive::DismountExtension"));
1.1929 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1930 +
1.1931 + // Empty closed file queue
1.1932 + TClosedFileUtils::Remove(DriveNumber());
1.1933 +
1.1934 + if(iExtInfo.iCount==0)
1.1935 + return(KErrNotFound);
1.1936 + if(iCurrentMount && (CurrentMount().LockStatus()!=0 || Mount().Count()>1))
1.1937 + return(KErrInUse);
1.1938 + for(TInt i=0;i<iExtInfo.iCount;++i)
1.1939 + {
1.1940 + if(iExtInfo.iInfo[i].iFactory==aFactory)
1.1941 + {
1.1942 + // cannot dismount a primary extension without dismounting the file system
1.1943 + if(i==0 && iExtInfo.iInfo[i].iIsPrimary)
1.1944 + return(KErrAccessDenied);
1.1945 + // slide any remaining extensions down
1.1946 + for(TInt j=i+1;j<iExtInfo.iCount;++j)
1.1947 + iExtInfo.iInfo[j-1].iFactory=iExtInfo.iInfo[j].iFactory;
1.1948 + iExtInfo.iCount--;
1.1949 + __ASSERT_DEBUG(iExtInfo.iCount>=0,Fault(EExtensionInfoCount1));
1.1950 + Dismount();
1.1951 + return(KErrNone);
1.1952 + }
1.1953 + }
1.1954 + return(KErrNotFound);
1.1955 + }
1.1956 +
1.1957 +TInt TDrive::ExtensionName(TDes& aExtensionName,TInt aPos)
1.1958 +//
1.1959 +// Return the extension name
1.1960 +//
1.1961 + {
1.1962 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1963 +
1.1964 + if(iFSys==NULL)
1.1965 + return(KErrNotReady);
1.1966 +
1.1967 + if(aPos<iExtInfo.iCount)
1.1968 + {
1.1969 + aExtensionName=iExtInfo.iInfo[aPos].iFactory->Name();
1.1970 + return(KErrNone);
1.1971 + }
1.1972 + return(KErrNotFound);
1.1973 + }
1.1974 +
1.1975 +#if defined(_LOCKABLE_MEDIA)
1.1976 +
1.1977 +TInt TDrive::LockDevice(TMediaPassword& aOld,TMediaPassword& aNew,TBool aStore)
1.1978 +//
1.1979 +// Lock media device
1.1980 +//
1.1981 + {
1.1982 + __PRINT(_L("TDrive::LockDevice"));
1.1983 + __CHECK_DRIVETHREAD(iDriveNumber);
1.1984 + if(iFSys==NULL)
1.1985 + return(KErrNotReady);
1.1986 + TInt r;
1.1987 + CMountCB* pM=NULL;
1.1988 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.1989 + TRAP(r,pM=FSys().NewMountL());
1.1990 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1.1991 + if(r!=KErrNone)
1.1992 + return(r);
1.1993 + pM->SetDrive(this);
1.1994 +
1.1995 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBLock, EF32TraceUidFileSys, DriveNumber(), aStore);
1.1996 + r=pM->Lock(aOld,aNew,aStore);
1.1997 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBLockRet, EF32TraceUidFileSys, r);
1.1998 +
1.1999 + pM->Close();
1.2000 + return(r);
1.2001 + }
1.2002 +
1.2003 +TInt TDrive::UnlockDevice(TMediaPassword& aPassword,TBool aStore)
1.2004 +//
1.2005 +// Unlock media device
1.2006 +//
1.2007 + {
1.2008 + __PRINT(_L("TDrive::UnlockDevice"));
1.2009 + __CHECK_DRIVETHREAD(iDriveNumber);
1.2010 + if(iFSys==NULL)
1.2011 + return(KErrNotReady);
1.2012 + TInt r;
1.2013 + CMountCB* pM=NULL;
1.2014 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.2015 + TRAP(r,pM=FSys().NewMountL());
1.2016 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1.2017 + if(r!=KErrNone)
1.2018 + return(r);
1.2019 +
1.2020 + // reset mount failure count - which is likely to be non-zero if drive is locked
1.2021 + iMountFailures = 0;
1.2022 +
1.2023 + pM->SetDrive(this);
1.2024 +
1.2025 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlock, EF32TraceUidFileSys, DriveNumber(), aStore);
1.2026 + r=pM->Unlock(aPassword,aStore);
1.2027 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBUnlockRet, EF32TraceUidFileSys, r);
1.2028 +
1.2029 + pM->Close();
1.2030 + return(r);
1.2031 + }
1.2032 +
1.2033 +TInt TDrive::ClearDevicePassword(TMediaPassword& aPassword)
1.2034 +//
1.2035 +// Clear password of media device
1.2036 +//
1.2037 + {
1.2038 + __PRINT(_L("TDrive::ClearDevicePassword"));
1.2039 + __CHECK_DRIVETHREAD(iDriveNumber);
1.2040 + if(iFSys==NULL)
1.2041 + return(KErrNotReady);
1.2042 + TInt r;
1.2043 + CMountCB* pM=NULL;
1.2044 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.2045 + TRAP(r,pM=FSys().NewMountL());
1.2046 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1.2047 + if(r!=KErrNone)
1.2048 + return(r);
1.2049 + pM->SetDrive(this);
1.2050 +
1.2051 + // ClearPassword() will only work if the card is already unlocked.
1.2052 + // If the stack powers down, the card will become locked, so now that TBusLocalDrive::Caps()
1.2053 + // no longer powers up ths stack, we need to unlock the card first - but ignore the error as
1.2054 + // the stack may unlock from the password store.
1.2055 + TDriveInfo info;
1.2056 + DriveInfo(info);
1.2057 + if (info.iMediaAtt & KMediaAttLocked)
1.2058 + UnlockDevice(aPassword, EFalse);
1.2059 +
1.2060 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPassword, EF32TraceUidFileSys, DriveNumber());
1.2061 + r=pM->ClearPassword(aPassword);
1.2062 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBClearPasswordRet, EF32TraceUidFileSys, r);
1.2063 +
1.2064 + pM->Close();
1.2065 + return(r);
1.2066 + }
1.2067 +
1.2068 +TInt TDrive::EraseDevicePassword()
1.2069 +//
1.2070 +// Erase password from the media device
1.2071 +//
1.2072 + {
1.2073 + __PRINT(_L("TDrive::EraseDevicePassword"));
1.2074 + __CHECK_DRIVETHREAD(iDriveNumber);
1.2075 + if(iFSys==NULL)
1.2076 + return(KErrNotReady);
1.2077 + TInt r;
1.2078 + CMountCB* pM=NULL;
1.2079 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.2080 + TRAP(r,pM=FSys().NewMountL());
1.2081 + TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewMountLRet, EF32TraceUidFileSys, r, pM);
1.2082 + if(r!=KErrNone)
1.2083 + return(r);
1.2084 + pM->SetDrive(this);
1.2085 +
1.2086 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePassword, EF32TraceUidFileSys, DriveNumber());
1.2087 + r=pM->ErasePassword();
1.2088 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBErasePasswordRet, EF32TraceUidFileSys, r);
1.2089 +
1.2090 + pM->Close();
1.2091 + return(r);
1.2092 + }
1.2093 +
1.2094 +#else
1.2095 +
1.2096 +TInt TDrive::LockDevice(TMediaPassword& /*aOld*/,TMediaPassword& /*aNew*/,TBool /*aStore*/)
1.2097 +//
1.2098 +// Lock media device
1.2099 +//
1.2100 + {
1.2101 + return(KErrNotSupported);
1.2102 + }
1.2103 +
1.2104 +TInt TDrive::UnlockDevice(TMediaPassword& /*aPassword*/,TBool /*aStore*/)
1.2105 +//
1.2106 +// Unlock media device
1.2107 +//
1.2108 + {
1.2109 + return(KErrNotSupported);
1.2110 + }
1.2111 +
1.2112 +TInt TDrive::ClearDevicePassword(TMediaPassword& /*aPassword*/)
1.2113 +//
1.2114 +// Clear password of media device
1.2115 +//
1.2116 + {
1.2117 + return(KErrNotSupported);
1.2118 + }
1.2119 +
1.2120 +TInt TDrive::EraseDevicePassword(TMediaPassword& /*aPassword*/)
1.2121 +//
1.2122 +// Clear password of media device
1.2123 +//
1.2124 + {
1.2125 + return(KErrNotSupported);
1.2126 + }
1.2127 +
1.2128 +#endif
1.2129 +
1.2130 +
1.2131 +
1.2132 +
1.2133 +/**
1.2134 +Gets the current notification state, which indicates whether the client
1.2135 +is notified of any read or write failures.
1.2136 +
1.2137 +The notification status is a property of the current session with
1.2138 +the file server, the value of which is stored in CSessionFs::iNotifyUser.
1.2139 +If set to ETrue, the client will receive notifications from the file system.
1.2140 +
1.2141 +Called by CMountCB::GetNotifyUser().
1.2142 +
1.2143 +@return True, if the client receives notifications from the file system,
1.2144 + false otherwise.
1.2145 +
1.2146 +@see CMountCB
1.2147 +*/
1.2148 +EXPORT_C TBool TDrive::GetNotifyUser()
1.2149 + {
1.2150 + __CHECK_DRIVETHREAD(iDriveNumber);
1.2151 + if(iDriveFlags & ENotifyOff)
1.2152 + return(EFalse);
1.2153 + else
1.2154 + {
1.2155 + CDriveThread* pT=NULL;
1.2156 +
1.2157 + const TInt r=FsThreadManager::GetDriveThread(iDriveNumber,&pT);
1.2158 +
1.2159 + //-- if this drive is synchronous, i.e. all requests are processed in the main FS thread,
1.2160 + //-- pretend that user notifications are turned off to avoid panic in the assert below.
1.2161 + //-- for synch. drives pT will always be NULL and it's not possible to obtain CSessionFs by drive number.
1.2162 + if(r == KErrAccessDenied)
1.2163 + return EFalse;
1.2164 +
1.2165 + __ASSERT_ALWAYS(r==KErrNone && pT,Fault(EDriveGetNotifyUser));
1.2166 + return(pT->IsSessionNotifyUser());
1.2167 + }
1.2168 + }
1.2169 +
1.2170 +
1.2171 +
1.2172 +
1.2173 +/**
1.2174 +Dismounts the current mount. This is method is called from outside, so do some finalisation work on mount.
1.2175 +After calling this function there is no current mount on the drive.
1.2176 +*/
1.2177 +EXPORT_C void TDrive::Dismount()
1.2178 + {
1.2179 + __PRINT1(_L("TDrive::Dismount() iCurrentMount:0x%x"),iCurrentMount);
1.2180 +
1.2181 + iMountFailures = 0;
1.2182 + if (!iCurrentMount)
1.2183 + return;
1.2184 +
1.2185 + TRAP_IGNORE(FlushCachedFileInfoL());
1.2186 +
1.2187 + //-- try our best to finalise the mount (the mount can decide to do some job during finalisation, e.g. write some data)
1.2188 + TRAP_IGNORE(iCurrentMount->FinaliseMountL());
1.2189 +
1.2190 + DoDismount();
1.2191 + }
1.2192 +
1.2193 +
1.2194 +
1.2195 +
1.2196 +/**
1.2197 +Forcibly dismounts the current mount and prevents it being remounted.
1.2198 +After calling this function there is no current mount on the drive.
1.2199 +*/
1.2200 +void TDrive::ForceDismount()
1.2201 + {
1.2202 + __PRINT1(_L("TDrive::ForceDismount() iCurrentMount:0x%x"),iCurrentMount);
1.2203 +
1.2204 + iMountFailures = 0;
1.2205 +
1.2206 + if(!iCurrentMount)
1.2207 + return;
1.2208 +
1.2209 + TRAP_IGNORE(FlushCachedFileInfoL());
1.2210 + iCurrentMount->SetDismounted(); //! this affects TDrive::ReMount()
1.2211 + DoDismount();
1.2212 + }
1.2213 +
1.2214 +/**
1.2215 + An internal method. Dismounts and closes a current mount.
1.2216 + This method must not involve writing data to the media, because it could have beeen physically changed before.
1.2217 + Called only from TDrive::CheckMount().
1.2218 +*/
1.2219 +void TDrive::DoDismount()
1.2220 + {
1.2221 + __PRINT1(_L("TDrive::DoDismount() iCurrentMount:0x%x"),iCurrentMount);
1.2222 +
1.2223 + iMountFailures = 0;
1.2224 +
1.2225 + if (!iCurrentMount)
1.2226 + return;
1.2227 +
1.2228 + TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismounted, EF32TraceUidFileSys, DriveNumber());
1.2229 + iCurrentMount->Dismounted();
1.2230 + TRACE0(UTF::EBorder, UTraceModuleFileSys::ECMountCBDismountedRet, EF32TraceUidFileSys);
1.2231 +
1.2232 + iCurrentMount->Close();
1.2233 + iCurrentMount=NULL;
1.2234 + }
1.2235 +
1.2236 +
1.2237 +/**
1.2238 +Return the number of active mounts associated with this drive.
1.2239 +(inactive mounts are those that have been forcibly dismounted)
1.2240 +*/
1.2241 +TInt TDrive::ActiveMounts() const
1.2242 + {
1.2243 + TInt activeMounts = 0;
1.2244 +
1.2245 + TInt idx = Mount().Count();
1.2246 + while(idx--)
1.2247 + {
1.2248 + if(((CMountCB*)Mount()[idx])->IsDismounted())
1.2249 + {
1.2250 + activeMounts++;
1.2251 + }
1.2252 + }
1.2253 +
1.2254 + __PRINT1(_L("TDrive::ActiveMounts = %d"), activeMounts);
1.2255 + return activeMounts;
1.2256 + }
1.2257 +
1.2258 +
1.2259 +
1.2260 +
1.2261 +/**
1.2262 +Reactivate any disactive mounts on the drive following a dismount.
1.2263 +(inactive mounts are those that have been foribly dismounted)
1.2264 +*/
1.2265 +void TDrive::ReactivateMounts()
1.2266 + {
1.2267 + __PRINT(_L("TDrive::ReactivateMounts"));
1.2268 +
1.2269 + TInt idx = Mount().Count();
1.2270 + while(idx--)
1.2271 + {
1.2272 + ((CMountCB*)Mount()[idx])->SetDismounted(EFalse);
1.2273 + }
1.2274 + }
1.2275 +
1.2276 +
1.2277 +
1.2278 +
1.2279 +/**
1.2280 +Increments the drive dismount lock. This defers dismount
1.2281 +of a file system until all clients have notified that it
1.2282 +is safe to do so.
1.2283 +
1.2284 +@see RFs::NotifyDismount
1.2285 +*/
1.2286 +void TDrive::DismountLock()
1.2287 + { iDismountLock++; }
1.2288 +
1.2289 +
1.2290 +
1.2291 +
1.2292 +/**
1.2293 +Decrements the drive dismount lock. When the lock count
1.2294 +reaches zero, the file system may be unmounted
1.2295 +
1.2296 +@see RFs::AllowDismount
1.2297 +@return The new lock count
1.2298 +*/
1.2299 +TInt TDrive::DismountUnlock()
1.2300 + {
1.2301 + return(--iDismountLock);
1.2302 + }
1.2303 +
1.2304 +
1.2305 +
1.2306 +
1.2307 +/**
1.2308 +Return the state of the dismount lock.
1.2309 +*/
1.2310 +TBool TDrive::DismountLocked() const
1.2311 + { return(iDismountLock); }
1.2312 +
1.2313 +
1.2314 +
1.2315 +
1.2316 +/**
1.2317 +Pending flag - set while waiting for clients to accept the dismount
1.2318 +*/
1.2319 +void TDrive::SetDismountDeferred(TBool aPending)
1.2320 + {
1.2321 + if(aPending)
1.2322 + iDriveFlags |= EDismountDeferred;
1.2323 + else
1.2324 + iDriveFlags &= ~EDismountDeferred;
1.2325 + }
1.2326 +
1.2327 +
1.2328 +
1.2329 +TInt TDrive::ControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2)
1.2330 +//
1.2331 +// General purpose test interface - .FSY specific.
1.2332 +//
1.2333 + {
1.2334 + TInt r=CheckMount();
1.2335 + if(r==KErrNone || (r==KErrInUse && iReason==KErrNone))
1.2336 + {
1.2337 + TRACETHREADID(aMessage);
1.2338 + TRACE5(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIO, EF32TraceUidFileSys,
1.2339 + DriveNumber(), aCommand, aParam1, aParam2, I64LOW(threadId));
1.2340 + r=CurrentMount().ControlIO(aMessage,aCommand,aParam1,aParam2);
1.2341 + TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBControlIORet, EF32TraceUidFileSys, r);
1.2342 + }
1.2343 + return(r);
1.2344 + }
1.2345 +
1.2346 +
1.2347 +
1.2348 +
1.2349 +/**
1.2350 +Gets the drive attributes
1.2351 +
1.2352 +@return The drive attributes.
1.2353 +*/
1.2354 +EXPORT_C TUint TDrive::Att()
1.2355 + {
1.2356 + TUint a=iAtt;
1.2357 + return(a);
1.2358 + }
1.2359 +
1.2360 +void TDrive::SetAtt(TUint aValue)
1.2361 +//
1.2362 +// set drive attributes
1.2363 +//
1.2364 + {
1.2365 + iAtt=aValue;
1.2366 + }
1.2367 +
1.2368 +EXPORT_C TBool TDrive::IsDriveThread() const
1.2369 +//
1.2370 +// Return ETrue if the current thread id is the same as that of the drive's drive thread
1.2371 +//
1.2372 + {
1.2373 + return(FsThreadManager::IsDriveThread(iDriveNumber,ETrue));
1.2374 + }
1.2375 +
1.2376 +EXPORT_C TBool TDrive::IsMainThread() const
1.2377 +//
1.2378 +// Reture ETrue if the current thread id is the same as that of the main file server thread
1.2379 +//
1.2380 + {
1.2381 + return(FsThreadManager::IsMainThread());
1.2382 + }
1.2383 +
1.2384 +EXPORT_C void TDrive::DriveFault(TBool aDriveError) const
1.2385 +//
1.2386 +//
1.2387 +//
1.2388 + {
1.2389 + if(aDriveError)
1.2390 + ::Fault(EFsDriveThreadError);
1.2391 + else
1.2392 + ::Fault(EFsMainThreadError);
1.2393 + }
1.2394 +
1.2395 +TInt TDrive::ClampFile(const TDesC& aName, TAny* aHandle)
1.2396 +//
1.2397 +// Attempt to clamp file
1.2398 +//
1.2399 + {
1.2400 + CMountCB* mount = (CMountCB*)&(CurrentMount());
1.2401 + TInt driveNo = DriveNumber();
1.2402 + return(mount->ClampFile(driveNo,aName,aHandle));
1.2403 + }
1.2404 +
1.2405 +
1.2406 +TInt TDrive::UnclampFile(CMountCB* aMount, RFileClamp* aHandle)
1.2407 +//
1.2408 +// Attempt to unclamp file
1.2409 +//
1.2410 + {
1.2411 + return(aMount->UnclampFile(aHandle));
1.2412 + }
1.2413 +
1.2414 +
1.2415 +TInt TDrive::ClampsOnDrive()
1.2416 +//
1.2417 +// Returns the number of clamps on this drive
1.2418 +//
1.2419 + {
1.2420 + Lock();
1.2421 + TInt clamps = IsMounted()?((CMountCB*)&(CurrentMount()))->NoOfClamps():0;
1.2422 + UnLock();
1.2423 + return (clamps);
1.2424 + }
1.2425 +
1.2426 +
1.2427 +
1.2428 +void TDrive::SetClampFlag(TBool aClamped)
1.2429 +//
1.2430 +// Indicate if any files are clamped
1.2431 +//
1.2432 + {
1.2433 + if(aClamped)
1.2434 + iDriveFlags |= EClampPresent;
1.2435 + else
1.2436 + iDriveFlags &= ~EClampPresent;
1.2437 + }
1.2438 +
1.2439 +
1.2440 +TBool TDrive::ClampFlag()
1.2441 +//
1.2442 +// Report if any files are clamped
1.2443 +//
1.2444 + { return(iDriveFlags & EClampPresent); }
1.2445 +
1.2446 +
1.2447 +
1.2448 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.2449 +TInt TDrive::ClearDeferredDismount()
1.2450 +// debug-only function for testing
1.2451 + {
1.2452 + Lock();
1.2453 + FsNotify::HandleDismount(EFsDismountRegisterClient, DriveNumber(), ETrue, KErrNone);
1.2454 + SetDismountDeferred(EFalse);
1.2455 + UnLock();
1.2456 + return KErrNone;
1.2457 + }
1.2458 +#endif
1.2459 +
1.2460 +
1.2461 +TInt TDrive::DismountProxyDrive()
1.2462 +//
1.2463 +// Dismount a proxy drive
1.2464 +//
1.2465 + {
1.2466 + __PRINT(_L("TDrive::DismountProxyDrive"));
1.2467 + __CHECK_DRIVETHREAD(iDriveNumber);
1.2468 +
1.2469 + if (!IsProxyDrive(iDriveNumber) || LocalDrives::DriveNumberToLocalDriveNumber(iDriveNumber) == KDriveInvalid)
1.2470 + return KErrArgument;
1.2471 +
1.2472 + if(iCurrentMount)
1.2473 + return(KErrInUse);
1.2474 +
1.2475 +
1.2476 + // Prevent ALL inactive mounts from EVER being remounted as they MAY (& probably do) point to
1.2477 + // this proxy-drive which we are about to delete....
1.2478 + // NB We could try to find out which mounts actually use this particular proxy-drive, but that's
1.2479 + // a bit tricky to determine if there are extensions present as CMountCB::ProxyDrive() will only
1.2480 + // return the first proxy drive in the chain.
1.2481 + TInt mCount=Mount().Count();
1.2482 + TInt u=(Mount().UniqueID()<<16);
1.2483 + for (TInt i=0;i<mCount;i++)
1.2484 + {
1.2485 + CMountCB* pM=(CMountCB*)Mount().At(u|i);
1.2486 + pM->SetProxyDriveDismounted();
1.2487 + }
1.2488 +
1.2489 + FsThreadManager::LockDrive(iDriveNumber);
1.2490 + // Proxy drives are responsible for managing the drive threads...
1.2491 + FsThreadManager::CloseDrive(iDriveNumber);
1.2492 + LocalDrives::ClearProxyDriveMapping(iDriveNumber);
1.2493 + FsThreadManager::UnlockDrive(iDriveNumber);
1.2494 +
1.2495 + return KErrNone;
1.2496 + }
1.2497 +
1.2498 +//----------------------------------------------------------------------------
1.2499 +/**
1.2500 + Complete, remove and delete notification requests
1.2501 + @param aCompletionCode completion code for some notifications
1.2502 +*/
1.2503 +void TDrive::DoCompleteDismountNotify(TInt aCompletionCode)
1.2504 + {
1.2505 + FsNotify::HandleDismount(EFsDismountRegisterClient, iDriveNumber, ETrue, KErrNone);
1.2506 + FsNotify::HandleDismount(EFsDismountNotifyClients, iDriveNumber, ETrue, aCompletionCode);
1.2507 + FsNotify::HandleDismount(EFsDismountForceDismount, iDriveNumber, ETrue, aCompletionCode);
1.2508 + }
1.2509 +
1.2510 +//----------------------------------------------------------------------------
1.2511 +/**
1.2512 + a helper method that allows forced dismounting current mount for volume formatting.
1.2513 +*/
1.2514 +TInt TDrive::ForceUnmountFileSystemForFormatting()
1.2515 + {
1.2516 + TInt nRes;
1.2517 +
1.2518 + //-- check if there are any clamps on this drive
1.2519 + nRes = ClampsOnDrive();
1.2520 + if(nRes > 0)
1.2521 + return KErrInUse;
1.2522 +
1.2523 + //-- purge all dirty data in the files associated with this drive's mount
1.2524 + CDriveThread* pT=NULL;
1.2525 + nRes = FsThreadManager::GetDriveThread(DriveNumber(), &pT);
1.2526 + if(nRes == KErrNone && pT)
1.2527 + {
1.2528 + pT->CompleteReadWriteRequests();
1.2529 + }
1.2530 +
1.2531 + PurgeDirty(CurrentMount());
1.2532 +
1.2533 + //--
1.2534 +
1.2535 + ForceDismount();
1.2536 +
1.2537 + DoCompleteDismountNotify(KErrDisMounted); //-- complete all dismount notifications
1.2538 +
1.2539 + return KErrNone;
1.2540 + }
1.2541 +
1.2542 +//-----------------------------------------------------------------------------
1.2543 +/**
1.2544 + Instantiate CFormatCB object for formatting the file ssytem on the given TDrive.
1.2545 +
1.2546 + @param aRequest file server request object
1.2547 + @param aFmtHandle out: format handle
1.2548 + @param aFmtMode format mode
1.2549 + @param apLDFormatInfo pointer to legacy parameters structure; NULL means "not used"
1.2550 + @param apVolFormatParam pointer to the newparameters structure; NULL means "not used"
1.2551 +
1.2552 + @return pointer to the instantiated CFormatCB object.
1.2553 +*/
1.2554 +CFormatCB* TDrive::FormatOpenL(CFsRequest* aRequest, TInt& aFmtHandle, TFormatMode aFmtMode, const TLDFormatInfo* apLDFormatInfo, const TVolFormatParam* apVolFormatParam)
1.2555 + {
1.2556 + ASSERT(!(apLDFormatInfo && apVolFormatParam)); //-- these parameters are mutually exclusive
1.2557 +
1.2558 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatL, EF32TraceUidFileSys, &FSys(), DriveNumber());
1.2559 +
1.2560 + CFormatCB* pFormat = CurrentMount().NewFormatL();
1.2561 +
1.2562 + TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFormatLRet, EF32TraceUidFileSys, KErrNone, pFormat);
1.2563 +
1.2564 + Formats->AddL(pFormat, ETrue);
1.2565 + pFormat->InitL(this, aFmtMode);
1.2566 +
1.2567 + if(aFmtMode & ESpecialFormat)
1.2568 + {
1.2569 + if(apLDFormatInfo)
1.2570 + {//-- the user has specified formatting parameters as TLDFormatInfo
1.2571 + pFormat->SetFormatParameters(apLDFormatInfo);
1.2572 + }
1.2573 + else if(apVolFormatParam && apVolFormatParam->SomeParamsSet())
1.2574 + {//-- the user has specified formatting parameters as TVolFormatParam
1.2575 + TInt nRes = pFormat->SetFormatParameters(apVolFormatParam);
1.2576 + User::LeaveIfError(nRes); //-- the particular file system might not support this feature
1.2577 + }
1.2578 + else
1.2579 + {//-- this is a special case, ESpecialFormat is set, but no parameters provided at all;
1.2580 + //-- invalidate CFormatCB::iSpecialInfo to make filesystem not to use it
1.2581 + pFormat->SetFormatParameters((TLDFormatInfo*)NULL);
1.2582 + }
1.2583 + }
1.2584 +
1.2585 +
1.2586 + // modify resource counter after initialised to ensure correct cleanup
1.2587 + AddDiskAccess(CurrentMount());
1.2588 + aFmtHandle = aRequest->Session()->Handles().AddL(pFormat, ETrue);
1.2589 +
1.2590 + return pFormat;
1.2591 + }
1.2592 +
1.2593 +
1.2594 +
1.2595 +
1.2596 +
1.2597 +EXPORT_C void UNUSED1() {}
1.2598 +EXPORT_C void UNUSED2() {}
1.2599 +EXPORT_C void UNUSED3() {}
1.2600 +
1.2601 +
1.2602 +
1.2603 +
1.2604 +
1.2605 +
1.2606 +
1.2607 +
1.2608 +