diff -r 000000000000 -r 96e5fb8b040d userlibandfileserver/fileserver/sfile/sf_std.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfile/sf_std.h Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,1927 @@ +// 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_std.h +// +// + + +#ifndef SF_STD_H +#define SF_STD_H + +#include "common.h" +#include "message.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sf_plugin.h" +#include "sf_func.h" +#include +#include "f32trace.h" +#include + +#define __PRINT1TEMP_ALWAYS(t,a) {{TBuftemp(a);RDebug::Print(t,&temp);}} +#define __PRINT2TEMP_ALWAYS(t,a,b) {{TBuftemp(b);RDebug::Print(t,a,&temp);}} +#define __PRINT3TEMP_ALWAYS(t,a,b,c) {{TBuftemp(c);RDebug::Print(t,a,b,&temp);}} +#define __PRINT4TEMP_ALWAYS(t,a,b,c,d) {{TBuftemp(d);RDebug::Print(t,a,b,c,&temp);}} + +#define _THRD_BUF() (_L("thread id 0x"));buf.AppendNum(RThread().Id(),EHex);buf.Append(_L(" ")) +#define __THRD_PRINT_ALWAYS(t) {{TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf);}} +#define __THRD_PRINT1_ALWAYS(t,a) {{TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a);}} +#define __THRD_PRINT2_ALWAYS(t,a,b) {{TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b);}} +#define __THRD_PRINT3_ALWAYS(t,a,b,c) {{TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b,c);}} +#define __THRD_PRINT4_ALWAYS(t,a,b,c,d) {{TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b,c,d);}} + + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) +#define __PRINT(t) {if (DebugReg&KFSERV) RDebug::Print(t);} +#define __PRINT1(t,a) {if (DebugReg&KFSERV) RDebug::Print(t,a);} +#define __PRINT2(t,a,b) {if (DebugReg&KFSERV) RDebug::Print(t,a,b);} +#define __PRINT3(t,a,b,c) {if (DebugReg&KFSERV) RDebug::Print(t,a,b,c);} +#define __PRINT4(t,a,b,c,d) {if (DebugReg&KFSERV) RDebug::Print(t,a,b,c,d);} +#define __IF_DEBUG(t) {if (DebugReg&KFLDR) RDebug::t;} +#define __LDRTRACE(t) {if (DebugReg&KFLDR) t;} +#define __PRINTALLOC(t,a,b,c) {if (DebugReg&KALLOC) RDebug::Print(t,a,b,c);} +#define __PRINT1TEMP(t,a) {if (DebugReg&KFSERV) {TBuftemp(a);RDebug::Print(t,&temp);}} +#define __PRINT2TEMP(t,a,b) {if (DebugReg&KFSERV) {TBuftemp(b);RDebug::Print(t,a,&temp);}} +#define __PRINT3TEMP(t,a,b,c) {if (DebugReg&KFSERV) {TBuftemp(c);RDebug::Print(t,a,b,&temp);}} +#define __PRINT4TEMP(t,a,b,c,d) {if (DebugReg&KFSERV) {TBuftemp(d);RDebug::Print(t,a,b,c,&temp);}} +#define __CALL(t) {t;} + +#define __THRD_PRINT(t) {if (DebugReg&KTHRD) {TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf);}} +#define __THRD_PRINT1(t,a) {if (DebugReg&KTHRD) {TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a);}} +#define __THRD_PRINT2(t,a,b) {if (DebugReg&KTHRD) {TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b);}} +#define __THRD_PRINT3(t,a,b,c) {if (DebugReg&KTHRD) {TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b,c);}} +#define __THRD_PRINT4(t,a,b,c,d) {if (DebugReg&KTHRD) {TBuf buf=_THRD_BUF();buf.Append(t);RDebug::Print(buf,a,b,c,d);}} + +#define __CACHE_PRINT(t) {if (DebugReg&KCACHE) RDebug::Print(t);} +#define __CACHE_PRINT1(t,a) {if (DebugReg&KCACHE) RDebug::Print(t,a);} +#define __CACHE_PRINT2(t,a,b) {if (DebugReg&KCACHE) RDebug::Print(t,a,b);} +#define __CACHE_PRINT3(t,a,b,c) {if (DebugReg&KCACHE) RDebug::Print(t,a,b,c);} +#define __CACHE_PRINT4(t,a,b,c,d) {if (DebugReg&KCACHE) RDebug::Print(t,a,b,c,d);} +#define __CACHE_PRINT5(t,a,b,c,d,e) {if (DebugReg&KCACHE) RDebug::Print(t,a,b,c,d,e);} +#define __CACHE_PRINT6(t,a,b,c,d,e,f) {if (DebugReg&KCACHE) RDebug::Print(t,a,b,c,d,e,f);} +#define __CACHE_PRINT7(t,a,b,c,d,e,f,g) {if (DebugReg&KCACHE) RDebug::Print(t,a,b,c,d,e,f,g);} +#define __PLUGIN_PRINT(t) {if (DebugReg&KPLUGIN) RDebug::Print(t);} +#define __PLUGIN_PRINT1(t,a) {if (DebugReg&KPLUGIN) RDebug::Print(t,a);} +#define __PLUGIN_PRINT2(t,a,b) {if (DebugReg&KPLUGIN) RDebug::Print(t,a,b);} +#define __PLUGIN_PRINT3(t,a,b,c) {if (DebugReg&KPLUGIN) RDebug::Print(t,a,b,c);} +#else +#define __PRINT(t) +#define __PRINT1(t,a) +#define __PRINT2(t,a,b) +#define __PRINT3(t,a,b,c) +#define __PRINT4(t,a,b,c,d) +#define __IF_DEBUG(t) +#define __LDRTRACE(t) +#define __PRINTALLOC(t,a,b,c) {if (DebugReg&KALLOC) RDebug::Print(t,a,b,c);} +#define __PRINT1TEMP(t,a) +#define __PRINT2TEMP(t,a,b) +#define __PRINT3TEMP(t,a,b,c) +#define __PRINT4TEMP(t,a,b,c,d) +#define __CALL(t) +#define __THRD_PRINT(t) +#define __THRD_PRINT1(t,a) +#define __THRD_PRINT2(t,a,b) +#define __THRD_PRINT3(t,a,b,c) +#define __THRD_PRINT4(t,a,b,c,d) +#define __CACHE_PRINT(t) +#define __CACHE_PRINT1(t,a) +#define __CACHE_PRINT2(t,a,b) +#define __CACHE_PRINT3(t,a,b,c) +#define __CACHE_PRINT4(t,a,b,c,d) +#define __CACHE_PRINT5(t,a,b,c,d,e) +#define __CACHE_PRINT6(t,a,b,c,d,e,f) +#define __CACHE_PRINT7(t,a,b,c,d,e,f,g) +#define __PLUGIN_PRINT(t) +#define __PLUGIN_PRINT1(t,a) +#define __PLUGIN_PRINT2(t,a,b) +#define __PLUGIN_PRINT3(t,a,b,c) +#endif + +const TInt KMaxTotalDriveReserved =0x100000; +const TInt KMaxSessionDriveReserved =0x10000; + +// If TFsFileDuplciate::DoRequestL() is called a new sub-session is created and +// the new sub-session handle is returned, mangled by KSubSessionMangleBit - +// this is to discourage use of the duplicated handle. +// If TFsFileAdopt::DoRequestL() is called then the passed sub-session handle is +// assumed to be already mangled by KSubSessionMangleBit and the same sub-session +// handle is returned de-mangled. +const TInt KSubSessionMangleBit = 0x4000; + + +#define __CHECK_DRIVETHREAD(d) {__ASSERT_DEBUG(FsThreadManager::IsDriveThread(d,ETrue),Fault(EFsDriveThreadError));} +#define __CHECK_MAINTHREAD() {__ASSERT_DEBUG(FsThreadManager::IsMainThread(),Fault(EFsMainThreadError));} + +#define __LAZY_DLL_UNLOAD + +const TInt KMaxTempNameAttempts=50; +const TInt KHeapMinSize=0x1000; +const TInt KHeapMaxSize=0x400000; +const TInt KLoaderStackSize=0x8000; + +//-- maximum file size that was supported before introducing File Server 64-bit addressing support. +//-- It is 2G-1. Used in legacy code that does not understand RFile64 +const TUint64 KMaxLegacyFileSize = 0x7fffffff; + +//-- absolute maximum file size that file server supports +const TUint64 KMaxSupportedFileSize = KMaxTUint64; + +//__DATA_CAGING__ +const TUint SHA1_LBLOCK=16; +const TUint SHA1_HASH=20; +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + +class TCorruptNameRec; +class TCorruptLogRec + { +public: + TCorruptLogRec(); + ~TCorruptLogRec(); + TInt Construct(TCorruptNameRec* aNameRec, TPtrC* aProcessName, TCorruptLogRec* aChain); + inline TPtrC ProcessName(){return iProcessName->Des();}; + static TInt GetLogRecord(TFsDebugCorruptLogRecordBuf& aLogRecord,TInt aLogRecNum); + static void DestroyList(); +private: + HBufC* iProcessName; + TCorruptNameRec* iNameRec; + TCorruptLogRec* iNext; + }; + +TInt OutputTraceInfo(TCorruptNameRec* aNameRec, CFsRequest* aRequest); + +class TText8FileReader + { + enum {EMaxLine=1024}; +public: + TText8FileReader(); + ~TText8FileReader(); + TInt Set(RFile& aFile); + TInt Read(TPtr& aPtr); +public: + RFile iFile; + TBuf8 iBuf; + TInt iBufPos; + TText* iFileDataBuf; + TInt iFileSize; + }; + +class TCorruptNameRec + { +public: + TCorruptNameRec(); + TInt Construct(TPtr* aName,TInt aReturnCode, TBool aUseOnce, TCorruptNameRec* aChain); + static void ResetListConsumed(); + inline TPtrC Name(){return iName->Des();}; + inline TInt ReturnCode(){return iReturnCode;}; + inline TBool Consumed(){return iConsumed;}; + inline void SetConsumed(){iConsumed=iUseOnce;}; + inline TCorruptNameRec* Next(){return iNext;}; +private: + HBufC* iName; + TInt iReturnCode; + TBool iUseOnce; + TBool iConsumed; + TCorruptNameRec* iNext; + }; +#endif +// + +// +_LIT(KFsClient,"FSCLIENT"); + +NONSHARABLE_CLASS(CSHA1) : public CBase + { +public: + static CSHA1* NewL(void); + void Update(const TDesC8& aMessage); + TPtrC8 Final(void); + ~CSHA1(void); + void Reset(void); +private: + CSHA1(void); + TUint iA; + TUint iB; + TUint iC; + TUint iD; + TUint iE; + TBuf8 iHash; + TUint iNl; + TUint iNh; + TUint iData[SHA1_LBLOCK*5]; + void DoUpdate(const TUint8* aData,TUint aLength); + void DoFinal(void); + void Block(); + void ConstructL(void); + TUint8* iTempData; + }; + +enum TFsPanic + { + ELdrImportedOrdinalDoesNotExist + }; +// +enum TFsFault + { + EDrvIllegalShareValue, //0 + EMainCreateScheduler, + EMainCreateServer, + EMainStartServer, + EMainCreateResources1, + EMainGetLocalFileSystem, + EMainGetLocalDefaultPath, + EInitConnectLocalDrive, + EMainCreateStartupThread1, + EInitDriveMappingDriveInfo, + EInitCreateDriveName, //10 + EMainStartupNoEStart, + ESesPathBadDrive, + EFileDuplicateLock, + ESysDefaultPathNotSupported, + ESysAddLocalFileSystem, + ESvrBadSessionIndex, + EGetLocalDrive1, + EGetLocalDrive2, + ELdrRestartInit, + ELdrRestartSemaphore, //20 + EStripBackSlashBadName, + EIsSubDirBadDes, + ERawDiskBadAccessCount2, + ERawDiskBadAccessCount1, + ERawDiskBadAccessCount, + EDriveNoDiskMounted, + ESvrNotifierIsNULL, + EMainCreateResources5, + EMainCreateStartupThread2, + EMainCreateStartupThread3, //30 + EMainCreateStartupThread4, + EMainStartupWriteToDiskSemaphore, + EMainCreateResources6, + EMainScanMediaDriversMem1, + EMainScanMediaDriversLocation, + EMainScanMediaDriversMem2, + EMainScanMediaDriverConnect, + EMainScanMediaDriverDirOpen, + EMainScanMediaDriverDirRead, + EMainLoadMediaDriver, //40 + EInitCreateMediaChangeNotifier, + ELdrCleanupCreate, + ELdrSchedulerCreate, + ELdrServerCreate, + ELdrFsConnect, + ELdrFsSetPath, + ELdrCacheInit, + ELdrSchedulerStopped, + ESvrFormatOpenFailed, + ESvrRawDiskOpenFailed, //50 + EProxyDriveConstruction, + ELocDrvInitLocalDrive, + ELocDrvDismountedLocalDrive, + EBaseExtConstruction, + ECreateProxyDriveL, + EExtensionInfoCount0, + EExtensionInfoCount1, + EExtensionInfoCount2, + EStdChangeRequestType, + EExtChangeNameLength, //60 + EDiskSpaceThreshold, + EDebugChangeType, + EBaseQueConstruction, + EChangeQueType, + EDiskSpaceQueType1, + EDiskSpaceQueType2, + EBaseQueCancel, + EDebugQueType, + EBaseRequestSrc, + EBaseRequestDest, //70 + EBaseRequestDrive, + EBaseRequestSubstedDrive, + EBaseRequestSetDrive, + EBaseRequestSetSubstedDrive, + EBaseRequestMessage, + EBaseRequestSet1, + EBaseRequestSet2, + EDiskSpaceQueDrive, + ENotifyInfoDestructor, + EChangeBadIndex, //80 + EBadDiskNotifyType, + EBadDebugNotifyType, + EDiskChangeDrive, + EBadChangeNotifyType, + EDiskBadIndex1, + EDiskBadIndex2, + EDiskBadIndex3, + ESvrFreeDiskSpace, + EFsThreadBadDrvNum, + EFsThreadConstructor, //90 + EFsThreadDriveClose1, + EFsThreadDriveClose2, + EFsThreadGetThread, + EMainInitialiseRomFs, + EFsDriveThreadError, + EFsMainThreadError, + ETFsSetSubstNotNull, + EMountFileSystemFSys, + EDisMountFileSystemFSys, + EIsValidDriveMapping, //100 + EInitDriveMappingSocketNo, + ECompleteNotifSocketNo, + EObjRemoveContainerNotFound, + EObjDestructorAccessCount, + EObjDestructorContainer, + EObjRemoveBadHandle, + EArrayIndexOutOfRange, + EObjFindBadHandle, + EObjRemoveObjectNotFound, + EObjFindIndexOutOfRange, //110 + ESubOpenBadHandle, + EMainDisconnectThread, + EInternalRequestProcess, + EInternalRequestComplete1, + EInternalRequestComplete2, + EInternalRequestComplete3, + ERequestThreadDestructor, + EThreadManagerInitDrive, + EDriveCurrentWriteFunction, + EDriveGetNotifyUser, //120 + EDriveThreadWriteable, + EDriveThreadNotifyUser1, + EDriveThreadNotifyUser2, + ERequestDestructorFree, + ESessionDisconnectThread1, + ESessionDisconnectThread2, + EDismountFsDriveThread, + EDisconnectRequestDispatch1, + EDisconnectRequestDispatch2, + EDisonncectRequestProcess, //130 + EDispatchObjectDispatch, + EDispatchObjectThread, + EInternalRequestDispatch1, + EInternalRequestDispatch2, + EInternalRequestDispatch3, + EFsObjectIxDestructor, + EDisconnectRequestComplete, + EMountExtensionFSys, + EObjectConDestructor, + EParseSubstSession, //140 + ELdrGetKernelInfoFailed, + EObjectIxMainThread, + ESwapFileSystemNull, + ESwapFileSystemMount, + ESwapFileSystemRom, + EReserveSpaceArithmetic, + ECloseSubBadMessage, + EFsCacheLockFailure, + EFsPluginThreadError, + EBadDismountNotifyType, //150 + ENotifyDismount, + EAllowDismount, + ENotifyDismountCancel, + EFileDuplicateAsyncReadRequest, + EFileFailedToServiceAsyncReadRequest, + ELdrCsIdWrap, + EFileShareBadPromoteCount, + EInternalRequestDispatchCancelPlugin, + EMainCreateStartupThread0, + ERequestAllocatorOpenSubFailed, //160 + ETParsePoolGet, + EInvalidDrive, + ELocDrvInvalidLocalDrive, + ELdrReaperCreate, + ELdrReaperCleanupTimerCreate, + EFsParsePoolLockFailure, + ELdrReaperCantGetDriveList, + EFileCacheCreateFailed, + EBadOperationIndex, + EBadOperationCompletionCode, //170 + EReadOffsetNonZero, + ETooManyOperations, + EInvalidOperationIndex, + EInvalidReadLength, + EInvalidWriteLength, + ERequestThreadNotInitialised, + EMemoryInfoFailed, + EMsgRestartBadFunction, + EPushOpNoCallback, + EFreeingMsgWithMsgOp, //180 + ENotUnused, + ELdrFileDataAllocInit, + ELdrFileDataAllocError, + EDismountLocked, + EInvalidMsgState, + EGetProxyDriveMapping1, + EGetProxyDriveMapping2, + EExtProxyDriveCaps, + EIsProxyDrive, + EClearProxyDriveMapping1, //190 + EClearProxyDriveMapping2, + ERequestQueueNotEmpty, + ESetupMediaChange, + ECancelNotifyChange, + EPluginOpError, + EBadMessageSlotIndex, + EInvalidCompletionFlags, + ECacheMemoryManagerCreateFailed, + EFileBodyIsNull, + ETraceLddLoadFailure, //200 + ETooManyDrivesPerSocket, + ENotificationFault, + EFsObjectOpen + }; + + +NONSHARABLE_CLASS(CFsObjectConIx) : public CBase + { +public: + static CFsObjectConIx* NewL(); + ~CFsObjectConIx(); + CFsObjectCon* CreateL(); + void Remove(CFsObjectCon* aCon); +protected: + CFsObjectConIx(); + void CreateContainerL(CFsObjectCon*& anObject); +private: + TInt iCount; + TInt iAllocated; + TInt iNextUniqueID; + CFsObjectCon** iContainers; + }; + +struct SFsObjectIxRec + { + TInt16 instance; + TInt16 uniqueID; + CFsObject* obj; + }; + +NONSHARABLE_CLASS(CFsObjectIx) : public CBase + { +public: + static CFsObjectIx* NewL(); + ~CFsObjectIx(); + TInt AddL(CFsObject* anObj,TBool aLock); + void Remove(TInt aHandle,TBool aLock); + CFsObject* At(TInt aHandle,TInt aUniqueID,TBool aLock); + CFsObject* At(TInt aHandle,TBool aLock); + TInt At(const CFsObject* anObj,TBool aLock); + CFsObject* operator[](TInt anIndex); + void CloseMainThreadObjects(); + inline TInt Count() const; + inline TInt ActiveCount() const; + inline void Lock(); + inline void Unlock(); +protected: + CFsObjectIx(); +private: + TInt iNumEntries; // number of actual entries in the index + TInt iHighWaterMark; // 1+highest active index + TInt iAllocated; // max entries before realloc needed + TInt iNextInstance; + SFsObjectIxRec *iObjects; + RFastLock iLock; + }; + +NONSHARABLE_CLASS(CFsObjectCon) : public CBase + { +protected: + enum {ENotOwnerID}; +public: + static CFsObjectCon* NewL(); + ~CFsObjectCon(); + void AddL(CFsObject* anObj,TBool aLock); + void Remove(CFsObject* anObj,TBool aLock); + CFsObject* operator[](TInt anIndex); + CFsObject* At(TInt aFindHandle) const; + CFsObject* AtL(TInt aFindHandle) const; + TInt FindByName(TInt& aFindHandle,const TDesC& aMatch) const; + inline void Lock(); + inline void Unlock(); + inline TInt UniqueID() const; + inline TInt Count() const; +protected: + CFsObjectCon(TInt aUniqueID); + TInt CheckUniqueName(const CFsObject* anObject) const; + TBool NamesMatch(const TName& anObjectName, const CFsObject* aCurrentObject) const; +public: + TInt iUniqueID; + TInt iCount; + TInt iAllocated; + CFsObject** iObjects; + RFastLock iLock; +friend class CFsObjectConIx; +friend class CFsObject; + }; + + +NONSHARABLE_CLASS(CFsSyncMessageScheduler) : public CActive + { +public: + static CFsSyncMessageScheduler* NewL(); + void DoCancel(); + void RunL(); + void Dispatch(CFsRequest* aRequest); + void CompleteSessionRequests(CSessionFs* aSession, TInt aValue); +private: + CFsSyncMessageScheduler(); + void ConstructL(); +private: + RThread iThread; + RFastLock iLock; + TDblQue iList; + TBool iSignalled; + }; + + +NONSHARABLE_CLASS(CNotifyMediaChange) : public CActive + { +public: + CNotifyMediaChange(RLocalDrive* aDrive,TInt aSocketNo); + void DoCancel() {}; + void RunL(); +private: + RLocalDrive* iDrive; + TInt iSocket; + }; + + +const TInt KMaxDrivesPerSocket=16; + +class LocalDrives + { +public: + static void Initialise(); + static TBusLocalDrive& GetLocalDrive(TInt aDriveNumber); + static CExtProxyDrive* GetProxyDrive(TInt aDrive); + static TInt InitProxyDrive(CFsRequest* aRequest); + static TInt MountProxyDrive(CFsRequest* aRequest); + static TInt DismountProxyDrive(TInt iDriveNumber); + static TBool IsValidDriveMapping(TInt aDrvNumber); + static TInt DriveNumberToLocalDriveNumber(TInt aDrvNumber); + static TInt SetDriveMappingL(CFsRequest* aRequest); + static void CompleteNotifications(TInt aSocket); + static void CompleteDriveNotifications(TInt aDriveNumber); + static TInt GetLocalSocket(TInt aControllerRelativeSocket, TMediaDevice aMediaType); + static TInt GetDriveFromLocalDrive(TInt aLocDrv); + static TInt GetLocalDriveNumber(TBusLocalDrive* aLocDrv); + static TBool IsProxyDrive(TInt aDrive); + static void ClearProxyDriveMapping(TInt aDrive); + static TBool IsProxyDriveInUse(CExtProxyDriveFactory* aDevice); + static TInt SetupMediaChange(TInt aDrive); + static void NotifyChangeCancel(TInt aDrive); +private: + static void InitDriveMapping(); + static TInt SwapDriveMapping(TInt aFirstDrive,TInt aSecondDrive); +private: + class TSocketDesc + { + public: + TInt iDriveNumbers[KMaxDrivesPerSocket]; // drive numbers assigned to this socket + CNotifyMediaChange* iMediaChanges; + TMediaDevice iMediaType; + TInt iControllerRelativeSocket; + }; + static TSocketDesc iSocketDescs[KMaxPBusSockets]; + static TBusLocalDrive iLocalDrives[KMaxLocalDrives]; + static TInt iMapping[KMaxDrives]; // maps drive to local drive + static TBool iMappingSet; + static TInt iReverseMapping[KMaxLocalDrives];// opposite mapping of iMapping. local drive to drive (1 to [potentially] many) + // i.e. LocalDrive1 -> DriveX + // LocalDrive2 -> DriveX + static TBool iIsMultiSlotDrive[KMaxDrives]; // index is drive number + static CExtProxyDrive* iProxyDriveMapping[KMaxProxyDrives]; + + friend void TFsAddCompositeMount::AddFsToCompositeMountL(TInt aDriveNumber, CFileSystem& aFileSystem, TInt aLocalDriveNumber); + friend void TDrive::MultiSlotDriveCheck(); // for dual/multi slot drive map swapping. (iMapping/iReverseMapping) + }; + +NONSHARABLE_CLASS(CLogon) : public CActive + { +public: + enum {EPriority=3000}; +public: + static CLogon* NewL(); + TInt Logon(RThread aThread); + virtual void DoCancel(); + virtual void RunL(); +protected: + CLogon(TInt aPriority); +private: + RThread iThread; + }; + +#ifdef __LAZY_DLL_UNLOAD +NONSHARABLE_CLASS(CLazyUnloadTimer): public CTimer + { +public: + CLazyUnloadTimer(); + ~CLazyUnloadTimer(); + static void New(); + static void Finish(); +private: + void RunL(); + void Start(); + }; +#endif + +NONSHARABLE_CLASS(CSessionLoader) : public CSession2 + { +private: + virtual void ServiceL(const RMessage2& aMessage); + TInt DeleteExecutable(const TDesC& aName); + }; + +NONSHARABLE_CLASS(CServerLoader) : public CServer2 + { +public: + enum {EPriority=2000}; +public: + static CServerLoader* New(); + virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const; + virtual TInt RunError(TInt aError); +private: + CServerLoader(TInt aPriority); + }; + +class RLoaderMsg : public RMessage2 + { +public: + TInt GetString(HBufC8*& aBuf, TInt aParam, TInt aMaxLen, TInt aHeadroom, TBool aReduce) const; + TInt GetLdrInfo(TLdrInfo& aInfo) const; + TInt UpdateLdrInfo(const TLdrInfo& aInfo) const; + }; + + void Fault(TFsFault aFault); + +class CSessionFs; +class TOperation; +class CRequestThread; + +typedef TInt (*TFsRequestFunc)(CFsRequest*); + +class TThreadTimer + { +public: + TThreadTimer(TInt (*aCallBackFunction)(TAny* aPtr),TAny* aPtr); + + void Start(CRequestThread* aRequestThread, TTimeIntervalMicroSeconds32 aTime); + void Stop(); + +private: + TTickCountQueLink iLink; + TCallBack iCallBack; + CRequestThread* iRequestThread; // the thread the timer is running on, NULL if timer not running + + friend class CFsDeltaTimer; + }; + +// Class adapted from CDeltaTimer (but unlike CDeltaTimer, not derived from CActive). +// Used to support multiple timer events in drive threads. +NONSHARABLE_CLASS(CFsDeltaTimer) : public CBase + { +public: + static CFsDeltaTimer* New(CRequestThread& aRequestThread, TInt aPriority); + ~CFsDeltaTimer(); + + void Start(TThreadTimer& aEntry, TTimeIntervalMicroSeconds32 aTime); + void Stop(TThreadTimer& aEntry); + + void RunL(); +private: + CFsDeltaTimer(CRequestThread& aRequestThread, TInt aPriority, TInt aTickPeriod); + void Cancel(); + void Activate(); + TInt QueueLong(TTimeIntervalMicroSeconds aTimeInMicroSeconds, TThreadTimer& aEntry); +private: + CRequestThread& iRequestThread; + TThreadId iThreadId; + RTimer iTimer; + TTickCountQue iQueue; + const TInt iTickPeriod; + TBool iQueueBusy; + RFastLock iLock; + TBool iRestartNeeded; // timer needs to be restarted as it was scheduled from a different thread +public: + TRequestStatus iStatus; + }; + + +NONSHARABLE_CLASS(CRequestThread) : public CBase + { +public: + TInt ThreadFunction(); + void DeliverBack(CFsRequest* aRequest, TBool aLowPriority = EFalse); + void DeliverFront(CFsRequest* aRequests); + + ~CRequestThread(); + + CFsDeltaTimer* Timer(); + + void CompleteAllRequests(TInt aValue); +protected: + CRequestThread(); + TInt DoStart(RThread& aThread); + inline TInt Initialise(); + void Deliver(CFsRequest* aRequest,TBool aIsFront, TBool aLowPriority = EFalse); + void Receive(); + virtual TInt DoThreadInitialise(); +protected: + CFsRequest* iRequest; + TDblQue iList; + RFastLock iListLock; + TBool iIsWaiting; + TBool iExit; + RThread iThread; + CFsDeltaTimer* iTimer; + TBool iLowPriority; // if true, drive thread's priority has been (temporarily) reduced + friend class CFsDeltaTimer; + }; + + + + +NONSHARABLE_CLASS(CDriveThread) : public CRequestThread + { +public: + void CompleteReadWriteRequests(); + void CompleteSessionRequests(CSessionFs* aSession, TInt aValue); + void CompleteClientRequests(TInt aValue); + TBool IsRequestWriteable(); + TBool IsSessionNotifyUser(); +private: + CDriveThread(); + static CDriveThread* NewL(); + TUint StartL(TInt aDrvNumber); + TInt DoThreadInitialise(); + + void StartFinalisationTimer(); + void StopFinalisationTimer(); + + static TInt FinaliseTimerEvent(TAny* aFileCache); +private: + TInt iDriveNumber; + TThreadTimer iFinaliseTimer; + +friend class FsThreadManager; + }; + +class CFsInternalRequest; + +NONSHARABLE_CLASS(CDisconnectThread) : public CRequestThread + { +public: + inline CFsInternalRequest* GetRequest(); +private: + static CDisconnectThread* NewL(); + TUint StartL(); + ~CDisconnectThread(); +private: + CFsInternalRequest* iRequest; +friend class FsThreadManager; + }; + +class CFsPlugin; +NONSHARABLE_CLASS(CPluginThread) : public CRequestThread + { +public: + CPluginThread(CFsPlugin& aPlugin); + ~CPluginThread(); + + void CompleteSessionRequests(CSessionFs* aSession, TInt aValue); + + /** @prototype */ + void OperationLockWait(); + + /** @prototype */ + void OperationLockSignal(); + +private: + static CPluginThread* NewL(CFsPlugin& aPlugin); + TUint StartL(); + virtual TInt DoThreadInitialise(); +private: + CFsPlugin& iPlugin; + + /** @prototype */ + RSemaphore iOperationLock; + +friend class FsPluginManager; + }; + +class TFsDriveThread + { +public: + TFsDriveThread(); +public: + RMutex iFSLock; + TBool iIsAvailable; + TBool iIsSync; + CDriveThread* iThread; + TUint iId; + TBool iIsHung; // drive is hung waiting for a critical notifier + TBool iMediaChangePending; // media change is pending while hung + }; + + +class FsThreadManager + { +public: + static TInt CreateDisconnectThread(); + static inline CDisconnectThread* GetDisconnectThread() {return(iDisconnectThread);} + static TBool IsDisconnectThread(); +// + static void SetMainThreadId(); + static TBool IsMainThread(); +// + static TInt InitDrive(TInt aDrvNumber,TBool aIsSync); + static TInt ChangeSync(TInt aDrvNumber,TBool aIsSync); + + static TInt GetDriveThread(TInt aDrvNumber, CDriveThread** aDrvThread); + static void CloseDrive(TInt aDrvNumber); + static TBool IsDriveThread(TInt aDrvNumber,TBool aLock); + static TBool IsDriveSync(TInt aDrvNumber,TBool aLock); + static TBool IsDriveAvailable(TInt aDrvNumber,TBool aLock); + static void LockDrive(TInt aDrvNumber); + static void UnlockDrive(TInt aDrvNumber); + static void SetDriveHung(TInt aDrvNumber, TBool aIsHung); + static TBool IsDriveHung(TInt aDrvNumber); + static void SetMediaChangePending(TInt aDrvNumber); + static void StartFinalisationTimer(TInt aDriveNumber); + static void StopFinalisationTimer(TInt aDriveNumber); +private: + inline static TFsDriveThread& GetFsDriveThread(TInt aDrvNumber) {return(iFsThreads[aDrvNumber]);} +private: + static TFsDriveThread iFsThreads[KMaxDrives]; + static TUint iMainId; + static CDisconnectThread* iDisconnectThread; + static TUint iDisconnectThreadId; + }; + + +const TInt KReservedDriveAccessArrayGranularity = 2; + +class TReservedDriveAccess + { +public: + inline TReservedDriveAccess(TInt aDriveNumber); + inline TReservedDriveAccess(TInt aDriveNumber, TInt aReservedSpace); +private: + TReservedDriveAccess(); +public: + TInt iDriveNumber; + TInt iReservedSpace; + TInt iReservedAccess; + }; + + +class CFsMessageRequest; +NONSHARABLE_CLASS(CSessionFs) : public CSession2 + { +public: + static CSessionFs* NewL(); + ~CSessionFs(); + virtual void CreateL(); + TInt CurrentDrive(); + void ServiceL(const RMessage2& aMessage); + TInt CountResources(); + void ResourceCountMarkStart(); + void ResourceCountMarkEnd(const RMessage2& aMessage); + TBool GetNotifyUser(); + void SetNotifyUser(TBool aNotification); + TBool IsChangeNotify(); + void SetSessionFlags(TUint32 aBitsToSet, TUint32 aBitsToClear); + TBool TestSessionFlags(TUint32 aFlags); + void CloseRequestCountInc(); + void CloseRequestCountDec(); + + // + virtual void Disconnect(const RMessage2& aMessage); + // + inline void IncResourceCount(); + inline void DecResourceCount(); + inline CFsObjectIx& Handles(); + inline HBufC& Path(); + inline void SetPath(HBufC* aPath); + inline TThreadId& ThreadId(); + inline void SetThreadId(const TThreadId& aId); + // + TUint Reserved(TInt aDriveNumber) const; + TInt SetReserved(const TInt aDriveNumber, const TInt aReservedValue); + TBool ReservedAccess(TInt aDriveNumber) const; + void SetReservedAccess(const TInt aDriveNumber, const TBool aReservedAccess); +private: + CSessionFs(); + +private: + TInt iResourceCountMark; + TInt iResourceCount; + TInt iSessionFlags; + RFastLock iSessionFlagsLock; + CFsObjectIx* iHandles; + HBufC* iPath; + CFsMessageRequest* iDisconnectRequest; + RArray iReservedDriveAccess; + TThreadId iId; + TInt iCloseRequestCount; // number of close requests owned by this sessions on the RequestAllocator close queue +friend class CFsDisconnectRequest; + }; + +NONSHARABLE_CLASS(CServerFs) : public CServer2 + { +public: + enum {EPriority=1000}; +public: + virtual ~CServerFs(); + static void New(); + virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const; + CSessionFs* operator[](TInt anIndex); + inline void SessionQueueLockWait(); + inline void SessionQueueLockSignal(); +protected: + // from CServerFs + void RunL(); + +private: + CServerFs(TInt aPriority); + // lock to protect iSessionQ + RFastLock iSessionQueueLock; + }; + +NONSHARABLE_CLASS(CActiveSchedulerFs) : public CActiveScheduler + { +public: + static void New(); + virtual void Error(TInt anError) const; + }; + +NONSHARABLE_CLASS(CActiveSchedulerLoader) : public CActiveScheduler + { +public: + static CActiveSchedulerLoader* New(); + virtual void Error(TInt anError) const; + }; + + +class TNameChecker + { +public: + TNameChecker(const TDesC& aPathName): iName(aPathName){}; + TBool IsIllegalChar(TText& aChar); + TBool IsIllegalName(); + TBool IsIllegalName(TText& aChar); + TBool IsIllegalPath(); + TBool IsIllegalPath(TText& aChar); + void SetName(const TDesC& aName){iName=aName;}; +private: + TBool IsIllegal(TText& aChar) const; +private: + TFileName iName; + TParse iParse; + }; + +enum TOperationFlags + { + ESync = 0x01, + EInternalRequest = 0x02, // NB Not really used! + EParseSrc = 0x04, + EParseDst = 0x08, + EFileShare = 0x10, // Operates on an open file share + }; + +class TOperation + { +public: + TBool IsChangeNotify() const; + TBool IsDiskSpaceNotify() const; + TBool IsWrite() const; + TUint NotifyType() const; + TBool IsCompleted() const; + TBool IsOpenSubSess() const; //used to allocate for close as well as open task for subsessions + TBool IsCloseSubSess() const; + + inline TBool IsSync() const; + inline TInt Function(); + inline TInt Initialise(CFsRequest* aRequest); + inline TInt PostInitialise(CFsRequest* aRequest); + inline TInt DoRequestL(CFsRequest* aRequest); + inline TFsPluginRequest::TF32ArgType Arg(TUint aIndex); + +public: + TInt iFunction; + TUint iFlags; + TFsRequestFunc iInitialise; + // optional processing step. Runs initially in context of main file server thread + // but may be executed again in drive thread context if request is postponed + TFsRequestFunc iPostInitialise; + TFsRequestFunc iDoRequestL; + TUint32 iArgs; + }; + +class TMsgOperation + { +public: + inline void Set(TInt64 aPos, TInt aLength, TUint8* aData, TInt aOffset = 0, TInt aNextState = 0); + inline void Set(TInt64 aPos, TInt aLength, TDesC8* aData, TInt aOffset = 0, TInt aNextState = 0); +public: + + typedef struct + { + TAny* iData; // pointer to local buffer (TUint8*) or remote client decriptor (TDesC8*) + TInt iTotalLength; + TInt64 iPos; + TInt iLength; // length of current fair-scheduled read/write + TInt iOffset; // offset into iData + } SReadWriteArgs; + + union + { + TInt iArgs[KMaxMessageArguments]; + SReadWriteArgs iReadWriteArgs; + }; + + TInt iFunction; // the current function (usually, but not always the same as TOperation.iFunction + TFsRequestFunc iComplete; // function to call when CFsMessageRequest::Complete() is called + CFsPlugin* iCurrentPlugin; // The current plugin at the stage this Operation was pushed + + TBool iClientRequest; // The current request originated through RFile/RFilePlugin, so uses a descriptor buffer: + // An EFSRV client request non-local handle non-local buffer descriptor + // A plugin request local handle local buffer descriptor + // An internal (cache) request local handle local buffer raw pointer + TInt iState; + TMsgOperation* iNext; + TMsgOperation* iPrev; + TBool iIsAllocated; + TAny* iScratchValue0; + TAny* iScratchValue1; + TInt64 iClientPosition; + }; + + + +NONSHARABLE_CLASS(CFsRequest) : public CBase + { +public: + /** Request states - these indicate a message's current stage of processing + */ + enum TReqStates + { + /** Need to call iOperation.iInitialise() */ + EReqStateInitialise, + /** Need to call PostInitialise() */ + EReqStatePostInitialise, + /** Need to call iOperation.iDoRequestL */ + EReqStateDoRequest, + }; + + + /** + Request actions - these indicate what further processing is required + and may be returned by any of: + + CFsRequest::iOperation->Initialise() + CFsPlugin::DoRequestL() + CFsMessageRequest::iOperation->iPostInitialise() + CFsRequest::iOperation->DoRequestL() + CFsMessageRequest::iCurrentOperation->iComplete() + + The last 3 bits of each return code are used in CFsMessageRequest::Complete() + as an array look up to determine what action to take + */ + enum TReqActions + { + /** + Continue with processing, dispatching to drive thread if necessary + NB same value as KErrNone to maintain compatibility with existing code + */ + EReqActionContinue = KErrNone, // 0x00000000, last 3 bits = 0 + + /** + Complete and free the message + */ + EReqActionComplete = KErrCompletion, // 0xFFFFFFEF, last 3 bits = 7 + + /** + A resource is in use, so dispatch message again to back of drive thread's request queue + If returned by Initialise(), then Initialse() will be called again + If returned by Complete(), then iPostInitialise() will be called again + */ + EReqActionBusy = -0x1002, // 0xFFFFEFFE, last 3 bits = 6 + + /** + Neither dispatch nor complete the message - + a plugin thread has taken ownership of the message + */ + EReqActionOwnedByPlugin = -0x1003, // 0xFFFFEFFD, last 3 bits = 5 + + /** + The request cannot be processed because there is already an active read/write request + for the associated file share. This request has been linked to the currently active + request and will be dispatched to the the drive thread when the current request has completed. + @see CFileShare::RequestStart() & CFileShare::RequestEnd() + */ + EReqActionPending = EReqActionOwnedByPlugin, + }; +public: + ~CFsRequest(); + + void ReadL(const TInt aMsgNum,TDes8& aDes); + void ReadL(const TInt aMsgNum,TDes8& aDes,TInt anOffset); + void ReadL(const TInt aMsgNum,TDes16& aDes); + void ReadL(const TInt aMsgNum,TDes16& aDes,TInt anOffset); + + void WriteL(const TInt aMsgNum,const TDesC8& aDes); + void WriteL(const TInt aMsgNum,const TDesC8& aDes,TInt anOffset); + void WriteL(const TInt aMsgNum,const TDesC16& aDes); + void WriteL(const TInt aMsgNum,const TDesC16& aDes,TInt anOffset); + + TInt Read(const TInt aMsgNum,TDes8& aDes); + TInt Read(const TInt aMsgNum,TDes8& aDes,TInt anOffset); + TInt Read(const TInt aMsgNum,TDes16& aDes); + TInt Read(const TInt aMsgNum,TDes16& aDes,TInt anOffset); + + TInt Write(const TInt aMsgNum,const TDesC8& aDes); + TInt Write(const TInt aMsgNum,const TDesC8& aDes,TInt anOffset); + TInt Write(const TInt aMsgNum,const TDesC16& aDes); + TInt Write(const TInt aMsgNum,const TDesC16& aDes,TInt anOffset); + + TInt GetDesLength(const TInt aMsgNum); + + inline void Kill(TInt aReason); + inline void Terminate(TInt aReason); + inline void Panic(const TDesC &aCategory,TInt aReason); + inline TBool ErrorPlugin(TInt aReason); + + TInt Read(TFsPluginRequest::TF32ArgType aType, TInt& aVal); + TInt Read(TFsPluginRequest::TF32ArgType aType, TUint& aVal); + TInt Read(TFsPluginRequest::TF32ArgType aType, TInt64& aVal); + // + TInt Read(TFsPluginRequest::TF32ArgType aType, TDes8& aDes, TInt aOffset = 0); + TInt Read(TFsPluginRequest::TF32ArgType aType, TDes16& aDes, TInt aOffset = 0); + // + TInt Write(TFsPluginRequest::TF32ArgType aType, const TDesC8& aDes, TInt aOffset = 0); + TInt Write(TFsPluginRequest::TF32ArgType aType, const TDesC16& aDes, TInt aOffset = 0); + + inline TInt Initialise(){return iOperation->Initialise(this);}; + virtual void Process()=0; + virtual void Complete(TInt aError)=0; + virtual void Dispatch()=0; + virtual void Free()=0; + // + virtual TParse& Src(); + virtual TParse& Dest(); + virtual TDrive* Drive(); + virtual TDrive* SubstedDrive(); + virtual void SetDrive(TDrive* aDrive); + virtual void SetSubstedDrive(TDrive* aDrive); + virtual const RMessage2& Message(); + // + inline TOperation* Operation(); + inline CSessionFs* Session(); + inline void SetSession(CSessionFs* aSession); + inline TInt DriveNumber(); + inline void SetDriveNumber(TInt aDriveNumber); + inline TBool IsCompleted(); + inline void SetCompleted(TBool aIsCompleted); + inline TUint ScratchValue(); + inline void SetScratchValue(const TUint aValue); + inline TInt64 ScratchValue64(); + inline void SetScratchValue64(const TInt64& aValue); + inline TBool IsSeparateThread(); + inline TBool IsPostOperation() const; + inline TBool IsPluginSpecific() const; + inline TBool IsExpectedResult(TInt err) const; + inline TBool IsChangeNotify() const; + inline void SetState(TReqStates aReqState); + inline TBool DirectToDrive(); + inline TBool IsDescData(TInt aMsgNum); + inline TInt FsFunction(); + +public: + CFsRequest(); +protected: + inline void Set(const TOperation& aOperation,CSessionFs* aSession); + inline void Set(CSessionFs* aSession); + inline void SetError(TInt aError); + inline TInt GetError() const; + inline void SetPostOperation(TBool aSet); + + inline TBool IsFsObjectOpen(); + inline void SetFsObjectOpen(TBool aSet); + void SetAndOpenScratchValue(const TInt64& aValue); + +private: + TInt GetSlot(TFsPluginRequest::TF32ArgType aType); +public: + TDblQueLink iLink; + CFsPlugin* iCurrentPlugin; + CFsPlugin* iOwnerPlugin; // the plugin which originated this request + TThreadId iClientThreadId; + TBool iDirectToDrive; +protected: + CSessionFs* iSession; + TOperation* iOperation; + TInt iDriveNumber; + TBool iIsCompleted; + TInt64 iScratchValue; + + TReqStates iReqState; + + /** defines for iFlags + */ + enum TFsRequestFlags + { + EIsAllocated = 0x01, + EFreeChanged = 0x02, // valid only for EFsFileWrite + EPostInterceptEnabled = 0x04, + EPostOperation = 0x08, + EFsObjectOpen = 0x10, + }; + TUint iFlags; + + TInt iError; + }; + +const TInt KOperationFunctionUnaltered = -1; + +NONSHARABLE_CLASS(CFsMessageRequest) : public CFsRequest + { +public: + void Set(const RMessage2& aMessage,CSessionFs* aSession); + void Set(const RMessage2& aMessage,const TOperation& aOperation,CSessionFs* aSession); + void Set(const TOperation& aOperation); + inline void SetPostInitialise(TFsRequestFunc aCacheFunction); + // + inline void SetMessage(RMessage2& aMessage); + // + virtual void Process(); + virtual void Complete(TInt aError); + + virtual void Dispatch(); + virtual void Free(); + virtual TDrive* Drive(); + virtual TDrive* SubstedDrive(); + virtual void SetDrive(TDrive* aDrive); + virtual void SetSubstedDrive(TDrive* aDrive); + virtual const RMessage2& Message(); + + inline TBool IsFreeChanged(); + inline void SetFreeChanged(TBool aChanged); + + inline TBool PostInterceptEnabled(); + inline void EnablePostIntercept(TBool aEnable); + + inline TBool IsAllocated(); + inline void SetAllocated(); + inline CFsMessageRequest(); + + TInt PushOperation(TInt64 aPos, TInt aLength, TUint8* aData, TInt aOffset = 0, TFsRequestFunc aCallback = NULL, TInt aNextState = 0, TInt aFunction = KOperationFunctionUnaltered); + TInt PushOperation(TInt64 aPos, TInt aLength, TDesC8* aData, TInt aOffset = 0, TFsRequestFunc aCallback = NULL, TInt aNextState = 0, TInt aFunction = KOperationFunctionUnaltered); + TInt PushOperation(TFsRequestFunc aCallback = NULL, TInt aNextState = 0, TInt aFunction = KOperationFunctionUnaltered); + void PopOperation(); + void SetOperationFunc(TInt aFunction); + TMsgOperation& CurrentOperation(); + inline TMsgOperation* CurrentOperationPtr(); + void Dispatch(TBool aInitialise, TBool aLowPriority = EFalse, TBool aDispatchToFront = EFalse); + + inline TInt& LastError(); + inline void SetLastError(TInt aLastError); + inline void Init(); + void ReStart(); + TBool IsPluginRequest(); + + // UID of the process to touching the file. (To be used in notification framework). + // TUid iUID; +private: + void DoNotify(TInt aError); + TInt DoInitialise(); + TInt PostInitialise(); + TBool DispatchToPlugin(); + void ProcessPostOperation(); + void ProcessPreOperation(); + void ProcessDriveOperation(); + TBool CurrentPluginWaiting(); + inline TInt DispatchToDrive(TBool aLowPriority, TBool aDispatchToFront); + TBool IsNotifierSpecific() const; + TBool IsNotifierSupported() const; +protected: + RMessage2 iMessage; + TDrive* iDrive; + TDrive* iSubstedDrive; +private: + TMsgOperation* iCurrentOperation; + TInt iLastError; + }; + + +NONSHARABLE_CLASS(TParsePool) + { +private: + enum {KEBlockSize = 4}; + +public: + static TInt Init(); + static TParsePool* Get(); + static void Release(TParsePool* aObject); + TParsePool (); + TParse& GetObject() {return iObject;}; + +private: + TParsePool* iNext; + TParsePool* iPrev; + + TBool iFree; + TParse iObject; + static TParsePool* iFreeHead; + static TParsePool* iClosedHead; + static TInt iCountFree; + static RFastLock iLock; + }; + + +NONSHARABLE_CLASS(CFsClientMessageRequest) : public CFsMessageRequest + { +public: + CFsClientMessageRequest(); + virtual TParse& Src(); + virtual TParse& Dest(); + virtual void Free(); + TInt AllocParseObjects(const TOperation& aOperation); +public: + CFsClientMessageRequest* iNext; +protected: + TParsePool* iPoolSrc; + TParsePool* iPoolDest; + }; + +NONSHARABLE_CLASS(CFsDisconnectRequest) : public CFsMessageRequest + { +public: + virtual void Process(); + virtual void Dispatch(); + virtual void Complete(TInt aError); + }; + +NONSHARABLE_CLASS(CFsInternalRequest) : public CFsRequest + { +public: + CFsInternalRequest(); + void Set(const TOperation& aOperation,CSessionFs* aSession); + // + inline void SetThreadHandle(TInt aThreadHandle); + inline TInt ThreadHandle(); + inline TRequestStatus& Status(); + inline TBool IsAllocated(); + inline void SetAllocated(); + // + virtual void Process(); + virtual void Complete(TInt aError); + virtual void Dispatch(); + virtual void Free(); +private: + TUint iThreadHandle; + TRequestStatus iStatus; + TBool iIsAllocated; + }; +const TInt KMaxRequestAllocated = 45; +const TInt KMaxOperationAllocated = KMaxRequestAllocated * 2; +const TInt KAllocReqBlock=15; + +class TParseCon + { +public: + TParse iParse; + TParseCon* iNext; + }; + + +class RequestAllocator + { +public: + static TInt GetMessageRequest(const TOperation& aOperation,const RMessage2& aMessage,CFsClientMessageRequest* &aRequest); + static void FreeRequest(CFsClientMessageRequest* aRequest); // Use the one from cache + static void OpenSubFailed(CSessionFs* aSession); + static TInt AllocRequest(TInt aNum); + + static TInt AllocOperation(); + static TInt GetOperation(TMsgOperation* &aOperation); + static void FreeOperation(TMsgOperation* aOperation); + + + static void Initialise(); +#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE) + inline static TInt TotalCount(); + static TInt CloseCount(); + static TInt FreeCount(); + inline static TInt AllocatedCount(); +private: + static TInt iAllocated; +#endif +public: + static RFastLock iCacheLock; +private: + static TInt iAllocNum; + static CFsClientMessageRequest* iFreeHead; + static CFsClientMessageRequest* iCloseHead; + + static TInt iAllocNumOperation; + static TMsgOperation* iFreeHeadSupOp; + }; + + +NONSHARABLE_CLASS(CNotifyInfo) : public CBase + { +public: + + enum TInfoType {EDiskSpace,EStdChange,EExtChange,EDebugChange,EDismount}; + +public: + ~CNotifyInfo(); + void Initialise(TInfoType aType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession); + void Complete(TInt aError); + // + inline CSessionFs* Session(); + inline TRequestStatus* Status(); + inline TInfoType Type() const {return(iType);} +public: + TDblQueLink iLink; +protected: + TInfoType iType; + TRequestStatus* iStatus; + RMessagePtr2 iMessage; + CSessionFs* iSession; + }; + + +NONSHARABLE_CLASS(CStdChangeInfo) : public CNotifyInfo + { +public: + void Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession); + TUint RequestNotifyType(CFsRequest* aRequest); + TBool IsMatching(CFsRequest* aRequest); +protected: + TNotifyType iChangeType; + }; + +NONSHARABLE_CLASS(CExtChangeInfo) : public CStdChangeInfo + { +public: + void Initialise(TNotifyType aChangeType,TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession,const TDesC& aName); + TBool IsMatching(CFsRequest* aRequest); +private: + TFileName iName; + }; + +NONSHARABLE_CLASS(CDiskSpaceInfo) : public CNotifyInfo + { +public: + void Initialise(TRequestStatus* aStatus,const RMessagePtr2& aMessage,CSessionFs* aSession,TInt64 aThreshold); + TBool IsMatching(TInt64& aBefore,TInt64& aAfter); +private: + TInt64 iThreshold; + }; + +NONSHARABLE_CLASS(CDebugChangeInfo) : public CNotifyInfo + { +public: + void Initialise(TUint aDebugType,TRequestStatus* iStatus,const RMessagePtr2& aMessage,CSessionFs* aSession); + TBool IsMatching(TUint aChange); +private: + TUint iDebugType; + }; + +NONSHARABLE_CLASS(CDismountNotifyInfo) : public CNotifyInfo + { +public: + ~CDismountNotifyInfo(); + void Initialise(TNotifyDismountMode aMode, TInt aDriveNumber,TRequestStatus* iStatus,const RMessagePtr2& aMessage,CSessionFs* aSession); + TBool IsMatching(TNotifyDismountMode aMode, TInt aDriveNumber, CSessionFs* aSession); +private: + TNotifyDismountMode iMode; + TInt iDriveNumber; + }; + +const TInt KMaxNotifyQues=KMaxDrives+1; +const TInt KMaxDiskQues=KMaxDrives; + +class TBaseQue + { +protected: + TBaseQue(); + ~TBaseQue(); + void DoAddNotify(CNotifyInfo* aInfo); + TBool DoCancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL); + void DoCancelAll(TInt aCompletionCode); + TBool IsEmpty(); +protected: + TDblQue iHeader; + RFastLock iQLock; + }; + +class TChangeQue :public TBaseQue + { +public: + TInt AddNotify(CNotifyInfo* aInfo); + TBool CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL); + void CancelAll(TInt aCompletionCode); + void CheckChange(CFsRequest* aRequest); + TBool IsEmpty(); + }; + +class TDiskSpaceQue : public TBaseQue + { +public: + inline void SetDriveNumber(TInt aDriveNumber) {iDriveNumber=aDriveNumber;} + TInt AddNotify(CNotifyInfo* aInfo); + TInt CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL); + void CancelAll(TInt aCompletionCode); + void CheckDiskSpace(); + void CheckDiskSpace(TInt64& aFreeDiskSpace); + TBool IsEmpty(); +private: + TInt GetFreeDiskSpace(TInt64& aFreeDiskSpace); +private: + TInt64 iFreeDiskSpace; + TInt iDriveNumber; + TInt64 iReservedDiskSpace; + }; + +class TDebugQue : public TBaseQue + { +public: + TInt AddNotify(CNotifyInfo* aInfo); + TInt CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL); + void CancelAll(TInt aCompletionCode); + void CheckDebug(TUint aDebugChange); + }; + +class TDismountNotifyQue : public TBaseQue + { +public: + TInt AddNotify(CNotifyInfo* aInfo); + TInt CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL); + void CancelAll(TInt aCompletionCode); + void CheckDismount(TNotifyDismountMode aMode, TInt aDrive, TBool aRemove, TInt aError); + TBool HandlePendingDismount(CSessionFs* aSession, TInt aDrive); + }; + +class FsNotify + { +public: + static void Initialise(); + static TInt AddChange(CNotifyInfo* aInfo,TInt aDrive); + static TInt AddDiskSpace(CNotifyInfo* aDiskInfo,TInt aDrive); + static TInt AddDebug(CNotifyInfo* aDebugInfo); + static TInt AddDismountNotify(CNotifyInfo* aDismountNotifyInfo); + static void DiskChange(TInt aDrive); + static void HandleChange(CFsRequest* aRequest,TInt aDrive); + static void HandleDiskSpace(CFsRequest* aRequest,TInt aDrive); + static void HandleDiskSpace(TInt aDrive, TInt64& aFreeSpace); + static void HandleDebug(TUint aFunction); + static void HandleDismount(TNotifyDismountMode aMode, TInt aDrive, TBool aRemove, TInt err); + static void CancelChangeSession(CSessionFs* aSession,TRequestStatus* aStatus=NULL); + static void CancelDiskSpaceSession(CSessionFs* aSession,TRequestStatus* aStatus=NULL); + static void CancelDebugSession(CSessionFs* aSession, TRequestStatus* aStatus=NULL); + static void CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus=NULL); + static void CancelSession(CSessionFs* aSession); + static TBool HandlePendingDismount(CSessionFs* aSession, TInt aDriveNumber); + static TBool IsChangeQueEmpty(TInt aDrive); + static TBool IsDiskSpaceQueEmpty(TInt aDrive); +private: + static TInt ChangeIndex(TInt aDrive); +private: + static TChangeQue iChangeQues[KMaxNotifyQues]; + static TDiskSpaceQue iDiskSpaceQues[KMaxDiskQues]; + static TDebugQue iDebugQue; + static TDismountNotifyQue iDismountNotifyQue; + }; + +class CObjPromotion : public CFsObject + { +public: + TInt UniqueID() const {return(CFsObject::UniqueID());} + }; + +NONSHARABLE_CLASS(CKernEventNotifier) : public CActive + { +public: + static CKernEventNotifier* New(TInt aPriority=EPriorityStandard); + ~CKernEventNotifier(); + void Start(); + inline TInt Change() const {return iChange;} +private: + CKernEventNotifier(TInt aPriority) : CActive(aPriority) {} + void RunL(); + void DoCancel(); +private: + static TInt LocaleChangeCallback(TAny* aPtr=NULL); + TInt FreeMemoryChangeCallback(); +private: + TInt iChange; + RChangeNotifier iChangeNotifier; + }; + +#if defined(_LOCKABLE_MEDIA) + +class TDelayedWriterInit + { +public: + const TDesC *iFileName; + const TDesC8 *iData; + const TDesC *iSemName; + }; + + +class TDelayedWriter + { +public: + TDelayedWriter(); + ~TDelayedWriter(); + + static TDelayedWriter *NewL(const TDelayedWriterInit *dwi); + void ConstructL(const TDelayedWriterInit *dwi); + + HBufC *iFileName; + HBufC8 *iData; + }; + +#endif + +extern CFsObjectConIx* TheContainer; +extern CFsObjectCon* FileSystems; +extern CFsObjectCon* Files; +extern CFsObjectCon* FileShares; +extern CFsObjectCon* Dirs; +extern CFsObjectCon* Formats; +extern CFsObjectCon* RawDisks; +extern CFsObjectCon* Extensions; +extern CFsObjectCon* ProxyDrives; + +extern CKernEventNotifier* TheKernEventNotifier; + +extern RThread TheServerThread; +extern RAllocator* ServerThreadAllocator; + +extern CServerFs* TheFileServer; + +extern HBufC* TheDriveNames[]; +extern TDrive TheDrives[KMaxDrives]; +extern TFileName TheDefaultPath; +extern RFTrace TheFtrace; + +extern SCapabilitySet AllCapabilities; +extern SCapabilitySet DisabledCapabilities; + +const TInt KDispatchObjectClose=KMaxTInt-1; +const TInt KSessionDisconnect=KMaxTInt-2; +const TInt KCancelSession=KMaxTInt-3; +const TInt KCancelPlugin=KMaxTInt-4; +const TInt KFileShareClose=KMaxTInt-5; +const TInt KFlushDirtyData=KMaxTInt-6; + +const TOperation DispatchObjectCloseOp= {KDispatchObjectClose, EInternalRequest, &TFsCloseObject::Initialise, NULL, &TFsCloseObject::DoRequestL }; +const TOperation SessionDisconnectOp= {KSessionDisconnect, EInternalRequest, &TFsSessionDisconnect::Initialise, NULL, &TFsSessionDisconnect::DoRequestL }; +const TOperation CancelSessionOp= {KCancelSession, EInternalRequest, &TFsCancelSession::Initialise, NULL, &TFsCancelSession::DoRequestL }; +const TOperation CancelPluginOp= {KCancelPlugin, EInternalRequest, &TFsCancelPlugin::Initialise, NULL, &TFsCancelPlugin::DoRequestL }; +const TOperation FileShareCloseOp= {KFileShareClose, EInternalRequest, &TFsCloseFileShare::Initialise, NULL, &TFsCloseFileShare::DoRequestL }; +const TOperation FlushDirtyDataOp= {KFlushDirtyData, EInternalRequest, &TFsFlushDirtyData::Initialise, NULL, &TFsFlushDirtyData::DoRequestL }; + +extern TBool OpenOnDriveZOnly; +extern TBool LocalFileSystemInitialized; +extern TBool StartupInitCompleted; +extern TBool RefreshZDriveCache; +extern TBool CompFsMounted; +extern TBool CompFsSync; + + TInt InitializeLocalFileSystem(const TDesC& aName); + void InstallRomFileSystemL(); + void InstallFatFileSystemL(); + TInt InstallFileSystem(CFileSystem* aSys,RLibrary aLib); + + TInt LoadFileSystem(const TDesC& aName); + + CFsObject* SessionObjectFromHandle(TInt aHandle,TInt aUniqueID, CSessionFs* aSession); + CFileShare* GetShareFromHandle(CSessionFs* aSession, TInt aHandle); + + TInt ValidateDrive(TInt aDriveNumber,CFsRequest* aRequest); + TInt ValidateDriveDoSubst(TInt aDriveNumber,CFsRequest* aRequest); + void ValidateAtts(TUint anEntryAtt,TUint& aSetAttMask,TUint& aClearAttMask); + TInt ParseSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath = ETrue); + TInt ParseNoWildSubstPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath = ETrue); + TInt ParseNoWildSubstPtr1(CFsRequest* aRequest,TParse& aParse); + TInt ParseNoWildSubstCheckPtr0(CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath = ETrue); + TInt ParseNoWildSubstCheckPtr1(CFsRequest* aRequest,TParse& aParse); + TInt ParseNoWildSubstFileCheckPtr1(CFsRequest* aRequest,TParse& aParse); + TInt ParseNoWildSubstCheckPathPtr0(CFsRequest* aRequest,TParse& aParse); + TInt ParseNoWildSubstCheckPathPtr1(CFsRequest* aRequest,TParse& aParse); + TInt ParsePathPtr0(CFsRequest* aRequest,TParse& aParse); + TInt ParseNotificationPath(CFsRequest* aRequest, TParse& aParse, TDes& aNotifyPath); + TBool IsIllegalFullName(const TDesC& aName); + TBool IsIllegalFullName(const TParse& aParse); + void AddResource(CMountCB& aMount); + void RemoveResource(CMountCB& aMount); + void AddDiskAccess(CMountCB& aMount); + void RemoveDiskAccess(CMountCB& aMount); + void NextInPath(const TDesC& aPath,TPtrC& anEntry,TInt& aPos); + TBool PowerOk(); + void Get16BitDllName(TDes& aFileName, const TDesC8& aDllName); + void Get8BitDllName(TDes8& aDllName, const TDesC& aFileName); + TInt MatchUidType(const TUidType &aMatch, const TUidType &aType); + TBool IsWriteFunction(TInt aFunction); + TInt InitLoader(); + TInt CheckDiskSpace(TInt64 aThreshold, CFsRequest* aRequest); + void CheckForLeaveAfterOpenL(TInt leaveError, CFsRequest* aRequest, TInt aHandle); + TInt ParseSubst(const TInt aP, CFsRequest* aRequest,TParse& aParse, TBool aUseSessionPath = ETrue); + +//#ifdef __DATA_CAGING__ + + TBool CompareResource(const TDesC & aThePath); + +#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__ + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const char* aDiag); + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, const char* aDiag); + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath,const TSecurityPolicy* aCap, const char* aDiag, TBool aExactMatchAllowed = EFalse); +#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__ + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, OnlyCreateWithNull aDiag); + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath, const TSecurityPolicy* aSysCap, const TSecurityPolicy* aPriCap, const TSecurityPolicy* aROCap, OnlyCreateWithNull aDiag); + TInt PathCheck(CFsRequest* aRequest, const TDesC& aThePath,const TSecurityPolicy* aCap, OnlyCreateWithNull aDiag, TBool aExactMatchAllowed = EFalse); +#endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__ + + TBool ComparePrivate(const TDesC & aThePath); + TBool CompareSystem(const TDesC & aThePath); + TBool SIDCheck(CFsRequest* aRequest, const TDesC& aThePath); + TBool ComparePaths(const TDesC& aPath1,const TDesC& aPath2); + TUint32 CalcNameHash(const TDesC& aName); + +const TInt KResourceLength = 9; +const TInt KSystemLength = 4; +const TInt KPrivateLength = 8; +const TInt KPrivateLengthCheck = 17; +const TInt KSIDLength = 8; +const TInt KSIDPathOffset = 9; + +_LIT(KSlash, "\\"); +_LIT(KPrivate,"\\Private"); +_LIT(KPrivateSlash,"\\Private\\"); +_LIT(KSysHash,"?:\\Sys\\Hash\\"); +const TInt KBSlash='\\'; +const TInt KHashFileReadSize = 1024*8; + + +const TInt KMsgPtr0 = 0; +const TInt KMsgPtr1 = 1; +const TInt KMsgPtr2 = 2; +const TInt KMsgPtr3 = 3; + +const TInt KIpcFunctionMask = 0x0000ffff; +const TInt KIpcFlagMask = 0xffff0000; +const TInt KIpcFlagOffset = 16; + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + void PrintStartUpReason(TMachineStartupType aReason); + TPtrC GetFunctionName(TInt aFunction); + void SimulateAllocFailure(TInt aFunctionReturnValue,TInt aFunction); + +extern TInt ErrorCondition; +extern TInt ErrorCount; +extern TUint32 DebugReg; +extern TInt UserHeapAllocFailCount; +extern TInt KernHeapAllocFailCount; +extern TInt MessageCount; + +void PrintHeapSize(const TDesC& aMessage); + +extern TCorruptNameRec* gCorruptFileNameList; +extern TCorruptLogRec* gCorruptLogRecordList; +extern TInt gNumberOfCorruptHits; +extern HBufC* gCorruptFileNamesListFile; +#endif + +typedef TPckgBuf TMediaPswdReplyNotifyInfoV1Buf; + +#if defined(__WINS__) + TInt MapWindowsFileName(TDes& aBuffer,const TDesC& aFileName); +#endif + +enum TDllFindMethod {EFindInPath, EFindInSystemLibs, EFindInSystemBin, EFindExhausted}; + +//--------------------------------------------------------------------------------------------------------------------- + +NONSHARABLE_CLASS(CFileBody) : public CBase, public CFileCB::MExtendedFileInterface + { +protected: + ~CFileBody(); + CFileBody(CFileCB* aFileCB, CFileCB::MExtendedFileInterface* aExtendedFileInterface); + void InitL(); + + TBool ExtendedFileInterfaceSupported(); + + // from MExtendedFileInterface + virtual void ReadL(TInt64 aPos,TInt& aLength,TDes8* aDes,const RMessagePtr2& aMessage, TInt aOffset = 0); + virtual void WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aDes,const RMessagePtr2& aMessage, TInt aOffset = 0); + virtual void SetSizeL(TInt64 aSize); + + +private: + CFileCB* iFileCB; + CFileCB::MExtendedFileInterface* iExtendedFileInterface; + TInt iFairSchedulingLen; + TBool iNotifyAsyncReadersPending; + TBool iDeleteOnClose; + +protected: + TInt iPromotedShares; + RArray* iAsyncReadRequests; + CFileCache* iFileCache; // pointer to owner CFileCache + TBool iLocalBufferSupport; + + /** + maximum file size supported by the filesystem that instantiates the CFileCB, associated with this object. + For example, FAT32 supports files not larger than 4GB-1. Other file systems can support larger files. + This member allows file server to know maximum allowed position in the file. + The default value is KMaxTUint64 + */ + TUint64 iMaxSupportedFileSize; + +public: + // Provides support for large file size ( file size > 4GB - 1) + // Upper / High 32 bit word of the file size is saved here. + // This can be non-zero only if the CFileShare::iMode is ORed with EFileBigFile + // and the file size is > 4GB - 1. + // This shall be queried by CFileCB::Size64() from file systems or by direct access from file server + // This shall be updated by CFileCB::SetSize64() from file systems or by direct access from file server. + TUint iSizeHigh; + +protected: +friend class CFileCB; +friend class CFileCache; + }; + +//--------------------------------------------------------------------------------------------------------------------- + +NONSHARABLE_CLASS(CMountBody) : public CBase, public CMountCB::MFileAccessor, public CMountCB::MFileExtendedInterface + { +protected: + CMountBody(CMountCB* aMountCB, CMountCB::MFileAccessor* aFileAccessor = NULL, CMountCB::MFileExtendedInterface* aFileInterface = NULL); + ~CMountBody(); + + // Clamping support + TInt ClampFile(const TInt aDriveNo,const TDesC& aName,TAny* aHandle); + TInt UnclampFile(RFileClamp* aHandle); + TInt IsFileClamped(const TInt64 aUniqueId); + TInt NoOfClamps(); + + // Internal support clamping + static TInt CompareClampsByIdAndCount(const RFileClamp& aClampA, const RFileClamp& aClampB); + static TInt CompareClampsById(const RFileClamp& aClampA, const RFileClamp& aClampB); + static TInt FindClampByIdAndCount(const RFileClamp& aClampA, const RFileClamp& aClampB); + static TInt FindClampById(const RFileClamp& aClampA, const RFileClamp& aClampB); + + // from MFileAccessor + virtual TInt GetFileUniqueId(const TDesC& aName, TInt64& aUniqueId); + virtual TInt Spare3(TInt aVal, TAny* aPtr1, TAny* aPtr2); + virtual TInt Spare2(TInt aVal, TAny* aPtr1, TAny* aPtr2); + virtual TInt Spare1(TInt aVal, TAny* aPtr1, TAny* aPtr2); + + // From MFileExtendedInterface + virtual void ReadSection64L(const TDesC& aName, TInt64 aPos, TAny* aTrg, TInt aLength, const RMessagePtr2& aMessage); + + void SetProxyDriveDismounted(); + TBool ProxyDriveDismounted(); + + + inline CFileSystem* GetFileSystem() const; + inline void SetFileSystem(CFileSystem* aFsys); + +private: + CMountCB* iMountCB; + RArray iClampIdentifiers; + TInt32 iClampCount; + CMountCB::MFileAccessor* iFileAccessor; + CMountCB::MFileExtendedInterface* iFileExtendedInterface; + TBool iProxyDriveDismounted; + CFileSystem* iFSys; ///< link to the FileSystem object that has produced the mount (iMountCB) +friend class CMountCB; + }; + + +#include "sf_ops.h" +#include "sf_std.inl" + + +#endif //SF_STD_H