Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32\sfile\sf_notif.cpp
//
//
#include "sf_std.h"
TChangeQue FsNotify::iChangeQues[KMaxNotifyQues];
TDiskSpaceQue FsNotify::iDiskSpaceQues[KMaxDiskQues];
TDebugQue FsNotify::iDebugQue;
TDismountNotifyQue FsNotify::iDismountNotifyQue;
void CNotifyInfo::Initialise(TInfoType aType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
//
//
//
{
iType=aType;
iStatus=aStatus;
iMessage=aMessage;
iSession=aSession;
};
CNotifyInfo::~CNotifyInfo()
//
//
//
{
__ASSERT_DEBUG(!iLink.iNext,Fault(ENotifyInfoDestructor));
}
void CNotifyInfo::Complete(TInt aError)
//
//
//
{
__PRINT2(_L("CNotifyInfo::Complete 0x%x error=%d"),this,aError);
if (iType != EDismount || !iMessage.IsNull()) // Dismount notifiers may be completed but remain in the list
{ // until handled by the client or the session is closed.
iMessage.Complete(aError);
}
}
void CStdChangeInfo::Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
//
//
//
{
iChangeType=aChangeType;
CNotifyInfo::Initialise(EStdChange,aStatus,aMessage,aSession);
}
TUint CStdChangeInfo::RequestNotifyType(CFsRequest* aRequest)
//
// return notification type for the request
//
{
TUint notifyType=aRequest->Operation()->NotifyType();
if(aRequest->Operation()->Function()==EFsRename)
{
__ASSERT_DEBUG(notifyType==(ENotifyDir|ENotifyFile|ENotifyEntry),Fault(EStdChangeRequestType));
if(aRequest->Src().NamePresent())
notifyType=ENotifyFile|ENotifyEntry;
else
notifyType=ENotifyDir|ENotifyEntry;
}
return(notifyType);
}
TBool CStdChangeInfo::IsMatching(CFsRequest* aRequest)
//
// return ETrue if operation type of request matches that of change notification
//
{
if((iChangeType&ENotifyAll) || (iChangeType&aRequest->Operation()->NotifyType()))
return(ETrue);
else
return(EFalse);
}
void CExtChangeInfo::Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession,const TDesC& aName)
//
//
//
{
__ASSERT_DEBUG(aName.Length()<=KMaxFileName-2,Fault(EExtChangeNameLength));
iName=aName;
iChangeType=aChangeType;
CNotifyInfo::Initialise(EExtChange,aStatus,aMessage,aSession);
}
TBool CExtChangeInfo::IsMatching(CFsRequest* aRequest)
//
// return ETrue if operation notify type of request matches that of change notification
// and paths match
//
{
TInt function=aRequest->Operation()->Function();
// if a rename occurred inform any requests if their path has been changed regardless of the notification type
if(function==EFsRename)
{
TBuf<KMaxFileName> renamePath=aRequest->Src().FullName().Mid(2);
renamePath+=_L("*");
if (iName.MatchF(renamePath)!=KErrNotFound)
return(ETrue);
}
//Special case where the dir the notifier is setup on has just been created
if(function==EFsMkDir)
{
TInt notDrive;
RFs::CharToDrive(aRequest->Src().Drive()[0],notDrive); //can not fail as the drive letter has been parsed already
if(aRequest->Src().Path().MatchF(iName) == 0 && aRequest->DriveNumber() == notDrive)
return ETrue;
}
//Special case where the File the notifier is setup on has just been created by temp as the name is not known unti it has been created
if(function==EFsRename||function==EFsFileOpen||function==EFsFileCreate||function==EFsFileReplace)
{
TInt notDrive;
RFs::CharToDrive(aRequest->Src().Drive()[0],notDrive); //can not fail as the drive letter has been parsed already
if(aRequest->Src().FullName().Mid(2).MatchF(iName) == 0 && aRequest->DriveNumber() == notDrive)
return ETrue;
}
//For the case of a file created using EFsFileTemp we can probably ignore it for special cases as it
//is created with a random name. Not specifically going to be being looked for
if((iChangeType&ENotifyAll) || (iChangeType&RequestNotifyType(aRequest)))
{
switch (function)
{
// Notify interested requests if a SetDriveName(), SetVolume() or RawDiskWrite() operation
// occcurred. By their nature, these operations have no distinct path. All outstanding
// requests monitoring the relevant TNotifyType are potentially interested in such operations
case EFsFileWrite:
case EFsFileWriteDirty:
case EFsFileSet:
case EFsFileSetAtt:
case EFsFileSetModified:
case EFsFileSetSize:
{
TBuf<KMaxFileName> root=iName;
root+=_L("*");
// NB share may be NULL if file server has initiated a flush of the file cache
CFileShare* share;
CFileCB* fileCache;
GetFileFromScratch(aRequest, share, fileCache);
if (share && share->File().FileName().MatchF(root) != KErrNotFound)
return(ETrue);
}
break;
case EFsSetDriveName:
case EFsSetVolume:
case EFsRawDiskWrite:
case EFsLockDrive:
case EFsUnlockDrive:
case EFsReserveDriveSpace:
{
return(ETrue);
}
default:
{
TBuf<KMaxFileName> root = iName;
root+=_L("*");
if(aRequest->Src().FullName().Mid(2).MatchF(root)!=KErrNotFound)
return(ETrue);
else if(function==EFsRename||function==EFsReplace||function==EFsFileRename)
{
// - rename/replace causes the file/path to disappear
if(aRequest->Dest().FullName().Mid(2).MatchF(root)!=KErrNotFound)
{
return(ETrue);
}
// - rename/replace causes the file/path to arrive
root=aRequest->Dest().FullName().Mid(2);
root+=_L("*");
if (iName.MatchF(root)!=KErrNotFound)
{
return(ETrue);
}
}
}
}
}
return(EFalse);
}
void CDiskSpaceInfo::Initialise(TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession,TInt64 aThreshold)
//
//
//
{
__ASSERT_DEBUG(aThreshold>0,Fault(EDiskSpaceThreshold));
iThreshold=aThreshold;
CNotifyInfo::Initialise(EDiskSpace,aStatus,aMessage,aSession);
}
TBool CDiskSpaceInfo::IsMatching(TInt64& aBefore,TInt64& aAfter)
//
// return ETrue if the threshold has been crossed
//
{
if((aBefore>=iThreshold&&aAfter<iThreshold)||(aBefore<=iThreshold&&aAfter>iThreshold))
return(ETrue);
return(EFalse);
}
void CDebugChangeInfo::Initialise(TUint aDebugType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
//
//
//
{
__ASSERT_DEBUG((aDebugType&KDebugNotifyMask)&&!(aDebugType&~KDebugNotifyMask),Fault(EDebugChangeType));
iDebugType=aDebugType;
CNotifyInfo::Initialise(EDebugChange,aStatus,aMessage,aSession);
}
TBool CDebugChangeInfo::IsMatching(TUint aFunction)
//
// return ETrue if debug notification type matches aFunction
//
{
if(iDebugType&aFunction)
return(ETrue);
return(EFalse);
}
CDismountNotifyInfo::~CDismountNotifyInfo()
{
switch(iMode)
{
case EFsDismountNotifyClients:
break;
case EFsDismountRegisterClient:
__ASSERT_ALWAYS(TheDrives[iDriveNumber].DismountUnlock() >= 0, Fault(ENotifyDismountCancel));
break;
default:
break;
}
}
void CDismountNotifyInfo::Initialise(TNotifyDismountMode aMode, TInt aDriveNumber, TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession)
{
iMode = aMode;
iDriveNumber=aDriveNumber;
CNotifyInfo::Initialise(EDismount,aStatus,aMessage,aSession);
if (iMode == EFsDismountRegisterClient)
TheDrives[iDriveNumber].DismountLock();
}
TBool CDismountNotifyInfo::IsMatching(TNotifyDismountMode aMode, TInt aDriveNumber, CSessionFs* aSession)
{
if((iDriveNumber == aDriveNumber) && (iMode == aMode) && (aSession == NULL || aSession == Session()))
return(ETrue);
return(EFalse);
}
TBaseQue::TBaseQue()
//
//
//
{
iHeader.SetOffset(_FOFF(CNotifyInfo,iLink));
TInt r=iQLock.CreateLocal();
__ASSERT_ALWAYS(r==KErrNone,Fault(EBaseQueConstruction));
}
TBaseQue::~TBaseQue()
//
//
//
{
iQLock.Close();
}
void TBaseQue::DoAddNotify(CNotifyInfo* aInfo)
//
// Add notification
// Que should be locked by calling function
//
{
iHeader.AddLast(*aInfo);
}
TBool TBaseQue::DoCancelSession(CSessionFs* aSession,TInt aCompletionCode, TRequestStatus* aStatus)
//
// Cancel notification(s) setup by aSession matching aStatus if set
// Que should be locked by calling function
//
{
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
TBool isFound=EFalse;
while((info=q++)!=NULL)
{
if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
{
isFound=ETrue;
info->Complete(aCompletionCode);
info->iLink.Deque();
delete(info);
if(aStatus)
break;
}
}
return(isFound);
}
void TBaseQue::DoCancelAll(TInt aCompletionCode)
//
// Cancel all notifications
// Que should be locked by calling function
//
{
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
info->Complete(aCompletionCode);
info->iLink.Deque();
delete(info);
}
__ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
}
TBool TBaseQue::IsEmpty()
//
// Que should be locked by calling function
//
{
return iHeader.IsEmpty();
}
TBool TChangeQue::IsEmpty()
//
//
//
{
iQLock.Wait();
TBool empty = TBaseQue::IsEmpty();
iQLock.Signal();
return(empty);
}
TInt TChangeQue::AddNotify(CNotifyInfo* aInfo)
//
//
//
{
iQLock.Wait();
TBaseQue::DoAddNotify(aInfo);
iQLock.Signal();
return(KErrNone);
}
TBool TChangeQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
//
//
//
{
iQLock.Wait();
TBool isFound=TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
iQLock.Signal();
return(isFound);
}
void TChangeQue::CancelAll(TInt aCompletionCode)
//
//
//
{
iQLock.Wait();
TBaseQue::DoCancelAll(aCompletionCode);
iQLock.Signal();
}
void TChangeQue::CheckChange(CFsRequest* aRequest)
//
// complete any notification in que that matches aRequest
//
{
iQLock.Wait();
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EStdChange||info->Type()==CNotifyInfo::EExtChange,Fault(EChangeQueType));
TBool isMatching;
if(info->Type()==CNotifyInfo::EStdChange)
isMatching=((CStdChangeInfo*)info)->IsMatching(aRequest);
else
isMatching=((CExtChangeInfo*)info)->IsMatching(aRequest);
if(isMatching)
{
__PRINT1(_L("TChangeQue::CheckChange()-Matching info=0x%x"),info);
info->Complete(KErrNone);
info->iLink.Deque();
delete(info);
}
}
iQLock.Signal();
}
TBool TDiskSpaceQue::IsEmpty()
//
//
//
{
iQLock.Wait();
TBool empty = TBaseQue::IsEmpty();
iQLock.Signal();
return(empty);
}
TInt TDiskSpaceQue::AddNotify(CNotifyInfo* aInfo)
//
//
//
{
iQLock.Wait();
TInt r=KErrNone;
if(iHeader.IsEmpty())
{
r=GetFreeDiskSpace(iFreeDiskSpace);
iReservedDiskSpace = TheDrives[iDriveNumber].ReservedSpace();
}
if(r==KErrNone)
TBaseQue::DoAddNotify(aInfo);
iQLock.Signal();
return(r);
}
TInt TDiskSpaceQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
//
//
//
{
iQLock.Wait();
TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
iQLock.Signal();
return(KErrNone);
}
void TDiskSpaceQue::CancelAll(TInt aCompletionCode)
//
//
//
{
iQLock.Wait();
TBaseQue::DoCancelAll(aCompletionCode);
iQLock.Signal();
}
void TDiskSpaceQue::CheckDiskSpace()
//
// Complete any disk space notification whose threshold has been crossed
//
{
iQLock.Wait();
if(iHeader.IsEmpty())
{
iQLock.Signal();
return;
}
TInt64 freeSpace;
TInt r=GetFreeDiskSpace(freeSpace);
TInt64 reservedSpace(TheDrives[iDriveNumber].ReservedSpace());
if(r==KErrNone)
{
if((freeSpace==iFreeDiskSpace) && (reservedSpace==iReservedDiskSpace))
{
iQLock.Signal();
return;
}
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDiskSpace,Fault(EDiskSpaceQueType1));
TInt64 newSessionFreeSpace(freeSpace);
TInt64 oldSessionFreeSpace(iFreeDiskSpace);
if(!info->Session()->ReservedAccess(iDriveNumber))
{
newSessionFreeSpace -= reservedSpace;
oldSessionFreeSpace -= iReservedDiskSpace;
}
if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
{
__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
info->Complete(KErrNone);
info->iLink.Deque();
delete(info);
}
}
iFreeDiskSpace=freeSpace;
iReservedDiskSpace=reservedSpace;
}
else
TBaseQue::DoCancelAll(KErrNone);
iQLock.Signal();
}
void TDiskSpaceQue::CheckDiskSpace(TInt64& aFreeDiskSpace)
//
//
//
{
iQLock.Wait();
if(iHeader.IsEmpty())
{
iQLock.Signal();
return;
}
TInt64 reservedSpace(TheDrives[iDriveNumber].ReservedSpace());
if((aFreeDiskSpace==iFreeDiskSpace) && (reservedSpace==iReservedDiskSpace))
{
iQLock.Signal();
return;
}
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDiskSpace,Fault(EDiskSpaceQueType2));
TInt64 newSessionFreeSpace(aFreeDiskSpace);
TInt64 oldSessionFreeSpace(iFreeDiskSpace);
if(!info->Session()->ReservedAccess(iDriveNumber))
{
newSessionFreeSpace -= reservedSpace;
oldSessionFreeSpace -= iReservedDiskSpace;
}
if(((CDiskSpaceInfo*)info)->IsMatching(oldSessionFreeSpace,newSessionFreeSpace))
{
__PRINT1(_L("TDiskSpaceQue::CheckDiskSpace()-Matching info=0x%x"),info);
info->Complete(KErrNone);
info->iLink.Deque();
delete(info);
}
}
iFreeDiskSpace=aFreeDiskSpace;
iReservedDiskSpace=reservedSpace;
iQLock.Signal();
}
TInt TDiskSpaceQue::GetFreeDiskSpace(TInt64& aFreeDiskSpace)
//
//
//
{
__ASSERT_DEBUG(iDriveNumber>=EDriveA&&iDriveNumber<=EDriveZ,Fault(EDiskSpaceQueDrive));
__CHECK_DRIVETHREAD(iDriveNumber);
TInt r=TheDrives[iDriveNumber].FreeDiskSpace(aFreeDiskSpace);
return(r);
}
TInt TDebugQue::AddNotify(CNotifyInfo* aInfo)
//
//
//
{
iQLock.Wait();
TBaseQue::DoAddNotify(aInfo);
iQLock.Signal();
return(KErrNone);
}
TInt TDebugQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
//
//
//
{
iQLock.Wait();
TBool isFound=TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
iQLock.Signal();
return(isFound);
}
void TDebugQue::CancelAll(TInt aCompletionCode)
//
//
//
{
iQLock.Wait();
TBaseQue::DoCancelAll(aCompletionCode);
iQLock.Signal();
}
void TDebugQue::CheckDebug(TUint aDebugChange)
//
// Complete any debug notification whose debug type matches aDebugChange
//
{
iQLock.Wait();
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDebugChange,Fault(EDebugQueType));
if(((CDebugChangeInfo*)info)->IsMatching(aDebugChange))
{
__PRINT1(_L("TDebugQue::CheckDebug()-Matching info=0x%x"),info);
info->Complete(KErrNone);
info->iLink.Deque();
delete(info);
}
}
iQLock.Signal();
}
TInt TDismountNotifyQue::AddNotify(CNotifyInfo* aInfo)
//
//
//
{
iQLock.Wait();
TBaseQue::DoAddNotify(aInfo);
iQLock.Signal();
return(KErrNone);
}
TInt TDismountNotifyQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
//
//
//
{
iQLock.Wait();
TBool isFound=TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
iQLock.Signal();
return(isFound);
}
void TDismountNotifyQue::CancelAll(TInt aCompletionCode)
//
//
//
{
iQLock.Wait();
TBaseQue::DoCancelAll(aCompletionCode);
iQLock.Signal();
}
void TDismountNotifyQue::CheckDismount(TNotifyDismountMode aMode, TInt aDrive, TBool aRemove, TInt aError)
//
// Complete any dismount notifications on the specified drive.
//
{
iQLock.Wait();
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDismount,Fault(EBadDismountNotifyType));
if(((CDismountNotifyInfo*)info)->IsMatching(aMode, aDrive, NULL))
{
__PRINT1(_L("TDismountNotifyQue::CheckDismount()-Matching info=0x%x"),info);
info->Complete(aError);
if(aRemove)
{
info->iLink.Deque();
delete(info);
}
}
}
__ASSERT_ALWAYS(!aRemove || TheDrives[aDrive].DismountLocked() == 0, Fault(EDismountLocked));
iQLock.Signal();
}
TBool TDismountNotifyQue::HandlePendingDismount(CSessionFs* aSession, TInt aDrive)
//
// Determine if the session has any outstanding dismount notifications on the specified drive.
//
{
iQLock.Wait();
TDblQueIter<CNotifyInfo> q(iHeader);
CNotifyInfo* info;
while((info=q++)!=NULL)
{
__ASSERT_DEBUG(info->Type()==CNotifyInfo::EDismount,Fault(EBadDismountNotifyType));
if(((CDismountNotifyInfo*)info)->IsMatching(EFsDismountRegisterClient, aDrive, aSession))
{
__PRINT1(_L("TDismountNotifyQue::CheckDismount()-Pending info=0x%x"),info);
info->iLink.Deque();
delete(info);
iQLock.Signal();
return ETrue;
}
}
iQLock.Signal();
return EFalse;
}
void FsNotify::Initialise()
//
//
//
{
for(TInt i=0;i<KMaxDiskQues;++i)
{
iDiskSpaceQues[i].SetDriveNumber(i);
}
}
TBool FsNotify::IsChangeQueEmpty(TInt aDrive)
//
//
//
{
if((iChangeQues[ChangeIndex(aDrive)].IsEmpty()) && (iChangeQues[ChangeIndex(KDriveInvalid)].IsEmpty()))
return ETrue;
return EFalse;
}
TInt FsNotify::AddChange(CNotifyInfo* aInfo,TInt aDrive)
//
//
//
{
__ASSERT_DEBUG(aInfo->Type()==CNotifyInfo::EStdChange||aInfo->Type()==CNotifyInfo::EExtChange,Fault(EBadChangeNotifyType));
__PRINT2(_L("FsNotify::AddChange() drive=%d,info=0x%x"),aDrive,aInfo);
iChangeQues[ChangeIndex(aDrive)].AddNotify(aInfo);
return(KErrNone);
}
TBool FsNotify::IsDiskSpaceQueEmpty(TInt aDrive)
//
//
//
{
if(iDiskSpaceQues[aDrive].IsEmpty())
return ETrue;
return EFalse;
}
TInt FsNotify::AddDiskSpace(CNotifyInfo* aInfo,TInt aDrive)
//
//
//
{
__ASSERT_DEBUG(aInfo->Type()==CNotifyInfo::EDiskSpace,Fault(EBadDiskNotifyType));
__ASSERT_DEBUG((aDrive>=EDriveA && aDrive<=EDriveZ),Fault(EDiskBadIndex1));
__PRINT2(_L("FsNotify::AddDiskSpace() drive=%d,info=0x%x"),aDrive,aInfo);
return(iDiskSpaceQues[aDrive].AddNotify(aInfo));
}
TInt FsNotify::AddDebug(CNotifyInfo* aDebugInfo)
//
//
//
{
__ASSERT_DEBUG(aDebugInfo->Type()==CNotifyInfo::EDebugChange,Fault(EBadDebugNotifyType));
__PRINT1(_L("FsNotify::AddDebug() info=0x%x"),aDebugInfo);
iDebugQue.AddNotify(aDebugInfo);
return(KErrNone);
}
TInt FsNotify::AddDismountNotify(CNotifyInfo* aDismountNotifyInfo)
//
//
//
{
__ASSERT_DEBUG(aDismountNotifyInfo->Type()==CNotifyInfo::EDismount,Fault(EBadDismountNotifyType));
__PRINT1(_L("FsNotify::AddDismountNotify() info=0x%x"),aDismountNotifyInfo);
iDismountNotifyQue.AddNotify(aDismountNotifyInfo);
return(KErrNone);
}
void FsNotify::HandleChange(CFsRequest* aRequest,TInt aDrive)
//
// Check whether any change notifications need to be completed due to aRequest on aDrive
//
{
__PRINT2(_L("FsNotify::HandleChange() aRequest=0x%x, aDrive=%d"),aRequest,aDrive);
if(!aRequest->IsChangeNotify())
return;
iChangeQues[ChangeIndex(aDrive)].CheckChange(aRequest);
iChangeQues[ChangeIndex(KDriveInvalid)].CheckChange(aRequest);
}
void FsNotify::HandleDiskSpace(CFsRequest* aRequest,TInt aDrive)
//
// Check whether any disk space notifications need to be completed due to aRequest on aDrive
//
{
__ASSERT_DEBUG((aDrive>=EDriveA && aDrive<=EDriveZ) || aDrive==KDriveInvalid,Fault(EDiskBadIndex2));
__PRINT2(_L("FsNotify::HandleDiskSpace() aRequest=0x%x, aDrive=%d"),aRequest,aDrive);
if(!aRequest->Operation()->IsDiskSpaceNotify())
return;
TInt f = aRequest->Operation()->Function();
if ((f == EFsFileWrite || f == EFsFileWriteDirty) && !((CFsClientMessageRequest*)aRequest)->IsFreeChanged())
return;
if (FsThreadManager::IsDriveThread(aDrive,EFalse))
iDiskSpaceQues[aDrive].CheckDiskSpace();
}
void FsNotify::HandleDiskSpace(TInt aDrive, TInt64& aFreeSpace)
//
//
//
{
__ASSERT_DEBUG((aDrive>=EDriveA && aDrive<=EDriveZ),Fault(EDiskBadIndex3));
__PRINT1(_L("FsNotify::HandleDiskSpace() aDrive=%d"),aDrive);
iDiskSpaceQues[aDrive].CheckDiskSpace(aFreeSpace);
}
void FsNotify::HandleDebug(TUint aFunction)
//
// Check whether any debug notifications need to be completed due to aFunction
//
{
__PRINT1(_L("FsNotify::HandleDebug() aFunction=0x%x"),aFunction);
if(!(aFunction&KDebugNotifyMask))
return;
iDebugQue.CheckDebug(aFunction);
}
void FsNotify::HandleDismount(TNotifyDismountMode aMode, TInt aDrive, TBool aRemove, TInt err)
//
// Handle dismount notifications for the given drive
//
{
__PRINT4(_L("FsNotify::HandleDismount() aMode = %d, aDrive=%d, aRemove=%d, err=%d"),aMode,aDrive,aRemove,err);
iDismountNotifyQue.CheckDismount(aMode, aDrive, aRemove, err);
}
TBool FsNotify::HandlePendingDismount(CSessionFs* aSession, TInt aDrive)
//
// Checks if the session has an outstanding notification registered on the drive
//
{
__PRINT1(_L("FsNotify::HandlePendingDismount() aDrive=%d"),aDrive);
return iDismountNotifyQue.HandlePendingDismount(aSession, aDrive);
}
void FsNotify::DiskChange(TInt aDrive)
//
// Complete all notifications in queus due to a disk change
//
{
__ASSERT_DEBUG((aDrive>=EDriveA && aDrive<=EDriveZ),Fault(EDiskChangeDrive));
__PRINT1(_L("FsNotify::DiskChange() aDrive=%d"),aDrive);
iChangeQues[ChangeIndex(aDrive)].CancelAll(KErrNone);
iChangeQues[ChangeIndex(KDriveInvalid)].CancelAll(KErrNone);
iDiskSpaceQues[aDrive].CancelAll(KErrNone);
iDebugQue.CancelAll(KErrNone);
// if there are any files containing dirty data, start issuing write-dirty data requests to trigger
// a critical notifier (CFileCache::HandleWriteDirtyError())
// otherwise purge all file caches
TDrive& drive=TheDrives[aDrive];
drive.FlushCachedFileInfo(ETrue);
}
void FsNotify::CancelChangeSession(CSessionFs* aSession,TRequestStatus* aStatus)
//
// Cancel change notifcation(s) setup by aSession and matching aStatus if not NULL
//
{
__PRINT2(_L("FsNotify::CancelChangeSession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
for(TInt i=0;i<KMaxNotifyQues;++i)
{
TBool isFound=iChangeQues[i].CancelSession(aSession,KErrCancel,aStatus);
if(aStatus && isFound)
break;
}
}
void FsNotify::CancelDiskSpaceSession(CSessionFs* aSession,TRequestStatus* aStatus)
//
// Cancel disk space notification(s) setup by aSession and matching aStatus if not NULL
//
{
__PRINT2(_L("FsNotify::CancelDiskSpaceSession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
for(TInt i=0;i<KMaxDiskQues;++i)
{
TBool isFound=iDiskSpaceQues[i].CancelSession(aSession,KErrCancel,aStatus);
if(aStatus && isFound)
break;
}
}
void FsNotify::CancelDebugSession(CSessionFs* aSession, TRequestStatus* aStatus)
//
// Cancel debug notification(s) setup by aSession and matching aStatus if not NULL
//
{
__PRINT2(_L("FsNotify::CancelDebugSession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
iDebugQue.CancelSession(aSession,KErrCancel,aStatus);
}
void FsNotify::CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus)
//
// Cancel all media removal notification(s) setup by aSession (if aStatus == NULL)
// else cancels all oustanding notifications(s) for the session
//
{
__PRINT2(_L("FsNotify::CancelDismountNotifySession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
iDismountNotifyQue.CancelSession(aSession,KErrCancel,aStatus);
}
void FsNotify::CancelSession(CSessionFs* aSession)
//
//
//
{
__PRINT(_L("FsNotify::CancelSession"));
FsNotify::CancelChangeSession(aSession);
FsNotify::CancelDiskSpaceSession(aSession);
FsNotify::CancelDebugSession(aSession);
FsNotify::CancelDismountNotifySession(aSession);
}
TInt FsNotify::ChangeIndex(TInt aDrive)
//
//
//
{
__ASSERT_DEBUG((aDrive>=EDriveA && aDrive<=EDriveZ) || aDrive==KDriveInvalid,Fault(EChangeBadIndex));
if(aDrive==KDriveInvalid)
return(0);
else
return(aDrive+1);
}