Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32\sfile\sf_ses.cpp
//
//
#include "sf_std.h"
#include "sf_file_cache.h"
#include "sf_memory_man.h"
#ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
#include "sf_notifier.h"
#endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
CSessionFs::CSessionFs()
:iSessionFlags((TInt)EFsSessionFlagsAll),
iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)),
iId(0)
{
}
CSessionFs *CSessionFs::NewL()
{
return new(ELeave) CSessionFs;
}
CSessionFs::~CSessionFs()
{
__PRINT1(_L("CSessionFs::~CSessionFs() deleting... = 0x%x"),this);
//take out all the reserved space set by this session
while(iReservedDriveAccess.Count())
{
TReservedDriveAccess& reserved = iReservedDriveAccess[0];
if(reserved.iReservedSpace)
{
TheDrives[reserved.iDriveNumber].SetReservedSpace(TheDrives[reserved.iDriveNumber].ReservedSpace() - reserved.iReservedSpace);
__ASSERT_DEBUG(TheDrives[reserved.iDriveNumber].ReservedSpace() >= 0,Fault(EReserveSpaceArithmetic));
}
iReservedDriveAccess.Remove(0);
}
iReservedDriveAccess.Close();
// Need to free the requests that we own from the close queue
while (iCloseRequestCount > 0)
RequestAllocator::OpenSubFailed(this);
if (iHandles)
delete iHandles;
delete iPath;
iSessionFlagsLock.Close();
if(iDisconnectRequest)
delete(iDisconnectRequest);
}
void CSessionFs::CreateL()
//
// Create any additional resources.
//
{
__PRINT1(_L("CSessionFs::CreateL 0x%x"),this);
iHandles=CFsObjectIx::NewL();
TInt r = iSessionFlagsLock.CreateLocal();
User::LeaveIfError(r);
RMessage2 m;
iDisconnectRequest=new(ELeave) CFsDisconnectRequest;
iDisconnectRequest->Set(m,SessionDisconnectOp,this);
}
TInt CSessionFs::CurrentDrive()
//
// Return the current drive.
//
{
TInt d;
TInt r=RFs::CharToDrive(Path()[0],d);
__ASSERT_ALWAYS(r==KErrNone,Fault(ESesPathBadDrive));
return(d);
}
TInt CSessionFs::CountResources()
//
// Return the number of resources owned by the session
//
{
/* what's this supposed to be doing ??
TInt count=User::LockedInc(iResourceCount);
User::LockedDec(iResourceCount);
return(count);
*/
return iResourceCount; // ... because that's all it does.
}
void CSessionFs::ResourceCountMarkStart()
//
// Mark resources at this point
//
{
iResourceCountMark = CountResources();
}
void CSessionFs::ResourceCountMarkEnd(const RMessage2& aMessage)
//
// End resource count and check same as count start
//
{
if (iResourceCountMark!=CountResources())
{
_LIT(KCategory,"CSessionFs");
aMessage.Panic(KCategory,ESesFoundResCountHeaven);
}
else
aMessage.Complete(KErrNone);
}
void CSessionFs::Disconnect(const RMessage2& aMessage)
{
__THRD_PRINT1(_L("CSessionFs::Disconnect() 0x%x"),this);
iHandles->CloseMainThreadObjects();
iDisconnectRequest->SetMessage((RMessage2&)aMessage);
iDisconnectRequest->Dispatch();
}
TUint CSessionFs::Reserved(TInt aDriveNumber) const
{
TReservedDriveAccess reserved(aDriveNumber);
TInt idx = iReservedDriveAccess.Find(reserved);
if(idx == KErrNotFound)
return 0;
return iReservedDriveAccess[idx].iReservedSpace;
}
TInt CSessionFs::SetReserved(const TInt aDriveNumber, const TInt aReservedValue)
{
TReservedDriveAccess reserved(aDriveNumber, aReservedValue);
TInt idx = iReservedDriveAccess.Find(reserved);
if(idx == KErrNotFound)
return iReservedDriveAccess.InsertInSignedKeyOrder(reserved);
iReservedDriveAccess[idx].iReservedSpace = aReservedValue;
return KErrNone;
}
TBool CSessionFs::ReservedAccess(TInt aDriveNumber) const
{
TReservedDriveAccess reserved(aDriveNumber);
TInt idx = iReservedDriveAccess.Find(reserved);
return idx == KErrNotFound ? EFalse : iReservedDriveAccess[idx].iReservedAccess;
}
void CSessionFs::SetReservedAccess(const TInt aDriveNumber, const TBool aReservedAccess)
{
TReservedDriveAccess reserved(aDriveNumber);
TInt idx = iReservedDriveAccess.Find(reserved);
if(idx != KErrNotFound)
iReservedDriveAccess[idx].iReservedAccess = aReservedAccess;
}
TBool CSessionFs::IsChangeNotify()
{
return TestSessionFlags(EFsSessionNotifyChange);
}
TBool CSessionFs::TestSessionFlags(TUint32 aFlags)
{
iSessionFlagsLock.Wait();
TBool b = (iSessionFlags & aFlags) == aFlags;
iSessionFlagsLock.Signal();
return(b);
}
void CSessionFs::SetSessionFlags(TUint32 aBitsToSet, TUint32 aBitsToClear)
{
iSessionFlagsLock.Wait();
iSessionFlags &= ~aBitsToClear;
iSessionFlags |= aBitsToSet;
iSessionFlagsLock.Signal();
}
void CSessionFs::CloseRequestCountInc()
{
iSessionFlagsLock.Wait();
iCloseRequestCount++;
iSessionFlagsLock.Signal();
}
void CSessionFs::CloseRequestCountDec()
{
iSessionFlagsLock.Wait();
iCloseRequestCount--;
iSessionFlagsLock.Signal();
}
//
// Start resource count
//
TInt TFsResourceCountMarkStart::DoRequestL(CFsRequest* aRequest)
{
aRequest->Session()->ResourceCountMarkStart();
return(KErrNone);
}
TInt TFsResourceCountMarkStart::Initialise(CFsRequest* /*aRequest*/)
{
return KErrNone;
}
//
// Check for resource heaven
//
TInt TFsResourceCountMarkEnd::DoRequestL(CFsRequest* aRequest)
{
aRequest->Session()->ResourceCountMarkEnd(aRequest->Message());
return(KErrNone);
}
TInt TFsResourceCountMarkEnd::Initialise(CFsRequest* /*aRequest*/)
{
return KErrNone;
}
//
// Return the number of resources owned by the session
//
TInt TFsResourceCount::DoRequestL(CFsRequest* aRequest)
{
TInt resCount=aRequest->Session()->CountResources();
TPckgC<TInt> pckg(resCount);
aRequest->WriteL(KMsgPtr0,pckg);
return(KErrNone);
}
TInt TFsResourceCount::Initialise(CFsRequest* /*aRequest*/)
{
return KErrNone;
}
//
// Set iNotifyUser
//
void CSessionFs::SetNotifyUser(TBool aNotification)
{
if(aNotification)
{
SetSessionFlags(EFsSessionNotifyUser, 0);
}
else
{
SetSessionFlags(0, EFsSessionNotifyUser);
}
}
//
// Get iNotifyUser
//
TBool CSessionFs::GetNotifyUser()
{
return TestSessionFlags(EFsSessionNotifyUser);
}
//
// Notify the user of any read or write failure
//
TInt TFsSetNotifyUser::DoRequestL(CFsRequest* aRequest)
{
TBool notification=aRequest->Message().Int0();
aRequest->Session()->SetNotifyUser(notification);
return(KErrNone);
}
TInt TFsSetNotifyUser::Initialise(CFsRequest* /*aRequest*/)
{
return KErrNone;
}
//
// Notify the user of any read or write failure
//
TInt TFsGetNotifyUser::DoRequestL(CFsRequest* aRequest)
{
TBool notification=aRequest->Session()->GetNotifyUser();
TPtrC8 pA((TUint8*)¬ification,sizeof(TBool));
aRequest->WriteL(KMsgPtr0,pA);
return(KErrNone);
}
TInt TFsGetNotifyUser::Initialise(CFsRequest* /*aRequest*/)
{
return KErrNone;
}
//
// Get the drive name
//
TInt TFsGetDriveName::DoRequestL(CFsRequest* aRequest)
{
TInt driveNum=aRequest->Drive()->DriveNumber();
TFileName driveName;
if (TheDriveNames[driveNum]==NULL)
driveName.SetLength(0);
else
driveName=(*TheDriveNames[driveNum]);
aRequest->WriteL(KMsgPtr1,driveName);
return(KErrNone);
}
TInt TFsGetDriveName::Initialise(CFsRequest* aRequest)
{
TInt r=ValidateDrive(aRequest->Message().Int0(),aRequest);
return(r);
}
//
// Set the drive name
//
TInt TFsSetDriveName::DoRequestL(CFsRequest* aRequest)
{
TInt driveNum=aRequest->Drive()->DriveNumber();
TFileName driveName;
aRequest->ReadL(KMsgPtr1,driveName);
// Validate name - return KErrBadName if it contains illegal characters such as
// * ? / | > <
TNameChecker checker(driveName);
TText badChar;
if (checker.IsIllegalName(badChar))
return(KErrBadName);
TInt len=((driveName.Length()+31)>>5)<<5; // % 32
if (TheDriveNames[driveNum]==NULL)
TheDriveNames[driveNum]=HBufC::New(len);
else if (TheDriveNames[driveNum]->Des().MaxLength()<len)
{
HBufC* temp=TheDriveNames[driveNum]->ReAlloc(len);
if (temp==NULL)
return(KErrNoMemory);
TheDriveNames[driveNum]=temp;
}
if (TheDriveNames[driveNum]==NULL || TheDriveNames[driveNum]->Des().MaxLength()<len)
return(KErrNoMemory);
*TheDriveNames[driveNum]=driveName;
return(KErrNone);
}
TInt TFsSetDriveName::Initialise(CFsRequest* aRequest)
{
TInt r=ValidateDrive(aRequest->Message().Int0(),aRequest);
if (r!=KErrNone)
return(r);
if (!KCapFsSetDriveName.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Set Drive Name")))
return KErrPermissionDenied;
return KErrNone;
}
TInt FlushCachedFiles(CSessionFs* aSession)
{
TInt retVal = KErrNone;
aSession->Handles().Lock();
TInt count = aSession->Handles().Count();
for (TInt n=0; n<count; n++)
{
CObjPromotion* obj = (CObjPromotion*)aSession->Handles()[n];
if (obj != NULL && obj->UniqueID() == FileShares->UniqueID())
{
CFileShare* share = (CFileShare*) obj;
if (!share->IsCorrectThread())
continue;
CFileCB& file=((CFileShare*) obj)->File();
CFileCache* fileCache = file.FileCache();
if (fileCache)
{
retVal = fileCache->FlushDirty();
if (retVal == CFsRequest::EReqActionBusy)
break;
}
}
}
aSession->Handles().Unlock();
return retVal;
}
TInt TFsFlushDirtyData::DoRequestL(CFsRequest* aRequest)
//
//
//
{
__CHECK_DRIVETHREAD(aRequest->DriveNumber());
// Flush all dirty data
TInt r = FlushCachedFiles(aRequest->Session());
if (r == CFsRequest::EReqActionBusy)
return r;
return KErrNone;
}
TInt TFsFlushDirtyData::Initialise(CFsRequest* /*aRequest*/)
//
//
//
{
return(KErrNone);
}
// Iterate though all file shares owned by this session and cancel any async requests
TInt CancelAsyncRequests(CSessionFs* aSession)
{
TInt retVal = KErrNone;
aSession->Handles().Lock();
TInt count = aSession->Handles().Count();
for (TInt n=0; n<count; n++)
{
CObjPromotion* obj = (CObjPromotion*)aSession->Handles()[n];
if (obj != NULL && obj->UniqueID() == FileShares->UniqueID())
{
CFileShare* share = (CFileShare*) obj;
if (!share->IsCorrectThread())
continue;
CFileCB& file=((CFileShare*) obj)->File();
file.CancelAsyncReadRequest(share, NULL);
}
}
aSession->Handles().Unlock();
return retVal;
}
TInt TFsCancelSession::DoRequestL(CFsRequest* aRequest)
{
__CHECK_DRIVETHREAD(aRequest->DriveNumber());
// Cancel any outstanding requests
CDriveThread* pT=NULL;
TInt r=FsThreadManager::GetDriveThread(aRequest->DriveNumber(), &pT);
if(r==KErrNone)
pT->CompleteSessionRequests(aRequest->Session(),KErrCancel);
// We must also cancel any ASYNC requests belonging to this session BEFORE
// ~CSessionFs() is called to avoid a KERN-EXEC 44 (EBadMessageHandle)
CancelAsyncRequests(aRequest->Session());
return(r);
}
TInt TFsCancelSession::Initialise(CFsRequest* /*aRequest*/)
{
return(KErrNone);
}
TInt TFsSessionDisconnect::DoRequestL(CFsRequest* aRequest)
{
__PRINT(_L("TFsSessionDisconnect::DoRequestL()"));
__ASSERT_DEBUG(FsThreadManager::IsDisconnectThread(),Fault(ESessionDisconnectThread1));
CDisconnectThread* pT=FsThreadManager::GetDisconnectThread();
// Complete requests on all plugins
CFsInternalRequest* pR=pT->GetRequest();
FsPluginManager::CompleteSessionRequests(aRequest->Session(), KErrCancel, pR);
// ...and on all drives
for(TInt i=0;i<KMaxDrives;++i)
{
FsThreadManager::LockDrive(i);
if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse))
{
FsThreadManager::UnlockDrive(i);
continue;
}
pR->Set(CancelSessionOp,aRequest->Session());
pR->SetDriveNumber(i);
pR->Status()=KRequestPending;
pR->Dispatch();
FsThreadManager::UnlockDrive(i);
User::WaitForRequest(pR->Status());
// check request completed or cancelled (by file system dismount which completes requests with KErrNotReady)
__ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2));
__THRD_PRINT2(_L("cancel session requests on drive %d r=%d"),i,pR->Status().Int());
if (TFileCacheSettings::Flags(i) & (EFileCacheWriteEnabled | EFileCacheWriteOn))
{
FsThreadManager::LockDrive(i);
if(!FsThreadManager::IsDriveAvailable(i,EFalse)||FsThreadManager::IsDriveSync(i,EFalse))
{
FsThreadManager::UnlockDrive(i);
continue;
}
// Flush dirty data
pR->Set(FlushDirtyDataOp,aRequest->Session());
pR->SetDriveNumber(i);
pR->Status()=KRequestPending;
pR->Dispatch();
FsThreadManager::UnlockDrive(i);
User::WaitForRequest(pR->Status());
// check request completed or cancelled (by file system dismount which completes requests with KErrNotReady)
__ASSERT_ALWAYS(pR->Status().Int()==KErrNone||pR->Status().Int()==KErrNotReady,Fault(ESessionDisconnectThread2));
__THRD_PRINT2(_L("Flush dirty data on drive %d r=%d"),i,pR->Status().Int());
}
}
FsNotify::CancelSession(aRequest->Session());
#ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
FsNotificationManager::RemoveNotificationRequest(aRequest->Session());
#endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
// don't delete session here, will be done in CFsDisconnectRequest::Complete()
return(KErrNone);
}
TInt TFsSessionDisconnect::Initialise(CFsRequest* /*aRequest*/)
{
return(KErrNone);
}
TInt TFsCancelPlugin::DoRequestL(CFsRequest* aRequest)
{
//__ASSERT_DEBUG(FsPluginManager::IsPluginThread(),Fault(EFsPluginThreadError));
FsPluginManager::CancelPlugin(aRequest->iCurrentPlugin,aRequest->Session());
TInt err = aRequest->iCurrentPlugin->SessionDisconnect(aRequest->Session());
return(err);
}
TInt TFsCancelPlugin::Initialise(CFsRequest* /*aRequest*/)
{
// Notify plugin of session disconnect
return(KErrNone);
}
TInt TFsSetSessionFlags::DoRequestL(CFsRequest* aRequest)
{
aRequest->Session()->SetSessionFlags(aRequest->Message().Int0(), aRequest->Message().Int1());
return(KErrNone);
}
TInt TFsSetSessionFlags::Initialise(CFsRequest* aRequest)
{
if (!KCapFsPlugin. CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Set Session Flags")))
return KErrPermissionDenied;
return KErrNone;
}
TInt TFsInitialisePropertiesFile::DoRequestL(CFsRequest* aRequest)
{
__PRINT(_L("**TFsInitialisePropertiesFile::DoRequestL**\n"));
TInt err = KErrNone;
TInt leaveErr = KErrNone;
const TBool isRomParam = aRequest->Message().Int2();
if(isRomParam)
{
const TAny* romAddress = aRequest->Message().Ptr0();
TBool isInRom = EFalse;
TRAP(leaveErr, User::IsRomAddress(isInRom, const_cast<TAny*>(romAddress)));
if (leaveErr == KErrNone)
{
const TInt length = aRequest->Message().Int1();
err = isInRom ? F32Properties::Initialise((TInt)romAddress, length) : KErrNotSupported;
}
}
else
{
err = KErrNotSupported;
}
#ifdef SYMBIAN_ENABLE_FAT_DIRECTORY_OPT
// Create the global cache memory manager for FAT dir cache (and other caches).
// Note: file cache uses its own cache memory manager.
if (CCacheMemoryManagerFactory::CacheMemoryManager() == NULL)
{
TGlobalCacheMemorySettings::ReadPropertiesFile();
TRAPD(r, CCacheMemoryManagerFactory::CreateL());
__ASSERT_ALWAYS(r==KErrNone,Fault(ECacheMemoryManagerCreateFailed));
}
#endif // SYMBIAN_ENABLE_FAT_DIRECTORY_OPT
// Create the page cache for file caching etc.
TGlobalFileCacheSettings::ReadPropertiesFile();
if (TGlobalFileCacheSettings::Enabled())
{
TRAPD(r, CCacheManagerFactory::CreateL());
__ASSERT_ALWAYS(r==KErrNone,Fault(EFileCacheCreateFailed));
}
User::LeaveIfError(leaveErr);
return(err);
}
TInt TFsInitialisePropertiesFile::Initialise(CFsRequest* aRequest)
{
if (!KCapDiskAdmin. CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Initialise Property File")))
{
return(KErrPermissionDenied);
}
if (aRequest->Message().SecureId() != KEstartUidValue)
{
return(KErrPermissionDenied);
}
aRequest->SetDriveNumber(EDriveZ);
return(KErrNone);
}