--- a/kernel/eka/bmarm/elocdu.def Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/bmarm/elocdu.def Fri Apr 23 22:20:31 2010 +0100
@@ -52,4 +52,19 @@
GetNextPhysicalAddress__14TLocDrvRequestRUlRi @ 51 NONAME R3UNUSED ; TLocDrvRequest::GetNextPhysicalAddress(unsigned long &, int &)
RegisterDmaDevice__6LocDrvP17DPrimaryMediaBaseiii @ 52 NONAME ; LocDrv::RegisterDmaDevice(DPrimaryMediaBase *, int, int, int)
ReadFromPageHandler__14TLocDrvRequestPvii @ 53 NONAME ; TLocDrvRequest::ReadFromPageHandler(void *, int, int)
+ __21DMediaDriverExtensioni @ 54 NONAME R3UNUSED ; DMediaDriverExtension::DMediaDriverExtension(int)
+ Close__21DMediaDriverExtension @ 55 NONAME R3UNUSED ; DMediaDriverExtension::Close(void)
+ DoDrivePartitionInfo__21DMediaDriverExtensionR14TPartitionInfo @ 56 NONAME R3UNUSED ; DMediaDriverExtension::DoDrivePartitionInfo(TPartitionInfo &)
+ ForwardRequest__21DMediaDriverExtensionR14TLocDrvRequest @ 57 NONAME R3UNUSED ; DMediaDriverExtension::ForwardRequest(TLocDrvRequest &)
+ MediaBusy__21DMediaDriverExtensioni @ 58 NONAME R3UNUSED ; DMediaDriverExtension::MediaBusy(int)
+ NotifyEmergencyPowerDown__21DMediaDriverExtension @ 59 NONAME R3UNUSED ; DMediaDriverExtension::NotifyEmergencyPowerDown(void)
+ NotifyPowerDown__21DMediaDriverExtension @ 60 NONAME R3UNUSED ; DMediaDriverExtension::NotifyPowerDown(void)
+ Read__21DMediaDriverExtensionixUlUi @ 61 NONAME ; DMediaDriverExtension::Read(int, long long, unsigned long, unsigned int)
+ Write__21DMediaDriverExtensionixUlUi @ 62 NONAME ; DMediaDriverExtension::Write(int, long long, unsigned long, unsigned int)
+ "_._21DMediaDriverExtension" @ 63 NONAME R3UNUSED ; DMediaDriverExtension::~DMediaDriverExtension(void)
+ Caps__21DMediaDriverExtensioniR5TDes8 @ 64 NONAME R3UNUSED ; DMediaDriverExtension::Caps(int, TDes8 &)
+ SetTotalSizeInBytes__12DMediaDriverR17TLocalDriveCapsV4 @ 65 NONAME R3UNUSED ; DMediaDriver::SetTotalSizeInBytes(TLocalDriveCapsV4 &)
+ ReadPaged__21DMediaDriverExtensionixUlUi @ 66 NONAME ; DMediaDriverExtension::ReadPaged(int, long long, unsigned long, unsigned int)
+ WritePaged__21DMediaDriverExtensionixUlUi @ 67 NONAME ; DMediaDriverExtension::WritePaged(int, long long, unsigned long, unsigned int)
+ Caps__11DLocalDriveiR5TDes8 @ 68 NONAME R3UNUSED ; DLocalDrive::Caps(int, TDes8 &)
--- a/kernel/eka/bwins/elocdu.def Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/bwins/elocdu.def Fri Apr 23 22:20:31 2010 +0100
@@ -49,4 +49,17 @@
?Set@TPartitionTableScanner@@QAEXPAEPAVTPartitionEntry@@H_J@Z @ 48 NONAME ; public: void __thiscall TPartitionTableScanner::Set(unsigned char *,class TPartitionEntry *,int,__int64)
?GetNextPhysicalAddress@TLocDrvRequest@@QAEHAAKAAH@Z @ 49 NONAME ; int TLocDrvRequest::GetNextPhysicalAddress(unsigned long &, int &)
?RegisterDmaDevice@LocDrv@@SAHPAVDPrimaryMediaBase@@HHH@Z @ 50 NONAME ; int LocDrv::RegisterDmaDevice(class DPrimaryMediaBase *, int, int, int)
+ ??0DMediaDriverExtension@@QAE@H@Z @ 51 NONAME ; public: __thiscall DMediaDriverExtension::DMediaDriverExtension(int)
+ ??1DMediaDriverExtension@@UAE@XZ @ 52 NONAME ; public: virtual __thiscall DMediaDriverExtension::~DMediaDriverExtension(void)
+ ?Caps@DMediaDriverExtension@@QAEHHAAVTDes8@@@Z @ 53 NONAME ; public: int __thiscall DMediaDriverExtension::Caps(int,class TDes8 &)
+ ?Close@DMediaDriverExtension@@UAEXXZ @ 54 NONAME ; public: virtual void __thiscall DMediaDriverExtension::Close(void)
+ ?DoDrivePartitionInfo@DMediaDriverExtension@@QAEHAAVTPartitionInfo@@@Z @ 55 NONAME ; public: int __thiscall DMediaDriverExtension::DoDrivePartitionInfo(class TPartitionInfo &)
+ ?ForwardRequest@DMediaDriverExtension@@QAEHAAVTLocDrvRequest@@@Z @ 56 NONAME ; public: int __thiscall DMediaDriverExtension::ForwardRequest(class TLocDrvRequest &)
+ ?MediaBusy@DMediaDriverExtension@@QAEHH@Z @ 57 NONAME ; public: int __thiscall DMediaDriverExtension::MediaBusy(int)
+ ?NotifyEmergencyPowerDown@DMediaDriverExtension@@UAEXXZ @ 58 NONAME ; public: virtual void __thiscall DMediaDriverExtension::NotifyEmergencyPowerDown(void)
+ ?NotifyPowerDown@DMediaDriverExtension@@UAEXXZ @ 59 NONAME ; public: virtual void __thiscall DMediaDriverExtension::NotifyPowerDown(void)
+ ?Read@DMediaDriverExtension@@QAEHH_JKI@Z @ 60 NONAME ; public: int __thiscall DMediaDriverExtension::Read(int,__int64,unsigned long,unsigned int)
+ ?SetTotalSizeInBytes@DMediaDriver@@QAEXAAVTLocalDriveCapsV4@@@Z @ 61 NONAME ; public: void __thiscall DMediaDriver::SetTotalSizeInBytes(class TLocalDriveCapsV4 &)
+ ?Write@DMediaDriverExtension@@QAEHH_JKI@Z @ 62 NONAME ; public: int __thiscall DMediaDriverExtension::Write(int,__int64,unsigned long,unsigned int)
+ ?Caps@DLocalDrive@@SAHHAAVTDes8@@@Z @ 63 NONAME ; public: static int __cdecl DLocalDrive::Caps(int,class TDes8 &)
--- a/kernel/eka/bx86/elocdu.def Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/bx86/elocdu.def Fri Apr 23 22:20:31 2010 +0100
@@ -52,4 +52,19 @@
?GetNextPhysicalAddress@TLocDrvRequest@@QAEHAAKAAH@Z @ 51 NONAME ; public: int __thiscall TLocDrvRequest::GetNextPhysicalAddress(unsigned long &,int &)
?RegisterDmaDevice@LocDrv@@SAHPAVDPrimaryMediaBase@@HHH@Z @ 52 NONAME ; public: static int __cdecl LocDrv::RegisterDmaDevice(class DPrimaryMediaBase *,int,int,int)
?ReadFromPageHandler@TLocDrvRequest@@QAEHPAXHH@Z @ 53 NONAME ; public: int __thiscall TLocDrvRequest::ReadFromPageHandler(void *,int,int)
+ ??0DMediaDriverExtension@@QAE@H@Z @ 54 NONAME ; public: __thiscall DMediaDriverExtension::DMediaDriverExtension(int)
+ ??1DMediaDriverExtension@@UAE@XZ @ 55 NONAME ; public: virtual __thiscall DMediaDriverExtension::~DMediaDriverExtension(void)
+ ?Caps@DMediaDriverExtension@@QAEHHAAVTDes8@@@Z @ 56 NONAME ; public: int __thiscall DMediaDriverExtension::Caps(int,class TDes8 &)
+ ?Close@DMediaDriverExtension@@UAEXXZ @ 57 NONAME ; public: virtual void __thiscall DMediaDriverExtension::Close(void)
+ ?DoDrivePartitionInfo@DMediaDriverExtension@@QAEHAAVTPartitionInfo@@@Z @ 58 NONAME ; public: int __thiscall DMediaDriverExtension::DoDrivePartitionInfo(class TPartitionInfo &)
+ ?ForwardRequest@DMediaDriverExtension@@QAEHAAVTLocDrvRequest@@@Z @ 59 NONAME ; public: int __thiscall DMediaDriverExtension::ForwardRequest(class TLocDrvRequest &)
+ ?MediaBusy@DMediaDriverExtension@@QAEHH@Z @ 60 NONAME ; public: int __thiscall DMediaDriverExtension::MediaBusy(int)
+ ?NotifyEmergencyPowerDown@DMediaDriverExtension@@UAEXXZ @ 61 NONAME ; public: virtual void __thiscall DMediaDriverExtension::NotifyEmergencyPowerDown(void)
+ ?NotifyPowerDown@DMediaDriverExtension@@UAEXXZ @ 62 NONAME ; public: virtual void __thiscall DMediaDriverExtension::NotifyPowerDown(void)
+ ?Read@DMediaDriverExtension@@QAEHH_JKI@Z @ 63 NONAME ; public: int __thiscall DMediaDriverExtension::Read(int,__int64,unsigned long,unsigned int)
+ ?Write@DMediaDriverExtension@@QAEHH_JKI@Z @ 64 NONAME ; public: int __thiscall DMediaDriverExtension::Write(int,__int64,unsigned long,unsigned int)
+ ?SetTotalSizeInBytes@DMediaDriver@@QAEXAAVTLocalDriveCapsV4@@@Z @ 65 NONAME ; public: void __thiscall DMediaDriver::SetTotalSizeInBytes(class TLocalDriveCapsV4 &)
+ ?ReadPaged@DMediaDriverExtension@@QAEHH_JKI@Z @ 66 NONAME ; public: int __thiscall DMediaDriverExtension::ReadPaged(int,__int64,unsigned long,unsigned int)
+ ?WritePaged@DMediaDriverExtension@@QAEHH_JKI@Z @ 67 NONAME ; public: int __thiscall DMediaDriverExtension::WritePaged(int,__int64,unsigned long,unsigned int)
+ ?Caps@DLocalDrive@@SAHHAAVTDes8@@@Z @ 68 NONAME ; public: static int __cdecl DLocalDrive::Caps(int,class TDes8 &)
--- a/kernel/eka/drivers/locmedia/dmasupport.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/locmedia/dmasupport.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -278,7 +278,7 @@
TInt r;
do
{
- __KTRACE_DMA(Kern::Printf(">PHYSADDR:SendReceive() iReqLen %d; iLenConsumed %d; fragments %d",iReqLen, iLenConsumed, fragments));
+ __KTRACE_DMA(Kern::Printf(">PHYSADDR:SendReceive() iReqLen %d; iLenConsumed %d; fragments %d",iReqLenClient, iLenConsumed, fragments));
OstTraceExt2( TRACE_DMASUPPORT, DDMAHELPER_SENDRECEIVE1, "PHYSADDR:SendReceive() iLenConsumed=%d; fragments=%d", iLenConsumed, fragments);
r = RequestStart();
if (r != KErrNone)
--- a/kernel/eka/drivers/locmedia/locmedia.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/locmedia/locmedia.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -71,6 +71,9 @@
class DPrimaryMediaBase::DBody : public DBase
{
public:
+ DBody(DPrimaryMediaBase& aPrimaryMediaBase);
+public:
+ DPrimaryMediaBase& iPrimaryMediaBase; // ptr to parent
TInt iPhysDevIndex;
TInt iRequestCount;
#ifdef __DEMAND_PAGING__
@@ -78,12 +81,24 @@
TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095)
TInt iMediaChanges;
#endif
+
+ // This bit mask indicates which local drives the media is attached to
+ TUint32 iRegisteredDriveMask;
+
+ // Set to ETrue for media extension drivers
+ TBool iMediaExtension;
+
+ // Media change DFCs to allow media change events from attached media
+ // to be handled in the context of an extension media's thread
+ TDfc iMediaChangeDfc;
+ TDfc iMediaPresentDfc;
};
#ifdef __DEMAND_PAGING__
DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives];
DPrimaryMediaBase* TheRomPagingMedia = NULL;
DPrimaryMediaBase* TheDataPagingMedia = NULL;
+TLocDrv* TheDataPagingDrive = NULL;
TBool DataPagingDeviceRegistered = EFalse;
class DPinObjectAllocator;
DPinObjectAllocator* ThePinObjectAllocator = NULL;
@@ -92,10 +107,29 @@
// In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks:
inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
{return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
+
+
+TBool DataPagingMedia(DPrimaryMediaBase* aPrimaryMedia)
+ {
+ for (TLocDrv* drv = TheDataPagingDrive; drv; drv = drv->iNextDrive)
+ if (drv->iPrimaryMedia == aPrimaryMedia)
+ return ETrue;
+ return EFalse;
+ }
+
inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
{return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
+#if defined(_DEBUG)
+ #define SETDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] |= (1 << (aBitNum & 31));}
+ #define CLRDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] &= ~(1 << (aBitNum & 31));}
+#else
+ #define SETDEBUGFLAG(aBitNum)
+ #define CLRDEBUGFLAG(aBitNum)
+#endif
+
+
/*
DPinObjectAllocator
@@ -104,6 +138,7 @@
(1) a queue of pre-allocated TVirtualPinObject's;
(2) a single pre-allocated DFragmentationPagingLock object:
this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails
+@internalTechnology
*/
NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase
{
@@ -157,7 +192,7 @@
delete iPreAllocatedDataLock;
}
- for (TInt n=0; n<iObjectCount; n++)
+ for (TInt n=0; iVirtualPinContainers!= NULL && n<iObjectCount; n++)
{
SVirtualPinContainer& virtualPinContainer = iVirtualPinContainers[n];
if (virtualPinContainer.iObject)
@@ -192,7 +227,7 @@
}
- SVirtualPinContainer* iVirtualPinContainers = new SVirtualPinContainer[aObjectCount];
+ iVirtualPinContainers = new SVirtualPinContainer[aObjectCount];
if (iVirtualPinContainers == NULL)
{
OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT3, this, KErrNoMemory );
@@ -260,6 +295,98 @@
#endif // __DEMAND_PAGING__
+/*
+TDriveIterator
+
+Internal class which supports iterating through all local drives (TLocDrv's)
+If there are media extensions present, then this will iterate through all attached drives.
+@internalTechnology
+*/
+class TDriveIterator
+ {
+public:
+ TDriveIterator();
+ TLocDrv* NextDrive();
+ inline TInt Index()
+ {return iIndex;}
+ static TLocDrv* GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia);
+ static TLocDrv* GetPhysicalDrive(TLocDrv* aDrv);
+
+#if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
+ static DMediaPagingDevice* PagingDevice(TInt aDriveNum, DPagingDevice::TType aType);
+#endif
+
+private:
+ TInt iIndex;
+ TLocDrv* iDrive;
+ };
+
+TDriveIterator::TDriveIterator() :
+ iIndex(0), iDrive(NULL)
+ {
+ }
+
+TLocDrv* TDriveIterator::NextDrive()
+ {
+ if (iDrive) // i.e. if not first time
+ {
+ if (iDrive->iNextDrive)
+ {
+ iDrive = iDrive->iNextDrive;
+ return iDrive;
+ }
+ iIndex++;
+ }
+
+ for (iDrive = NULL; iIndex < KMaxLocalDrives; iIndex++)
+ {
+ iDrive = TheDrives[iIndex];
+ if (iDrive)
+ break;
+ }
+
+ return iDrive;
+ }
+
+/*
+Returns the first TLocDrv in the chain of attached drives which matches DPrimaryMediaBase
+*/
+TLocDrv* TDriveIterator::GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia)
+ {
+ TLocDrv* drive = TheDrives[aDriveNum];
+ while (drive && drive->iPrimaryMedia != aPrimaryMedia)
+ {
+ drive = drive->iNextDrive ? drive->iNextDrive : NULL;
+ }
+ return drive;
+ }
+
+/*
+Returns the last TLocDrv in the chain of attached drives -
+i.e. the TLocDrv attached to physical media rather than a TLocDrv corresponding to a media extension
+*/
+TLocDrv* TDriveIterator::GetPhysicalDrive(TLocDrv* aDrv)
+ {
+ __ASSERT_DEBUG(aDrv, LOCM_FAULT());
+ while (aDrv->iNextDrive)
+ aDrv = aDrv->iNextDrive;
+ return aDrv;
+ }
+
+#if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
+DMediaPagingDevice* TDriveIterator::PagingDevice(TInt aDriveNum, DPagingDevice::TType aType)
+ {
+ TLocDrv* drive = TheDrives[aDriveNum];
+ DMediaPagingDevice* pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL;
+ while (drive && (pagingDevice == NULL || (pagingDevice->iType & aType) == 0))
+ {
+ drive = drive->iNextDrive ? drive->iNextDrive : NULL;
+ pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL;
+ }
+ return pagingDevice;
+ }
+#endif
+
/********************************************
* Local drive device base class
********************************************/
@@ -312,7 +439,8 @@
/********************************************
* Local drive interface class
********************************************/
-DLocalDrive::DLocalDrive()
+DLocalDrive::DLocalDrive() :
+ iMediaChangeObserver(MediaChangeCallback, this, TCallBackLink::EDLocalDriveObject)
{
// iLink.iNext=NULL;
}
@@ -489,42 +617,6 @@
m.Length()=KMaxLocalDriveCapsLength; // for pinning
r=iDrive->Request(m);
- if(r == KErrNone && iDrive->iMedia != NULL && iDrive->iMedia->iDriver != NULL)
- {
- // Fill in default media size if not specified by the driver
- //
- // - This uses the members of TLocalDriveCapsV4 which was primarily used
- // to report NAND flash characteristics, but are general enough to be
- // used to report the size of any type of media without adding yet
- // another extension to TLocalDriveCapsVx.
- //
-
- TLocalDriveCapsV4& caps = *(TLocalDriveCapsV4*)capsBuf.Ptr();
-
- if(caps.iSectorSizeInBytes == 0)
- {
- // Fill in a default value for the disk sector size
- caps.iSectorSizeInBytes = 512;
-
- // Zero the number of sectors, as a sector count makes no sense without a sector size
- // - Fault in debug mode if a sector count is provided to ensure that media driver creators
- // set this value,but in release mode continue gracefully be recalculating the sector count.
- __ASSERT_DEBUG(caps.iNumberOfSectors == 0, LOCM_FAULT());
- caps.iNumberOfSectors = 0;
- caps.iNumPagesPerBlock = 1; // ...to ensure compatiility with NAND semantics
- }
-
- if(caps.iNumberOfSectors == 0)
- {
- const Int64 totalSizeInSectors = iDrive->iMedia->iDriver->TotalSizeInBytes() / caps.iSectorSizeInBytes;
- __ASSERT_DEBUG(I64HIGH(totalSizeInSectors) == 0, LOCM_FAULT());
-
- if(I64HIGH(totalSizeInSectors) == 0)
- {
- caps.iNumberOfSectors = I64LOW(totalSizeInSectors);
- }
- }
- }
#if defined(OST_TRACE_COMPILER_IN_USE) && defined(_DEBUG)
const TLocalDriveCapsV5& caps=*(const TLocalDriveCapsV5*)capsBuf.Ptr();
@@ -593,7 +685,11 @@
{
OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLISREMOVABLE, "EControlIsRemovable; TLocDrvRequest Object=0x%x", (TUint) &m);
TInt sockNum;
- r=iDrive->iPrimaryMedia->IsRemovableDevice(sockNum);
+
+ // Pass request on to last chained drive
+ TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive);
+ r = drv->iPrimaryMedia->IsRemovableDevice(sockNum);
+
if (r)
kumemput32(a1,&sockNum,sizeof(TInt));
break;
@@ -636,7 +732,11 @@
OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLSETMOUNTINFO, "EControlSetMountInfo; TLocDrvRequest Object=0x%x", (TUint) &m);
m.Id()=ERead;
r=m.ProcessMessageData(a1);
- DPrimaryMediaBase* pM=iDrive->iPrimaryMedia;
+
+ // Pass request on to last chained drive
+ TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive);
+ DPrimaryMediaBase* pM = drv->iPrimaryMedia;
+
if(!pM || r!=KErrNone)
break;
@@ -874,11 +974,15 @@
TBuf8<KMaxQueryDeviceLength> queryBuf;
queryBuf.SetMax();
queryBuf.FillZ();
-
+
+ DThread* pT = m.Client();
+ r = Kern::ThreadDesRead(pT, (TDes8*)a2, queryBuf, 0 ,KChunkShiftBy0);
+
+ queryBuf.SetMax();
m.Id() = EQueryDevice;
- m.iArg[0] = a1; // RLocalDrive::TQueryDevice
+ m.iArg[0] = a1; // RLocalDrive::TQueryDevice
m.RemoteDes() = (TAny*)queryBuf.Ptr(); // overload this
- m.Length() = KMaxLocalDriveCapsLength; // for pinning
+ m.Length() = KMaxQueryDeviceLength;
OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE, "EQueryDevice; TLocDrvRequest Object=0x%x", (TUint) &m);
r=iDrive->Request(m);
OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE_RETURN, "EQueryDevice Return; TLocDrvRequest Object=0x%x", (TUint) &m);
@@ -1033,7 +1137,7 @@
OstTrace1(TRACE_FLOW, DLOCALDRIVE_UNLOCKMOUNTINFO_ENTRY, "> DLocalDrive::UnlockMountInfo;aPrimaryMedia=%x", (TUint) &aPrimaryMedia);
DMediaPagingDevice* pagingDevice = aPrimaryMedia.iBody->iPagingDevice;
- if (pagingDevice == NULL || pagingDevice->iMountInfoDataLock == NULL)
+ if (pagingDevice == NULL)
{
OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT1, this );
return;
@@ -1065,50 +1169,52 @@
}
#endif // __DEMAND_PAGING__
-void DLocalDrive::NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange)
+void DLocalDrive::NotifyChange()
{
- OstTraceExt2( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange;aPrimaryMedia=%x;aMediaChange=%d", (TUint) &aPrimaryMedia, aMediaChange );
-#ifndef __DEMAND_PAGING__
- aPrimaryMedia;
-#endif
-
- // Complete any notification request on media change or power down
- if (aMediaChange)
+ OstTrace0( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange");
+
+
+ // Complete any notification request on media change
+ DThread* pC=NULL;
+ NKern::LockSystem();
+ if (iCleanup.iThread)
{
- DThread* pC=NULL;
- NKern::LockSystem();
- if (iCleanup.iThread)
- {
- pC=iCleanup.iThread;
- pC->Open();
- }
- NKern::UnlockSystem();
- if (pC)
+ pC=iCleanup.iThread;
+ pC->Open();
+ }
+ NKern::UnlockSystem();
+ if (pC)
+ {
+ TBool b = ETrue;
+ // if change not yet queued, queue it now
+ if (iNotifyChangeRequest->IsReady())
{
- TBool b = ETrue;
- // if change not yet queued, queue it now
- if (iNotifyChangeRequest->IsReady())
- {
- *((TBool*) iNotifyChangeRequest->Buffer()) = b;
- Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone);
- }
- // If change has not even been requested by the client, maintain the pre-wdp behaviour
- // and write data immediately back to client (possibly taking a page fault)
- // N.B. Must NOT do this on data paging media
+ *((TBool*) iNotifyChangeRequest->Buffer()) = b;
+ Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone);
+ }
+ // If change has not even been requested by the client, maintain the pre-wdp behaviour
+ // and write data immediately back to client (possibly taking a page fault)
+ // N.B. Must NOT do this on data paging media
#ifdef __DEMAND_PAGING__
- else if (!DataPagingDfcQ(&aPrimaryMedia))
+ else if (!DataPagingDfcQ(iDrive->iPrimaryMedia))
#else
- else
+ else
#endif
- {
- Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL);
- }
- pC->AsyncClose();
+ {
+ Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL);
}
+ pC->AsyncClose();
}
OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this );
}
+// This function is called by the primary media when a media change occurs
+TInt DLocalDrive::MediaChangeCallback(TAny* aLocalDrive, TInt /* aNotifyType*/)
+ {
+ ((DLocalDrive*) aLocalDrive)->NotifyChange();
+ return KErrNone;
+ }
+
TLocalDriveCleanup::TLocalDriveCleanup()
{
}
@@ -1127,6 +1233,33 @@
NKern::LockSystem();
}
+
+EXPORT_C TInt DLocalDrive::Caps(TInt aDriveNumber, TDes8& aCaps)
+ {
+ if(!Kern::CurrentThreadHasCapability(ECapabilityTCB,__PLATSEC_DIAGNOSTIC_STRING("Checked by ELOCD.LDD (Local Media Driver)")))
+ {
+ return KErrPermissionDenied;
+ }
+
+
+ if (aDriveNumber >= KMaxLocalDrives)
+ return KErrArgument;
+
+ TLocDrv* drive = TheDrives[aDriveNumber];
+ if (!drive)
+ return KErrNotSupported;
+
+ TLocDrvRequest request;
+ memclr(&request, sizeof(request));
+
+ request.Drive() = drive;
+ request.Id() = DLocalDrive::ECaps;
+ request.Length() = aCaps.Length();
+ request.RemoteDes() = (TAny*) aCaps.Ptr();
+
+ return request.SendReceive(&drive->iPrimaryMedia->iMsgQ);
+ }
+
/********************************************
* Local drive request class
********************************************/
@@ -1155,6 +1288,14 @@
{
OstTraceFunctionEntry1( TLOCDRVREQUEST_READREMOTE_ENTRY, this );
TInt r;
+
+ if (Flags() & TLocDrvRequest::EKernelBuffer)
+ {
+ (void)memcpy((TAny*) aDes->Ptr(), (TAny*)((TUint32)RemoteDes()+anOffset), aDes->MaxLength());
+ aDes->SetLength(aDes->MaxLength());
+ return KErrNone;
+ }
+
DThread* pT=RemoteThread();
if (!pT)
pT=Client();
@@ -1294,6 +1435,14 @@
{
OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITEREMOTE_ENTRY, this );
TInt r;
+
+ if (Flags() & TLocDrvRequest::EKernelBuffer)
+ {
+ (void)memcpy((TAny*)((TUint32)RemoteDes()+anOffset), (TAny*) aDes->Ptr(), aDes->Length());
+ OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, KErrNone );
+ return KErrNone;
+ }
+
DThread* pC=Client();
DThread* pT=RemoteThread();
if (!pT)
@@ -1303,12 +1452,12 @@
if (Flags() & ETClientBuffer)
{
r = Kern::ThreadBufWrite(pT, (TClientBuffer*) RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
- OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, r );
+ OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r );
return r;
}
#endif
r = Kern::ThreadDesWrite(pT,RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
- OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r );
+ OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT3, this, r );
return r;
}
@@ -1489,7 +1638,7 @@
OstTraceExt2( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION6, "Read/Write request length=0x%x; position=0x%x", (TUint) Length(), (TUint) Pos() );
if (DriverFlags() & RLocalDrive::ELocDrvWholeMedia)
{
- if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iDriver->iTotalSizeInBytes)
+ if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iPartitionInfo.iMediaSizeInBytes)
{
r = KErrArgument;
break;
@@ -1519,9 +1668,22 @@
memclr(this, sizeof(TLocDrv));
iDriveNumber=aDriveNumber;
iPartitionNumber=-1;
+ iMediaChangeObserver.iFunction = MediaChangeCallback;
+ iMediaChangeObserver.iPtr= this;
+ iMediaChangeObserver.iObjectType = TCallBackLink::ETLocDrvObject;
OstTraceFunctionExit1( TLOCDRV_TLOCDRV_EXIT, this );
}
+TInt TLocDrv::MediaChangeCallback(TAny* aLocDrv, TInt aNotifyType)
+ {
+ __ASSERT_DEBUG(aNotifyType == DPrimaryMediaBase::EMediaChange || aNotifyType == DPrimaryMediaBase::EMediaPresent, LOCM_FAULT());
+ if (aNotifyType == DPrimaryMediaBase::EMediaPresent)
+ return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaPresentDfc.Enque();
+ else
+ return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaChangeDfc.Enque();
+ }
+
+
/**
Initialises the DMedia entity with the media device number and ID.
@@ -1588,6 +1750,26 @@
OstTraceFunctionExit0( _HANDLEMSG_EXIT );
}
+
+void mediaChangeDfc(TAny* aPtr)
+ {
+ DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr;
+ pM->NotifyMediaChange();
+ }
+
+void mediaPresentDfc(TAny* aPtr)
+ {
+ DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr;
+ pM->NotifyMediaPresent();
+ }
+
+DPrimaryMediaBase::DBody::DBody(DPrimaryMediaBase& aPrimaryMediaBase) :
+ iPrimaryMediaBase(aPrimaryMediaBase),
+ iMediaChangeDfc(mediaChangeDfc, &aPrimaryMediaBase, KMaxDfcPriority),
+ iMediaPresentDfc(mediaPresentDfc, &aPrimaryMediaBase, KMaxDfcPriority)
+ {
+ }
+
EXPORT_C DPrimaryMediaBase::DPrimaryMediaBase()
: iMsgQ(handleMsg, this, NULL, 1),
iDeferred(NULL, NULL, NULL, 0), // callback never used
@@ -1627,15 +1809,18 @@
{
OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT1, this, r );
return r;
- }
- iBody = new DBody;
+ }
+ iBody = new DBody(*this);
if (iBody == NULL)
{
OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT2, this, KErrNoMemory );
return KErrNoMemory;
- }
-
-
+ }
+ if (iDfcQ)
+ {
+ iBody->iMediaChangeDfc.SetDfcQ(iDfcQ);
+ iBody->iMediaPresentDfc.SetDfcQ(iDfcQ);
+ }
#ifdef __DEMAND_PAGING__
TInt pageSize = Kern::RoundToPageSize(1);
@@ -1697,7 +1882,7 @@
NKern::LockSystem();
TBool first=iConnectionQ.IsEmpty();
- iConnectionQ.Add(&aLocalDrive->iLink);
+ iConnectionQ.Add(&aLocalDrive->iMediaChangeObserver.iLink);
NKern::UnlockSystem();
if (first)
{
@@ -1765,6 +1950,52 @@
OstTraceFunctionExit1( DPRIMARYMEDIABASE_DISCONNECT_EXIT2, this );
}
+
+/**
+Connects a TLocDrv containing a media extension to the next primary media in the chain
+*/
+TInt DPrimaryMediaBase::Connect(TLocDrv* aLocDrv)
+ {
+ TInt r = KErrNone;
+
+ NKern::LockSystem();
+ TBool first = iConnectionQ.IsEmpty();
+ iConnectionQ.Add(&aLocDrv->iMediaChangeObserver.iLink);
+ NKern::UnlockSystem();
+
+ if (first && !iDfcQ)
+ {
+ r = OpenMediaDriver();
+ if (r!=KErrNone)
+ {
+ NKern::LockSystem();
+ aLocDrv->iMediaChangeObserver.iLink.Deque();
+ NKern::UnlockSystem();
+ }
+ }
+ return r;
+ }
+
+TInt DPrimaryMediaBase::HandleMediaNotPresent(TLocDrvRequest& aReq)
+ {
+ TInt reqId = aReq.Id();
+
+ if (reqId == DLocalDrive::ECaps)
+ DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes()); // fill in stuff we know even if no media present
+
+ TInt r = QuickCheckStatus();
+ if (r != KErrNone &&
+ reqId != DLocalDrive::EForceMediaChange && // EForceMediaChange, and
+ reqId != DLocalDrive::EReadPasswordStore && // Password store operations
+ reqId != DLocalDrive::EWritePasswordStore && // do not require the media
+ reqId != DLocalDrive::EPasswordStoreLengthInBytes) // to be ready.)
+ {
+ return r;
+ }
+
+ return KErrNone;
+ }
+
EXPORT_C TInt DPrimaryMediaBase::Request(TLocDrvRequest& aReq)
/**
Issues a local drive request. It is called from TLocDrv::Request() function .
@@ -1785,7 +2016,7 @@
@see TLocDrvRequest
*/
{
-OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this );
+ OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this );
__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq));
__KTRACE_OPT(KLOCDRV,Kern::Printf("this=%x, ReqId=%d, Pos=%lx, Len=%lx, remote thread %O",this,aReq.Id(),aReq.Pos(),aReq.Length(),aReq.RemoteThread()));
@@ -1794,18 +2025,13 @@
TInt reqId = aReq.Id();
- if (reqId == DLocalDrive::ECaps)
- DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes()); // fill in stuff we know even if no media present
-
- TInt r = QuickCheckStatus();
- if (r != KErrNone && aReq.Id()!=DLocalDrive::EForceMediaChange && // EForceMediaChange, and
- aReq.Id()!=DLocalDrive::EReadPasswordStore && // Password store operations
- aReq.Id()!=DLocalDrive::EWritePasswordStore && // do not require the media
- aReq.Id()!=DLocalDrive::EPasswordStoreLengthInBytes) // to be ready.)
- {
+ TInt r = HandleMediaNotPresent(aReq);
+ if (r != KErrNone)
+ {
OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r );
return r;
- }
+ }
+
// for ERead & EWrite requests, get the linear address for pinning & DMA
@@ -2250,7 +2476,7 @@
case EConnect:
{
DLocalDrive* pD=(DLocalDrive*)m.Ptr0();
- iConnectionQ.Add(&pD->iLink);
+ iConnectionQ.Add(&pD->iMediaChangeObserver.iLink);
m.Complete(KErrNone, EFalse);
OstTraceFunctionExit1( DPRIMARYMEDIABASE_HANDLEMSG_EXIT1, this );
return;
@@ -2274,6 +2500,22 @@
{
TUint flags = (TUint) m.Pos();
+ // For media extension drivers, send a copy of the request to the next drive in the chain and wait for it.
+ TLocDrv* drv = m.Drive();
+ if (drv->iNextDrive)
+ {
+ TLocDrvRequest request;
+ request.Drive() = drv->iNextDrive;
+ request.Id() = DLocalDrive::EForceMediaChange;
+ request.Pos() = m.Pos(); // flags
+
+ request.SendReceive(&drv->iNextDrive->iPrimaryMedia->iMsgQ);
+
+ CompleteRequest(m, request.iValue);
+ return;
+ }
+
+
// if KForceMediaChangeReOpenDriver specified wait for power up,
// and then re-open this drive's media driver
__KTRACE_OPT(KLOCDRV, Kern::Printf("EForceMediaChange, flags %08X\n", flags));
@@ -2504,18 +2746,18 @@
if (m.iValue == DLocalDrive::EForceMediaChange)
{
__ASSERT_DEBUG(((TUint) m.Pos()) == (TUint) KForceMediaChangeReOpenMediaDriver, LOCM_FAULT());
-
iCurrentReq=NULL;
TLocDrv* pL = m.Drive();
DMedia* media = pL->iMedia;
+
if (media && media->iDriver)
CloseMediaDrivers(media);
iState=EOpening;
StartOpenMediaDrivers();
- NotifyClients(ETrue,pL);
+ NotifyClients(EMediaChange, pL);
CompleteRequest(m, r);
OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT, this, r );
return r;
@@ -2542,7 +2784,7 @@
if (!(m.Flags() & TLocDrvRequest::EAdjusted))
{
// If this isn't the only partition, don't allow access to the whole media
- if (iTotalPartitionsOpened > 1)
+ if (TDriveIterator::GetPhysicalDrive(m.Drive())->iPrimaryMedia->iTotalPartitionsOpened > 1)
m.DriverFlags() &= ~RLocalDrive::ELocDrvWholeMedia;
r=m.CheckAndAdjustForPartition();
}
@@ -2686,7 +2928,7 @@
// we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive
// would involve memory allocation which might cause deadlock if the kernel heap were to grow
#ifdef __DEMAND_PAGING__
- if (DataPagingDfcQ(this))
+ if (DataPagingMedia(this))
{
__KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this));
OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this);
@@ -2694,21 +2936,30 @@
}
#endif
- TInt i;
- for (i=0; i<KMaxLocalDrives; i++)
+
+ // Don't close any media extension drivers either, since it won't serve any purpose
+ // and keeping the driver open allows it to maintain internal state
+ if (iBody->iMediaExtension)
{
- TLocDrv* pL=TheDrives[i];
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for extension media %08X", this));
+ return;
+ }
+
+
+ TDriveIterator driveIter;
+ for (TLocDrv* pL = driveIter.NextDrive(); pL != NULL; pL = driveIter.NextDrive())
+ {
if (pL && pL->iPrimaryMedia==this)
{
- __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",i));
- OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", i );
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",driveIter.Index()));
+ OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", driveIter.Index());
if (aMedia == NULL || pL->iMedia == aMedia)
{
pL->iMedia=NULL;
}
}
}
- for (i=iLastMediaId; i>=iMediaId; i--)
+ for (TInt i=iLastMediaId; i>=iMediaId; i--)
{
DMedia* pM=TheMedia[i];
if (aMedia == NULL || pM == aMedia)
@@ -2865,7 +3116,7 @@
if (pM->iDriver)
{
#ifdef __DEMAND_PAGING__
- if (DataPagingDfcQ(this))
+ if (DataPagingMedia(this))
{
__KTRACE_OPT(KLOCDRV,Kern::Printf("DoPartitionInfoComplete(%d) Close Media Driver aborted for data paging media %08X", this));
OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE2, "Close Media Driver for data paging media 0x%08x", this);
@@ -2931,10 +3182,10 @@
TInt id=iMediaId; // start with primary media
TInt partitionsOnThisMedia=PartitionCount();
TInt partition=0;
- TInt j;
- for (j=0; j<KMaxLocalDrives; j++)
+
+ TDriveIterator driveIter;
+ for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive())
{
- TLocDrv* pD=TheDrives[j];
if (pD && pD->iPrimaryMedia==this)
{
if (totalPartitions==0)
@@ -2948,9 +3199,8 @@
partition=0;
partitionsOnThisMedia=TheMedia[id]->PartitionCount();
}
- __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",j,id,partition));
- OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", j, id, partition );
-
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",driveIter.Index(),id,partition));
+ OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", driveIter.Index(), id, partition );
pD->iMedia=TheMedia[id];
pD->iPartitionNumber=partition;
memcpy(pD, pD->iMedia->iPartitionInfo.iEntry+partition, sizeof(TPartitionEntry));
@@ -3216,10 +3466,10 @@
OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this );
}
-void DPrimaryMediaBase::NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv)
+void DPrimaryMediaBase::NotifyClients(TNotifyType aNotifyType, TLocDrv* aLocDrv)
//
-// Notify all clients of a media change or power-down event
+// Notify all clients of a media change or media present event
//
{
OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this );
@@ -3227,11 +3477,23 @@
SDblQueLink* pL=iConnectionQ.iA.iNext;
while (pL!=&iConnectionQ.iA)
{
- DLocalDrive* pD=_LOFF(pL,DLocalDrive,iLink);
+ // Get pointer to TCallBackLink
+ TCallBackLink* pCallBackLink = _LOFF(pL,TCallBackLink,iLink);
+
+ // The link is embedded in either a TLocDrv or a DLocalDrive object;
+ // find out which one it is and then get TLocDrv pointer from that
+ __ASSERT_DEBUG(pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject || pCallBackLink->iObjectType == TCallBackLink::ETLocDrvObject, LOCM_FAULT());
+ TLocDrv* locDrv;
+ if (pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject)
+ locDrv = ((DLocalDrive*) _LOFF(pCallBackLink,DLocalDrive, iMediaChangeObserver))->iDrive;
+ else
+ locDrv = ((TLocDrv*) _LOFF(pCallBackLink,TLocDrv, iMediaChangeObserver))->iNextDrive;
+
// Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or
// the specified drive matches this one
- if (aLocDrv == NULL || aLocDrv == pD->iDrive)
- pD->NotifyChange(*this, aMediaChange);
+ if (aLocDrv == NULL || aLocDrv == locDrv)
+ pCallBackLink->CallBack(aNotifyType);
+
pL=pL->iNext;
}
OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this );
@@ -3249,32 +3511,13 @@
OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState );
- TInt state=iState;
-
- __ASSERT_DEBUG(iBody, LOCM_FAULT());
-
-#ifdef __DEMAND_PAGING__
- iBody->iMediaChanges++;
-
- // As data paging media never close, need to ensure the media driver cancels
- // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange().
- // DMediaDriver::NotifyPowerDown() should do this
- if(DataPagingDfcQ(this))
- NotifyPowerDown();
-#endif
-
- // complete any outstanding requests with KErrNotReady
- // and any force media change requests with KErrNone
- SetClosed(KErrNotReady);
-
- // close all media drivers on this device
- if (state>=EOpening)
- {
- CloseMediaDrivers();
- }
+ // This should only be called in the context of the media thread
+ __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT());
+
+ MediaChange();
// notify all connections that media change has occurred
- NotifyClients(ETrue);
+ NotifyClients(EMediaChange);
// complete any force media change requests
iWaitMedChg.CompleteAll(KErrNone);
@@ -3343,8 +3586,6 @@
CloseMediaDrivers();
SetClosed(KErrNotReady);
}
-
- NotifyClients(EFalse);
OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYPOWERDOWN_EXIT, this );
}
@@ -3414,17 +3655,56 @@
}
CloseMediaDrivers();
SetClosed(KErrNotReady);
- NotifyClients(EFalse);
OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this );
}
+
+/**
+Called by NotifyMediaPresent() and NotifyMediaChange() to ensure the media is in the correct state
+*/
+void DPrimaryMediaBase::MediaChange()
+ {
+ // Media has been inserted, so we need to cancel any outstanding requests and
+ // ensure that the partition info is read again
+ TInt state = iState;
+
+ __ASSERT_DEBUG(iBody, LOCM_FAULT());
+
+#ifdef __DEMAND_PAGING__
+ iBody->iMediaChanges++;
+
+ // As data paging media never close, need to ensure the media driver cancels
+ // any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange().
+ // DMediaDriver::NotifyPowerDown() should do this
+ if (DataPagingMedia(this))
+ NotifyPowerDown();
+#endif
+
+ // complete any outstanding requests with KErrNotReady
+ // and any force media change requests with KErrNone
+ SetClosed(KErrNotReady);
+
+ // close all media drivers on this device
+ if (state>=EOpening)
+ {
+ CloseMediaDrivers();
+ }
+ }
+
EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent()
/**
Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present.
*/
{
OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this );
- NotifyClients(ETrue);
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaPresent state %d",iMediaId,iState));
+
+ // This should only be called in the context of the media thread
+ __ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT());
+
+ MediaChange();
+
+ NotifyClients(EMediaPresent);
OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this );
}
@@ -3575,10 +3855,10 @@
TInt id=iMediaId; // start with primary media
TInt partitionsOnThisMedia=PartitionCount();
TInt partition=0;
- TInt j;
- for (j=0; j<KMaxLocalDrives; j++)
+
+ TDriveIterator driveIter;
+ for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive())
{
- TLocDrv* pD=TheDrives[j];
if (pD && pD->iPrimaryMedia==this)
{
if (totalPartitions==0)
@@ -3939,7 +4219,7 @@
TInt retVal = KErrGeneral;
for (TInt i=0; retVal != KErrNone && i < KPageInRetries; i++)
{
- m.Flags() = TLocDrvRequest::EPaging;
+ m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging;
TLocDrv* pL=NULL;
if(aDrvNumber == EDriveRomPaging) // ROM paging
{
@@ -3978,7 +4258,7 @@
m.Id() = DMediaPagingDevice::ECodePageInRequest;
m.Flags() |= TLocDrvRequest::ECodePaging;
pL=TheDrives[aDrvNumber];
- __ASSERT_DEBUG(pL&&(pL->iPrimaryMedia==iPrimaryMedia),LOCM_FAULT()); // valid drive number?
+ __ASSERT_DEBUG(pL && TDriveIterator::GetDrive(aDrvNumber, iPrimaryMedia) ,LOCM_FAULT()); // valid drive number?
m.Drive()=pL;
#ifdef __DEMAND_PAGING_BENCHMARKS__
__e32_atomic_add_ord32(&iMediaPagingInfo.iCodePageInCount, (TUint) 1);
@@ -4101,7 +4381,7 @@
TInt retVal = KErrGeneral;
for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
{
- m.Flags() = TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging | (aBackground ? TLocDrvRequest::EBackgroundPaging : 0);
+ m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging | (aBackground ? TLocDrvRequest::EBackgroundPaging : 0);
m.Id() = DLocalDrive::EWrite;
m.Drive() = TheDrives[iDataPagingDriveNumber];
@@ -4197,7 +4477,7 @@
TLocDrvRequest& m=*(TLocDrvRequest*)(aReq);
- m.Flags() = TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging;
+ m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging;
m.Id() = DLocalDrive::EDeleteNotify;
m.Drive() = TheDrives[iDataPagingDriveNumber];
@@ -4230,7 +4510,6 @@
}
-
EXPORT_C TInt TLocDrvRequest::WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset)
{
OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITETOPAGEHANDLER_ENTRY, this );
@@ -4418,6 +4697,28 @@
OstTraceFunctionExit1( DMEDIADRIVER_SETTOTALSIZEINBYTES_EXIT, this );
}
+/**
+For non NAND devices, i.e. devices which don't set TLocalDriveCapsV4::iNumOfBlocks,
+set iSectorSizeInBytes, iNumberOfSectors & iNumPagesPerBlock appropriately to allow
+TLocalDriveCapsV4::MediaSizeInBytes() to correctly return the media size
+
+Media drivers should call this when they receive a DLocalDrive::ECaps request
+*/
+EXPORT_C void DMediaDriver::SetTotalSizeInBytes(TLocalDriveCapsV4& aCaps)
+ {
+ if (aCaps.iNumOfBlocks == 0)
+ {
+ aCaps.iSectorSizeInBytes = 512;
+ aCaps.iNumPagesPerBlock = 1; // ...to ensure compatibility with NAND semantics
+ Int64 numberOfSectors = iTotalSizeInBytes >> 9;
+ while (I64HIGH(numberOfSectors) > 0)
+ {
+ aCaps.iNumPagesPerBlock<<= 1;
+ numberOfSectors>>= 1;
+ }
+ aCaps.iNumberOfSectors = I64LOW(numberOfSectors);
+ }
+ }
@@ -4649,37 +4950,25 @@
// Create TLocDrv / DMedia objects to handle a media device
__KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %lS dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia));
OstTraceExt5( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE1, "aDevice=%d; aDriveCount=%d; aDriveList=%d; aPrimaryMedia=0x%08x; aNumMedia=%d", (TInt) aDevice, (TInt) aDriveCount, (TInt) *aDriveList, (TUint) aPrimaryMedia, (TInt) aNumMedia );
-
- const TInt* p=aDriveList;
- TInt i;
- TInt r=0;
+
if (UsedMedia+aNumMedia>KMaxLocalDrives)
{
OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse");
return KErrInUse;
- }
- for (i=0; i<aDriveCount; ++i)
- {
- TInt drv = *p++;
- // -1 means not used; this is to enable Dual-slot MMC support
- if (drv == -1)
- continue;
- __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv));
- OstTrace1( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE2, "Registering drive=%d", drv );
- if (TheDrives[drv])
- {
- __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv));
- OstTrace1( TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT2, "< Drive %d already in use; KErrInUse", drv);
- return KErrInUse;
- }
}
+
+ // make a local copy of the name
HBuf* pN=HBuf::New(aName);
if (!pN)
{
OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory");
return KErrNoMemory;
- }
- TInt lastMedia=UsedMedia+aNumMedia-1;
+ }
+
+ // Register the primary media and any secondary media
+ TInt lastMedia = UsedMedia+aNumMedia-1;
+ TInt i;
+ TInt r=0;
for (i=UsedMedia; i<=lastMedia; ++i)
{
if (i==UsedMedia)
@@ -4700,29 +4989,88 @@
return r;
}
}
-
__KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia));
OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia );
UsedMedia+=aNumMedia;
- p=aDriveList;
+
+ if (__IS_EXTENSION(aDevice))
+ aPrimaryMedia->iBody->iMediaExtension = ETrue;
+
+ // Register the drives
+ const TInt* p=aDriveList;
for (i=0; i<aDriveCount; ++i)
{
- TInt drv=*p++;
+ TInt drv = *p++;
+ // -1 means not used; this is to enable Dual-slot MMC support
if (drv == -1)
continue;
- TLocDrv* pL=new TLocDrv(drv);
- if (!pL)
- {
+
+ __KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv));
+ if (!__IS_EXTENSION(aDevice) && TheDrives[drv])
+ {
+ __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv));
+ return KErrInUse;
+ }
+ else if (__IS_EXTENSION(aDevice) && !TheDrives[drv])
+ {
+ __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d not initialized", drv));
+ return KErrNotReady;
+ }
+
+ TLocDrv* pNewDrive = new TLocDrv(drv);
+ if (!pNewDrive)
+ {
OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory");
return KErrNoMemory;
- }
- TheDrives[drv]=pL;
- DriveNames[drv]=pN;
- pL->iPrimaryMedia=aPrimaryMedia;
- __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pL));
- OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE5, "Drive=%d; TLocDrv 0x%08x;", (TInt) drv, (TUint) pL );
+ }
+
+
+ TLocDrv* pOldDrive = TheDrives[drv];
+ aPrimaryMedia->iBody->iRegisteredDriveMask|= (0x1 << drv);
+ pNewDrive->iNextDrive = pOldDrive;
+
+ TheDrives[drv] = pNewDrive;
+ DriveNames[drv] = pN;
+ pNewDrive->iPrimaryMedia = aPrimaryMedia;
+
+
+ if (pOldDrive)
+ {
+ TInt r = pOldDrive->iPrimaryMedia->Connect(pNewDrive);
+ if (r != KErrNone)
+ return r;
+
+#ifdef __DEMAND_PAGING__
+ // If we've hooked a drive letter which is being used for ROM paging by a media driver
+ // which does not report the ROM partition, then we need to change iFirstLocalDriveNumber
+ // so that ROM page-in requests go directly to that driver
+ DMediaPagingDevice* oldPagingDevice = pOldDrive->iPrimaryMedia->iBody->iPagingDevice;
+ if (oldPagingDevice &&
+ (oldPagingDevice->iType & DPagingDevice::ERom) &&
+ oldPagingDevice->iRomPagingDriveNumber == KErrNotFound &&
+ oldPagingDevice->iFirstLocalDriveNumber == drv)
+ {
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: hooking ROM paging device with no defined ROM partition"));
+ TInt n;
+ for (n=0; n<KMaxLocalDrives; ++n)
+ {
+ if(TheDrives[n] && TheDrives[n]->iPrimaryMedia == pOldDrive->iPrimaryMedia)
+ {
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: Changing iFirstLocalDriveNumber from %d to %d", oldPagingDevice->iFirstLocalDriveNumber, n));
+ oldPagingDevice->iFirstLocalDriveNumber = n;
+ break;
+ }
+ }
+ __ASSERT_ALWAYS(n < KMaxLocalDrives, LOCM_FAULT());
+ }
+#endif
+
+ }
+
+ __KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pNewDrive));
}
+
OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 );
return KErrNone;
}
@@ -4807,11 +5155,12 @@
EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages)
{
OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY );
+// SETDEBUGFLAG(KLOCDPAGING);
__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift));
OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift);
- TInt i;
+ TInt i = 0;
if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData)))
{
@@ -4821,20 +5170,23 @@
}
-
- for(i=0; i<KMaxLocalDrives; i++)
+ // Check for duplicate drives
+ if (!aPrimaryMedia->iBody->iMediaExtension)
{
- if (ThePagingDevices[i] == NULL)
- continue;
- if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom))
+ for(i=0; i<KMaxLocalDrives; i++)
{
- aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device
- __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i));
- }
- if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData))
- {
- aPagingType&=~DPagingDevice::EData; // already have a Data paging device
- __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i));
+ if (ThePagingDevices[i] == NULL)
+ continue;
+ if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) && (aPagingType & DPagingDevice::ERom))
+ {
+ aPagingType&=~DPagingDevice::ERom; // already have a ROM paging device
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i));
+ }
+ if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData))
+ {
+ aPagingType&=~DPagingDevice::EData; // already have a Data paging device
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i));
+ }
}
}
@@ -4915,12 +5267,16 @@
// Send an ECaps message to wake up the media driver & ensure all partitions are
// reported, then search for paged-data or paged-ROM partitions
+ // NB: older media drivers supporting ROM and/or code paging only may not have started their DFC queues,
+ // so for these media drivers, use the first local drive supported for ROM-pagin-in requests and
+ // assume the media driver itself will adjust the request position internally to match the ROM partition
+ // @see DMediaPagingDevice::Read()
if ((aPagingType & DPagingDevice::EData) ||
(aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady))
{
// the message queue must have been started already (by the media driver calling iMsgQ.Receive())
- // otherwise we can't send the DLocalDrive::EQueryDevice request
- if (aPrimaryMedia->iDfcQ && !aPrimaryMedia->iMsgQ.iReady)
+ // otherwise we can't send the DLocalDrive::ECaps request
+ if (!aPrimaryMedia->iDfcQ || !aPrimaryMedia->iMsgQ.iReady)
{
__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started"));
OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady");
@@ -4955,7 +5311,7 @@
if (r != KErrNone)
{
- OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< Caps::retval=%d - return KErrNotSupported",r);
+ OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< retval=%d",r);
// Media driver failure; media maybe recoverable after boot.
// Can't register any page drives so return not supported.
return KErrNotSupported;
@@ -4967,20 +5323,25 @@
drive = TheDrives[i];
if(drive && drive->iPrimaryMedia == aPrimaryMedia)
{
- __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x size %x", i, drive->iPartitionType, I64LOW(drive->iPartitionLen)));
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x base %lx size %lx name %lS", i, drive->iPartitionType, drive->iPartitionBaseAddr, drive->iPartitionLen, DriveNames[i] ? DriveNames[i] : &KNullDesC8));
// ROM partition ?
- if ((romPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypeROM))
+ if ((romPagingDriveNumber == KErrNotFound) &&
+ (drive->iPartitionType == KPartitionTypeROM) &&
+ (aPagingType & DPagingDevice::ERom))
{
__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE5, "Found ROM partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen));
romPagingDriveNumber = i;
}
// swap partition ?
- else if ((dataPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypePagedData))
+ else if ((dataPagingDriveNumber == KErrNotFound) &&
+ (drive->iPartitionType == KPartitionTypePagedData) &&
+ (aPagingType & DPagingDevice::EData))
{
__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE6, "Found SWAP partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen) );
dataPagingDriveNumber = i;
+ TheDataPagingDrive = drive;
swapSize = drive->iPartitionLen >> aReadShift;
}
}
@@ -5006,6 +5367,9 @@
}
pagingDevice->iType = aPagingType;
+ if (aPrimaryMedia->iBody->iMediaExtension)
+ pagingDevice->iType|= DPagingDevice::EMediaExtension;
+
pagingDevice->iReadUnitShift = aReadShift;
pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber;
@@ -5016,12 +5380,13 @@
#ifdef __DEBUG_DEMAND_PAGING__
Kern::Printf("PagingDevice :");
- Kern::Printf("iType 0x%x\n", pagingDevice->iType);
- Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift);
- Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber);
- Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber);
- Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber);
- Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize);
+ Kern::Printf("Name %lS", firstLocalDriveNumber >= 0 && DriveNames[firstLocalDriveNumber] ? DriveNames[firstLocalDriveNumber] : &KNullDesC8);
+ Kern::Printf("iType 0x%x", pagingDevice->iType);
+ Kern::Printf("iReadUnitShift 0x%x", pagingDevice->iReadUnitShift);
+ Kern::Printf("iFirstLocalDriveNumber 0x%x", pagingDevice->iFirstLocalDriveNumber);
+ Kern::Printf("iRomPagingDriveNumber 0x%x", pagingDevice->iRomPagingDriveNumber);
+ Kern::Printf("iDataPagingDriveNumber 0x%x", pagingDevice->iDataPagingDriveNumber);
+ Kern::Printf("iSwapSize 0x%x", pagingDevice->iSwapSize);
#endif
@@ -5042,24 +5407,38 @@
if(aPagingType & DPagingDevice::ECode)
{
for (i=0; i<aDriveCount; ++i)
- pagingDevice->iDrivesSupported|=(0x1<<aPagingDriveList[i]);
+ pagingDevice->iDrivesSupported |= (0x1<<aPagingDriveList[i]);
}
pagingDevice->iName = DeviceName[aPagingType];
+ // If ThePinObjectAllocator has already been created with a smaller number of pages,
+ // delete it & then re-create it
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: ThePinObjectAllocator %x", ThePinObjectAllocator));
+ if (ThePinObjectAllocator && ThePinObjectAllocator->iFragmentGranularity < Kern::RoundToPageSize(1) * aNumPages)
+ {
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Recreating ThePinObjectAllocator..."));
+ delete ThePinObjectAllocator;
+ ThePinObjectAllocator = NULL;
+ }
+
+
+ TInt r;
if (ThePinObjectAllocator == NULL)
- ThePinObjectAllocator = new DPinObjectAllocator();
- if(!ThePinObjectAllocator)
{
- __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator"));
- OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory");
- return KErrNoMemory;
- }
- TInt r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages);
- if (r != KErrNone)
- {
- __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator"));
- OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r);
- return r;
+ ThePinObjectAllocator = new DPinObjectAllocator();
+ if(!ThePinObjectAllocator)
+ {
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator"));
+ OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory");
+ return KErrNoMemory;
+ }
+ r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages);
+ if (r != KErrNone)
+ {
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator"));
+ OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r);
+ return r;
+ }
}
@@ -5089,7 +5468,14 @@
for (i=0; i<aDriveCount; ++i)
{
TLocDrv* pD=TheDrives[*p++];
- pD->iPagingDrv=1;
+ pD->iPagingDrv = 1;
+ // mark all attached drives as pageable too - this is really
+ // only to avoid hitting an ASSERT in DMediaDriver::Complete()
+ while (pD->iNextDrive)
+ {
+ pD->iNextDrive->iPagingDrv = 1;
+ pD = pD->iNextDrive;
+ }
}
}
@@ -5133,6 +5519,7 @@
__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("< RegisterPagingDevice"));
OstTraceFunctionExit0( LOCDRV_REGISTERPAGINGDEVICE_EXIT14 );
+// CLRDEBUGFLAG(KLOCDPAGING);
return KErrNone;
}
@@ -5208,6 +5595,7 @@
TLocDrv* pL=TheDrives[i];
if (pL)
{
+ pL = TDriveIterator::GetPhysicalDrive(TheDrives[i]);
++drives;
TInt sockNum;
DPrimaryMediaBase* pM=pL->iPrimaryMedia;
@@ -5347,11 +5735,7 @@
#if defined(__DEMAND_PAGING__) && defined(__CONCURRENT_PAGING_INSTRUMENTATION__)
case EMediaHalGetROMConcurrencyInfo:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5363,11 +5747,7 @@
}
case EMediaHalGetCodeConcurrencyInfo:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5379,11 +5759,7 @@
}
case EMediaHalGetDataConcurrencyInfo:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5395,17 +5771,20 @@
}
case EMediaHalResetConcurrencyInfo:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
- if(!device)
- break;
TUint index=(TInt)a2;
if(index>EMediaPagingStatsCode)
break;
- ResetConcurrencyStats(device, (TMediaPagingStats)index);
+
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
+ if (device)
+ ResetConcurrencyStats(device, (TMediaPagingStats)index);
+ device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
+ if (device)
+ ResetConcurrencyStats(device, (TMediaPagingStats)index);
+ device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
+ if (device)
+ ResetConcurrencyStats(device, (TMediaPagingStats)index);
+
r=KErrNone;
break;
}
@@ -5413,11 +5792,7 @@
#if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
case EMediaHalGetROMPagingBenchmark:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5429,11 +5804,7 @@
}
case EMediaHalGetCodePagingBenchmark:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5445,11 +5816,7 @@
}
case EMediaHalGetDataInPagingBenchmark:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5461,11 +5828,7 @@
}
case EMediaHalGetDataOutPagingBenchmark:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5477,27 +5840,26 @@
}
case EMediaHalResetPagingBenchmark:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
- if(!device)
- break;
TUint index=(TInt)a2;
if(index>EMediaPagingStatsCode)
break;
- ResetBenchmarkStats(device, (TMediaPagingStats)index);
+
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
+ if (device)
+ ResetBenchmarkStats(device, (TMediaPagingStats)index);
+ device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
+ if (device)
+ ResetBenchmarkStats(device, (TMediaPagingStats)index);
+ device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
+ if (device)
+ ResetBenchmarkStats(device, (TMediaPagingStats)index);
+
r=KErrNone;
break;
}
case EMediaHalGetPagingInfo:
{
- TInt drvNo=(TInt)a1;
- TLocDrv* drv=TheDrives[drvNo];
- if(!drv)
- break;
- DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
+ DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, (DPagingDevice::TType) 0xFF);
if(!device)
break;
NKern::FMWait(&device->iInstrumentationLock);
@@ -5737,6 +6099,309 @@
/******************************************************************************
+ DMediaDriverExtension base class
+ ******************************************************************************/
+
+EXPORT_C DMediaDriverExtension::DMediaDriverExtension(TInt aMediaId) :
+ DMediaDriver(aMediaId)
+ {
+ }
+
+/**
+*/
+EXPORT_C DMediaDriverExtension::~DMediaDriverExtension()
+ {
+ }
+
+/**
+Closes the media driver.
+
+This default implementation simply deletes this DMediaDriverExtension object.
+
+Media drivers can provide their own implementation, which gives them
+the opportunity to clean up resources before closure; for example,
+cancelling a DFC.
+Any replacement function must call this base class function as
+the last instruction.
+*/
+EXPORT_C void DMediaDriverExtension::Close()
+ {
+ DMediaDriver::Close();
+ }
+
+/**
+DoDrivePartitionInfo()
+
+Fills out the passed TPartitionInfo object with information from the attached drives
+*/
+EXPORT_C TInt DMediaDriverExtension::DoDrivePartitionInfo(TPartitionInfo& aInfo)
+ {
+ memclr(&aInfo, sizeof(aInfo));
+ aInfo.iPartitionCount = 0;
+ aInfo.iMediaSizeInBytes = 0;
+
+ TDriveIterator driveIter;
+ for (TLocDrv* drv = driveIter.NextDrive(); drv != NULL; drv = driveIter.NextDrive())
+ {
+ if (drv && drv->iPrimaryMedia == iPrimaryMedia)
+ {
+ TLocDrv* attachedDrive = drv->iNextDrive;
+ __ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
+ TLocDrvRequest m;
+ memclr(&m, sizeof(m));
+
+ TBuf8<KMaxLocalDriveCapsLength> capsBuf;
+ capsBuf.SetMax();
+ capsBuf.FillZ();
+ m.Drive() = attachedDrive;
+ m.Id() = DLocalDrive::ECaps;
+ m.RemoteDes() = (TAny*)capsBuf.Ptr();
+ m.Length() = KMaxLocalDriveCapsLength;
+ TInt r = attachedDrive->iPrimaryMedia->Request(m);
+
+ __KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("DMediaDriverExtension::PartitionInfo(ECaps: i %d: r %d ", driveIter.Index(), r));
+
+ // NB The ECaps call might legitimately fail if one of the attached drives is removable
+ // If this happens, just ignore & proceed to the next attached drive
+ if (r == KErrNone)
+ {
+ aInfo.iEntry[aInfo.iPartitionCount] = *attachedDrive;
+ // Set the media size to be that of the largest attached media
+ // This is only needed to ensure that the test in TLocDrvRequest::CheckAndAdjustForPartition()
+ // with the ELocDrvWholeMedia flag set succeeds: A further check on whether a request's
+ // position & length are outside the media will be made when its is delievered to the attached media....
+ aInfo.iMediaSizeInBytes = Max(
+ aInfo.iMediaSizeInBytes,
+ ((TLocalDriveCapsV4*) capsBuf.Ptr())->MediaSizeInBytes());
+ }
+
+
+ aInfo.iPartitionCount++;
+ }
+ }
+
+ return KErrNone;
+ }
+
+/**
+ForwardRequest() -
+
+forwards the request onto the next attached drive in the chain
+*/
+EXPORT_C TInt DMediaDriverExtension::ForwardRequest(TLocDrvRequest& aRequest)
+ {
+ TLocDrv* drive = aRequest.Drive();
+ TLocDrv* attachedDrive = drive->iNextDrive;
+ __ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
+ aRequest.Drive() = attachedDrive;
+
+
+ TInt r = attachedDrive->iPrimaryMedia->HandleMediaNotPresent(aRequest);
+ if (r != KErrNone)
+ {
+ return r;
+ }
+
+ aRequest.Forward(&attachedDrive->iPrimaryMedia->iMsgQ, EFalse);
+ return KErrNone;
+ }
+
+
+TInt DMediaDriverExtension::SendRequest(TInt aReqId, TBool aPagingRequest, TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
+ {
+ __ASSERT_DEBUG(aLen > 0, LOCM_FAULT());
+
+ // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice()
+ if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber)))
+ return KErrArgument;
+
+ TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia);
+ __ASSERT_DEBUG(drive, LOCM_FAULT());
+ TLocDrv* attachedDrive = drive->iNextDrive;
+ __ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
+
+ TLocDrvRequest request;
+ memclr(&request, sizeof(request));
+
+ request.Drive() = attachedDrive;
+ request.Id() = aReqId;
+ request.Length() = aLen;
+ request.RemoteDes() = (TAny*) aData;
+ request.Pos() = aPos;
+ request.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EAdjusted;
+
+#ifdef __DEMAND_PAGING__
+ if (aPagingRequest)
+ {
+ request.Flags()|= TLocDrvRequest::EPaging;
+ // If the buffer is page aligned, use SendToMainQueueDfcAndBlock() as this
+ // is more efficient if the attached drive use DMA.
+ const TInt KPageSizeMask = 4096-1;
+ if (aData & KPageSizeMask)
+ {
+ return attachedDrive->iPrimaryMedia->SendReceive(request, aData);
+ }
+ else
+ {
+ attachedDrive->iPrimaryMedia->iBody->iPagingDevice->SendToMainQueueDfcAndBlock(&request);
+ return 0;
+ }
+ }
+#else
+ aPagingRequest;
+#endif
+
+ return attachedDrive->iPrimaryMedia->SendReceive(request, aData);
+ }
+
+
+/**
+Read() -
+
+reads data from the next attached drive in the chain
+
+N.B. The position is assumed to be already adjusted i.e. relative to the start of the
+media, not the partition
+*/
+EXPORT_C TInt DMediaDriverExtension::Read(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
+ {
+ return SendRequest(DLocalDrive::ERead, EFalse, aDriveNumber, aPos, aData, aLen);
+ }
+
+/**
+Write() -
+
+writes data to the next attached drive in the chain
+
+N.B. The position is assumed to be already adjusted i.e. relative to the start of the
+media, not the partition
+*/
+EXPORT_C TInt DMediaDriverExtension::Write(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
+ {
+ return SendRequest(DLocalDrive::EWrite, EFalse, aDriveNumber, aPos, aData, aLen);
+ }
+
+
+#ifdef __DEMAND_PAGING__
+/**
+ReadPaged() -
+
+Sends a paging read request to the specified attached drive
+
+N.B. The position is assumed to be already adjusted i.e. relative to the start of the
+media, not the partition
+*/
+EXPORT_C TInt DMediaDriverExtension::ReadPaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
+ {
+ return SendRequest(DLocalDrive::ERead, ETrue, aDriveNumber, aPos, aData, aLen);
+ }
+
+/**
+WritePaged() -
+
+Send a paging write request to the specified attached drive
+
+N.B. The position is assumed to be already adjusted i.e. relative to the start of the
+media, not the partition
+*/
+EXPORT_C TInt DMediaDriverExtension::WritePaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
+ {
+ return SendRequest(DLocalDrive::EWrite, ETrue, aDriveNumber, aPos, aData, aLen);
+ }
+#endif // __DEMAND_PAGING__
+
+
+
+/**
+Caps() -
+
+gets the caps from the next attached drive in the chain
+
+N.B. The position is assumed to be already adjusted i.e. relative to the start of the
+media, not the partition
+*/
+EXPORT_C TInt DMediaDriverExtension::Caps(TInt aDriveNumber, TDes8& aCaps)
+ {
+ // Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice()
+ if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber)))
+ return KErrArgument;
+
+ TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia);
+ __ASSERT_DEBUG(drive, LOCM_FAULT());
+ TLocDrv* attachedDrive = drive->iNextDrive;
+ __ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
+
+ TLocDrvRequest request;
+ memclr(&request, sizeof(request));
+
+ request.Drive() = attachedDrive;
+ request.Id() = DLocalDrive::ECaps;
+ request.Length() = aCaps.Length();
+ request.RemoteDes() = (TAny*) aCaps.Ptr();
+
+ return request.SendReceive(&attachedDrive->iPrimaryMedia->iMsgQ);
+ }
+
+
+
+EXPORT_C void DMediaDriverExtension::NotifyPowerDown()
+ {
+ }
+
+EXPORT_C void DMediaDriverExtension::NotifyEmergencyPowerDown()
+ {
+ }
+
+
+/**
+Returns ETrue if this media - or any media which this TLocDrv is attached to - is busy
+*/
+EXPORT_C TBool DMediaDriverExtension::MediaBusy(TInt aDriveNumber)
+ {
+ for (TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia);
+ drive;
+ drive = drive->iNextDrive)
+ {
+ DPrimaryMediaBase* primaryMedia = drive->iPrimaryMedia;
+ __ASSERT_DEBUG(primaryMedia, LOCM_FAULT());
+
+ if ((primaryMedia->iMsgQ.iMessage && primaryMedia->iMsgQ.iMessage->iState != TMessageBase::EFree) ||
+ !primaryMedia->iMsgQ.iQ.IsEmpty() ||
+ primaryMedia->iBody->iMediaChangeDfc.Queued() ||
+ primaryMedia->iBody->iMediaPresentDfc.Queued())
+ return ETrue;
+
+#ifdef __DEMAND_PAGING__
+ DMediaPagingDevice* pagingDevice = iPrimaryMedia->iBody->iPagingDevice;
+ if (pagingDevice)
+ {
+ if ((pagingDevice->iMainQ.iMessage && pagingDevice->iMainQ.iMessage->iState != TMessageBase::EFree) ||
+ !pagingDevice->iMainQ.iQ.IsEmpty())
+ return ETrue;
+ }
+#endif
+ }
+
+ return EFalse;
+ }
+
+
+TCallBackLink::TCallBackLink()
+ {
+ memclr(this, sizeof(this));
+ }
+
+TCallBackLink::TCallBackLink(TInt (*aFunction)(TAny* aPtr, TInt aParam),TAny* aPtr, TObjectType aObjectType) :
+ iFunction(aFunction), iPtr(aPtr), iObjectType(aObjectType)
+ {
+ }
+
+TInt TCallBackLink::CallBack(TInt aParam) const
+ {
+ return (*iFunction)(iPtr, aParam);
+ }
+
+/******************************************************************************
Entry point
******************************************************************************/
DECLARE_STANDARD_EXTENSION()
@@ -5745,6 +6410,7 @@
// install the HAL function
TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL);
+
#ifdef __DEMAND_PAGING__
if (r==KErrNone)
{
@@ -5757,6 +6423,7 @@
__KTRACE_OPT(KBOOT,Kern::Printf("Installing LocDrv device in kernel returned %d",r));
}
#endif // __DEMAND_PAGING__
+
return r;
}
--- a/kernel/eka/drivers/medata/pccd_ata.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/medata/pccd_ata.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -1785,6 +1785,7 @@
aInfo.iFileSystemId=KDriveFileSysFAT;
aInfo.iHiddenSectors=iHiddenSectors;
aInfo.iBlockSize=KAtaSectorSize;
+ SetTotalSizeInBytes(aInfo);
return KErrCompletion; // synchronous completion
}
--- a/kernel/eka/drivers/medint/iram.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/medint/iram.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -200,6 +200,7 @@
caps.iEraseBlockSize=TInternalRamDrive::MaxSize(); // overload for RAM drive to avoid
// F32 depending on memory model
caps.iBlockSize=1;
+ SetTotalSizeInBytes(caps);
return KErrNone;
}
--- a/kernel/eka/drivers/medlfs/flash_media.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/medlfs/flash_media.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -163,10 +163,11 @@
__KTRACE_OPT(KLOCDRV,Kern::Printf(">DMediaDriverFlash::Request %d",id));
if (id==DLocalDrive::ECaps)
{
- TLocalDriveCapsV2& c=*(TLocalDriveCapsV2*)m.RemoteDes();
+ TLocalDriveCapsV4& c=*(TLocalDriveCapsV4*)m.RemoteDes();
r=Caps(c);
c.iSize=m.Drive()->iPartitionLen;
c.iPartitionType=m.Drive()->iPartitionType;
+ SetTotalSizeInBytes(c);
return r;
}
switch (id)
--- a/kernel/eka/drivers/medmmc/medmmc.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/drivers/medmmc/medmmc.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -797,17 +797,8 @@
}
else
{
-#if defined(__DEMAND_PAGING__) && !defined(__WINS__)
- if (DMediaPagingDevice::PageInRequest(*iCurrentReq))
- {
- r = iCurrentReq->WriteToPageHandler(NULL, 0, 0);
- }
- else
-#endif // __DEMAND_PAGING__
- {
- TPtrC8 zeroDes(NULL, 0);
- r = iCurrentReq->WriteRemote(&zeroDes,0);
- }
+ TPtrC8 zeroDes(NULL, 0);
+ r = iCurrentReq->WriteRemote(&zeroDes,0);
}
// error occurred or read all from cache so complete immediately
@@ -2957,12 +2948,7 @@
TUint usrOfst = I64LOW(iReqCur - iReqStart);
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_LATENCY1, "Begin writing user data" );
-#if defined(__DEMAND_PAGING__) && !defined(__WINS__)
- if (DMediaPagingDevice::PageInRequest(*iCurrentReq))
- r=iCurrentReq->WriteToPageHandler((TUint8 *)(&extrView[0]), len, usrOfst);
- else
-#endif // __DEMAND_PAGING__
- r = iCurrentReq->WriteRemote(&extrView,usrOfst);
+ r = iCurrentReq->WriteRemote(&extrView,usrOfst);
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_LATENCY2, "End writing user data" );
@@ -2973,19 +2959,10 @@
TInt DMmcMediaDriverFlash::ReadDataFromUser(TDes8& aDes, TInt aOffset)
{
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_READDATAFROMUSER_ENTRY ,"DMmcMediaDriverFlash::ReadDataFromUser;aOffset=%d;this=%x", aOffset, (TUint) this);
- TInt r = KErrNotSupported;
-#ifndef __WINS__
- if (DMediaPagingDevice::PageOutRequest(*iCurrentReq))
- {
- r = iCurrentReq->ReadFromPageHandler((TAny*) aDes.Ptr(), aDes.MaxLength(), aOffset);
- OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAFROMUSER_EXIT1, this, r );
- return r;
- }
- else
-#endif // #ifndef __WINS__
- r = iCurrentReq->ReadRemote(&aDes, aOffset);
-
- OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAFROMUSER_EXIT2, this, r );
+
+ TInt r = iCurrentReq->ReadRemote(&aDes, aOffset);
+
+ OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAFROMUSER_EXIT1, this, r );
return r;
}
@@ -3698,6 +3675,7 @@
c.iSize = drive.iPartitionLen;
c.iPartitionType = drive.iPartitionType;
c.iHiddenSectors = (TUint) (drive.iPartitionBaseAddr >> KDiskSectorShift);
+ SetTotalSizeInBytes(c);
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT1, this, r );
return r;
}
--- a/kernel/eka/eabi/elocdu.def Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/eabi/elocdu.def Fri Apr 23 22:20:31 2010 +0100
@@ -64,4 +64,23 @@
_ZTI10DDmaHelper @ 63 NONAME ; #<TI>#
_ZTV10DDmaHelper @ 64 NONAME ; #<VT>#
_ZN14TLocDrvRequest19ReadFromPageHandlerEPvii @ 65 NONAME
+ _ZN21DMediaDriverExtension14ForwardRequestER14TLocDrvRequest @ 66 NONAME
+ _ZN21DMediaDriverExtension15NotifyPowerDownEv @ 67 NONAME
+ _ZN21DMediaDriverExtension20DoDrivePartitionInfoER14TPartitionInfo @ 68 NONAME
+ _ZN21DMediaDriverExtension24NotifyEmergencyPowerDownEv @ 69 NONAME
+ _ZN21DMediaDriverExtension4CapsEiR5TDes8 @ 70 NONAME
+ _ZN21DMediaDriverExtension4ReadEixmj @ 71 NONAME
+ _ZN21DMediaDriverExtension5CloseEv @ 72 NONAME
+ _ZN21DMediaDriverExtension5WriteEixmj @ 73 NONAME
+ _ZN21DMediaDriverExtension9MediaBusyEi @ 74 NONAME
+ _ZN21DMediaDriverExtensionC2Ei @ 75 NONAME
+ _ZN21DMediaDriverExtensionD0Ev @ 76 NONAME
+ _ZN21DMediaDriverExtensionD1Ev @ 77 NONAME
+ _ZN21DMediaDriverExtensionD2Ev @ 78 NONAME
+ _ZTI21DMediaDriverExtension @ 79 NONAME
+ _ZTV21DMediaDriverExtension @ 80 NONAME
+ _ZN12DMediaDriver19SetTotalSizeInBytesER17TLocalDriveCapsV4 @ 81 NONAME
+ _ZN21DMediaDriverExtension10WritePagedEixmj @ 82 NONAME
+ _ZN21DMediaDriverExtension9ReadPagedEixmj @ 83 NONAME
+ _ZN11DLocalDrive4CapsEiR5TDes8 @ 84 NONAME
--- a/kernel/eka/include/d32locd.h Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/include/d32locd.h Fri Apr 23 22:20:31 2010 +0100
@@ -36,17 +36,22 @@
enum TMediaDevice { EFixedMedia0, EFixedMedia1, EFixedMedia2, EFixedMedia3,
EFixedMedia4, EFixedMedia5, EFixedMedia6, EFixedMedia7,
ERemovableMedia0, ERemovableMedia1, ERemovableMedia2, ERemovableMedia3,
- EInvalidMedia
+ EInvalidMedia,
+ EMediaExtension0, EMediaExtension1, EMediaExtension2, EMediaExtension3,
+ EMediaExtension4, EMediaExtension5, EMediaExtension6, EMediaExtension7,
};
#define __IS_REMOVABLE(aDevice) (aDevice>=ERemovableMedia0 && aDevice<=ERemovableMedia3)
#define __IS_FIXED(aDevice) ((TUint)aDevice<=EFixedMedia7)
+#define __IS_EXTENSION(aDevice) (aDevice>=EMediaExtension0 && aDevice<=EMediaExtension7)
+
#define MEDIA_DEVICE_IRAM EFixedMedia0
#define MEDIA_DEVICE_LFFS EFixedMedia1
#define MEDIA_DEVICE_NAND EFixedMedia2
#define MEDIA_DEVICE_MMC ERemovableMedia0
#define MEDIA_DEVICE_PCCARD ERemovableMedia1
#define MEDIA_DEVICE_CSA ERemovableMedia2
+#define MEDIA_DEVICE_NFE EMediaExtension0
typedef signed int TSocket;
@@ -506,6 +511,16 @@
};
typedef TPckgBuf<TPageDeviceInfo> TPageDeviceInfoBuf;
+class TLocalDriveFinaliseInfo
+/**
+@internalTechnology
+*/
+ {
+public:
+ TInt iMode; // @see RFs::TFinaliseDrvMode
+ };
+typedef TPckgBuf<TLocalDriveFinaliseInfo> TLocalDriveFinaliseInfoBuf;
+
class RLocalDrive : public RBusLogicalChannel
/**
Interface class to local media
@@ -553,6 +568,7 @@
ELocDrvWholeMedia = 0x40000000 /**< Set to access whole media, rather than partition */
};
+ // @see TBusLocalDrive::QueryDevice()
enum TQueryDevice
{
// Symbian publishedPartner range
@@ -567,7 +583,14 @@
EQueryLicenseeFirst = 0x8000,
EQueryLicenseeLast = 0xBFFF,
+ // Finalize Drive - called as a result of a call to RFs::FinaliseDrives()
+ EQueryFinaliseDrive = EQuerySymbianPublishedPartnerFirst + 0, // @internalTechnology
+
EQueryPageDeviceInfo = EQuerySymbianTestFirst, /**< @see TPageDeviceInfo */
+
+ // NFE test driver
+ EQuerySymbianNfeTestFirst = EQuerySymbianTestFirst+0x10,
+ EQuerySymbianNfeTestEnd = EQuerySymbianTestFirst+0x1F,
};
public:
inline TVersion VersionRequired() const;
--- a/kernel/eka/include/drivers/locmedia.h Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/include/drivers/locmedia.h Fri Apr 23 22:20:31 2010 +0100
@@ -166,6 +166,46 @@
class TLocDrvRequest;
class DPrimaryMediaBase;
+/*
+TCallBackLink
+
+@internalComponent
+
+Internal class which allows a list of callbacks to be linked together.
+*/
+
+NONSHARABLE_CLASS(TCallBackLink)
+ {
+public:
+ enum TObjectType
+ {
+ EDLocalDriveObject, // object containing this TCallBackLink is a DLocalDrive
+ ETLocDrvObject, // object containing this TCallBackLink is a TLocDrv
+ };
+
+public:
+ TCallBackLink();
+ TCallBackLink(TInt (*aFunction)(TAny* aPtr, TInt aParam),TAny* aPtr, TObjectType aObjectType);
+ TInt CallBack(TInt aParam) const;
+public:
+ /**
+ A pointer to the callback function.
+ */
+ TInt (*iFunction)(TAny* aPtr, TInt aParam);
+
+
+ /**
+ A pointer that is passed to the callback function when
+ the function is called.
+ */
+ TAny* iPtr;
+
+ TObjectType iObjectType;
+
+ SDblQueLink iLink;
+ };
+
+
/**
@publishedPartner
@released
@@ -275,19 +315,22 @@
Query device
*/
EQueryDevice=32,
-
};
public:
DLocalDrive();
~DLocalDrive();
-public:
+
virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); /**< @internalComponent */
virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); /**< @internalComponent */
-public:
- void NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange);
-public:
+
+ void NotifyChange();
+
inline void Deque(); /**< @internalComponent */
+ static TInt MediaChangeCallback(TAny* aLocalDrive, TInt aNotifyType); /**< @internalComponent */
+
+ IMPORT_C static TInt Caps(TInt aDriveNumber, TDes8& aCaps);
+
private:
#ifdef __DEMAND_PAGING__
TInt LockMountInfo(DPrimaryMediaBase& aPrimaryMedia, TLocDrvRequest& aReq);
@@ -296,10 +339,10 @@
TInt ReadPasswordData(TLocDrvRequest& aReq, TLocalDrivePasswordData& aPswData, TMediaPassword& aOldPasswd, TMediaPassword& aNewPasswd);
public:
- TLocDrv* iDrive; /**< @internalComponent */
- SDblQueLink iLink; /**< @internalComponent */
+ TLocDrv* iDrive; /**< @internalComponent */
+ TCallBackLink iMediaChangeObserver; /**< @internalComponent */
TClientDataRequest<TBool>* iNotifyChangeRequest; /**< @internalComponent */
- TLocalDriveCleanup iCleanup; /**< @internalComponent */
+ TLocalDriveCleanup iCleanup; /**< @internalComponent */
};
/**
@@ -341,7 +384,7 @@
ECodePaging=0x20, // a code paging request
EDataPaging=0x40, // a data paging request
ETClientBuffer=0x80, // RemoteDes() points to a TClientBuffer
- EKernelBuffer=0x100, // RemoteDes() points to a kernel-side buffer
+ EKernelBuffer=0x100, // RemoteDes() points to a kernel-side buffer : set for all paging requests and media extension requests
};
public:
@@ -493,7 +536,7 @@
@internalComponent
*/
inline void DLocalDrive::Deque()
- { iLink.Deque(); }
+ { iMediaChangeObserver.iLink.Deque(); }
@@ -647,6 +690,7 @@
inline TInt Connect(DLocalDrive* aLocalDrive);
inline void Disconnect(DLocalDrive* aLocalDrive);
inline TInt Request(TLocDrvRequest& aRequest);
+ static TInt MediaChangeCallback(TAny* aLocDrv, TInt aNotifyType);
public:
TInt iDriveNumber;
DMedia* iMedia;
@@ -661,6 +705,14 @@
TUint8 iSpare3;
#endif
DDmaHelper* iDmaHelper;
+
+ // Media extension stuff:
+
+ /** ptr to the next TLocDrv object in the chain. Null if not a media extension */
+ TLocDrv* iNextDrive;
+
+ /** media change callback - called when the next media in the chain has a media change */
+ TCallBackLink iMediaChangeObserver;
};
/**
@@ -827,7 +879,7 @@
public:
IMPORT_C DPrimaryMediaBase();
-public:
+
// provided by implementation
IMPORT_C virtual TInt Create(TMediaDevice aDevice, TInt aMediaId, TInt aLastMediaId);
IMPORT_C virtual TInt Connect(DLocalDrive* aLocalDrive);
@@ -841,7 +893,7 @@
IMPORT_C virtual void DeltaCurrentConsumption(TInt aCurrent);
IMPORT_C virtual void DefaultDriveCaps(TLocalDriveCapsV2& aCaps);
IMPORT_C virtual TBool IsRemovableDevice(TInt& aSocketNum);
-public:
+
// used by implementation
IMPORT_C void NotifyMediaChange();
IMPORT_C void NotifyPowerDown();
@@ -849,7 +901,7 @@
IMPORT_C void NotifyPsuFault(TInt anError);
IMPORT_C void NotifyMediaPresent();
IMPORT_C void PowerUpComplete(TInt anError);
-public:
+
IMPORT_C virtual void HandleMsg(TLocDrvRequest& aRequest);
IMPORT_C virtual TInt DoRequest(TLocDrvRequest& aRequest);
TInt OpenMediaDriver();
@@ -862,7 +914,10 @@
void CompleteRequest(TLocDrvRequest& aMsg, TInt aResult);
IMPORT_C void RunDeferred();
void SetClosed(TInt anError);
- void NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv=NULL);
+
+ enum TNotifyType {EMediaChange, EMediaPresent};
+ void NotifyClients(TNotifyType aNotifyType, TLocDrv* aLocDrv=NULL);
+
TInt InCritical();
void EndInCritical();
void UpdatePartitionInfo();
@@ -882,6 +937,13 @@
void RequestCountDec();
#endif
+ // called by LocDrv::RegisterMediaDevice() for media extensions
+ TInt Connect(TLocDrv* aLocDrv);
+
+ void MediaChange();
+ TInt HandleMediaNotPresent(TLocDrvRequest& aReq);
+
+
public:
TInt iLastMediaId; /**< @internalComponent */
TMessageQue iMsgQ;
@@ -1148,6 +1210,7 @@
virtual void NotifyEmergencyPowerDown()=0;
public:
IMPORT_C void SetTotalSizeInBytes(Int64 aTotalSizeInBytes, TLocDrv* aLocDrv=NULL);
+ IMPORT_C void SetTotalSizeInBytes(TLocalDriveCapsV4& aCaps);
IMPORT_C Int64 TotalSizeInBytes();
IMPORT_C void SetCurrentConsumption(TInt aValue);
IMPORT_C TInt InCritical();
@@ -1165,6 +1228,74 @@
};
+/**
+@internalTechnology
+@prototype
+
+An abstract base class for media driver 'extensions' within the local media subsystem
+*/
+class DMediaDriverExtension : public DMediaDriver
+ {
+public:
+ IMPORT_C DMediaDriverExtension(TInt aMediaId);
+ IMPORT_C virtual ~DMediaDriverExtension();
+ IMPORT_C virtual void Close();
+
+ virtual TInt Request(TLocDrvRequest& aRequest) = 0;
+
+ virtual TInt PartitionInfo(TPartitionInfo &anInfo) = 0;
+
+ IMPORT_C virtual void NotifyPowerDown();
+
+ IMPORT_C virtual void NotifyEmergencyPowerDown();
+
+ /**
+ Retrieve partition info from all the attached drives
+ */
+ IMPORT_C TInt DoDrivePartitionInfo(TPartitionInfo &anInfo);
+ /**
+ Forward a request to the next attached drive
+ */
+ IMPORT_C TInt ForwardRequest(TLocDrvRequest& aRequest);
+
+ /**
+ Read from the specified attached drive
+ */
+ IMPORT_C TInt Read(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen);
+
+ /**
+ Write to the specified attached drive
+ */
+ IMPORT_C TInt Write(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen);
+
+ /**
+ Get the Caps from the specified attached drive
+ */
+ IMPORT_C TInt Caps(TInt aDriveNumber, TDes8& aCaps);
+
+ /**
+ Return whether the media is busy i.e. if it has any pending requests or DFCs
+ */
+ IMPORT_C TBool MediaBusy(TInt aDriveNumber);
+
+#ifdef __DEMAND_PAGING__
+ /**
+ Send a paging read request to the specified attached drive
+ */
+ IMPORT_C TInt ReadPaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen);
+
+ /**
+ Send a paging write request to the specified attached drive
+ */
+ IMPORT_C TInt WritePaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen);
+#endif
+
+private:
+ TInt SendRequest(TInt aReqId, TBool aPagingRequest, TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen);
+
+ };
+
+
/**
--- a/kernel/eka/include/e32ver.h Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/include/e32ver.h Fri Apr 23 22:20:31 2010 +0100
@@ -28,7 +28,7 @@
const TInt KE32MajorVersionNumber=2;
const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=3064;
+const TInt KE32BuildVersionNumber=3066;
const TInt KMachineConfigurationMajorVersionNumber=1;
const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mcodepaging.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mcodepaging.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -64,7 +64,7 @@
*/
static DCodePagedMemoryManager TheManager;
- friend DPagingDevice* CodePagingDevice(TInt aDiveNum);
+ friend DPagingDevice* CodePagingDevice(TInt aDriveNum);
};
@@ -131,6 +131,8 @@
{
TRACEB(("DCodePagedMemoryManager::InstallPagingDevice drive=%d",i));
TAny* null = 0;
+ if(aDevice->iType & DPagingDevice::EMediaExtension)
+ __e32_atomic_store_ord_ptr(&iDevice[i], null);
if(!__e32_atomic_cas_ord_ptr(&iDevice[i], &null, aDevice)) // set iDevice[i]=aDevice if it was originally 0
{
// paging device already registered...
@@ -207,11 +209,11 @@
TInt DCodePagedMemoryManager::CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& aPageArrayEntry)
{
- if(aPageInfo->IsDirty()==false)
+ if(!aPageInfo->IsDirty())
return KErrNone;
// shouldn't be asked to clean a page which is writable...
- __NK_ASSERT_DEBUG(aPageInfo->IsWritable()==false);
+ __NK_ASSERT_DEBUG(!aPageInfo->IsWritable());
// Note, memory may have been modified by the CodeModifier class.
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -656,6 +656,15 @@
}
// Store the device, blocking any other devices from installing.
+ // unless the device is a media extension device
+ if(aDevice->iType & DPagingDevice::EMediaExtension)
+ {
+ delete iSwapManager;
+ iSwapManager = NULL;
+ TAny* null = 0;
+ __e32_atomic_store_ord_ptr(&iDevice, null);
+ }
+
if (!NKern::CompareAndSwap((TAny*&)iDevice, (TAny*)NULL, (TAny*)aDevice))
{// Data paging device already installed.
__KTRACE_OPT2(KPAGING,KBOOT,Kern::Printf("**** Attempt to install more than one data paging device !!!!!!!! ****"));
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mrom.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mrom.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -502,6 +502,8 @@
}
TAny* null = 0;
+ if(aDevice->iType & DPagingDevice::EMediaExtension)
+ __e32_atomic_store_ord_ptr(&iDevice, null);
if(!__e32_atomic_cas_ord_ptr(&iDevice, &null, aDevice)) // set iDevice=aDevice if it was originally 0
{
// ROM paging device already registered...
@@ -969,6 +971,11 @@
MmuLock::Lock();
SPageInfo::FromPhysAddr(iNewPage)->SetShadow(aIndex,aMemory->PageInfoFlags());
MmuLock::Unlock();
+
+#ifdef BTRACE_KERNEL_MEMORY
+ BTrace4(BTrace::EKernelMemory, BTrace::EKernelMemoryMiscAlloc, KPageSize);
+ ++Epoc::KernelMiscPages;
+#endif
}
RamAllocLock::Unlock();
@@ -992,6 +999,11 @@
{
RamAllocLock::Lock();
TheMmu.FreeRam(&iNewPage, 1, EPageFixed);
+
+#ifdef BTRACE_KERNEL_MEMORY
+ BTrace4(BTrace::EKernelMemory, BTrace::EKernelMemoryMiscFree, KPageSize);
+ --Epoc::KernelMiscPages;
+#endif
RamAllocLock::Unlock();
}
if(IsAttached())
--- a/kernel/eka/memmodel/epoc/mmubase/mmubase.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/memmodel/epoc/mmubase/mmubase.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -651,6 +651,17 @@
}
+TInt MmuBase::FreeRamZone(TUint aZoneId, TPhysAddr& aZoneBase, TUint& aZoneBytes)
+ {
+ TUint zonePages;
+ TInt r = iRamPageAllocator->GetZoneAddress(aZoneId, aZoneBase, zonePages);
+ if (r != KErrNone)
+ return r;
+ aZoneBytes = zonePages << KPageShift;
+ return MmuBase::FreePhysicalRam(aZoneBase, aZoneBytes);
+ }
+
+
TInt MmuBase::ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize)
{
__KTRACE_OPT(KMMU,Kern::Printf("Mmu::ClaimPhysicalRam(%08x,%x)",aPhysAddr,aSize));
@@ -1263,14 +1274,14 @@
#endif
#ifdef BTRACE_RAM_ALLOCATOR
- // Must check for -1 as that is the default value of aCategroy for
+ // Must check for -1 as that is the default value of aCategory for
// BTrace::Prime() which is intended to prime all categories that are
// currently enabled via a single invocation of BTrace::Prime().
if(aCategory==BTrace::ERamAllocator || (TInt)aCategory == -1)
{
NKern::ThreadEnterCS();
Mmu::Wait();
- Mmu::Get().iRamPageAllocator->SendInitialBtraceLogs();
+ Mmu::Get().iRamPageAllocator->DoBTracePrime();
Mmu::Signal();
NKern::ThreadLeaveCS();
}
@@ -2051,6 +2062,45 @@
/**
+Free a RAM zone which was previously allocated by one of these methods:
+Epoc::AllocPhysicalRam(), Epoc::ZoneAllocPhysicalRam() or
+TRamDefragRequest::ClaimRamZone().
+
+All of the pages in the RAM zone must be allocated and only via one of the methods
+listed above, otherwise a system panic will occur.
+
+@param aZoneId The ID of the RAM zone to free.
+@return KErrNone If the operation was successful.
+ KErrArgument If a RAM zone with ID aZoneId was not found.
+
+@pre Calling thread must be in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+*/
+EXPORT_C TInt Epoc::FreeRamZone(TUint aZoneId)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreeRamZone");
+ MmuBase& m = *MmuBase::TheMmu;
+ MmuBase::Wait();
+ TPhysAddr zoneBase;
+ TUint zoneBytes;
+ TInt r = m.FreeRamZone(aZoneId, zoneBase, zoneBytes);
+#ifdef BTRACE_KERNEL_MEMORY
+ if (r == KErrNone)
+ {
+ BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysFree, zoneBytes, zoneBase);
+ Epoc::DriverAllocdPhysRam -= zoneBytes;
+ }
+#endif
+ MmuBase::Signal();
+ return r;
+ }
+
+
+/**
Translate a virtual address to the corresponding physical address.
@param aLinAddr The virtual address to be translated.
@@ -3244,7 +3294,7 @@
{
NKern::LockSystem();
SPagingDevice* device = &iPagingDevices[aId];
- if(device->iInstalled)
+ if((device->iInstalled) && !(aDevice->iType & DPagingDevice::EMediaExtension))
{
__KTRACE_OPT2(KPAGING,KBOOT,Kern::Printf("**** Attempt to install more than one ROM paging device !!!!!!!! ****"));
//Panic(EDeviceAlreadyExists);
--- a/kernel/eka/release.txt Fri Apr 23 22:14:19 2010 +0100
+++ b/kernel/eka/release.txt Fri Apr 23 22:20:31 2010 +0100
@@ -1,3 +1,23 @@
+Version 2.00.3066
+=================
+(Made by vfebvre 15/04/2010)
+
+1. migubarr
+ 1. REQ 415-7212 NFE drive encryption on Demand Paging-enabled device
+ PackageReleaseID=453228 FeatureReleaseID=447937
+
+
+Version 2.00.3065
+=================
+(Made by vfebvre 15/04/2010)
+
+1. ahiron
+ 1. DEF145202: E32TEST T_IIC test failure investigation (KERN-EXEC 17)
+
+2. vfebvre
+ 1. MINOR_CHANGE Temporarily disable crash-prone test T_SOUND2 until it is fixed (DEF144934)
+
+
Version 2.00.3064
=================
(Made by vfebvre 14/04/2010)
--- a/kerneltest/e32test/iic/t_iic.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/e32test/iic/t_iic.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -1522,6 +1522,8 @@
gChanSlaveI2c.Close();
UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
+// Not safe to assume that heap clean-up has completed for the channels just closed, so insert a delay.(DEF145202)
+ User::After(20 * 1000);
__KHEAP_MARKEND;
gTest.Next(_L("Free kernel-side proxy IIC client"));
@@ -1598,6 +1600,8 @@
gChanSlaveI2c.Close();
UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
+// Not safe to assume that heap clean-up has completed for the channels just closed, so insert a delay.(DEF145202)
+ User::After(20 * 1000);
__KHEAP_MARKEND;
gTest.Next(_L("Free kernel-side proxy IIC client"));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mediaext/d_nfe.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -0,0 +1,1779 @@
+// 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:
+// e32test\mediext\d_nfe.cpp
+//
+//
+
+#include <drivers/locmedia.h>
+#include <platform.h>
+#include <variantmediadef.h>
+#include "nfe.h"
+
+#if defined(_DEBUG)
+ #define TRACE_ENABLED
+#else
+#endif
+
+#if defined(TRACE_ENABLED)
+#define __KTRACE_PRINT(p) {p;}
+#else
+#define __KTRACE_PRINT(p)
+#endif
+
+
+
+
+// Variant parameters for test Media Extension Driver
+
+
+const TInt KNfeThreadPriority = 24; // same as file server
+const TInt KNfeDiskOpReady = 100; //100%
+//const TInt KNfeDiskOpStart = 0; //0%
+
+_LIT(KPddName, "Media.NFE");
+#define NFE_DRIVENAME "NFE"
+#define NFE_NUMMEDIA 1
+
+// Define the array of local drives which we're attaching to
+__ASSERT_COMPILE(sizeof(TNfeDeviceInfo) <= 256); // KMaxQueryDeviceLength
+
+// Define the array of local code-paging drives which we're attaching to
+#ifdef __DEMAND_PAGING__
+ __ASSERT_COMPILE(NFE_PAGEDRIVECOUNT <= TNfeDeviceInfo::ENfeMaxPartitionEntries);
+ __ASSERT_COMPILE(NFE_DRIVECOUNT >= NFE_PAGEDRIVECOUNT);
+ #define SECTOR_SHIFT 9
+#endif // #ifdef __DEMAND_PAGING__
+
+
+
+
+class DPrimaryMediaExt : public DPrimaryMediaBase
+ {
+public:
+ DPrimaryMediaExt(TInt aInstance);
+public:
+ TInt iInstance;
+ TDfcQue iNfeDfcQ;
+ };
+
+
+
+// Get the number of drives in the drive array belonging to this instance
+TInt DriveCount(TInt aInstance)
+ {
+ static const TInt NfeInstanceDriveCounts[NFE_INSTANCE_COUNT]={NFE_INSTANCE_DRIVE_COUNTS};
+ return NfeInstanceDriveCounts[aInstance];
+ }
+
+// Get a pointer to the first drive in the drive array belonging to this instance
+const TInt* DriveList(TInt aInstance)
+ {
+ static const TInt NfeDriveNumbers[NFE_DRIVECOUNT]={NFE_DRIVELIST};
+ TInt driveListOffset = 0;
+ for (TInt n=0; n<aInstance; n++)
+ driveListOffset+= DriveCount(n);
+ return NfeDriveNumbers + driveListOffset;
+ }
+
+const TInt* DriveLetterList(TInt aInstance)
+ {
+ static const TInt NfeDriveLetters[NFE_DRIVECOUNT]={NFE_DRIVELETTERLIST};
+ TInt driveListOffset = 0;
+ for (TInt n=0; n<aInstance; n++)
+ driveListOffset+= DriveCount(n);
+ return NfeDriveLetters + driveListOffset;
+ }
+
+TInt DriveLetter(TInt aIndex)
+ {
+ static const TInt NfeDriveLetters[NFE_DRIVECOUNT]={NFE_DRIVELETTERLIST};
+ return NfeDriveLetters[aIndex];
+ }
+
+TChar DriveLetterToAscii(TInt aDriveLetter)
+ {
+ return aDriveLetter >= 0 && aDriveLetter <= 25 ? aDriveLetter +'A' : '?';
+ }
+
+#ifdef __DEMAND_PAGING__
+ // Get the number of drives in the paged drive array belonging to this instance
+ TInt PageDriveCount(TInt aInstance)
+ {
+ #if NFE_PAGEDRIVECOUNT > 0
+ static const TInt NfeInstancePageDriveCounts[NFE_INSTANCE_COUNT]={NFE_INSTANCE_PAGEDRIVE_COUNTS};
+ return NfeInstancePageDriveCounts[aInstance];
+ #else
+ return 0;
+ #endif
+ }
+
+ // Get a pointer to the first drive in the paged drive array belonging to this instance
+ const TInt* PageDriveList(TInt aInstance)
+ {
+ #if NFE_PAGEDRIVECOUNT > 0
+ static const TInt NfePageDriveNumbers[NFE_PAGEDRIVECOUNT]={NFE_PAGEDRIVELIST};
+ TInt driveListOffset = 0;
+ for (TInt n=0; n<aInstance; n++)
+ driveListOffset+= PageDriveCount(n);
+ return NfePageDriveNumbers + driveListOffset;
+ #else
+ return NULL;
+ #endif
+ }
+
+ // Get the number of paging type belonging to this instance
+ TInt PagingType(TInt aInstance)
+ {
+ #if NFE_PAGEDRIVECOUNT > 0
+ static const TInt NfeInstancePagingType[NFE_INSTANCE_COUNT]={NFE_INSTANCE_PAGING_TYPE};
+ return NfeInstancePagingType[aInstance];
+ #else
+ return 0;
+ #endif
+ }
+
+ // get the instance of the swap drive
+ TInt SwapInstance()
+ {
+ for (TInt i=0; i<NFE_INSTANCE_COUNT; i++)
+ if (PagingType(i) & DPagingDevice::EData)
+ return i;
+ return KErrNotFound;
+ }
+#endif // #ifdef __DEMAND_PAGING__
+
+
+const char* DriveStatus(TNfeDiskStatus aStatus)
+ {
+ const char* KNfeUnmounted = "Unmounted";
+ const char* KNfeDecrypted = "Decrypted";
+ const char* KNfeDecrypting = "Decrypting";
+ const char* KNfeEncrypted = "Encrypted";
+ const char* KNfeEncrypting = "Encrypting";
+ const char* KNfeWiping = "Wiping";
+ const char* KNfeCorrupted = "Corrupted";
+ const char* KNfeUnrecognised = "Unrecognised";
+
+ switch(aStatus)
+ {
+ case ENfeUnmounted:
+ return KNfeUnmounted;
+ case ENfeDecrypted:
+ return KNfeDecrypted;
+ case ENfeDecrypting:
+ return KNfeDecrypting;
+ case ENfeEncrypted:
+ return KNfeEncrypted;
+ case ENfeEncrypting:
+ return KNfeEncrypting;
+ case ENfeWiping:
+ return KNfeWiping;
+ case ENfeCorrupted:
+ return KNfeCorrupted;
+ default:
+ return KNfeUnrecognised;
+
+ }
+ }
+
+
+DPrimaryMediaExt::DPrimaryMediaExt(TInt aInstance) : iInstance(aInstance)
+ {
+ }
+
+
+#define NFE_FAULT() Kern::Fault("NFEMEDIA",__LINE__)
+
+// disk encryption/decryption/wiping is only performed after the following period of inactivity
+// NB USB Mass Storage tends to 'poll' the media driver by sending ECaps every second or so, so we need
+// to ensure this timeout period is significantly less to ensure the timer DFC thread gets a chance to run...
+const TInt KNotBusyInterval = 200; // 200 mS
+
+
+
+class DPhysicalDeviceMediaNFE : public DPhysicalDevice
+ {
+public:
+ DPhysicalDeviceMediaNFE();
+ virtual TInt Install();
+ virtual void GetCaps(TDes8& aDes) const;
+ virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* anInfo, const TVersion& aVer);
+ virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
+ virtual TInt Info(TInt aFunction, TAny* a1);
+ };
+
+
+class DMediaDriverNFE : public DMediaDriverExtension
+ {
+public:
+ class TPropertyObserver
+ {
+ public:
+ void Close();
+ static void PropertySubsCompleteFn(TAny* aPtr, TInt aReason);
+ public:
+ TInt iDriveIndex;
+ DMediaDriverNFE* iMediaExt;
+ RPropertyRef iProperty;
+ TPropertySubsRequest* iPropertySubsRequest;
+ TDfc* iPropertyDfc; // N.B. subscription call backs don't occur in our thread context, hence the need for this DFC
+ TInt iValue;
+ };
+
+public:
+ DMediaDriverNFE(TInt aMediaId);
+ ~DMediaDriverNFE();
+
+ // replacing pure virtual
+ virtual TInt Request(TLocDrvRequest& aRequest);
+ virtual TInt PartitionInfo(TPartitionInfo &anInfo);
+
+ TInt DoCreate(TInt aMediaId);
+ void Close();
+
+ TNfeDriveInfo* GetSwapDrive();
+
+private:
+ TInt HandleRead(TLocDrvRequest& aRequest);
+ TInt HandleWrite(TLocDrvRequest& aRequest);
+ TInt HandleFormat(TLocDrvRequest& aRequest);
+ TInt HandleCaps(TLocDrvRequest& aReq);
+
+
+ void EncryptBuffer(TDes8& aBuffer);
+ void DecryptBuffer(TDes8& aBuffer);
+
+ inline TUint8 EncryptByte(TUint8 aByte) {return (TUint8) (aByte ^ 0xDD);}
+ inline TUint8 DecryptByte(TUint8 aByte) {return (TUint8) (aByte ^ 0xDD);}
+ inline TInt DriveIndex(TInt aDriveNum) {return iDriveNumToIndex[aDriveNum];}
+
+ static void IdleTimerCallBack(TAny* aMediaDriver);
+ static void TimerDfcFunction(TAny* aMediaDriver);
+
+ // Publish & Subscribe stuff - used to listen to requests from UI
+ static void FromUiPropertyDfcFunction(TAny* aObserver);
+ void FromUiPropertyDfc(TPropertyObserver& aObserver);
+
+ // Publish & Subscribe stuff - used to listen to status setting from other NFE drives
+ static void StatusToUiPropertyDfcFunction(TAny* aObserver);
+ void StatusToUiPropertyDfc(TPropertyObserver& aObserver);
+
+ void StartEncrypting();
+ void StartDecrypting();
+
+ TInt HandleDiskContent(); // called from idle timer DFC
+
+ TNfeDriveInfo* NextDrive();
+
+ TBool AdjustRequest(TNfeDriveInfo*& aDriveInfo, TInt64& aCurrentPos, TInt64& aCurrentLen);
+
+ void SetStatus(TNfeDriveInfo& aDi, TNfeDiskStatus aStatus);
+
+ TBool ValidBootSector(TUint8* aBuffer);
+ TUint32 VolumeId(TUint8* aBuffer);
+ void CheckBootSector(TNfeDriveInfo &aDriveInfo);
+ TInt WriteEncryptionStatusToBootSector(TNfeDriveInfo &aDi, TBool aFinalised = EFalse);
+
+private:
+ TInt iInstance; // media drive instance
+
+ // A local buffer use for encryting / decrypting
+ // For paging requests we need this to be page aligned, so allocate enough to cater for
+ // the worst case of up to 4K being wasted at the start of the buffer and the end
+ enum {KSectorSize = 512, KPageSize = 4096, KBufSize = 65536};
+ TUint8 iNonPageAlignedBuffer[KBufSize + KPageSize*2];
+ // a pointer to the start of the first page in iNonPageAlignedBuffer
+ TUint8* iBuffer;
+
+
+ // Idle timer & DFC for kicking an encryption pass
+ NTimer iIdleTimer;
+ TDfc iTimerDfc;
+
+ TInt iDriveIndex; // index of local drive number currently being encrypted
+ TInt iDriveNumToIndex[KMaxPartitionEntries]; // maps drive numbers to index
+
+ TBool iBusy;
+
+ const TInt* iDriveList; // pointer into the drives in NFE_DRIVELIST belonging to this media driver
+ const TInt* iDriveLetterList; // pointer into the drive letter in NFE_DRIVELETTERLIST belonging to this media driver
+
+ // Publish & subscribe stuff which handles drive command notification events from the UI
+ TPropertyObserver iFromUiPropertyObserver[NFE_DRIVECOUNT];
+
+ // Publish & subscribe stuff which handles drive status notification events from the other NFE drives
+ TPropertyObserver iStatusToUiPropertyObserver[NFE_DRIVECOUNT];
+
+ TBool iDriveFinalised;
+
+public:
+ // Partition information etc for drives this driver is attached to
+ TNfeDeviceInfo iInfo;
+ };
+
+
+
+class TBootSectorStatus
+ {
+public:
+ TUint8 iFatBootSectorData[128];
+
+ enum {ENfeBootSectorSignature = 0x2045464E}; // 'NFE '
+ TUint32 iSignature;
+
+ TNfeDiskStatus iStatus;
+ TBool iFinalised;
+ TInt64 iEncryptEndPos; // position of the last encrypted byte +1. Only written when device is powered down
+ };
+
+
+DPhysicalDeviceMediaNFE::DPhysicalDeviceMediaNFE()
+ {
+ __KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::DPhysicalDeviceMediaNFE()"));
+ iUnitsMask=0x1;
+ iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
+ }
+
+/**
+Install the Internal NFE PDD.
+*/
+TInt DPhysicalDeviceMediaNFE::Install()
+ {
+ __KTRACE_PRINT(Kern::Printf(": TInt DPhysicalDeviceMediaNFE::Install()"));
+
+ return SetName(&KPddName);
+ }
+
+void DPhysicalDeviceMediaNFE::GetCaps(TDes8& /*aDes*/) const
+ {
+ }
+
+/**
+Create an NFE media driver.
+*/
+TInt DPhysicalDeviceMediaNFE::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
+ {
+ __KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::Create()"));
+
+ if (!Kern::QueryVersionSupported(iVersion,aVer))
+ return KErrNotSupported;
+
+ TInt r=KErrNoMemory;
+
+ DMediaDriverNFE* pD = new DMediaDriverNFE(aMediaId);
+ aChannel=pD;
+ if (pD)
+ r=pD->DoCreate(aMediaId);
+
+ if (r == KErrNone)
+ pD->OpenMediaDriverComplete(KErrNone);
+
+ return r;
+ }
+
+TInt DPhysicalDeviceMediaNFE::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
+ {
+ TInt r;
+ if (!Kern::QueryVersionSupported(iVersion,aVer))
+ r = KErrNotSupported;
+ else if (aDeviceType == MEDIA_DEVICE_NFE)
+ return r = KErrNone;
+ else
+ r = KErrNotSupported;
+
+// __KTRACE_PRINT(Kern::Printf("DPhysicalDeviceMediaNFE::Validate() aDeviceType %d NfeDeviceType %d r %d", aDeviceType, MEDIA_DEVICE_NFE, r));
+ return r;
+ }
+
+TInt DPhysicalDeviceMediaNFE::Info(TInt aFunction, TAny*)
+//
+// Return the priority of this media driver
+//
+ {
+// __KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::Info()"));
+
+ if (aFunction==EPriority)
+ return KMediaDriverPriorityNormal;
+
+ if (aFunction==EMediaDriverPersistent)
+ return KErrNone;
+
+ return KErrNotSupported;
+ }
+
+DMediaDriverNFE::DMediaDriverNFE(TInt aMediaId) :
+ DMediaDriverExtension(aMediaId),
+ iInstance(((DPrimaryMediaExt*) iPrimaryMedia)->iInstance),
+ iIdleTimer(IdleTimerCallBack,this),
+ iTimerDfc(TimerDfcFunction,this,2),
+ iDriveList (DriveList(iInstance)),
+ iDriveLetterList (DriveLetterList(iInstance))
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::DMediaDriverNFE()", iInstance));
+ iInfo.iDriveCount = DriveCount(iInstance);
+
+ __ASSERT_ALWAYS(Kern::RoundToPageSize(1) == KPageSize, NFE_FAULT());
+
+ // Align the buffer to a page boundary to improve efficiency for paging requests
+ iBuffer = &iNonPageAlignedBuffer[0];
+ iBuffer = (TUint8*) ((((TUint32) &iNonPageAlignedBuffer[0]) + KPageSize-1) & ~(KPageSize-1));
+ }
+
+DMediaDriverNFE::~DMediaDriverNFE()
+//
+// Destructor.
+//
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::~DMediaDriverNFE()", iInstance));
+
+ TInt i;
+ for (i=0; i<TNfeDeviceInfo::ENfeMaxPartitionEntries; i++)
+ {
+ RPropertyRef* property = (RPropertyRef*) iInfo.iDrives[i].iStatusToUiProperty;
+ if (property)
+ {
+ property->Delete();
+ delete property;
+ }
+ property = (RPropertyRef*) iInfo.iDrives[i].iToUiProperty;
+ if (property)
+ {
+ property->Delete();
+ delete property;
+ }
+ property = (RPropertyRef*) iInfo.iDrives[i].iProgressToUiProperty;
+ if (property)
+ {
+ property->Delete();
+ delete property;
+ }
+ }
+
+ for (i=0; i<NFE_DRIVECOUNT; i++)
+ {
+ iFromUiPropertyObserver[i].Close();
+ iStatusToUiPropertyObserver[i].Close();
+ }
+ }
+
+
+TInt CreateKey(RPropertyRef*& aProperty, TUint aKey)
+ {
+ aProperty = new RPropertyRef;
+ if (aProperty == NULL)
+ return KErrNoMemory;
+ TInt r = aProperty->Attach(KNfeUID, aKey);
+ if (r != KErrNone)
+ return r;
+
+ static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
+ r = aProperty->Define( RProperty::EInt, KPassPolicy, KPassPolicy );
+ if (r != KErrNone && r != KErrAlreadyExists)
+ return r;
+ return KErrNone;
+ }
+
+TInt DMediaDriverNFE::DoCreate(TInt /*aMediaId*/)
+//
+// Create the media driver.
+//
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: TInt DMediaDriverNFE::DoCreate()", iInstance));
+
+ // Associate the idle timer DFC with our thread
+ iTimerDfc.SetDfcQ(iPrimaryMedia->iDfcQ);
+
+ // Publish & Subscribe stuff - used to initiate an encryption pass from the test app
+ static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
+ TInt r;
+ TInt i;
+
+ TInt swapInstance = KErrNotFound;
+#if defined (__DEMAND_PAGING__)
+ swapInstance = SwapInstance();
+#endif
+
+ // **************************************************************************************
+ // Set up P&S publishers so we can publish the status for our drives
+ // **************************************************************************************
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Setting up StatusToUi, ToUi, ProgressToUi P&S publisher & FromUi P&S observer", iInstance));
+
+ for (i = 0; i<DriveCount(iInstance); i++)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d:drive index %d", iInstance, i));
+ TInt driveLetter = iDriveLetterList[i];
+ __KTRACE_PRINT(Kern::Printf("NFE%d:drive letter %c", iInstance, (TInt) DriveLetterToAscii(driveLetter)));
+
+ // no point setting up P&S for the swap drive
+ if (driveLetter == -1)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Skipping P&S for swap partition", iInstance, i));
+ continue;
+ }
+
+ r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iStatusToUiProperty, NFE_KEY(driveLetter, KNfeStatusToUiKey));
+ if (r != KErrNone)
+ return r;
+
+ r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iToUiProperty, NFE_KEY(driveLetter, KNfeToUiKey));
+ if (r != KErrNone)
+ return r;
+
+ r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iProgressToUiProperty, NFE_KEY(driveLetter, KNfeProgressToUiKey));
+ if (r != KErrNone)
+ return r;
+
+ TPropertyObserver& observer = iFromUiPropertyObserver[i];
+ observer.iDriveIndex = i;
+ observer.iMediaExt = this;
+ observer.iPropertySubsRequest = new TPropertySubsRequest(TPropertyObserver::PropertySubsCompleteFn, &observer);
+ if (observer.iPropertySubsRequest == NULL)
+ return KErrNoMemory;
+
+ observer.iPropertyDfc = new TDfc(FromUiPropertyDfcFunction,&observer,iPrimaryMedia->iDfcQ,2);
+ if (observer.iPropertyDfc == NULL)
+ return KErrNoMemory;
+
+ r = observer.iProperty.Attach(KNfeUID, NFE_KEY(driveLetter, KNfeToThreadKey));
+ if (r != KErrNone)
+ return r;
+ r = observer.iProperty.Define(
+ RProperty::EInt,
+ KPassPolicy,
+ KPassPolicy);
+ if (r != KErrNone && r != KErrAlreadyExists)
+ return r;
+
+ r = observer.iProperty.Subscribe(*observer.iPropertySubsRequest);
+ if (r != KErrNone)
+ return r;
+ }
+
+ // **************************************************************************************
+ // If this instance owns the swap partition,
+ // set up P&S listeners so we can get status notification events from the other drives
+ // **************************************************************************************
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Setting up StatusToUi P&S observer", iInstance));
+
+ for (i = 0; i < (iInstance == swapInstance ? NFE_DRIVECOUNT : -1); i++)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d:drive index %d", iInstance, i));
+ __KTRACE_PRINT(Kern::Printf("NFE%d:drive letter %c", iInstance, (TInt) DriveLetterToAscii(DriveLetter(i))));
+
+ // no point setting up P&S for the swap drive
+ if (DriveLetter(i) == -1)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Skipping StatusToUi P&S observer for swap partition", iInstance, i));
+ continue;
+ }
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Setting up StatusToUi P&S observer for drive %c", iInstance, i, (TInt) DriveLetterToAscii(DriveLetter(i))));
+ TPropertyObserver& observer = iStatusToUiPropertyObserver[i];
+ observer.iDriveIndex = i;
+ observer.iMediaExt = this;
+ observer.iPropertySubsRequest = new TPropertySubsRequest(TPropertyObserver::PropertySubsCompleteFn, &observer);
+ if (observer.iPropertySubsRequest == NULL)
+ return KErrNoMemory;
+
+ observer.iPropertyDfc = new TDfc(StatusToUiPropertyDfcFunction,&observer,iPrimaryMedia->iDfcQ,2);
+ if (observer.iPropertyDfc == NULL)
+ return KErrNoMemory;
+
+ r = observer.iProperty.Attach(KNfeUID, NFE_KEY(DriveLetter(i), KNfeStatusToUiKey));
+ if (r != KErrNone)
+ return r;
+ r = observer.iProperty.Define(
+ RProperty::EInt,
+ KPassPolicy,
+ KPassPolicy);
+ if (r != KErrNone && r != KErrAlreadyExists)
+ return r;
+
+ r = observer.iProperty.Subscribe(*observer.iPropertySubsRequest);
+ if (r != KErrNone)
+ return r;
+ }
+
+ return(KErrNone);
+ }
+
+void DMediaDriverNFE::TPropertyObserver::Close()
+ {
+ iProperty.Close();
+ delete iPropertyDfc;
+ iPropertyDfc = NULL;
+ delete iPropertySubsRequest;
+ iPropertySubsRequest = NULL;
+ }
+
+void DMediaDriverNFE::TPropertyObserver::PropertySubsCompleteFn(TAny* aPtr, TInt /*aReason*/)
+ {
+ TPropertyObserver* self = (TPropertyObserver*) aPtr;
+ // Queue a DFC to ensure we're running in the correct thread
+ self->iPropertyDfc->Enque();
+ }
+
+void DMediaDriverNFE::FromUiPropertyDfcFunction(TAny* aObserver)
+ {
+ TPropertyObserver& observer = *(TPropertyObserver*) aObserver;
+ observer.iMediaExt->FromUiPropertyDfc(observer);
+ }
+
+void DMediaDriverNFE::FromUiPropertyDfc(TPropertyObserver& aObserver)
+ {
+ // Get the value of request from the UI
+ TInt err = aObserver.iProperty.Get(aObserver.iValue);
+
+ TInt r = aObserver.iProperty.Subscribe(*aObserver.iPropertySubsRequest);
+ __ASSERT_ALWAYS(r == KErrNone, NFE_FAULT());
+
+ TInt driveLetter = iDriveLetterList[aObserver.iDriveIndex];
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::FromUiPropertyDfc() cmd %d driveLetter %c",
+ iInstance, aObserver.iValue, (TInt) DriveLetterToAscii(driveLetter)));
+
+ // is this our drive letter ?
+ TInt driveCount = DriveCount(iInstance);
+ TNfeDriveInfo* driveInfo = NULL;
+
+ for (TInt i=0; i<driveCount; i++)
+ {
+ TInt myDriveLetter = iDriveLetterList[i];
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Comparing drive %c with myDrive %c", iInstance, (TInt) DriveLetterToAscii(driveLetter), (TInt) DriveLetterToAscii(myDriveLetter)));
+
+ if (myDriveLetter == driveLetter)
+ {
+ TInt driveNumber = iDriveList[i];
+ driveInfo = &iInfo.iDrives[iDriveNumToIndex[driveNumber]];
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Drive Match found driveNumber %d", iInstance, driveInfo->iLocalDriveNum));
+
+ __ASSERT_ALWAYS(driveInfo->iProgressToUiProperty, NFE_FAULT());
+ ((RPropertyRef*) (driveInfo->iProgressToUiProperty))->Set(0);
+ // Wake up the possibly waiting client, whether or not the request
+ // was successfull.
+ ((RPropertyRef*) (driveInfo->iToUiProperty))->Set( err ); // Return value ignored
+ break;
+ }
+ }
+
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: err %d aObserver.iValue %d swap %x swap state %d", iInstance, err, aObserver.iValue, GetSwapDrive(), GetSwapDrive() ? GetSwapDrive()->Status() : -1));
+
+ if (err == KErrNone && aObserver.iValue == ENfeEncryptDisk && driveInfo != NULL)
+ {
+ if (driveInfo->Status() == ENfeDecrypted)
+ {
+ SetStatus(*driveInfo, ENfeEncrypting);
+ StartEncrypting();
+ }
+ }
+ if (err == KErrNone && aObserver.iValue == ENfeDecryptDisk && driveInfo != NULL)
+ {
+ if (driveInfo->Status() == ENfeEncrypted)
+ {
+ SetStatus(*driveInfo, ENfeDecrypting);
+ StartDecrypting();
+ }
+ }
+ }
+
+
+void DMediaDriverNFE::StatusToUiPropertyDfcFunction(TAny* aObserver)
+ {
+ TPropertyObserver& observer = *(TPropertyObserver*) aObserver;
+ observer.iMediaExt->StatusToUiPropertyDfc(observer);
+ }
+
+void DMediaDriverNFE::StatusToUiPropertyDfc(TPropertyObserver& aObserver)
+ {
+ // Get the value of request from the UI
+ TInt err = aObserver.iProperty.Get(aObserver.iValue);
+
+ TInt r = aObserver.iProperty.Subscribe(*aObserver.iPropertySubsRequest);
+ __ASSERT_ALWAYS(r == KErrNone, NFE_FAULT());
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::StatusToUiPropertyDfc() status %d driveLetter %c",
+ iInstance, aObserver.iValue, DriveLetter(aObserver.iDriveIndex) >=0 ? DriveLetter(aObserver.iDriveIndex)+'A' : '?'));
+
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: err %d aObserver.iValue %d swap %x swap state %d", iInstance, err, aObserver.iValue, GetSwapDrive(), GetSwapDrive() ? GetSwapDrive()->Status() : -1));
+
+ if (err == KErrNone && (aObserver.iValue == ENfeEncrypted || aObserver.iValue == ENfeEncrypting))
+ {
+ // If any drive is being or is already encrypted then we have to encrypt the swap partition...
+ TNfeDriveInfo* diSwap = GetSwapDrive();
+ if (diSwap != NULL && diSwap->Status() == ENfeDecrypted)
+ {
+ SetStatus(*diSwap, ENfeEncrypting);
+ StartEncrypting();
+ }
+ }
+ }
+
+
+void DMediaDriverNFE::Close()
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::Close()", iInstance));
+ DMediaDriverExtension::Close();
+ }
+
+
+void DMediaDriverNFE::SetStatus(TNfeDriveInfo& aDi, TNfeDiskStatus aStatus)
+ {
+ if (aStatus != aDi.Status())
+ {
+ aDi.SetStatus(aStatus);
+ __KTRACE_PRINT(Kern::Printf("NFE%d: SetStatus = %s", iInstance, DriveStatus(aDi.Status())));
+ }
+ }
+
+void TNfeDriveInfo::SetStatus(TNfeDiskStatus aStatus)
+ {
+ iStatus = aStatus;
+ if (IsUDADrive())
+ {
+ // Update the status pub&sub variable for UI
+ __ASSERT_ALWAYS(iStatusToUiProperty, NFE_FAULT());
+ ((RPropertyRef*) iStatusToUiProperty)->Set(aStatus);
+ }
+ }
+
+
+
+
+TInt DMediaDriverNFE::Request(TLocDrvRequest& aReq)
+ {
+// __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::DoRequest() : Req %d drv %d flags %x pos %lx len %lx", iInstance, reqId, aReq.Drive()->iDriveNumber, aReq.Flags(), aReq.Pos(), aReq.Length()));
+
+ TInt r = KErrNotSupported;
+
+ TInt reqId = aReq.Id();
+ TNfeDriveInfo& di = iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
+
+ switch (reqId)
+ {
+#if defined(__DEMAND_PAGING__)
+ case DMediaPagingDevice::ERomPageInRequest:
+ BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_NFE,&aReq);
+ r=HandleRead(aReq);
+ break;
+
+ case DMediaPagingDevice::ECodePageInRequest:
+ BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_NFE,&aReq);
+ r=HandleRead(aReq);
+ break;
+
+#endif // __DEMAND_PAGING__
+
+ case DLocalDrive::ERead:
+ r=HandleRead(aReq);
+ break;
+
+ case DLocalDrive::EWrite:
+ WriteEncryptionStatusToBootSector(di, EFalse); // a write to the drive clears the finalised state
+ r=HandleWrite(aReq);
+ break;
+
+ case DLocalDrive::ECaps:
+ r = HandleCaps(aReq);
+ break;
+
+ case DLocalDrive::EFormat:
+ r = HandleFormat(aReq);
+ break;
+
+ // API used by T_NFE to query state etc.
+ case DLocalDrive::EQueryDevice:
+ switch((TInt) aReq.iArg[0])
+ {
+ case EQueryNfeDeviceInfo:
+ {
+ TNfeDeviceInfo& deviceInfo = *(TNfeDeviceInfo*) aReq.RemoteDes();
+ iInfo.iMediaSizeInBytes = iTotalSizeInBytes;
+ deviceInfo = iInfo;
+
+ r = KErrCompletion;
+ break;
+ }
+ case RLocalDrive::EQueryFinaliseDrive:
+ {
+// TLocalDriveFinaliseInfo& finaliseInfo = *(TLocalDriveFinaliseInfo*) aReq.RemoteDes();
+// __KTRACE_PRINT(Kern::Printf("NFE%d: EQueryFinaliseDrive iMode %d", iInstance, finaliseInfo.iMode));
+
+ // write to boot sector to indicate that the drive has ben finalised
+ WriteEncryptionStatusToBootSector(di, ETrue);
+ }
+ default:
+ r = KErrNotSupported;
+ break;
+ }
+ break;
+
+ default:
+ r = ForwardRequest(aReq);
+ break;
+ }
+
+// __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::DoRequest() : ret: %d", iInstance, r));
+
+ if (!di.iDriveFinalised && iBusy)
+ {
+ // Restart the idle timer after processing a request
+ iIdleTimer.Cancel();
+ iTimerDfc.Cancel();
+ iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
+ }
+
+ return r;
+ }
+
+/**
+PartitionInfo()
+
+ Reads the partition information from the attached drive(s).
+ Note: this method is also called when a removable card is removed, so can
+ be used to detect a memory card insertions/removals. Assumes the swap
+ partition is encrypted if any encrypted FAT drives are found
+*/
+TInt DMediaDriverNFE::PartitionInfo(TPartitionInfo& aInfo)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::PartitionInfo()", iInstance));
+
+ TInt r = DoDrivePartitionInfo(aInfo);
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DoDrivePartitionInfo() r %d", iInstance, r));
+ if (r != KErrNone)
+ return r;
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: *** Slave drives partition info ***", iInstance));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iMediaSizeInBytes %lx", iInstance, aInfo.iMediaSizeInBytes));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionCount %d", iInstance, aInfo.iPartitionCount));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: ", iInstance));
+
+ TInt i;
+
+ __ASSERT_DEBUG(aInfo.iPartitionCount <= TNfeDeviceInfo::ENfeMaxPartitionEntries, NFE_FAULT());
+ for (i=0; i<aInfo.iPartitionCount; i++)
+ {
+ TInt driveNum = iDriveList[i];
+ iDriveNumToIndex[driveNum] = i;
+
+ TNfeDriveInfo& di = iInfo.iDrives[i];
+
+ di.iDriveFinalised = EFalse; // a remount clears the finalised state
+
+ // Make a copy of the TPartitionEntry
+ di.iEntry = aInfo.iEntry[i];
+
+
+ // save the local drive number
+ di.iLocalDriveNum = driveNum;
+ di.iDriveLetter = iDriveLetterList[i];
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DriveNum %d", iInstance, driveNum));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: DriveLetter %c", iInstance, (TInt) DriveLetterToAscii(di.iDriveLetter)));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionBaseAddr %lX", iInstance, di.iEntry.iPartitionBaseAddr));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionLen %lx", iInstance, di.iEntry.iPartitionLen));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionType %x", iInstance, di.iEntry.iPartitionType));
+
+
+ // If the drive was removed, reset it's state
+ if (di.iEntry.iPartitionType == KPartitionTypeEmpty)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Empty Partition, setting state to ENfeUnmounted", iInstance));
+ SetStatus(di, ENfeUnmounted);
+ }
+
+ // Is this an unencrypted FAT partition ?
+ if (di.IsUDADrive())
+ {
+ r = Read(di.iLocalDriveNum, di.iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
+ if (r != KErrNone)
+ return r;
+ CheckBootSector(di);
+ }
+
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: status = %s", iInstance, DriveStatus(di.Status())));
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iEncryptStartPos %lX", iInstance, di.iEncryptStartPos));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: iEncryptEndPos %lX", iInstance, di.iEncryptEndPos));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: ", iInstance));
+ }
+
+
+
+#ifdef COMPOSITE_DRIVES
+ // Accumulate the sizes of consecutive FAT drives & report the accumulated size back in the first FAT partition
+ for (i=0; i<aInfo.iPartitionCount; i++)
+ {
+ aInfo.iEntry[i] = iInfo.iDrives[i].iEntry;
+
+ if (iInfo.iDrives[i].IsUDADrive())
+ {
+ aInfo.iEntry[i].iPartitionLen = 0;
+ for (TInt j=i; j<aInfo.iPartitionCount; j++)
+ {
+ if (iInfo.iDrives[j].IsUDADrive())
+ {
+ aInfo.iEntry[i].iPartitionLen+= iInfo.iDrives[j].iEntry.iPartitionLen;
+ }
+ }
+ iInfo.iDrives[i].iCompositeSize = aInfo.iEntry[i].iPartitionLen;
+ i = j;
+ }
+ }
+#endif
+
+
+ SetTotalSizeInBytes(aInfo.iMediaSizeInBytes);
+
+
+ return KErrCompletion; // synchronous completion
+ }
+
+/**
+HandleCaps() -
+
+Return the Caps for a particular drive
+
+Queries the caps from the attached drive, ORs in appropriate paging flags & returns
+*/
+TInt DMediaDriverNFE::HandleCaps(TLocDrvRequest& aReq)
+ {
+ // Get caps from slave drive
+ // NB if we didn't want to alter anything then we could just call ForwardRequest(aReq);
+ TBuf8<sizeof(TLocalDriveCapsV6)> slaveCapsBuf;
+ TLocalDriveCapsV6& slaveCaps = *(TLocalDriveCapsV6*) slaveCapsBuf.Ptr();
+ slaveCapsBuf.SetMax();
+ slaveCapsBuf.FillZ();
+ TInt r = Caps(aReq.Drive()->iDriveNumber, slaveCapsBuf);
+ if (r != KErrNone)
+ return r;
+
+#ifdef COMPOSITE_DRIVES
+ TInt driveNum = aReq.Drive()->iDriveNumber;
+ TInt driveIndex = DriveIndex(driveNum);
+ if (iInfo.iDrives[driveIndex].iCompositeSize)
+ slaveCaps.iSize = iInfo.iDrives[driveIndex].iCompositeSize;
+#endif
+
+ // copy slave caps to returned caps
+ TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)aReq.RemoteDes();
+ caps = slaveCaps;
+
+ // set the paging flags
+#ifdef __DEMAND_PAGING__
+ TLocDrv& drive = *aReq.Drive();
+ if (drive.iPrimaryMedia->iPagingMedia)
+ caps.iMediaAtt|=KMediaAttPageable;
+ if (drive.iPagingDrv)
+ caps.iDriveAtt|=KDriveAttPageable;
+#endif // __DEMAND_PAGING__
+
+ return KErrCompletion;
+ }
+
+
+/**
+AdjustRequest() -
+
+Adjusts position & length if a request crosses these boundaries:
+- the start of the partition (if RLocalDrive::ELocDrvWholeMedia set)
+- the current encrytion point (iEncryptEndPos) N.B. this will point to the end of the partition
+ if the drive is fully encrypted
+
+For composite drives, it also adjusts the position, length & drive number as appropriate to cater for
+crossing partition boundaries
+
+returns ETrue if buffer needs encrypting/decrypting
+*/
+
+TBool DMediaDriverNFE::AdjustRequest(TNfeDriveInfo*& aDriveInfo, TInt64& aCurrentPos, TInt64& aCurrentLen)
+ {
+#ifdef COMPOSITE_DRIVES
+ while (aCurrentPos >= aDriveInfo->iEntry.iPartitionLen)
+ {
+ aCurrentPos-= aDriveInfo->iEntry.iPartitionLen;
+ aDriveInfo++;
+ }
+ if (aCurrentPos + aCurrentLen > aDriveInfo->iEntry.iPartitionLen)
+ aCurrentLen = aDriveInfo->iEntry.iPartitionLen - aCurrentPos;
+#endif
+
+ // do we need to encrypt/decrypt this buffer ?
+ TBool encodeBuffer = EFalse;
+
+ if ((aDriveInfo->Status() == ENfeEncrypted) || aDriveInfo->Status() == ENfeEncrypting)
+ {
+// __ASSERT_DEBUG(aDriveInfo->iEncryptEndPos <= aDriveInfo->iEntry.iPartitionBaseAddr + aDriveInfo->iEntry.iPartitionLen, NFE_FAULT());
+
+ if (aCurrentPos < aDriveInfo->iEncryptStartPos)
+ {
+ aCurrentLen = Min(aCurrentLen, aDriveInfo->iEncryptStartPos - aCurrentPos);
+ encodeBuffer = EFalse;
+ }
+ else if (aCurrentPos < aDriveInfo->iEncryptEndPos)
+ {
+ aCurrentLen = Min(aCurrentLen, aDriveInfo->iEncryptEndPos - aCurrentPos);
+ encodeBuffer = ETrue;
+ }
+ else
+ {
+ encodeBuffer = EFalse;
+ }
+ }
+
+ return encodeBuffer;
+ }
+
+
+TInt DMediaDriverNFE::HandleRead(TLocDrvRequest& aReq)
+ {
+ TInt r = KErrNone;
+ TInt64 currentPos = aReq.Pos();
+ TInt64 remainingLength = aReq.Length();
+ TInt desPos = 0;
+ TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
+
+// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleRead pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
+
+
+ di->iReadRequestCount++;
+
+ if (aReq.Flags() & TLocDrvRequest::ECodePaging)
+ di->iCodePagingRequesCount++;
+ if (aReq.Flags() & TLocDrvRequest::EDataPaging)
+ di->iDataPagingReadRequestCount++;
+
+
+ // just forward the request if the drive is not encrypted
+ if (di->Status() == ENfeDecrypted)
+ return ForwardRequest(aReq);
+
+
+ while(remainingLength)
+ {
+ TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
+
+ TBool decryptBuffer = AdjustRequest(di, currentPos, currentLength);
+
+ // Read from attached drive
+#ifdef __DEMAND_PAGING__
+ if (DMediaPagingDevice::PagingRequest(aReq))
+ r = ReadPaged(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
+ else
+#endif
+ r = Read(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
+ if(r != KErrNone)
+ break;
+
+ TPtr8 des(iBuffer, I64LOW(currentLength), I64LOW(currentLength));
+
+ // decrypt buffer
+ if (decryptBuffer)
+ DecryptBuffer(des);
+
+ // write back to user
+ r = aReq.WriteRemote(&des, desPos);
+ if(r != KErrNone)
+ break;
+
+ remainingLength-= currentLength;
+ currentPos+= currentLength;
+ desPos+= I64LOW(currentLength);
+ }
+
+ return r == KErrNone ? KErrCompletion : r;
+ }
+
+TInt DMediaDriverNFE::HandleWrite(TLocDrvRequest& aReq)
+ {
+ TInt r = KErrNone;
+ TInt64 currentPos = aReq.Pos();
+ TInt64 remainingLength = aReq.Length();
+ TInt desPos = 0;
+ TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
+
+// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleWrite pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
+
+
+ di->iWriteRequestCount++;
+ if (aReq.Flags() & TLocDrvRequest::EDataPaging)
+ di->iDataPagingWriteRequestCount++;
+
+
+ // just forward the request if the drive is not encrypted
+ if (di->Status() == ENfeDecrypted)
+ return ForwardRequest(aReq);
+
+ while(remainingLength)
+ {
+ TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
+
+ TBool encryptBuffer = AdjustRequest(di, currentPos, currentLength);
+
+ // read from user
+ TPtr8 des(iBuffer,0,I64LOW(currentLength));
+ r = aReq.ReadRemote(&des, desPos);
+ if(r != KErrNone)
+ break;
+
+ // get the length of data read from the user in case user's
+ // descriptor is shorter than advertised
+ currentLength = des.Length();
+ if (currentLength == 0)
+ break;
+
+ // writing to sector zero ?
+ if (currentPos >= di->iEntry.iPartitionBaseAddr &&
+ currentPos < di->iEntry.iPartitionBaseAddr + KSectorSize &&
+ di->IsUDADrive())
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Write to sector #0 detected", iInstance));
+
+
+ TUint8* bootSector = iBuffer;
+ TUint8 bootSectorBuffer[KSectorSize];
+ // writing partial sector ?
+ if (currentPos > di->iEntry.iPartitionBaseAddr || currentLength < KSectorSize)
+ {
+ bootSector = bootSectorBuffer;
+ r = Read(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) bootSector, KSectorSize);
+ if(r != KErrNone)
+ break;
+ TInt64 readLen = KSectorSize;
+ TBool encryptBuffer = AdjustRequest(di, di->iEntry.iPartitionBaseAddr, readLen);
+ if (encryptBuffer)
+ {
+ TPtr8 des(bootSectorBuffer,KSectorSize,KSectorSize);
+ DecryptBuffer(des);
+ }
+ TInt sectorOffset = (TInt) (currentPos - di->iEntry.iPartitionBaseAddr);
+ TInt64 copyLen = currentLength;
+ if (copyLen > KSectorSize-sectorOffset)
+ copyLen = KSectorSize-sectorOffset;
+ memcpy(bootSectorBuffer+sectorOffset, iBuffer, (TInt) copyLen);
+ }
+
+ if ((di->Status() == ENfeUnmounted || di->Status() == ENfeCorrupted) &&
+ ValidBootSector(bootSector))
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Setting status to ENfeDecrypted", iInstance ));
+ di->SetStatus(ENfeDecrypted);
+ }
+ di->iUniqueID = VolumeId(bootSector); // update the Volume ID
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Setting Volume ID to %08X", iInstance, di->iUniqueID ));
+ TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
+ if (di->Status() == ENfeEncrypting || di->Status() == ENfeDecrypting)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Adding NFE status record to boot sector", iInstance ));
+ bootSectorStatus->iSignature = TBootSectorStatus::ENfeBootSectorSignature;
+ bootSectorStatus->iEncryptEndPos = di->iEncryptEndPos;
+ bootSectorStatus->iStatus = di->Status();
+ bootSectorStatus->iFinalised = EFalse;
+ }
+ }
+
+ // encrypt the buffer
+ if (encryptBuffer)
+ EncryptBuffer(des);
+
+ // write the data to the attached drive
+#ifdef __DEMAND_PAGING__
+ if (DMediaPagingDevice::PagingRequest(aReq))
+ r = WritePaged(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
+ else
+#endif
+ r = Write(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
+ if(r != KErrNone)
+ break;
+
+ remainingLength-= currentLength;
+ currentPos+= currentLength;
+ desPos+= I64LOW(currentLength);
+ }
+
+ return r == KErrNone ? KErrCompletion : r;
+ }
+
+TInt DMediaDriverNFE::HandleFormat(TLocDrvRequest& aReq)
+ {
+ TInt r = KErrNone;
+ TInt64 currentPos = aReq.Pos();
+ TInt64 remainingLength = aReq.Length();
+ TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
+
+// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleFormat pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
+
+
+ // just forward the request if the drive is not encrypted
+ if (di->Status() == ENfeDecrypted)
+ return ForwardRequest(aReq);
+
+ // otherwise create a buffer containing NULLs, encrypt it and write that to the attached drive
+ while(remainingLength && r == KErrNone)
+ {
+ TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
+
+ TBool encryptBuffer = AdjustRequest(di, currentPos, currentLength);
+
+ memclr(iBuffer, KBufSize);
+ TPtr8 des(iBuffer,KBufSize,KBufSize);
+
+ if (encryptBuffer)
+ EncryptBuffer(des);
+
+ r = Write(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
+ if(r != KErrNone)
+ break;
+
+ remainingLength-= currentLength;
+ currentPos+= currentLength;
+ }
+
+ return r == KErrNone ? KErrCompletion : r;
+ }
+
+
+void DMediaDriverNFE::EncryptBuffer(TDes8& aBuffer)
+ {
+ TInt len = aBuffer.Length();
+ for(TInt i=0; i<len; i++)
+ aBuffer[i] = EncryptByte(aBuffer[i]);
+ }
+
+void DMediaDriverNFE::DecryptBuffer(TDes8& aBuffer)
+ {
+ TInt len = aBuffer.Length();
+ for(TInt i=0; i<len; i++)
+ aBuffer[i] = DecryptByte(aBuffer[i]);
+ }
+
+
+TNfeDriveInfo* DMediaDriverNFE::GetSwapDrive()
+ {
+ for (TInt i=0; i<iInfo.iDriveCount; i++)
+ {
+ TNfeDriveInfo& di = iInfo.iDrives[i];
+ if (di.iEntry.iPartitionType == KPartitionTypePagedData)
+ {
+ return &di;
+ }
+ }
+ return NULL; // swap drive not found
+ }
+
+/**
+Get the first/next drive to encrypt
+*/
+
+TNfeDriveInfo* DMediaDriverNFE::NextDrive()
+ {
+ for (iDriveIndex = 0; iDriveIndex<iInfo.iDriveCount; iDriveIndex++)
+ {
+ TNfeDriveInfo& di = iInfo.iDrives[iDriveIndex];
+ TNfeDiskStatus status = iInfo.iDrives[iDriveIndex].Status();
+ if (status == ENfeEncrypting || status == ENfeDecrypting)
+ {
+ di.iEncryptStartPos = di.iEncryptEndPos = di.iEntry.iPartitionBaseAddr;
+
+ // write to boot sector to indicate we are encrypting/decrypting this drive
+ WriteEncryptionStatusToBootSector(di);
+
+ return &di;
+ }
+ }
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Finished encrypting / decrypting", iInstance));
+ iBusy = EFalse;
+ return NULL;
+ }
+
+
+/**
+Finds the first unencrypted drive & kicks off the idle timer -
+when this expires the encryption of the drive will start
+*/
+void DMediaDriverNFE::StartEncrypting()
+ {
+ // start encrypting if not already doing so
+ if (!iBusy)
+ {
+ iBusy = ETrue;
+ TNfeDriveInfo* di = NextDrive();
+ if (di)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Start encrypting drive %d...", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
+ iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
+ }
+ }
+ }
+
+/**
+Finds the first unencrypted drive & kicks off the idle timer -
+when this expires the encryption of the drive will start
+*/
+void DMediaDriverNFE::StartDecrypting()
+ {
+ // start encrypting if not already doing so
+ if (!iBusy)
+ {
+ iBusy = ETrue;
+ TNfeDriveInfo* di = NextDrive();
+ if (di)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Start decrypting drive %d...", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
+ iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
+ }
+ }
+ }
+
+/**
+Idle timer callback
+Kicks off a DFC to ensure we are running in the correct thread
+*/
+void DMediaDriverNFE::IdleTimerCallBack(TAny* aMediaDriver)
+ {
+ ((DMediaDriverNFE*)aMediaDriver)->iTimerDfc.Add();
+ }
+
+/**
+Idle timer DFC
+*/
+void DMediaDriverNFE::TimerDfcFunction(TAny* aMediaDriver)
+ {
+ ((DMediaDriverNFE*) aMediaDriver)->HandleDiskContent();
+ }
+
+
+TBool DMediaDriverNFE::ValidBootSector(TUint8* aBuffer)
+ {
+ if (aBuffer[0] == 0xEB || aBuffer[0] == 0xE9)
+ return ETrue;
+ else
+ return EFalse;
+ }
+
+
+TUint32 DMediaDriverNFE::VolumeId(TUint8* aBuffer)
+ {
+ TUint16 rootDirEntries;
+ TUint32 uniqueID;
+ memcpy(&rootDirEntries,&aBuffer[17], 2); // 17 TUint16 iRootDirEntries
+ TBool fat32 = rootDirEntries == 0;
+ TInt pos = fat32 ? 67 : 39; // get position of VolumeID
+ memcpy(&uniqueID,&aBuffer[pos],4);
+ return uniqueID;
+ }
+
+void DMediaDriverNFE::CheckBootSector(TNfeDriveInfo &aDi)
+ {
+ TNfeDiskStatus fatBootSectorStatus = ENfeDecrypted;
+
+ // Try to determine whether the FAT boot sector is encypted
+ if (ValidBootSector(iBuffer))
+ {
+ fatBootSectorStatus = ENfeDecrypted;
+ __KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is decrypted", iInstance));
+ }
+ else
+ {
+ TPtr8 des(iBuffer, KSectorSize, KSectorSize);
+ DecryptBuffer(des);
+ if (ValidBootSector(iBuffer))
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is encrypted", iInstance));
+ fatBootSectorStatus = ENfeEncrypted;
+ }
+ else
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is corrupted", iInstance));
+ fatBootSectorStatus = ENfeCorrupted;
+ }
+ }
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: fatBootSectorStatus %d", iInstance, fatBootSectorStatus));
+
+ // Find out whether the volume has changed
+ TUint32 uniqueID = VolumeId(iBuffer);
+ TBool volumeChanged = uniqueID != aDi.iUniqueID;
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Old Volume ID %08X", iInstance, aDi.iUniqueID));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: New Volume ID %08X", iInstance, uniqueID));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: volumeChanged %d", iInstance, volumeChanged));
+ aDi.iUniqueID = uniqueID;
+
+
+
+ TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iSignature %08X", iInstance, bootSectorStatus->iSignature));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iStatus %d", iInstance, bootSectorStatus->iStatus));
+ __KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iEncryptEndPos %lx", iInstance, bootSectorStatus->iEncryptEndPos));
+
+
+ /*
+ If there IS NFE info in the boot sector, restore the encryption settings -
+ unless the 'finalised' flag is clear which indicates that the media was removed or power was lost
+ while encrypting the device...
+
+ If there is no NFE info in the boot sector and there has been a volume change, then we can decide
+ whether the drive is encrypted/decrypted/corrupt by examining the boot sector
+ */
+ if (volumeChanged &&
+ fatBootSectorStatus != ENfeCorrupted &&
+ bootSectorStatus->iSignature == TBootSectorStatus::ENfeBootSectorSignature &&
+ !bootSectorStatus->iFinalised)
+ {
+ SetStatus(aDi, ENfeCorrupted);
+ }
+ else if (volumeChanged &&
+ fatBootSectorStatus != ENfeCorrupted &&
+ bootSectorStatus->iFinalised &&
+ bootSectorStatus->iSignature == TBootSectorStatus::ENfeBootSectorSignature &&
+ (bootSectorStatus->iStatus == ENfeDecrypting || bootSectorStatus->iStatus == ENfeEncrypting))
+ {
+ SetStatus(aDi, bootSectorStatus->iStatus);
+ aDi.iEncryptEndPos = bootSectorStatus->iEncryptEndPos;
+
+ // write to boot sector to indicate we are no longer finalised
+ WriteEncryptionStatusToBootSector(aDi, EFalse);
+
+ iBusy = ETrue;
+ }
+ else if (volumeChanged || aDi.Status() == ENfeUnmounted)
+ {
+ SetStatus(aDi, fatBootSectorStatus);
+ if (aDi.Status() == ENfeEncrypted)
+ {
+ aDi.iEncryptStartPos = aDi.iEntry.iPartitionBaseAddr;
+ aDi.iEncryptEndPos = aDi.iEntry.iPartitionBaseAddr + aDi.iEntry.iPartitionLen;
+ }
+ }
+ }
+
+
+TInt DMediaDriverNFE::WriteEncryptionStatusToBootSector(TNfeDriveInfo &aDi, TBool aFinalised)
+ {
+ if (!aDi.IsUDADrive())
+ return KErrNone;
+
+ if (aDi.iDriveFinalised == aFinalised)
+ return KErrNone;
+
+ TNfeDiskStatus status = aDi.Status();
+
+ TInt64 currentPos = aDi.iEntry.iPartitionBaseAddr;
+ TInt64 currentLen = KSectorSize;
+ TNfeDriveInfo* di = &aDi;
+ TBool encodeBuffer = EFalse;
+
+ if (status == ENfeEncrypting || status == ENfeEncrypted || status == ENfeDecrypting)
+ encodeBuffer = AdjustRequest(di, currentPos, currentLen);
+
+
+ TInt r = Read(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
+ if (r != KErrNone)
+ return r;
+ TPtr8 des(iBuffer, I64LOW(currentLen), I64LOW(currentLen));
+
+ if (encodeBuffer)
+ DecryptBuffer(des);
+
+
+ TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
+
+ if (status == ENfeEncrypting || status == ENfeDecrypting)
+ {
+ bootSectorStatus->iSignature = TBootSectorStatus::ENfeBootSectorSignature;
+ bootSectorStatus->iEncryptEndPos = di->iEncryptEndPos;
+ bootSectorStatus->iStatus = status;
+ bootSectorStatus->iFinalised = aFinalised;
+ }
+ else
+ {
+ bootSectorStatus->iSignature = 0;
+ bootSectorStatus->iEncryptEndPos = 0;
+ bootSectorStatus->iStatus = ENfeUnmounted;
+ bootSectorStatus->iFinalised = EFalse;
+ }
+
+ if (encodeBuffer)
+ EncryptBuffer(des);
+
+
+ r = Write(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
+ return r;
+ }
+
+
+/**
+HandleDiskContent -
+
+Called from Idle timer DFC
+
+Starts encrypting the current drive (iDrives[iDriveIndex]) from the current encryption position (iEncryptEndPos)
+*/
+TInt DMediaDriverNFE::HandleDiskContent()
+ {
+ TNfeDriveInfo* di = &iInfo.iDrives[iDriveIndex];
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Starting to encrypt Drive %d at pos %lx", iInstance, di->iLocalDriveNum, di->iEncryptEndPos));
+
+ if (di->iDriveFinalised)
+ {
+ __KTRACE_PRINT(Kern::Printf("HandleDiskContent aborting as drive has been finalised", iInstance));
+ return KErrNone;
+ }
+
+// TInt KBackgroundPriority = 7; //*test*
+// Kern::SetThreadPriority(KBackgroundPriority); //*test*
+
+ TInt r = KErrNone;
+ for (;;)
+ {
+ // If we've finished encryting this drive, change the state and move on to the next drive
+ if (r != KErrNone || di->iEncryptEndPos >= di->iEntry.iPartitionBaseAddr + di->iEntry.iPartitionLen)
+ {
+ if (di->Status() == ENfeEncrypting)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Finished encrypting Drive %d r %d", iInstance, di->iLocalDriveNum, r));
+ SetStatus(*di, r == KErrNone ? ENfeEncrypted : ENfeCorrupted);
+ }
+ if (di->Status() == ENfeDecrypting)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Finished decrypting Drive %d r %d", iInstance, di->iLocalDriveNum, r));
+ SetStatus(*di, r == KErrNone ? ENfeDecrypted : ENfeCorrupted);
+ }
+
+ // write to boot sector to indicate we have finished encrypting/decrypting this drive
+ r = WriteEncryptionStatusToBootSector(*di);
+
+ di = NextDrive();
+ if (di == NULL)
+ {
+ r = KErrCompletion;
+ break;
+ }
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Starting to encrypt Drive %d", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
+ }
+
+ // If this media or any of the attached media are busy, stop encrypting & wait for the next idle timeout
+ if (MediaBusy(di->iLocalDriveNum))
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Media is busy !!!", iInstance));
+ r = KErrNone; // goto sleep & wait for another timer event
+ break;
+ }
+
+ TInt64& pos = di->iEncryptEndPos;
+ TInt64 partitionEnd = di->iEntry.iPartitionBaseAddr + di->iEntry.iPartitionLen;
+ TInt len = (TInt) Min (partitionEnd - pos, KBufSize);
+
+#if defined(TRACE_ENABLED)
+ // print position every 1/16 of the partition size
+ TInt64 printPos = Max((di->iEntry.iPartitionLen >> 4) & ~(KBufSize-1), KBufSize);
+ if (((di->iEncryptEndPos - di->iEncryptStartPos)% printPos) == 0)
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Encrypting drive %d from %lx to %lx end %lx", iInstance, di->iLocalDriveNum, pos, pos + len, partitionEnd));
+#endif
+// __KTRACE_PRINT(Kern::Printf("NFE%d: Encrypting drive %d from %lx to %lx end %lx", iInstance, di->iLocalDriveNum, pos, pos + len, partitionEnd));
+
+
+ // Read a buffer, encrypt it, and then write it back
+ // retry in case of media change
+ const TInt KRetries = 5;
+ r = KErrNotReady;
+ for (TInt i=0; r == KErrNotReady && i < KRetries; i++)
+ {
+ r = Read(di->iLocalDriveNum, pos, (TLinAddr) iBuffer, len);
+ if (r != KErrNone)
+ continue;
+
+ TPtr8 des(iBuffer,len,len);
+ if (di->Status() == ENfeEncrypting)
+ EncryptBuffer(des);
+ else
+ DecryptBuffer(des);
+
+ r = Write(di->iLocalDriveNum, pos, (TLinAddr) iBuffer, len);
+ }
+
+ if (r == KErrNone)
+ pos+= len;
+
+ if (di->iProgressToUiProperty) // no iProgressToUiProperty for swap drive
+ {
+ TInt progress = (TInt) (KNfeDiskOpReady * (pos - di->iEntry.iPartitionBaseAddr) / di->iEntry.iPartitionLen);
+// __KTRACE_PRINT(Kern::Printf("NFE%d: Progess %d ", progress));
+ ((RPropertyRef*) (di->iProgressToUiProperty))->Set( progress ); // Return value ignored
+ }
+ }
+
+ __KTRACE_PRINT(Kern::Printf("NFE%d: HandleDiskContent returned %d", iInstance, r));
+
+ // If not completed, start the idle timer & try again later
+ if (r != KErrCompletion)
+ iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
+
+// Kern::SetThreadPriority(KNfeThreadPriority); //*test*
+
+ return r;
+ }
+
+
+
+DECLARE_EXTENSION_PDD()
+ {
+ __KTRACE_PRINT(Kern::Printf("DECLARE_EXTENSION_PDD()"));
+ return new DPhysicalDeviceMediaNFE;
+ }
+
+DECLARE_STANDARD_EXTENSION()
+ {
+ __KTRACE_PRINT(Kern::Printf("DECLARE_STANDARD_EXTENSION()"));
+
+
+ // Create the media driver factory object and register this with the kernel
+ __KTRACE_PRINT(Kern::Printf("Creating NFE PDD"));
+ DPhysicalDeviceMediaNFE* device = new DPhysicalDeviceMediaNFE;
+ if (device == NULL)
+ return KErrNoMemory;
+ TInt r = Kern::InstallPhysicalDevice(device);
+ __KTRACE_PRINT(Kern::Printf("Installing NFE PDD in extension init - name %s r:%d", NFE_DRIVENAME, r));
+ if (r != KErrNone)
+ return r;
+
+ TInt swapInstance = KErrNotFound;
+#if defined (__DEMAND_PAGING__)
+ swapInstance = SwapInstance();
+#endif
+
+ DPrimaryMediaExt* primaryMedia[NFE_INSTANCE_COUNT];
+ TInt instance;
+
+ for (instance=0; instance<NFE_INSTANCE_COUNT; instance++)
+ {
+ // Register this media device & define which drives we want to attach to.
+ // These drives must already be registered with the local media subsystem
+ // i.e. this media's kernel extension must be defined AFTER any attached
+ // media's kernel extension in the appropriate .IBY file
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Creating NFE primary media", instance));
+ DPrimaryMediaExt* pM = new DPrimaryMediaExt(instance);
+ if (pM == NULL)
+ return KErrNoMemory;
+ primaryMedia[instance] = pM;
+
+ _LIT(KMediaThreadName,"NfeThread?");
+ HBuf* pMediaThreadName = HBuf::New(KMediaThreadName);
+ (*pMediaThreadName)[9] = (TUint8) ('0' + (TUint8) instance);
+
+ TInt r = Kern::DfcQInit(&pM->iNfeDfcQ,KNfeThreadPriority,pMediaThreadName);
+ if (r != KErrNone)
+ return r;
+
+#ifdef CPU_AFFINITY_ANY
+ NKern::ThreadSetCpuAffinity((NThread*)(pM->iNfeDfcQ.iThread), KCpuAffinityAny);
+#endif
+
+
+ pM->iDfcQ = &pM->iNfeDfcQ;
+ pM->iMsgQ.Receive();
+
+
+ const TInt* driveList = DriveList(instance);
+ TInt driveCount = DriveCount(instance);
+
+ TBuf<4> driveName(_L("NFE?"));
+ driveName[3] = (TUint8) ('0' + (TUint8) instance);
+
+
+ r = LocDrv::RegisterMediaDevice(
+ MEDIA_DEVICE_NFE,
+ driveCount, driveList,
+ pM, NFE_NUMMEDIA, driveName);
+ if (r != KErrNone)
+ return r;
+
+
+#if defined (__DEMAND_PAGING__)
+ if (PagingType(instance))
+ {
+ // Define which of the drives we have already attached to have code or data paging enabled
+ const TInt* pageDriveList = PageDriveList(instance);
+ TInt pageDriveCount = PageDriveCount(instance);
+
+ r = LocDrv::RegisterPagingDevice(pM,pageDriveList,pageDriveCount,PagingType(instance),SECTOR_SHIFT,NFE_NUM_PAGES);
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Installing NFE PagingDevice in extension init - r:%d", pM->iInstance, r));
+ // Ignore error if demand paging not supported by kernel
+ if (r == KErrNotSupported)
+ r = KErrNone;
+ if (r != KErrNone)
+ return r;
+ }
+
+
+#endif // __NAND_DEMAND_PAGING__
+
+ /*
+ If there is a swap partition we need to make sure all instances have their PartitionInfo() called
+ so that we can flag the swap partition as 'encrypted' if there are any encrypted drives at all
+ */
+ if (swapInstance != KErrNotFound)
+ {
+ TBuf8<sizeof(TLocalDriveCapsV6)> capsBuf;
+ capsBuf.SetMax();
+ capsBuf.FillZ();
+ DLocalDrive::Caps(driveList[0], capsBuf);
+ }
+ }
+
+
+ // If we encounter an encrypted drive belonging to ANY NFE instance, then assume the swap partition is
+ // encrypted too. We need to do this because the swap partition has no equivalent of the boot sector
+ if (swapInstance != KErrNotFound)
+ {
+ __KTRACE_PRINT(Kern::Printf("NFE: Searching for encrypted drives to determine whether swap partition should be encrypted..."));
+ TBool encryptedDriveFound = EFalse;
+ TNfeDriveInfo* swapDriveInfo = NULL;
+ for (instance=0; instance<NFE_INSTANCE_COUNT; instance++)
+ {
+ DPrimaryMediaExt* pM = primaryMedia[instance];
+ DMediaDriverNFE* mediaDriver = (DMediaDriverNFE*) pM->iDriver;
+ __ASSERT_ALWAYS(mediaDriver, NFE_FAULT());
+
+ if (swapDriveInfo == NULL)
+ swapDriveInfo = mediaDriver->GetSwapDrive();
+
+ for (TInt i=0; i<mediaDriver->iInfo.iDriveCount; i++)
+ {
+ TNfeDriveInfo& di = mediaDriver->iInfo.iDrives[i];
+ __KTRACE_PRINT(Kern::Printf("NFE%d: Testing drive %d DriveLetter %c status %s",
+ instance, di.iLocalDriveNum, (TInt) DriveLetterToAscii(di.iDriveLetter), DriveStatus(di.Status()) ));
+ if (di.Status() == ENfeEncrypted || di.Status() == ENfeEncrypting)
+ encryptedDriveFound = ETrue;
+ }
+ }
+ if (swapDriveInfo)
+ {
+ swapDriveInfo->SetStatus(encryptedDriveFound ? ENfeEncrypted : ENfeDecrypted);
+ swapDriveInfo->iEncryptEndPos = swapDriveInfo->iEntry.iPartitionBaseAddr + swapDriveInfo->iEntry.iPartitionLen;
+
+ __KTRACE_PRINT(Kern::Printf("NFE: Setting swap partition state to %s...", DriveStatus(swapDriveInfo->Status())));
+ }
+ }
+
+
+ return r;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mediaext/nfe.h Fri Apr 23 22:20:31 2010 +0100
@@ -0,0 +1,163 @@
+// 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:
+// e32test\mediext\nfe.h
+//
+//
+
+#ifndef __NFE_H__
+#define __NFE_H__
+
+#include <d32locd.h>
+
+
+
+// The following is stolen from the genuine NDE driver interface from nfe_interface.h
+// >>>>>nfe_interface.h
+enum TNfeCommands
+ {
+ ENfeDiskStatus = 0, // No longer used, preserved for SC/BC.
+ ENfeEncryptDisk = 1,
+ ENfeDecryptDisk = 2,
+ ENfeWipeDisk = 3,
+ // Debug commands below, enabled only in RnD compiled extension
+ ENfePause = 128,
+ ENfeContinue = 129,
+ };
+
+enum TNfeDiskStatus
+ {
+ ENfeUnmounted = 0,
+ ENfeDecrypted = 8,
+ ENfeDecrypting = 9,
+ ENfeEncrypted = 10,
+ ENfeEncrypting = 11,
+ ENfeWiping = 12,
+ ENfeCorrupted = 13,
+ };
+
+
+
+// The keys under the KNfeUID category are generated by combining the constants
+// below with drive number by using the NFE_KEY macro below.
+const TUint KNfeToThreadKey = 1;
+const TUint KNfeToUiKey = 2;
+const TUint KNfeToExtKey = 3; // No longer used, preserved for SC/BC.
+const TUint KNfeProgressToUiKey = 4;
+const TUint KNfeStatusToUiKey = 5; // Replaces ENfeDiskStatus command.
+
+//- Macros ------------------------------------------------------------------
+// Calculates pub&sub key for given drive and id. Top 8 bits are used for the
+// drives. Bottom 8 bits are used for the ids. The rest of the bits are
+// reserved and use zero value. The key layout:
+// dddddddd0000000000000000kkkkkkkk
+// ^bit 31 ^bit 0
+#define NFE_KEY(drive, id) (((drive) << 24) | (0xFF & (id)))
+// <<<<nfe_interface.h
+
+
+
+
+// copy of TPartitionEntry from locmedia.h
+#ifndef __KERNEL_MODE__
+class TPartitionEntry
+ {
+public:
+ Int64 iPartitionBaseAddr;
+ Int64 iPartitionLen;
+ TUint16 iBootIndicator;
+ TUint16 iPartitionType;
+ };
+#endif
+
+enum
+ {
+ EQueryNfeDeviceInfo = RLocalDrive::EQuerySymbianNfeTestFirst+0,
+ };
+
+class TNfeDriveInfo
+ {
+public:
+ inline TBool IsUDADrive()
+ {return PartitionIsFAT(iEntry.iPartitionType) || PartitionIsFAT32(iEntry.iPartitionType); }
+
+#ifdef __KERNEL_MODE__
+ void SetStatus(TNfeDiskStatus aStatus);
+#endif
+ inline TNfeDiskStatus Status() { return iStatus; }
+
+private:
+ TNfeDiskStatus iStatus; // @see TNfeDiskStatus
+
+public:
+ TInt iLocalDriveNum;
+ TInt iDriveLetter;
+ TPartitionEntry iEntry;
+ Int64 iCompositeSize;
+
+ /**
+ position of first encrypted byte - normally the same as
+ iEntry.iPartitionBaseAddr unless the MBR has been changed
+ */
+ TInt64 iEncryptStartPos;
+
+ /**
+ position of the last encrypted byte +1 - normally the same as
+ iEntry.iPartitionBaseAddr+iEntry.iPartitionLen if the drive is fully
+ encrypted
+ */
+ TInt64 iEncryptEndPos;
+
+ TInt iReadRequestCount;
+ TInt iWriteRequestCount;
+ TInt iCodePagingRequesCount;
+ TInt iDataPagingReadRequestCount;
+ TInt iDataPagingWriteRequestCount;
+
+ TAny* iStatusToUiProperty;
+ TAny* iToUiProperty;
+ TAny* iProgressToUiProperty;
+ TUint32 iUniqueID; // FAT volume ID
+ TBool iDriveFinalised;
+ };
+
+/**
+NFE media details - for testing purposes only
+This is a structure used to communicate NFE-related information
+from the NFE media driver to a test application
+
+@internalTechnology
+@prototype
+*/
+class TNfeDeviceInfo
+ {
+public:
+ enum {ENfeMaxPartitionEntries = 2};
+ TNfeDriveInfo iDrives[ENfeMaxPartitionEntries];
+
+ TInt iDriveCount;
+
+ TInt64 iMediaSizeInBytes;
+ };
+
+typedef TPckgBuf<TNfeDeviceInfo> TNfeDeviceInfoBuf;
+
+
+// Publish & Subscribe is used to initiate an encryption pass - to emulate the behaviour of the genuine NFE UI & driver
+//const TUid KNfeUID = TUid::Uid(0xA000E7C5); // UID of NFE test mdia driver (D_NFE.MMP)
+const TUid KNfeUID = {0x100039e3};
+
+
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mediaext/t_nfe.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -0,0 +1,406 @@
+// 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:
+// e32test\mediext\t_nfe.cpp
+//
+//
+
+#define __E32TEST_EXTENSION__
+
+#include <e32test.h>
+#include <f32file.h>
+
+
+RTest test(_L("t_nfe"));
+
+#include <d32locd.h>
+#include <e32property.h>
+#include "nfe.h"
+
+
+TBusLocalDrive Drive;
+TBool TheWaitFlag = EFalse; // wait for drive to be encrypted before exiting test
+TBool TheFinaliseDriveFlag = EFalse;
+TBool TheDisplayStatusFlag = EFalse; // display drive status and then exit (i.e. don't encrypt)
+TBool TheEncryptDriveFlag = ETrue;
+
+TInt FindNfeDrive(TInt aDriveNum)
+/**
+Find the next NFE drive
+
+@return Local drive identifier.
+*/
+ {
+ TInt drive = KErrNotFound;
+
+// test.Printf(_L("Searching for NFE drive:\n"));
+
+ for (TInt i = aDriveNum; i < KMaxLocalDrives && drive < 0; ++i)
+ {
+ RLocalDrive d;
+ TBool change = EFalse;
+
+ if(d.Connect(i, change) == KErrNone)
+ {
+// test.Printf(_L("Connected to local drive %d\n"), i);
+ TLocalDriveCapsV4 dc;
+ TPckg<TLocalDriveCapsV4> capsPack(dc);
+ capsPack.FillZ();
+
+ if(d.Caps(capsPack) != KErrNone)
+ continue;
+ if (dc.iType == EMediaNANDFlash || dc.iType == EMediaHardDisk)
+ {
+ TNfeDeviceInfo nfeDeviceInfo;
+ TPtr8 nfeDeviceInfoBuf((TUint8*) &nfeDeviceInfo, sizeof(nfeDeviceInfo));
+ nfeDeviceInfoBuf.FillZ();
+
+ TInt r = d.QueryDevice((RLocalDrive::TQueryDevice) EQueryNfeDeviceInfo, nfeDeviceInfoBuf);
+
+// test.Printf(_L("EQueryNfeDeviceInfo on local drive %d returned %d\n"), i, r);
+ if (r == KErrNone)
+ {
+ test.Printf(_L("\nFound NFE on local drive %d\n"), i);
+ drive = i;
+ }
+ }
+ d.Close();
+ }
+ }
+ return drive;
+ }
+
+
+
+const TDesC* DriveStatus(TNfeDiskStatus aStatus)
+ {
+ _LIT(KNfeUnmounted, "Unmounted");
+ _LIT(KNfeDecrypted, "Decrypted");
+ _LIT(KNfeDecrypting, "Decrypting");
+ _LIT(KNfeEncrypted, "Encrypted");
+ _LIT(KNfeEncrypting, "Encrypting");
+ _LIT(KNfeWiping, "Wiping");
+ _LIT(KNfeCorrupted, "Corrupted");
+ _LIT(KNfeUnrecognised, "Unrecognised");
+
+ switch(aStatus)
+ {
+ case ENfeUnmounted:
+ return &KNfeUnmounted;
+ case ENfeDecrypted:
+ return &KNfeDecrypted;
+ case ENfeDecrypting:
+ return &KNfeDecrypting;
+ case ENfeEncrypted:
+ return &KNfeEncrypted;
+ case ENfeEncrypting:
+ return &KNfeEncrypting;
+ case ENfeWiping:
+ return &KNfeWiping;
+ case ENfeCorrupted:
+ return &KNfeCorrupted;
+ default:
+ return &KNfeUnrecognised;
+
+ }
+ }
+
+TInt DriveStatus(TInt aNfeDrive, TNfeDiskStatus& aStatus, TInt &aProgress)
+ {
+ TInt r = RProperty::Get(
+ KNfeUID,
+ NFE_KEY(aNfeDrive, KNfeStatusToUiKey),
+ *(TInt*) &aStatus);
+ if (r != KErrNone)
+ return r;
+ r = RProperty::Get(
+ KNfeUID,
+ NFE_KEY(aNfeDrive, KNfeProgressToUiKey),
+ *(TInt*) &aProgress);
+ return r;
+ }
+
+void DisplayNfeDeviceInfo(TInt aNfeDrive, TNfeDeviceInfo& aDeviceInfo)
+ {
+ test.Printf(_L("Stats: \n"));
+
+ RLocalDrive d;
+ TBool change = EFalse;
+ TInt r = d.Connect(aNfeDrive, change);
+ test (r == KErrNone);
+
+ TPtr8 nfeDeviceInfoBuf((TUint8*) &aDeviceInfo, sizeof(aDeviceInfo));
+ nfeDeviceInfoBuf.FillZ();
+ r = d.QueryDevice((RLocalDrive::TQueryDevice) EQueryNfeDeviceInfo, nfeDeviceInfoBuf);
+ test (r == KErrNone || r == KErrNotSupported);
+
+ d.Close();
+
+ test.Printf(_L("iDriveCount %d\n"), aDeviceInfo.iDriveCount);
+ test.Printf(_L("iMediaSizeInBytes %lx\n"), aDeviceInfo.iMediaSizeInBytes);
+
+ for (TInt i=0; i<aDeviceInfo.iDriveCount; i++)
+ {
+ TNfeDriveInfo& di = aDeviceInfo.iDrives[i];
+
+ test.Printf(_L("*** drive index %d ***\n"), i);
+ test.Printf(_L("iLocalDriveNum %x\n"), di.iLocalDriveNum);
+ test.Printf(_L("iDriveLetter %c\n"), di.iDriveLetter >= 0 && di.iDriveLetter <= 25 ? di.iDriveLetter +'A' : '?');
+ test.Printf(_L("iState %d\n"), di.Status());
+
+ test.Printf(_L("State = %S\n"), DriveStatus(di.Status()));
+
+ test.Printf(_L("iEncryptStartPos %lx\n"), di.iEncryptStartPos);
+ test.Printf(_L("iEncryptEndPos %lx\n"), di.iEncryptEndPos);
+ test.Printf(_L("iPartitionBaseAddr %lx\n"), di.iEntry.iPartitionBaseAddr);
+ test.Printf(_L("iPartitionLen %lx\n"), di.iEntry.iPartitionLen);
+ test.Printf(_L("iPartitionType %x\n"), di.iEntry.iPartitionType);
+
+ test.Printf(_L("iReadRequestCount %d\n"), di.iReadRequestCount);
+ test.Printf(_L("iWriteRequestCount %d\n"), di.iWriteRequestCount);
+ test.Printf(_L("iCodePagingRequesCount %d\n"), di.iCodePagingRequesCount);
+ test.Printf(_L("iDataPagingReadRequestCount %d\n"), di.iDataPagingReadRequestCount);
+ test.Printf(_L("iDataPagingWriteRequestCount %d\n"), di.iDataPagingWriteRequestCount);
+ test.Printf(_L("iUniqueID %08X\n"), di.iUniqueID);
+ }
+ }
+
+void EncryptDrive(TInt aNfeDrive)
+ {
+ // subscribe to cmd acknowledgement property - KNfeToUiKey
+ RProperty propToUi;
+ test.Printf(_L("Attaching ToUi property"));
+ TInt r = propToUi.Attach(KNfeUID,NFE_KEY(aNfeDrive,KNfeToUiKey));
+ test.Printf(_L("Attaching returned %d"), r);
+ if (r != KErrNone)
+ return;
+
+
+ TRequestStatus status;
+ propToUi.Subscribe( status );
+
+
+ // Issue command
+ test.Printf(_L("Encrypting drive %c...\n"), aNfeDrive+'A');
+ r = RProperty::Set(
+ KNfeUID,
+ NFE_KEY(aNfeDrive, KNfeToThreadKey),
+ ENfeEncryptDisk);
+ test.Printf(_L("Encrypting drive %c, r %d\n"), aNfeDrive+'A', r);
+ test (r == KErrNone);
+
+ // wait for ack
+ User::WaitForRequest( status );
+ r = status.Int();
+ test.Printf(_L("cmd status %d"), r);
+ test (r == KErrNone);
+ }
+
+void DecryptDrive(TInt aNfeDrive)
+ {
+ // subscribe to cmd acknowledgement property - KNfeToUiKey
+ RProperty propToUi;
+ test.Printf(_L("Attaching ToUi property"));
+ TInt r = propToUi.Attach(KNfeUID,NFE_KEY(aNfeDrive,KNfeToUiKey));
+ test.Printf(_L("Attaching returned %d"), r);
+ if (r != KErrNone)
+ return;
+
+
+ TRequestStatus status;
+ propToUi.Subscribe( status );
+
+
+ // Issue command
+ test.Printf(_L("Decrypting drive %c...\n"), aNfeDrive+'A');
+ r = RProperty::Set(
+ KNfeUID,
+ NFE_KEY(aNfeDrive, KNfeToThreadKey),
+ ENfeDecryptDisk);
+ test.Printf(_L("Decrypting drive %c, r %d\n"), aNfeDrive+'A', r);
+ test (r == KErrNone);
+
+ // wait for ack
+ User::WaitForRequest( status );
+ r = status.Int();
+ test.Printf(_L("cmd status %d"), r);
+ test (r == KErrNone);
+ }
+
+void WaitForFinish(TInt aNfeDrive, TBool aEncrypt)
+ {
+ TNfeDiskStatus diskStatus = ENfeCorrupted;
+ TInt progress = 0;
+
+ TInt r = DriveStatus(aNfeDrive, diskStatus, progress);
+ test (r == KErrNone);
+
+ // Poll progress status.
+ while (diskStatus != (aEncrypt ? ENfeEncrypted : ENfeDecrypted ))
+ {
+ r = DriveStatus(aNfeDrive, diskStatus, progress);
+ test (r == KErrNone);
+ test.Printf(_L("Drive %c, r %d progress %3u%% status %S\n"), aNfeDrive+'A', r, progress, DriveStatus((TNfeDiskStatus) diskStatus));
+
+
+ if (TheFinaliseDriveFlag && progress > 10)
+ {
+ TheFinaliseDriveFlag = EFalse;
+ RFs fs;
+ TInt r = fs.Connect();
+ test_KErrNone(r);
+
+ r = fs.FinaliseDrive(aNfeDrive, RFs::EFinal_RW);
+ test_KErrNone(r);
+ return;
+ }
+
+ User::After( 1000 * 500 );
+ }
+ test.Printf( _L("\nFinished\n") );
+ }
+
+//
+// E32Main
+//
+
+TInt ParseCommandArguments()
+ {
+ TInt tokenCount = 0;
+ TChar driveToTest = 'C';;
+
+ TBuf<0x100> cmd;
+ User::CommandLine(cmd);
+ TLex lex(cmd);
+
+ for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
+ {
+ tokenCount++;
+ // Get the drive letter
+ if (tokenCount == 1)
+ {
+ TChar ch = token[0];
+ if (ch.IsAlpha())
+ {
+ if(token.Length() > 0)
+ {
+ driveToTest=token[0];
+ driveToTest.UpperCase();
+ }
+ }
+ RDebug::Print(_L("drive=%C"), (TUint) driveToTest);
+ continue;
+ }
+
+ else if (token.CompareF(_L("-d")) == 0)
+ {
+ TheEncryptDriveFlag = EFalse;
+ }
+ else if (token.CompareF(_L("-e")) == 0)
+ {
+ TheEncryptDriveFlag = ETrue;
+ }
+ else if (token.CompareF(_L("-f")) == 0)
+ {
+ TheFinaliseDriveFlag = ETrue;
+ }
+ else if (token.CompareF(_L("-w")) == 0)
+ {
+ TheWaitFlag = ETrue;
+ }
+ else if (token.CompareF(_L("-s")) == 0)
+ {
+ TheDisplayStatusFlag = ETrue;
+ }
+ }
+
+ return driveToTest;
+ }
+
+TInt E32Main()
+ {
+ test.Title();
+ test.Start(_L("NFE tests"));
+
+ RFs fs;
+
+ TInt r = fs.Connect();
+ test_KErrNone(r);
+
+ TChar driveToTest = ParseCommandArguments();
+
+ TInt drive;
+ r = fs.CharToDrive(driveToTest,drive);
+ test_KErrNone(r);
+
+
+ TVolumeInfo volumeInfo;
+ r = fs.Volume(volumeInfo, drive);
+ test(r == KErrNone);
+
+
+
+ TNfeDiskStatus diskStatus = ENfeCorrupted;
+ TInt progress = 0;
+
+ r = DriveStatus(drive, diskStatus, progress);
+ test.Printf(_L("drive %c diskStatus %S, progress %d r %d\n"), drive+'A', DriveStatus(diskStatus), progress, r);
+
+ if (TheDisplayStatusFlag)
+ {
+ test.Printf(_L("*** press any key ***"));
+ test.Getch();
+ test.End();
+ test.Close();
+ return 0;
+ }
+
+ if (r == KErrNone && diskStatus == ENfeDecrypted && TheEncryptDriveFlag)
+ {
+ test.Next(_L("Encrypting NFE drive"));
+ EncryptDrive(drive);
+ r = DriveStatus(drive, diskStatus, progress);
+ test.Printf(_L("drive %c diskStatus %S, progress %d r %d\n"), drive+'A', DriveStatus(diskStatus), progress, r);
+ }
+
+ if (r == KErrNone && diskStatus == ENfeEncrypted && !TheEncryptDriveFlag)
+ {
+ test.Next(_L("Decrypting NFE drive"));
+ DecryptDrive(drive);
+ r = DriveStatus(drive, diskStatus, progress);
+ test.Printf(_L("drive %c diskStatus %S, progress %d r %d\n"), drive+'A', DriveStatus(diskStatus), progress, r);
+ }
+
+
+ if (r == KErrNone && TheWaitFlag)
+ {
+ test.Next(_L("Waiting for finish"));
+ WaitForFinish(drive, TheEncryptDriveFlag);
+ }
+
+
+ for(TInt nfeDrive = FindNfeDrive(0); nfeDrive != KErrNotFound; nfeDrive = FindNfeDrive(++nfeDrive))
+ {
+ TNfeDeviceInfo deviceInfo;
+ DisplayNfeDeviceInfo(nfeDrive, deviceInfo);
+ }
+
+ fs.Close();
+
+ test.End();
+ test.Close();
+
+ return 0;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mediaext/t_nfe.mmp Fri Apr 23 22:20:31 2010 +0100
@@ -0,0 +1,33 @@
+// 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:
+// e32test/group/t_nfe.mmp
+//
+//
+
+target t_nfe.exe
+targettype exe
+
+capability All
+
+sourcepath ../mediaext
+source t_nfe.cpp
+
+library euser.lib efsrv.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+
+
+SMPSAFE
--- a/kerneltest/e32test/multimedia/t_sound2.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/e32test/multimedia/t_sound2.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -2379,6 +2379,10 @@
Test.Title();
Test.Start(_L("Load"));
+ // --- TEMPORARILY DISABLING T_SOUND2
+ Test.Printf(_L("T_SOUND2 DISABLED UNTIL DEF144934 IS FIXED\n"));
+ CHECK(0);
+ // --- TEMPORARILY DISABLING T_SOUND2
if (Load()==KErrNotFound)
{
Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n"));
--- a/kerneltest/f32test/demandpaging/t_nandpaging.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/demandpaging/t_nandpaging.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -28,6 +28,7 @@
//! @SYMTestPriority High
//! @SYMTestStatus Implemented
+#define __E32TEST_EXTENSION__
#include <e32test.h>
RTest test(_L("T_NANDPAGING"));
@@ -38,6 +39,7 @@
#include <f32dbg.h>
#include "testdefs.h"
#include <hal.h>
+#include "nfe.h"
TInt DriveNumber=-1; // Parameter - Which drive? -1 = autodetect.
@@ -544,9 +546,53 @@
return;
}
+ // If the NFE test media driver extension is present, ALL the drive is encrypted;
+ // this means that there will be very few free blocks in the free block reservoir: this effectively
+ // disables background garbage collection and all block erasing needs to happen on the fly...
+ TNfeDeviceInfo nfeDeviceinfo;
+ TPtr8 nfeDeviceInfoBuf((TUint8*) &nfeDeviceinfo, sizeof(nfeDeviceinfo));
+ nfeDeviceInfoBuf.FillZ();
+ TInt r = Drive.QueryDevice((RLocalDrive::TQueryDevice) EQueryNfeDeviceInfo, nfeDeviceInfoBuf);
+/*
+ if (r == KErrNone)
+ {
+ test.Printf(_L("NFE device detected, aborting garbage collection test for now\n"));
+ return;
+ }
+*/
+ // Create some free blocks by creating a huge file and then deleting it....
+ if (r == KErrNone)
+ {
+ test.Printf(_L("NFE device detected\n"));
+ RFile file;
+
+ TBuf<256> tempFileName = _L("?:\\f32-tst\\");
+ tempFileName[0] = 'A'+DriveNumber;
+
+ r = TheFs.MkDirAll(tempFileName);
+ test(r==KErrNone || r== KErrAlreadyExists);
+
+ tempFileName+= _L("TEMP.TXT");
+
+ r = file.Replace(TheFs, tempFileName, EFileWrite);
+ test_KErrNone(r);
+
+ for (TInt fileSize = KMaxTInt; fileSize > 0; fileSize >>= 1)
+ {
+ r = file.SetSize(fileSize);
+ test.Printf(_L("Setting file size to %d, r %d\n"), fileSize, r);
+ if (r == KErrNone)
+ break;
+ }
+ file.Close();
+ r = TheFs.Delete(tempFileName);
+ test_KErrNone(r);
+ }
+
+
+
TInt timeout;
TInt writesNeeded=100;
- TInt r = KErrNone;
RFile tempFile;
TInt i;
TInt ii;
@@ -593,6 +639,7 @@
for (ii=0; ii<MaxDeferLoops; ii++) // Repeat the test, 'MaxDeferLoops' number of times. This can be set on cammand line.
{
+ writesNeeded=100;
timeout=20;
do // while ((pageGarbageCount==0) && (timeout>0));
// ie, while garbage collection hasn't happened, or timed out
--- a/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -11,9 +11,11 @@
// Contributors:
//
// Description:
-// f32test\scndrv\t_scn32dr1.cpp
+// f32test\filesystem\fat\t_scn32dr1.cpp
+// Tests that ScanDrive fixes known errors to a Rugged FAT drive
//
-//
+
+#define __E32TEST_EXTENSION__
#include <f32file.h>
#include <e32test.h>
@@ -262,10 +264,10 @@
{
pos += BootSector.ReservedSectors() * BootSector.BytesPerSector();
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TPtr8 buf(&data[0], 4);
r=TheRawDisk.Read(pos, buf);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
}
@@ -290,7 +292,7 @@
return val;
}
-LOCAL_C void WriteFat(TInt aFatIndex,TInt aValue,const TUint8* aFat)
+LOCAL_C void WriteToFatBuf(TInt aFatIndex,TInt aValue,const TUint8* aFat)
//
// Write a value to both fats starting at aFat
//
@@ -344,7 +346,7 @@
{
TInt nRes = ReadBootSector(TheFs, CurrentDrive(), KBootSectorNum<<KDefaultSectorLog2, BootSector);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
if(!BootSector.IsValid())
{
@@ -580,6 +582,18 @@
aName.SetLength(i);
}
+TDes& MakePrintable(TDes& aDes)
+ {
+ TInt len = aDes.Length();
+
+ for (TInt i=0; i<len; i++)
+ {
+ if ((TUint8) aDes[i] < 0x20)
+ aDes[i] = '?';
+ }
+ return aDes;
+ }
+
GLDEF_C TBool DumpDirEntry(TInt aNum, const TUint8* aEntry)
//
// Dump a single directory entry to the log. Return false if it was end of
@@ -603,9 +617,9 @@
ExtractNameString(name, aEntry);
TInt ord = aEntry[0];
if (ord & KDirLastLongEntry)
- RDebug::Print(_L("%5d: %-15S #%-2d LAST"), aNum, &name, ord & ~KDirLastLongEntry);
+ RDebug::Print(_L("%5d: %-15S #%-2d LAST"), aNum, &MakePrintable(name), ord & ~KDirLastLongEntry);
else
- RDebug::Print(_L("%5d: %-15S #%-2d"), aNum, &name, ord & ~KDirLastLongEntry);
+ RDebug::Print(_L("%5d: %-15S #%-2d"), aNum, &MakePrintable(name), ord & ~KDirLastLongEntry);
}
else if (!IsValidDirEntry(d))
{
@@ -618,7 +632,7 @@
TBuf<11> name;
name.Copy(d->Name());
RDebug::Print(_L("%5d: '%S' %S start %-5d size %d"),
- aNum, &name, DirAttributes(d->Attributes()), d->StartCluster(), d->Size());
+ aNum, &MakePrintable(name), DirAttributes(d->Attributes()), d->StartCluster(), d->Size());
}
return ETrue;
}
@@ -696,12 +710,12 @@
if (aStart < 2 && gDiskType != EFat32)
{
HBufC8* buf=HBufC8::New(BootSector.RootDirEntries() * KSizeOfFatDirEntry);
- test(buf != NULL);
+ test_NotNull(buf);
TPtr8 ptr=buf->Des();
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheRawDisk.Read(gRootDirStart, ptr);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
DumpRootDir(buf->Ptr());
delete(buf);
@@ -712,12 +726,12 @@
if (GetFatEntry(cluster, aFat) != 0)
{
HBufC8* buf=HBufC8::New(gBytesPerCluster);
- test(buf!=NULL);
+ test_NotNull(buf);
TPtr8 ptr=buf->Des();
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheRawDisk.Read(ClusterToByte(cluster), ptr);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
RDebug::Print(_L("Cluster %d @ 0x%08X:"), cluster, ClusterToByte(cluster));
DumpDirCluster(ptr.Ptr());
@@ -786,12 +800,12 @@
//
{
HBufC8* buf=HBufC8::New(gBytesPerCluster*2);
- test(buf!=NULL);
+ test_NotNull(buf);
TPtr8 ptr=buf->Des();
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheRawDisk.Read(ClusterToByte(aCluster), ptr);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
RDebug::Print(_L("Cluster %d @ 0x%08X:"), aCluster, ClusterToByte(aCluster));
TFatDirEntry* d = (TFatDirEntry*)ptr.Ptr() + aEntry;
@@ -829,7 +843,7 @@
nRes = FormatFatDrive(TheFs, CurrentDrive(), ETrue);
#endif
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
}
@@ -847,7 +861,7 @@
num[0] = TText(aDepth % 26 + 'A');
aDir+=num;
r=TheFs.MkDir(aDir);
- test(r==KErrNone);
+ test_KErrNone(r);
}
}
@@ -860,7 +874,7 @@
while(aDepth--)
{
r=TheFs.RmDir(aDir);
- test(r==KErrNone);
+ test_KErrNone(r);
aDir.SetLength(aDir.Length()-2);
}
}
@@ -877,7 +891,7 @@
aDir2=aDir1;
aDir2+=_L("a\\");
TInt r=TheFs.MkDir(aDir2);
- test(r==KErrNone);
+ test_KErrNone(r);
// create dir with depth of 126 directories - one short of max depth
CreateDeepDir(aDir1,101);
// create dir with depth of 90
@@ -891,7 +905,7 @@
{
DeleteDeepDir(aDir2,64);
TInt r=TheFs.RmDir(aDir2);
- test(r==KErrNone);
+ test_KErrNone(r);
aDir2.SetLength(aDir2.Length()-2);
DeleteDeepDir(aDir1,102);
DeleteDeepDir(aDir1,24);
@@ -925,7 +939,7 @@
aLong[len+1] = TText(count%26 + 'A');
count++;
TInt r=temp.Create(TheFs,aLong,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
}
}
@@ -944,7 +958,7 @@
aLong[len+1] = TText(count%26 + 'A');
count++;
TInt r=TheFs.Delete(aLong);
- test(r==KErrNone || r==KErrNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound);
}
}
@@ -966,7 +980,7 @@
name[2]=(TUint16)(count/26%26+'a');
name[3]=(TUint16)(count%26+'a');
r=TheFs.Delete(name);
- test(r==KErrNone || r==KErrNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound);
++count;
}
}
@@ -990,7 +1004,7 @@
name[2]=(TUint16)(count/26%26+'a');
name[3]=(TUint16)(count%26+'a');
r=f.Create(TheFs, name, EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
f.Close();
++count;
}
@@ -1012,7 +1026,7 @@
dir[1]=(TUint16)(count/26+'a');
dir[2]=(TUint16)(count%26+'a');
r=TheFs.MkDir(dir);
- test(r==KErrNone);
+ test_KErrNone(r);
entriesSoFar+=2;
++count;
}
@@ -1032,7 +1046,7 @@
dir[1]=TUint16(count/26+'a');
dir[2]=TUint16(count%26+'a');
r=TheFs.RmDir(dir);
- test(r==KErrNone);
+ test_KErrNone(r);
entriesSoFar-=2;
++count;
}
@@ -1045,27 +1059,27 @@
{
test.Next(_L("Delete Directory Structure"));
TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\almostfull\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
TInt entriesNeeded=(gEntriesPerCluster-2) / 2; //7*2entries + . + .. = full sector
for (TInt i = 0; i < entriesNeeded; i++)
{
TFileName file=_L("\\scndrv\\dir2\\full\\__a");
file.AppendNum(i);
r=TheFs.Delete(file);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
}
r=TheFs.RmDir(_L("\\scndrv\\dir2\\full\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\scndrv\\dir2\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
TFileName veryLongName=(_L("\\scndrv\\dir1\\"));
MakeVeryLongName(veryLongName);
r=TheFs.Delete(veryLongName);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\scndrv\\dir1\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\scndrv\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
}
LOCAL_C void CreateDirectoryStructure()
@@ -1076,34 +1090,34 @@
test.Next(_L("Create Directory Structure"));
// cluster 3 (root dir is cluster 2)
TInt r=TheFs.MkDir(_L("\\scndrv\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 4
r=TheFs.MkDir(_L("\\scndrv\\dir1\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
TFileName veryLongName=(_L("\\scndrv\\dir1\\"));
MakeVeryLongName(veryLongName);
RFile f;
// cluster 5
r=f.Create(TheFs,veryLongName,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.SetSize(512);
- test(r==KErrNone);
+ test_KErrNone(r);
f.Close();
// cluster 6
r=TheFs.MkDir(_L("\\scndrv\\dir2\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 7
r=TheFs.MkDir(_L("\\scndrv\\dir2\\full\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 8
r=TheFs.MkDir(_L("\\scndrv\\dir2\\somedirwith3entries\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 9
r=TheFs.MkDir(_L("\\scndrv\\dir2\\somedir2with3entries\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 10
r=TheFs.MkDir(_L("\\scndrv\\dir2\\almostfull\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// cluster 11-17
TInt entriesNeeded=(gEntriesPerCluster-2) / 2; //7*2entries + . + .. = full sector
for (TInt i = 0; i < entriesNeeded; i++)
@@ -1112,11 +1126,11 @@
file.AppendNum(i);
LastInFull = file;
r=f.Create(TheFs,file,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
if (i < 7)
{
r=f.SetSize(512);
- test(r==KErrNone);
+ test_KErrNone(r);
}
f.Close();
}
@@ -1132,14 +1146,14 @@
file1.AppendNum(1);
file2.AppendNum(2);
r=f.Create(TheFs,file1,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.SetSize(512);
- test(r==KErrNone);
+ test_KErrNone(r);
f.Close();
r=f.Create(TheFs,file2,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.SetSize(512);
- test(r==KErrNone);
+ test_KErrNone(r);
f.Close();
}
@@ -1165,16 +1179,16 @@
// contains aOffset
ExtBufLen = 2 * gBytesPerCluster;
ExtBufPtr = HBufC8::New(ExtBufLen);
- test(ExtBufPtr != NULL);
+ test_NotNull(ExtBufPtr);
// read the clusters in
ExtBufAdd = aOffset - aOffset % gBytesPerCluster;
TInt clust = (ExtBufAdd - (gDataStartBytes - gRootDirStart)) /gBytesPerCluster + 2;
RDebug::Print(_L("Extension buffer for cluster %d allocated"), clust);
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TPtr8 des(ExtBufPtr->Des());
r=TheRawDisk.Read(gRootDirStart + ExtBufAdd, des);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
}
// convert to offset in the extension buffer
@@ -1209,10 +1223,10 @@
// reads directory section of disk into buffer
//
{
- test(aCluster != 1);
+ test_Value(aCluster, aCluster != 1);
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
if (aCluster == -1) // all clusters ?
{
@@ -1233,7 +1247,7 @@
r=TheRawDisk.Read(gRootDirStart + pos, dirPtr);
}
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
}
@@ -1243,21 +1257,21 @@
//
{
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheRawDisk.Read(gFatStartBytes, aFatBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
}
-LOCAL_C void WriteDirDisk(TDes8& aDirBuf, TInt aCluster = -1)
+LOCAL_C void WriteDirEntryToDisk(TDes8& aDirBuf, TInt aCluster = -1)
//
-// writes dir buffer to disk
+// writes dir entry buffer to disk
//
{
- test(aCluster != 1);
+ test_Value(aCluster, aCluster != 1);
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
if (aCluster == -1)
{
@@ -1278,29 +1292,29 @@
r=TheRawDisk.Write(gRootDirStart + pos, dirPtr);
}
- test(r==KErrNone);
+ test_KErrNone(r);
if (ExtBufPtr)
{
TPtr8 des(ExtBufPtr->Des());
r=TheRawDisk.Write(gRootDirStart + ExtBufAdd, des);
- test(r==KErrNone);
+ test_KErrNone(r);
}
TheRawDisk.Close();
}
-LOCAL_C void WriteFatDisk(TDes8& aFatBuf, TInt aStart=0)
+LOCAL_C void WriteFatToDisk(TDes8& aFatBuf, TInt aStart=0)
//
// writes fat buffer to disk
//
{
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TInt fatCount=BootSector.NumberOfFats() - aStart;
TInt pos = gFatStartBytes + aStart * gFatSizeSectors*BootSector.BytesPerSector();
while(fatCount--)
{
r=TheRawDisk.Write(pos, aFatBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
pos += gFatSizeSectors*BootSector.BytesPerSector();
}
TheRawDisk.Close();
@@ -1357,15 +1371,15 @@
gFatTestEntries = KMaxFatSize;
gFatTestSize = PosInBytes(gFatTestEntries);
FatBufPtr=HBufC8::New(gFatTestSize);
- test(FatBufPtr!=NULL);
+ test_NotNull(FatBufPtr);
DirBufPtr=HBufC8::New(DirBufferSize());
- test(DirBufPtr!=NULL);
+ test_NotNull(DirBufPtr);
// Buffers for reading from disk
FatDiskPtr=HBufC8::New(gFatTestSize);
- test(FatDiskPtr!=NULL);
+ test_NotNull(FatDiskPtr);
DirDiskPtr=HBufC8::New(DirBufferSize());
- test(DirDiskPtr!=NULL);
+ test_NotNull(DirDiskPtr);
}
LOCAL_C TBool IsSameAsDrive(const TDes8& aFatBuf,const TDes8& aDirBuf)
@@ -1452,12 +1466,12 @@
else if (ExtBufPtr)
{
HBufC8* extPtr = HBufC8::New(ExtBufLen);
- test(extPtr != NULL);
+ test_NotNull(extPtr);
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TPtr8 des(extPtr->Des());
r=TheRawDisk.Read(ExtBufAdd+gRootDirStart, des);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
TInt i = FindUnMatch(ExtBufPtr->Ptr(), extPtr->Ptr(), ExtBufLen);
if (i >= 0)
@@ -1506,7 +1520,7 @@
if(aAddEOfDir)
WriteEndOfDir(aTrg.iBytePos+aTrg.iLength*KSizeOfFatDirEntry);
TPtr8 dirBuf=DirBufPtr->Des();
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
}
LOCAL_C TBool TestPartialEntry(TEntryInfo aEntry)
@@ -1516,7 +1530,7 @@
{
test.Next(_L("TestPartialEntry"));
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
WriteDelete(aEntry.iBytePos,aEntry.iLength);
TPtr8 fatBuf=FatBufPtr->Des();
@@ -1539,7 +1553,7 @@
if(aAddEOfDir)
WriteEndOfDir(aTrg.iBytePos+aTrg.iLength*KSizeOfFatDirEntry);
TPtr8 dirBuf=DirBufPtr->Des();
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
}
LOCAL_C TBool TestMatchingEntry(TEntryInfo aToDelete)
@@ -1550,7 +1564,7 @@
test.Next(_L("TestMatchingEntries"));
WriteDelete(aToDelete.iBytePos,aToDelete.iLength);
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TPtr8 fatBuf=FatBufPtr->Des();
TPtr8 dirBuf=DirBufPtr->Des();
@@ -1574,8 +1588,8 @@
CDir* dirs;
// check no entries in the root directory
TInt r=TheFs.GetDir(KRoot,KEntryAttMaskSupported,ESortNone,dirs);
- test(r==KErrNone);
- test(dirs->Count()==0);
+ test_KErrNone(r);
+ test_Equal(0,dirs->Count());
delete(dirs);
dirs=NULL;
@@ -1593,13 +1607,13 @@
RFile file;
r=file.Replace(TheFs,TestFileName,EFileShareExclusive);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
// get short name
TFileName shortName;
r=TheFs.GetShortName(TestFileName,shortName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(shortName==KOrigShortName);
// must be first entry in root, modify to read like
@@ -1608,26 +1622,26 @@
TInt bytePos=ClusterEntryToBytes(0,1);
RRawDisk raw;
r=raw.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TBuf8<1> buf(1);
//-- change 2nd character in the short name (Fat DOS entry)
buf[0]=(TUint8)'\xC4';
r=raw.Write(gRootDirStart+bytePos+1,buf);
- test(r==KErrNone);
+ test_KErrNone(r);
//-- fix the fiddled short name checksum in the corresponding VFat entry
bytePos=ClusterEntryToBytes(0,0);
buf[0]=(TUint8)0x2f;
r=raw.Write(gRootDirStart+bytePos+13,buf);
- test(r==KErrNone);
+ test_KErrNone(r);
// retrieve short name from media.
// Note: do not use RFs::GetShortName() as its behaviours are code page dependent.
bytePos=ClusterEntryToBytes(0,1);
TBuf8<11> shortNameBuf8;
r=raw.Read(gRootDirStart+bytePos,shortNameBuf8);
- test(r==KErrNone);
+ test_KErrNone(r);
shortNameBuf8 = DosNameFromStdFormat(shortNameBuf8);
shortName.Copy(shortNameBuf8);
raw.Close();
@@ -1638,15 +1652,15 @@
//TheFs.SetDebugRegister(KFSYS);
r=TheFs.ScanDrive(gSessionPath);
TheFs.SetDebugRegister(0);
- test(r==KErrNone);
+ test_KErrNone(r);
DumpData(NULL, 0, 20);
// retrieve short name from media.
r=raw.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
bytePos=ClusterEntryToBytes(0,1);
r=raw.Read(gRootDirStart+bytePos,shortNameBuf8);
- test(r==KErrNone);
+ test_KErrNone(r);
shortNameBuf8 = DosNameFromStdFormat(shortNameBuf8);
shortName.Copy(shortNameBuf8);
raw.Close();
@@ -1655,7 +1669,7 @@
// delete file
r=TheFs.Delete(TestFileName);
- test(r==KErrNone);
+ test_KErrNone(r);
}
LOCAL_C void TestMountAndScan()
@@ -1668,46 +1682,47 @@
test.Next(_L("TestMountAndScan"));
HBufC8* newFat=HBufC8::New(gFatTestSize);
- test(newFat!=NULL);
+ test_NotNull(newFat);
TPtr8 fat=newFat->Des();
TPtr8 origFat=FatBufPtr->Des();
TPtr8 origDir=DirBufPtr->Des();
// set cluster of \scndrv\dir1\ to a hanging cluster
ReadFatDisk(fat);
- WriteFat(gClusterDir1ext,35,fat.Ptr());
- WriteFat(35,36,fat.Ptr());
- WriteFatDisk(fat);
+ WriteToFatBuf(gClusterDir1ext,35,fat.Ptr());
+ WriteToFatBuf(35,36,fat.Ptr());
+ WriteFatToDisk(fat);
// set the default path to something other than the current drive
TFileName fsName;
TInt r=TheFs.FileSystemName(fsName,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TFileName origDefPath, newDefPath;
r=TheFs.SessionPath(origDefPath);
- test(r==KErrNone);
+ test_KErrNone(r);
newDefPath=origDefPath;
newDefPath[0]=(TText)'z';
r=TheFs.SetSessionPath(newDefPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r = TheFs.ExtensionName(extName,gSessionPath[0]-'A',0);
if (r == KErrNone)
{
primaryExtensionExists = ETrue;
}
r=TheFs.DismountFileSystem(fsName,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
// mount file system and check scandrive corrects error
TBool isMount;
if (primaryExtensionExists)
r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount);
else
r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount);
- test(isMount && r==KErrNone);
+ test(isMount);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(origFat,origDir);
test(res);
r=TheFs.SetSessionPath(origDefPath);
- test(r==KErrNone);
+ test_KErrNone(r);
delete newFat;
}
@@ -1721,14 +1736,14 @@
TBool primaryExtensionExists = EFalse;
TFileName fsName;
TInt r=TheFs.FileSystemName(fsName,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r = TheFs.ExtensionName(extName,gSessionPath[0]-'A',0);
if (r == KErrNone)
{
primaryExtensionExists = ETrue;
}
r=TheFs.DismountFileSystem(fsName,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
// RFs::MountFileSystemAndScan twice consecutively
// first time
@@ -1737,15 +1752,37 @@
r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount);
else
r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount);
- test(isMount && r==KErrNone);
+ test(isMount);
+ test_KErrNone(r);
// and a second time
if (primaryExtensionExists)
r=TheFs.MountFileSystemAndScan(fsName,extName,gSessionPath[0]-'A',isMount);
else
r=TheFs.MountFileSystemAndScan(fsName,gSessionPath[0]-'A',isMount);
- test(!isMount && r==KErrAccessDenied);
+ test(!isMount);
+ test_Equal(KErrAccessDenied,r);
}
+
+static void CreateContiguousClusterChain(TUint32 aStartIndex, TUint32 aEndIndex, const TUint8* aFatPtr, TBool aMarkEoc)
+/*
+ * Creates a contiguous cluster chain in the FAT buffer.
+ *
+ * @param aStartIndex The first cluster index of the chain
+ * aEndIndex The last cluster index of the chain
+ * aFatPtr FAT table buffer pointer
+ * aMarkEoc If ETrue, aEndIndex will be marked as EOC, else it will be a hanging cluster chain
+ */
+ {
+ // Write cluster chain
+ for(TUint i=aStartIndex; i<aEndIndex; ++i)
+ WriteToFatBuf(i, i+1, aFatPtr);
+ // Mark EOC if needed
+ if (aMarkEoc)
+ WriteToFatBuf(aEndIndex, gEndOfChain, aFatPtr);
+ }
+
+
LOCAL_C void DoHangingClusters()
//
// Tests that scandrive removes hanging clusters
@@ -1753,42 +1790,42 @@
{
test.Next(_L("Check Hanging clusters"));
HBufC8* newFat=HBufC8::New(gFatTestSize);
- test(newFat!=NULL);
+ test_NotNull(newFat);
TPtr8 fat=newFat->Des();
TPtr8 origFat=FatBufPtr->Des();
TPtr8 origDir=DirBufPtr->Des();
- // set cluster of \scndrv\dir1\ to a hanging cluster
+ // Set cluster of \scndrv\dir1\ to hanging cluster chain
test.Start(_L("Test hanging cluster in \\scndrv\\dir1\\"));
ReadFatDisk(fat);
- WriteFat(gClusterDir1ext,35,fat.Ptr());
- WriteFat(35,36,fat.Ptr());
- WriteFatDisk(fat);
+ WriteToFatBuf(gClusterDir1ext,35,fat.Ptr());
+ WriteToFatBuf(35,36,fat.Ptr());
+ WriteFatToDisk(fat); // gClusterDir1ext->35->36
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(origFat,origDir);
test(res);
- // set cluster chain of first entry of \scndrv\dir1\ to
+ // Set cluster chain of first entry of \scndrv\dir1\ to
// larger size than file size
test.Next(_L("Test hanging cluster in first entry"));
ReadFatDisk(fat);
- WriteFat(gClusterDir1ext,39,fat.Ptr());
- WriteFat(39,500,fat.Ptr());
- WriteFat(500,gEndOfChain,fat.Ptr());
- WriteFatDisk(fat);
+ WriteToFatBuf(gClusterDir1ext,39,fat.Ptr());
+ WriteToFatBuf(39,500,fat.Ptr());
+ CreateContiguousClusterChain(500, 505, fat.Ptr(), ETrue);
+ WriteFatToDisk(fat); // gClusterDir1ext->39->500->501->502->503->504->505->EOC
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(origFat,origDir);
test(res);
- // set cluster of \scndrv\ to a hanging cluster
+ // Set cluster of \scndrv\ to a hanging cluster
test.Next(_L("Test hanging cluster of \\scndrv\\"));
ReadFatDisk(fat);
- WriteFat(gClusterScnDrv,511,fat.Ptr());
- WriteFatDisk(fat);
+ WriteToFatBuf(gClusterScnDrv,511,fat.Ptr());
+ WriteFatToDisk(fat); // gClusterScnDrv->511
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(origFat,origDir);
test(res);
@@ -1803,7 +1840,7 @@
{
test.Next(_L("Check lost clusters"));
HBufC8* newFat=HBufC8::New(gFatTestSize);
- test(newFat!=NULL);
+ test_NotNull(newFat);
TPtr8 fat=newFat->Des();
TPtr8 origFat=FatBufPtr->Des();
TPtr8 origDir=DirBufPtr->Des();
@@ -1813,12 +1850,10 @@
// write cluster chain
test.Start(_L("Test removal of lost cluster chain"));
ReadFatDisk(fat);
- for(TInt i=25;i<35;++i)
- WriteFat(i,i+1,fat.Ptr());
- WriteFat(35,gEndOfChain,fat.Ptr());
- WriteFatDisk(fat);
+ CreateContiguousClusterChain(25, 35, fat.Ptr(), ETrue);
+ WriteFatToDisk(fat); // 25->26->27->28->29->30->31->32->33->34->35->EOC
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(origFat,origDir);
test(res);
@@ -1829,17 +1864,17 @@
TInt off = j*BootSector.BytesPerSector()+j*7%512;
fat[off]=1;
}
- WriteFatDisk(fat);
+ WriteFatToDisk(fat);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(origFat,origDir);
test(res);
// write semi-random changes to second fat
test.Next(_L("Test semi-random changes to second fat"));
- WriteFatDisk(fat, 1);
+ WriteFatToDisk(fat, 1);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(origFat,origDir);
test(res);
@@ -1847,6 +1882,74 @@
test.End();
}
+
+static void DoHangingAndLostClusters()
+/*
+ * Tests that ScanDrive fixes MULTIPLE hanging clusters and removes lost clusters.
+ * It creates multiple hanging and lost cluster chains in the FAT table and
+ * expects ScanDrive to fix them all.
+ */
+ {
+ test.Start(_L("Check multiple hanging and lost cluster chains"));
+ HBufC8* newFat = HBufC8::New(gFatTestSize);
+ test_NotNull(newFat);
+ TPtr8 fat = newFat->Des();
+ TPtr8 origFat = FatBufPtr->Des();
+ TPtr8 origDir = DirBufPtr->Des();
+ ReadFatDisk(origFat);
+ ReadDirDisk(origDir);
+
+ test.Printf(_L("Create multiple hanging cluster chains\n"));
+ ReadFatDisk(fat);
+ // Set hanging cluster for the file in \scndrv\dir1
+ // gClusterDir1ext+1->25->26->27->28->29->30->31->32->33->34->35
+ WriteToFatBuf(gClusterDir1ext+1, 25, fat.Ptr());
+ CreateContiguousClusterChain(25, 35, fat.Ptr(), EFalse);
+ // Set hanging cluster for the first file in \scndrv\dir2
+ // gClusterDir2_AFull+1->249->250->53->54->55->EOC
+ WriteToFatBuf(gClusterDir2_AFull+1, 249, fat.Ptr());
+ WriteToFatBuf(249, 250, fat.Ptr());
+ WriteToFatBuf(250, 53, fat.Ptr());
+ CreateContiguousClusterChain(53, 55, fat.Ptr(), ETrue);
+ // Set hanging cluster for the fourth file in \scndrv\dir2
+ // gClusterDir2_AFull+4->59->60->61->62->63
+ WriteToFatBuf(gClusterDir2_AFull+4, 59, fat.Ptr());
+ CreateContiguousClusterChain(59, 63, fat.Ptr(), EFalse);
+ // Set hanging cluster for the second file in \scndrv\dir2
+ // gClusterDir2_AFull+2->67->68->69->EOC
+ WriteToFatBuf(gClusterDir2_AFull+2, 67, fat.Ptr());
+ CreateContiguousClusterChain(67, 69, fat.Ptr(), ETrue);
+
+ test.Printf(_L("Create multiple lost clusters\n"));
+ // Create 1st lost cluster chain (clusters 36-45)
+ CreateContiguousClusterChain(36, 45, fat.Ptr(), ETrue);
+ // Create 2nd lost cluster chain (clusters 246-248,56-58)
+ CreateContiguousClusterChain(246, 248, fat.Ptr(), EFalse);
+ WriteToFatBuf(248, 56, fat.Ptr());
+ CreateContiguousClusterChain(56, 58, fat.Ptr(), ETrue);
+ // Create 3rd lost cluster chain (clusters 251-253,564-566, with hanging end)
+ CreateContiguousClusterChain(251, 253, fat.Ptr(), EFalse);
+ WriteToFatBuf(253, 564, fat.Ptr());
+ CreateContiguousClusterChain(564, 566, fat.Ptr(), EFalse);
+
+ // Flush all FAT changes to the media
+ WriteFatToDisk(fat);
+
+ test.Next(_L("Test ScanDrive fixes multiple hanging and lost cluster chains"));
+ TInt r = TheFs.CheckDisk(gSessionPath); // CheckDisk should detect an error
+ test_Value(r, r != KErrNone);
+ r = TheFs.ScanDrive(gSessionPath); // ScanDrive should find the errors and fix them
+ test_KErrNone(r);
+ r = TheFs.CheckDisk(gSessionPath);
+ test_KErrNone(r);
+ TBool res = IsSameAsDrive(origFat, origDir);
+ test(res);
+
+ delete newFat;
+ test.End();
+ }
+
+
LOCAL_C void DoPartEntries()
//
// Tests that scandrive detects/corrects partial entries
@@ -1860,9 +1963,9 @@
TPtr8 dirBuf=DirBufPtr->Des();
TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedirwith3entries\\"));
- test(r==KErrNone || r==KErrNotFound || KErrPathNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound || r==KErrPathNotFound);
r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedir2with3entries\\"));
- test(r==KErrNone || r==KErrNotFound || KErrPathNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound || r==KErrPathNotFound);
if (BootSector.RootDirEntries() != 0)
{
@@ -1871,7 +1974,7 @@
test.Next(_L("Partial entry at end of rootdir"));
FillUpRootDir(2);
r=temp.Create(TheFs,_L("\\temp"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
ReadDirDisk(dirBuf);
ReadFatDisk(fatBuf);
@@ -1891,7 +1994,7 @@
CreatePartialEntry(partial2,3,EFalse);
// entry has been allocated a cluster which scandrive should delete along with partial entry
if (last > 0)
- WriteFat(last,0,fatBuf.Ptr());
+ WriteToFatBuf(last,0,fatBuf.Ptr());
res=TestPartialEntry(partial2);
test(res);
@@ -1899,26 +2002,26 @@
test.Next(_L("Test directory reclaim"));
last = GetStartCluster(gClusterDir2_Full,gEntriesPerCluster-2);
WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2));
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
TInt entry = GetFatEntry(gClusterDir2_Full, fatBuf.Ptr());
- WriteFat(gClusterDir2_Full,gEndOfChain,fatBuf.Ptr());
+ WriteToFatBuf(gClusterDir2_Full,gEndOfChain,fatBuf.Ptr());
while (entry && (entry & gEndOfChain) != gEndOfChain)
{
TInt next = GetFatEntry(entry, fatBuf.Ptr());
- WriteFat(entry,0,fatBuf.Ptr());
+ WriteToFatBuf(entry,0,fatBuf.Ptr());
entry = next;
}
if (last > 0)
- WriteFat(last,0,fatBuf.Ptr());
+ WriteToFatBuf(last,0,fatBuf.Ptr());
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(fatBuf,dirBuf);
test(res);
// use last entry of first cluster in \scndrv\dir2\full\
test.Next(_L("Partial entry at end of subdir"));
r=temp.Create(TheFs,_L("\\scndrv\\dir2\\full\\temp"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
ReadDirDisk(dirBuf);
ReadFatDisk(fatBuf);
@@ -1931,12 +2034,12 @@
test.Next(_L("Partial entry preceeding end-of-dir marker"));
last = GetStartCluster(gClusterDir2_AFull,14);
if (last > 0)
- WriteFat(last,0,fatBuf.Ptr());
+ WriteToFatBuf(last,0,fatBuf.Ptr());
last = GetStartCluster(gClusterDir2_AFull,8);
if (last > 0)
- WriteFat(last,0,fatBuf.Ptr());
+ WriteToFatBuf(last,0,fatBuf.Ptr());
WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_AFull,14));
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
TEntryInfo partial4(ClusterEntryToBytes(gClusterDir2_AFull,8),6);
CreatePartialEntry(partial4,4,EFalse);
res=TestPartialEntry(partial4);
@@ -1952,14 +2055,14 @@
// create entry in \scndrv\dir2\almostfull\
// test.Next(_L("Partial entry with invalid dos name"));
// r=temp.Create(TheFs,_L("\\scndrv\\dir2\\almostfull\\Dodgy file name"),EFileShareAny);
-// test(r==KErrNone);
+// test_KErrNone(r);
// temp.Close();
// ReadDirDisk(dirBuf);
// TInt dosStart=ClusterEntryToBytes(gClusterDir2_AFull,4);
// dirBuf[dosStart+4]=0x1;
// WriteDirDisk(dirBuf);
// r=TheFs.ScanDrive(gSessionPath);
-// test(r==KErrNone);
+// test_KErrNone(r);
// WriteDelete(dosStart-2*32,3);
// res=IsSameAsDrive(fatBuf,dirBuf);
// test(res);
@@ -1971,26 +2074,26 @@
last = GetStartCluster(gClusterDir2_Full,gEntriesPerCluster-1);
WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2));
WriteEndOfDir(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-1));
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
TFileName longFile=_L("\\scndrv\\dir2\\full\\");
MakeVeryLongName(longFile);
r=temp.Create(TheFs,longFile,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
ReadDirDisk(dirBuf);
- WriteFat(gClusterDir2_Full,gClusterDir2_SD3E,fatBuf.Ptr());
- WriteFat(gClusterDir2_SD3E,gClusterDir2_SD23E,fatBuf.Ptr());
- WriteFat(gClusterDir2_SD23E,gEndOfChain,fatBuf.Ptr());
+ WriteToFatBuf(gClusterDir2_Full,gClusterDir2_SD3E,fatBuf.Ptr());
+ WriteToFatBuf(gClusterDir2_SD3E,gClusterDir2_SD23E,fatBuf.Ptr());
+ WriteToFatBuf(gClusterDir2_SD23E,gEndOfChain,fatBuf.Ptr());
if (last > 0)
- WriteFat(last,0,fatBuf.Ptr());
+ WriteToFatBuf(last,0,fatBuf.Ptr());
TEntryInfo partial5(ClusterEntryToBytes(gClusterDir2_Full,gEntriesPerCluster-2),19);
CreatePartialEntry(partial5,7,EFalse);
res=TestPartialEntry(partial5);
test(res);
r=TheFs.Delete(longFile);
- test(r==KErrNone || r==KErrNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound);
r=TheFs.Delete(_L("\\temp"));
- test(r==KErrNone || r==KErrNotFound);
+ test_Value(r, r==KErrNone || r==KErrNotFound);
}
ReadDirDisk(dirBuf);
@@ -2040,16 +2143,16 @@
test.Next(_L("matching entries in same subdir"));
// delete entries to allow contiguous clusters in \scndrv\dir2\full directory
TInt r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedirwith3entries\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\scndrv\\dir2\\somedir2with3entries\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
// ensure directory is expanded
RFile temp;
r=temp.Create(TheFs,_L("\\scndrv\\dir2\\full\\temp"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
r=TheFs.Delete(_L("\\scndrv\\dir2\\full\\temp"));
- test(r==KErrNone);
+ test_KErrNone(r);
ReadDirDisk(dirBuf);
ReadFatDisk(fatBuf);
TEntryInfo from4(ClusterEntryToBytes(gClusterDir2_Full,4),2);
@@ -2062,14 +2165,14 @@
test.Next(_L("matching entries in diff dirs + new cluster"));
// delete last entry in directory
r=TheFs.Delete(LastInFull);
- test(r==KErrNone);
+ test_KErrNone(r);
TFileName veryLongName=_L("\\scndrv\\dir2\\full\\");
MakeVeryLongName(veryLongName);
r=temp.Create(TheFs,veryLongName,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
temp.Close();
r=TheFs.Delete(veryLongName);
- test(r==KErrNone);
+ test_KErrNone(r);
ReadDirDisk(dirBuf);
ReadFatDisk(fatBuf);
TEntryInfo from5(ClusterEntryToBytes(gClusterDir1,2),19);
@@ -2099,7 +2202,7 @@
ReadFatDisk(fatBuf);
// run scandisk and compare
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(fatBuf,dirBuf);
test(res);
// Create a entry with matching start cluster and check fixed up
@@ -2126,7 +2229,7 @@
ReadFatDisk(fatBuf);
TInt r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(fatBuf,dirBuf);
test(res);
@@ -2219,9 +2322,9 @@
name.AppendNumFixedWidth(i+totalFilesCreated, EHex, 3);
RFile f;
r = f.Create(TheFs, name, EFileShareAny);
- test(r == KErrNone);
+ test_KErrNone(r);
r = f.Write(buf);
- test(r == KErrNone);
+ test_KErrNone(r);
f.Close();
}
@@ -2254,7 +2357,7 @@
}
- WriteDirDisk(dirBuf, cluster);
+ WriteDirEntryToDisk(dirBuf, cluster);
totalFilesCreated += filesThisTime;
test.Printf(_L(" created %d entries\n"), totalFilesCreated);
}
@@ -2266,7 +2369,7 @@
test.Printf(_L("Running ScanDrive\n"), filesThisTime);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TBool res=IsSameAsDrive(fatBuf,dirBuf);
test(res);
@@ -2278,17 +2381,17 @@
name.Append(_L("tempfile."));
name.AppendNumFixedWidth(i, EHex, 3);
r = TheFs.Delete(name);
- test(r == KErrNone);
+ test_KErrNone(r);
}
ReadDirDisk(dirBuf);
ReadFatDisk(fatBuf);
WriteEndOfDir(ClusterEntryToBytes(cluster, startEntry));
- WriteDirDisk(dirBuf);
+ WriteDirEntryToDisk(dirBuf);
test.Printf(_L("Running ScanDrive\n"), filesThisTime);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
res=IsSameAsDrive(fatBuf,dirBuf);
test(res);
}
@@ -2329,6 +2432,7 @@
DoPartEntries();
DoLostClusters();
DoHangingClusters();
+ DoHangingAndLostClusters();
TestMountAndScan();
TestConsecutiveMountAndScans();
DeleteDirectoryStructure();
@@ -2350,7 +2454,7 @@
{
TInt r;
r = TheFs.CharToDrive(gSessionPath[0], gDriveNumber);
- test( KErrNone == r );
+ test_KErrNone(r);
//-- set up console output
@@ -2368,7 +2472,7 @@
// check this is not the internal ram drive
TVolumeInfo v;
r=TheFs.Volume(v);
- test(r==KErrNone);
+ test_KErrNone(r);
if(v.iDrive.iMediaAtt&KMediaAttVariableSize)
{
test.Printf(_L("Error: Internal ram drive not tested\n"));
@@ -2376,7 +2480,7 @@
}
r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
DoTests();
--- a/kerneltest/f32test/filesystem/fat/t_tscan32.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/filesystem/fat/t_tscan32.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -11,9 +11,10 @@
// Contributors:
//
// Description:
-// f32test\scndrv\t_tscan32.cpp
+// f32test\filesystem\fat\t_tscan32.cpp
//
-//
+
+#define __E32TEST_EXTENSION__
#include <f32file.h>
#include <e32test.h>
@@ -36,9 +37,9 @@
#ifdef _DEBUG
GLREF_D RTest test;
-GLDEF_D TInt TheFunctionNumber;
-GLDEF_D TInt TheOpNumber;
-GLDEF_D TInt TheFailCount;
+GLDEF_D TInt TheFunctionNumber; // Indicates which test to run
+GLDEF_D TInt TheOpNumber; // Indicates which file operation to be tested
+GLDEF_D TInt TheFailCount;
GLDEF_D TBool IsReset;
GLDEF_D TFileName TestExeName=_L("?:\\T_SCANDR.EXE"); //Renaming it to fit in one root dir entry.
GLDEF_D TFileName LogFileName=_L("?:\\T_SCANDR.LOG"); //Renaming it to fit in one root dir entry.
@@ -56,8 +57,8 @@
const TInt KDirAttrLongMask = KDirAttrLongName | KDirAttrDirectory | KDirAttrArchive;
const TInt KDirLastLongEntry = 0x40;
-GLDEF_D TInt WriteFailValue;
-
+GLDEF_D TInt WriteFailValue; // Indicates what error should return from a write failure
+ // Value assigned in t_scn32dr2 and t_scn32dr3
LOCAL_C TFatBootSector BootSector;
LOCAL_D RRawDisk TheRawDisk;
@@ -79,7 +80,13 @@
LOCAL_D HBufC8* gFatBuf = NULL;
LOCAL_D TInt gFatAddr = -1;
-enum TFatChain {EChainStd,EChainAlternate,EChainBackwards,EChainForwards};
+enum TFatChain
+ {
+ EChainStd, // Cluster chain grows contiguously
+ EChainAlternate, // Cluster chain grows forward but not contiguously
+ EChainBackwards, // Cluster chain first goes backwards(up to 3.5kb for fat16 file) and then forwards
+ EChainForwards // Cluster chain first goes forward (upto 3.5kb for fat16 file) and then backwards
+ };
LOCAL_C TBool IsInternalRam()
//
@@ -88,7 +95,7 @@
{
TVolumeInfo v;
TInt r=TheFs.Volume(v,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
return(v.iDrive.iMediaAtt&KMediaAttVariableSize);
}
@@ -102,10 +109,10 @@
TInt r=log.Open(TheFs,LogFileName,EFileShareExclusive|EFileWrite);
if(r!=KErrNone)
test.Printf(_L("error=%d\n"),r);
- test(r==KErrNone);
+ test_KErrNone(r);
TInt size;
r=log.Size(size);
- test(r==KErrNone);
+ test_KErrNone(r);
TBuf8<16> buf;
buf.SetLength(4);
buf[0]=(TUint8)TheFunctionNumber;
@@ -113,7 +120,7 @@
buf[2]=(TUint8)TheFailCount;
buf[3]='\n';
r=log.Write(size,buf,buf.Length());
- test(r==KErrNone);
+ test_KErrNone(r);
test.Printf(_L("Written func=%d,op=%d,fail=%d\n"),TheFunctionNumber,TheOpNumber,TheFailCount);
log.Close();
}
@@ -141,8 +148,8 @@
TInt r=log.Open(TheFs,LogFileName,EFileShareExclusive);
if(r!=KErrNone)
test.Printf(_L("error in ReadLogFile()=%d\n"),r);
- test(r==KErrNone);
- test(r==KErrNone);
+ test_KErrNone(r);
+
TInt fileSize;
r=log.Size(fileSize);
if(fileSize==0)
@@ -187,7 +194,7 @@
*/
static void DoZeroFillMedia(TInt64 aStartPos, TInt64 aEndPos, RRawDisk& aWriter)
{
- test(aStartPos >=0 && aEndPos >=0 && aStartPos < aEndPos);
+ test(aStartPos >=0 && aEndPos >=0 && aStartPos < aEndPos);
if(aStartPos == aEndPos)
return;
@@ -198,7 +205,7 @@
const TUint32 KBufSz=65536*2; //-- buffer with zeroes
nRes = buf.CreateMax(KBufSz);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
buf.FillZ();
@@ -209,7 +216,7 @@
TPtrC8 ptr(buf.Ptr(), bytesToWrite);
nRes = aWriter.Write(aStartPos, ptr);
- test(nRes == KErrNone || nRes == KErrDiskFull);
+ test_Value(nRes, nRes == KErrNone || nRes == KErrDiskFull);
aStartPos+=bytesToWrite;
rem-=bytesToWrite;
@@ -227,7 +234,7 @@
{
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
TUint32 startPos = gDataStartBytes;
if (gDiskType == EFat32)
@@ -269,7 +276,7 @@
{
TInt nRes = ReadBootSector(TheFs, CurrentDrive(), KBootSectorNum<<KDefaultSectorLog2, BootSector);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
if(!BootSector.IsValid())
{
@@ -323,7 +330,7 @@
if (!gFatBuf)
{
gFatBuf=HBufC8::New(gBytesPerCluster);
- test(gFatBuf!=NULL);
+ test_NotNull(gFatBuf);
gFatAddr = -1;
}
@@ -339,10 +346,10 @@
if (gFatAddr < 0 || pos < gFatAddr || pos >= gFatAddr + gBytesPerCluster)
{
TPtr8 ptr=gFatBuf->Des();
- TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
+ test_KErrNone(r);
r=TheRawDisk.Read(pos, ptr);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
gFatAddr = pos;
}
@@ -550,6 +557,18 @@
aName.SetLength(i);
}
+TDes& MakePrintable(TDes& aDes)
+ {
+ TInt len = aDes.Length();
+
+ for (TInt i=0; i<len; i++)
+ {
+ if ((TUint8) aDes[i] < 0x20)
+ aDes[i] = '?';
+ }
+ return aDes;
+ }
+
GLDEF_C TBool DumpDirEntry(TInt aNum, const TUint8* aEntry)
//
// Dump a single directory entry to the log. Return false if it was end of
@@ -569,9 +588,9 @@
ExtractNameString(name, aEntry);
TInt ord = aEntry[0];
if (ord & KDirLastLongEntry)
- RDebug::Print(_L("%5d: %-15S #%-2d LAST"), aNum, &name, ord & ~KDirLastLongEntry);
+ RDebug::Print(_L("%5d: %-15S #%-2d LAST"), aNum, &MakePrintable(name), ord & ~KDirLastLongEntry);
else
- RDebug::Print(_L("%5d: %-15S #%-2d"), aNum, &name, ord & ~KDirLastLongEntry);
+ RDebug::Print(_L("%5d: %-15S #%-2d"), aNum, &MakePrintable(name), ord & ~KDirLastLongEntry);
}
else if (!IsValidDirEntry(d))
return EFalse;
@@ -580,7 +599,7 @@
TBuf<11> name;
name.Copy(d->Name());
RDebug::Print(_L("%5d: '%S' %S cluster %d"),
- aNum, &name, DirAttributes(d->Attributes()), d->StartCluster());
+ aNum, &MakePrintable(name), DirAttributes(d->Attributes()), d->StartCluster());
}
return ETrue;
}
@@ -619,12 +638,12 @@
if (GetFatEntry(cluster, aFat) != 0)
{
HBufC8* buf=HBufC8::New(gBytesPerCluster);
- test(buf!=NULL);
+ test_NotNull(buf);
TPtr8 ptr=buf->Des();
TInt r=TheRawDisk.Open(TheFs,gSessionPath[0]-'A');
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheRawDisk.Read(ClusterToByte(cluster), ptr);
- test(r==KErrNone);
+ test_KErrNone(r);
TheRawDisk.Close();
RDebug::Print(_L("Cluster %d @ 0x%08X:"), cluster, ClusterToByte(cluster));
DumpDirCluster(ptr.Ptr());
@@ -708,7 +727,7 @@
dir[1]=TUint16(count/26+'a');
dir[2]=TUint16(count%26+'a');
r=TheFs.MkDir(dir);
- test(r==KErrNone);
+ test_KErrNone(r);
entriesSoFar+=2;
++count;
}
@@ -733,7 +752,7 @@
dir[1]=TUint16(count/26+'a');
dir[2]=TUint16(count%26+'a');
r=TheFs.RmDir(dir);
- test(r==KErrNone);
+ test_KErrNone(r);
entriesSoFar-=2;
++count;
}
@@ -755,7 +774,7 @@
{
TEntry entry;
TInt r=TheFs.Entry(aName,entry);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
return(r==KErrNone?(TBool)ETrue:(TBool)EFalse);
}
@@ -794,7 +813,7 @@
//
{
TInt r=TheFs.Entry(aName,aEntry);
- test(r==KErrNone);
+ test_KErrNone(r);
}
LOCAL_C TBool IsSameEntryDetails(TEntry aOldEntry,TEntry aNewEntry)
@@ -817,9 +836,9 @@
TInt size1,size2;
size1=size2=0;
TInt r=file1.Create(TheFs,aNameOne,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file2.Create(TheFs,aNameTwo,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
// one entry for file1 for every 40 entries for file2
// if file 1 subseqently deleted then 7 entries available
// in that fat sector - ~3.5kb file size - for fat16
@@ -831,15 +850,15 @@
{
size1+=gBytesPerCluster;
r=file1.SetSize(size1);
- test(r==KErrNone);
+ test_KErrNone(r);
first=EFalse;
--entries;
}
else
{
size2+=gBytesPerCluster*ratio;
- r=file1.SetSize(size1);
- test(r==KErrNone);
+ r=file2.SetSize(size2);
+ test_KErrNone(r);
first=ETrue;
entries-=ratio;
}
@@ -892,7 +911,7 @@
TFileName fullName(aName);
fullName.Append(fn);
TInt r = TheFs.Delete(fullName);
- test(r == KErrNone);
+ test_KErrNone(r);
entry += 1 + (fn.Length() + 12) / 13;
}
RDebug::Print(_L("CleanDirectory(%S, %d)"), &aName, aClusters);
@@ -927,7 +946,7 @@
fullName.Append(fn);
RFile file;
TInt r = file.Create(TheFs,fullName,EFileShareAny);
- test(r == KErrNone);
+ test_KErrNone(r);
file.Close();
entry += 1 + (fn.Length() + 12) / 13;
}
@@ -942,7 +961,7 @@
//
{
TInt r=TheFs.Delete(_L("\\fat\\file2"));
- test(r==KErrNone||KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(aIsDir)
return(TheFs.RmDir(aName));
else
@@ -956,7 +975,7 @@
//
{
TInt r=DeleteAlternateEntry(aName,aIsDir);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
RFile file;
if(aIsDir)
{
@@ -970,17 +989,17 @@
if(r!=KErrNone)
return(r);
r=file.SetSize(1); //ensure file allocated a start cluster
- test(r==KErrNone);
+ test_KErrNone(r);
}
CreateAlternate(_L("\\fat\\file1"),_L("\\fat\\file2"));
r=TheFs.Delete(_L("\\fat\\file1"));
- test(r==KErrNone);
+ test_KErrNone(r);
if(aIsDir)
ExpandDirectory(aName,aSize);
else
{
r=file.SetSize(aSize);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
}
return(KErrNone);
@@ -992,11 +1011,11 @@
//
{
TInt r=TheFs.Delete(_L("\\fat\\file2"));
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
r=TheFs.Delete(_L("\\fat\\file4"));
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
r=TheFs.Delete(_L("\\fat\\file5"));
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(aIsDir)
r=TheFs.RmDir(aName);
else
@@ -1011,16 +1030,16 @@
//
{
TInt r=DeleteForwardEntry(aName,aIsDir);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
RFile file1,file2,entry;
r=file1.Create(TheFs,_L("\\fat\\file1"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file1.SetSize(EntriesPerFatSector()*gBytesPerCluster);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file2.Create(TheFs,_L("\\fat\\file2"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file2.SetSize(EntriesPerFatSector()*gBytesPerCluster);
- test(r==KErrNone);
+ test_KErrNone(r);
if(aIsDir)
{
r=TheFs.MkDir(aName);
@@ -1033,27 +1052,27 @@
if(r!=KErrNone)
return(r);
r=entry.SetSize(1); // ensure entry has start cluster allocated
- test(r==KErrNone);
+ test_KErrNone(r);
}
CreateAlternate(_L("\\fat\\file3"),_L("\\fat\\file4"));
RFile file5;
r=file5.Create(TheFs,_L("\\fat\\file5"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file5.SetSize(EntriesPerFatSector()*gBytesPerCluster*2);
- test(r==KErrNone);
+ test_KErrNone(r);
file1.Close();
file2.Close();
file5.Close();
r=TheFs.Delete(_L("\\fat\\file1"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Delete(_L("\\fat\\file3"));
- test(r==KErrNone);
+ test_KErrNone(r);
if(aIsDir)
ExpandDirectory(aName,aSize);
else
{
r=entry.SetSize(aSize);
- test(r==KErrNone);
+ test_KErrNone(r);
entry.Close();
}
return(KErrNone);
@@ -1065,9 +1084,9 @@
//
{
TInt r=TheFs.Delete(_L("\\fat\\file2"));
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
r=TheFs.Delete(_L("\\fat\\file3"));
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(aIsDir)
r=TheFs.RmDir(aName);
else
@@ -1082,7 +1101,7 @@
//
{
TInt r=DeleteBackwardEntry(aName,aIsDir);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
CreateAlternate(_L("\\fat\\file1"),_L("\\fat\\file2"));
RFile entry;
if(aIsDir)
@@ -1097,22 +1116,22 @@
if(r!=KErrNone)
return(r);
r=entry.SetSize(1);
- test(r==KErrNone);
+ test_KErrNone(r);
}
RFile file3;
r=file3.Create(TheFs,_L("\\fat\\file3"),EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file3.SetSize(EntriesPerFatSector()*gBytesPerCluster);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Delete(_L("\\fat\\file1"));
- test(r==KErrNone);
+ test_KErrNone(r);
file3.Close();
if(aIsDir)
ExpandDirectory(aName,aSize);
else
{
r=entry.SetSize(aSize);
- test(r==KErrNone);
+ test_KErrNone(r);
entry.Close();
}
return(KErrNone);
@@ -1135,7 +1154,7 @@
//
{
TInt r=DeleteStdEntry(aName,aIsDir);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(aIsDir)
{
r=TheFs.MkDir(aName);
@@ -1150,12 +1169,12 @@
if(r==KErrNone)
{
r=file.SetSize(aSize);
- test(r==KErrNone);
+ test_KErrNone(r);
}
else if(r==KErrAlreadyExists)
{
TInt res =file.Open(TheFs,aName,EFileShareAny);
- test(res==KErrNone);
+ test_KErrNone(res);
}
else
return(r);
@@ -1206,28 +1225,28 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Delete(aName);
if(r==KErrNone)
break;
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(!EntryExists(aName));
++TheOpNumber;
TheFailCount=0;
@@ -1262,18 +1281,18 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aName,ETrue,aChain,aDirSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(aName);
if(r==KErrNone)
break;
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
RDebug::Print(_L("%6d: ScanDrive = %d"), __LINE__, r);
if (r != KErrNone)
@@ -1282,16 +1301,16 @@
DumpFat();
DumpData(NULL, 0, 200);
}
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
RDebug::Print(_L("%6d: CheckDisk = %d"), __LINE__, r);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(!EntryExists(aName));
++TheOpNumber;
TheFailCount=0;
@@ -1309,31 +1328,31 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=DeleteEntry(aName,ETrue,EChainStd);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.MkDir(aName);
if(r==KErrNone)
break;
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aName));
r=DeleteEntry(aName,ETrue,EChainStd);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1351,9 +1370,9 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aOldName,aIsDir,aChain,aSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
r=DeleteEntry(aNewName,aIsDir,aChain);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
GetEntryDetails(aOldName,oldEntryInfo);
if(IsReset)
{
@@ -1361,34 +1380,29 @@
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Rename(aOldName,aNewName);
if(r==KErrNone)
break;
- if(r!=WriteFailValue)
- {
- test.Printf(_L("r=%d\n"),r);
- test(EFalse);
- }
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
// no start cluster if aSize==0
if(aSize!=0)
test(OneEntryExists(aOldName,aNewName));
++failCount;
}
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aNewName) && !EntryExists(aOldName));
GetEntryDetails(aNewName,newEntryInfo);
test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
r=DeleteEntry(aNewName,aIsDir,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1410,16 +1424,16 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aOldName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
if(aBothExist)
{
r=CreateEntry(aNewName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
}
else
{
r=DeleteEntry(aNewName,EFalse,aChain);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
}
GetEntryDetails(aOldName,oldEntryInfo);
if(IsReset)
@@ -1428,15 +1442,15 @@
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Replace(aOldName,aNewName);
if(r==KErrNone)
break;
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
if(!aBothExist && aFileSize!=0)
test(OneEntryExists(aOldName,aNewName));
else if(aBothExist)
@@ -1444,14 +1458,14 @@
++failCount;
}
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aNewName) && !EntryExists(aOldName));
GetEntryDetails(aNewName,newEntryInfo);
test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
r=DeleteEntry(aNewName,EFalse,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1468,35 +1482,35 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=DeleteEntry(aName,EFalse,EChainStd);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Create(TheFs,aName,EFileShareAny);
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aName));
r=DeleteEntry(aName,EFalse,EChainStd);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1519,28 +1533,28 @@
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Temp(TheFs,aPath,temp,EFileShareAny);
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
test(r==WriteFailValue);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(temp));
r=DeleteEntry(temp,EFalse,EChainStd);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1558,9 +1572,9 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aOldName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
r=DeleteEntry(aNewName,EFalse,aChain);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
GetEntryDetails(aOldName,oldEntryInfo);
if(IsReset)
{
@@ -1569,34 +1583,34 @@
}
RFile file;
r=file.Open(TheFs,aOldName,EFileShareExclusive|EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file.Rename(aNewName);
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
file.Close();
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
if(aFileSize)
test(OneEntryExists(aOldName,aNewName));
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aNewName) && !EntryExists(aOldName));
GetEntryDetails(aNewName,newEntryInfo);
test(IsSameEntryDetails(oldEntryInfo,newEntryInfo));
r=DeleteEntry(aNewName,EFalse,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheOpNumber;
TheFailCount=0;
}
@@ -1615,12 +1629,12 @@
if(aAlreadyExists)
{
r=CreateEntry(aName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
}
else
{
r=DeleteEntry(aName,EFalse,aChain);
- test(r==KErrNone||r==KErrNotFound);
+ test_Value(r, r==KErrNone||r==KErrNotFound);
}
if(IsReset)
{
@@ -1628,28 +1642,28 @@
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Replace(TheFs,aName,EFileShareAny);
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
test(EntryExists(aName));
r=DeleteEntry(aName,EFalse,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
if(!aAlreadyExists)
{
++TheOpNumber;
@@ -1675,54 +1689,54 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aName,EFalse,aChain,aOldFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file.SetSize(aNewFileSize);
// close the file before testing the return value!
file.Close();
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
file.Close();
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
TInt size;
r=file.Size(size);
- test(r==KErrNone);
- test(size==aNewFileSize||size==aOldFileSize);
+ test_KErrNone(r);
+ test_Value(size, size==aNewFileSize||size==aOldFileSize);
file.Close();
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Open(TheFs,aName,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
TInt fileSize;
r=file.Size(fileSize);
- test(r==KErrNone);
- test(aNewFileSize==fileSize);
+ test_KErrNone(r);
+ test_Equal(aNewFileSize,fileSize);
file.Close();
r=DeleteEntry(aName,EFalse,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
++TheFunctionNumber;
TheFailCount=0;
}
@@ -1739,7 +1753,7 @@
TInt newSize=(aFileSize>=aPos+aLength)?aFileSize:aPos+aLength;
HBufC8* desPtr;
desPtr=HBufC8::New(aLength);
- test(desPtr!=NULL);
+ test_NotNull(desPtr);
TPtr8 des=desPtr->Des();
des.SetLength(aLength);
InitialiseWriteBuffer(des);
@@ -1747,64 +1761,64 @@
{
test.Printf(_L("failCount=%d\n"),failCount);
r=CreateEntry(aName,EFalse,aChain,aFileSize);
- test(r==KErrNone||r==KErrAlreadyExists);
+ test_Value(r, r==KErrNone||r==KErrAlreadyExists);
if(IsReset)
{
++TheFailCount;
WriteLogFile();
}
r=SetWriteFailOn(failCount);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Open(TheFs,aName,EFileShareAny|EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file.Write(aPos,des,aLength);
if(r==KErrNone)
{
r=TheFs.ControlIo(gSessionPath[0]-'A',KControlIoWriteFailOff);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
break;
}
- test(r==WriteFailValue);
+ test_Equal(WriteFailValue,r);
file.Close();
r=TheFs.ScanDrive(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Open(TheFs,aName,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
TInt fileSize;
r=file.Size(fileSize);
// with fair scheduling enabled it's possible for the file
// size to grow even if the write appears to have failed...
-// test(fileSize==aFileSize||fileSize==newSize);
- test(fileSize>=aFileSize && fileSize <= newSize);
+// test_Value(fileSize, fileSize==aFileSize||fileSize==newSize);
+ test_Value(fileSize, fileSize>=aFileSize && fileSize <= newSize);
file.Close();
++failCount;
}
r=TheFs.CheckDisk(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Open(TheFs,aName,EFileShareAny);
- test(r==KErrNone);
+ test_KErrNone(r);
TInt fileSize;
r=file.Size(fileSize);
- test(r==KErrNone);
- test(newSize==fileSize);
+ test_KErrNone(r);
+ test_Equal(newSize,fileSize);
HBufC8* desPtr2;
desPtr2=HBufC8::New(aLength);
- test(desPtr2!=NULL);
+ test_NotNull(desPtr2);
TPtr8 des2=desPtr2->Des();
des2.SetLength(aLength);
r=file.Read(aPos,des2,des2.Length());
- test(r==KErrNone);
+ test_KErrNone(r);
r=des2.Compare(des);
- test(r==0);
+ test_KErrNone(r);
file.Close();
r=DeleteEntry(aName,EFalse,aChain);
- test(r==KErrNone);
+ test_KErrNone(r);
delete desPtr;
delete desPtr2;
++TheFunctionNumber;
@@ -1973,7 +1987,7 @@
ClearDiskData();
r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
switch(TheFunctionNumber)
{
@@ -1981,15 +1995,15 @@
case(1):{
TestOperation1();
r=TheFs.MkDir(_L("\\fat\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.MkDir(_L("\\test\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.MkDir(_L("\\ANother\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.MkDir(_L("\\test\\subdir1\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.MkDir(_L("\\test\\subdir2\\"));
- test(r==KErrNone);}
+ test_KErrNone(r);}
case(2):{
TestOperation2();
// add some filler files
@@ -2037,15 +2051,15 @@
DeleteEntry(_L("\\test\\subdir1\\FillerTwo"),EFalse,EChainStd);
DeleteEntry(_L("\\test\\subdir1\\FillerOne"),EFalse,EChainStd);
r=TheFs.RmDir(_L("\\test\\subdir2\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\test\\subdir1\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\ANother\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\test\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\fat\\"));
- test(r==KErrNone);
+ test_KErrNone(r);
if (gFatBuf)
{
delete gFatBuf;
--- a/kerneltest/f32test/group/bld.inf Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/group/bld.inf Fri Apr 23 22:20:31 2010 +0100
@@ -31,6 +31,8 @@
../../../userlibandfileserver/fileserver/inc/runtests.h /epoc32/include/
PRJ_TESTMMPFILES
+../../e32test/mediaext/t_nfe
+
// These tests must be run early on so they do not time out on LFFS disks.
#ifdef WINS
@@ -259,6 +261,7 @@
t_plugin_v2beta.mmp
t_localtime
+
#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
t_file64bit manual
fhserver64bit support
--- a/kerneltest/f32test/group/t_nandpaging.mmp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/group/t_nandpaging.mmp Fri Apr 23 22:20:31 2010 +0100
@@ -17,6 +17,7 @@
TARGET t_nandpaging.exe
TARGETTYPE EXE
+userinclude ../../e32test/mediaext
SOURCEPATH ../demandpaging
SOURCE t_nandpaging.cpp
LIBRARY euser.lib efsrv.lib hal.lib
--- a/kerneltest/f32test/group/wintest.bat Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/group/wintest.bat Fri Apr 23 22:20:31 2010 +0100
@@ -175,6 +175,7 @@
echo FlashResumeTime 0 >>%EPOCROOT%epoc32\data\epoc.ini
echo FlashWriteTime 0 >>%EPOCROOT%epoc32\data\epoc.ini
echo NandDriverType=XSR >>%EPOCROOT%epoc32\data\epoc.ini
+ echo MediaExtensionDriver=?medtestnfe.pdd >>%EPOCROOT%epoc32\data\epoc.ini
if exist %BASEPATH%e32\rombuild\platsec.settings (
type %BASEPATH%e32\rombuild\platsec.settings >>%EPOCROOT%epoc32\data\epoc.ini
) else (
--- a/kerneltest/f32test/server/t_misc.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/kerneltest/f32test/server/t_misc.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -15,10 +15,16 @@
//
//
+#define __E32TEST_EXTENSION__
#include <f32file.h>
#include <e32test.h>
#include "t_server.h"
+// If there is an NFE media driver present, then because of the way EDeleteNotify requests work,
+// the data retrieved from a deleted file will not be a buffer full of zero's, but instead a buffer
+// full of decrypted zero's
+#define __NFE_MEDIA_DRIVER_PRESENT__
+
#ifdef __VC32__
// Solve compilation problem caused by non-English locale
#pragma setlocale("english")
@@ -26,6 +32,8 @@
GLDEF_D RTest test(_L("T_MISC"));
+const TUint KBufLength = 0x100;
+
LOCAL_C void Test1()
//
// Open, write to and read from a file
@@ -34,19 +42,19 @@
test.Next(_L("Open, write to and read from a file"));
TInt r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Create(TheFs,_L("Hello.Wld"),EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
r=file.Write(_L8("Hello World"),11);
- test(r==KErrNone);
+ test_KErrNone(r);
file.Close();
r=file.Open(TheFs,_L("Hello.Wld"),EFileRead);
- test(r==KErrNone);
+ test_KErrNone(r);
TBuf8<256> buf;
r=file.Read(buf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(buf==_L8("Hello World"));
file.Close();
}
@@ -59,17 +67,17 @@
test.Next(_L("Open and read from a file"));
TInt r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
RFile file;
r=file.Open(TheFs,_L("Hello.Wld"),EFileRead);
- test(r==KErrNone);
+ test_KErrNone(r);
TBuf8<256> buf;
r=file.Read(buf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(buf==_L8("Hello World"));
file.Close();
r=TheFs.Delete(_L("HELLO.WLD"));
- test(r==KErrNone);
+ test_KErrNone(r);
}
LOCAL_C void Test3()
@@ -80,25 +88,25 @@
test.Next(_L("Create nested directories"));
TInt r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TheFs.ResourceCountMarkStart();
//
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\A.B"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\RIGHT\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
//
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\ONE\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\TWO\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\THREE\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\TWO\\BOTTOM\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
//
r=TheFs.MkDirAll(_L("\\F32-TST\\RIGHT\\TOP\\MID\\BOT\\"));
- test(r==KErrNone || r==KErrAlreadyExists);
+ test_Value(r, r == KErrNone || r==KErrAlreadyExists);
}
LOCAL_C void Test4()
@@ -109,58 +117,58 @@
test.Next(_L("Test returned error values"));
TInt r=TheFs.SetSessionPath(gSessionPath);
- test(r==KErrNone);
+ test_KErrNone(r);
TheFs.ResourceCountMarkStart();
//
r=TheFs.MkDir(_L("\\"));
- test(r==KErrAlreadyExists);
+ test_Value(r, r == KErrAlreadyExists);
r=TheFs.MkDir(_L("\\LEFT"));
- test(r==KErrAlreadyExists);
+ test_Value(r, r == KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\"));
- test(r==KErrAlreadyExists);
+ test_Value(r, r == KErrAlreadyExists);
r=TheFs.MkDir(_L("\\F32-TST\\LEFT\\..\\NEWDIR\\"));
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
r=TheFs.MkDir(_L("\\F32-TST\\NEWDIR\\SUBDIR\\"));
- test(r==KErrPathNotFound);
+ test_Value(r, r == KErrPathNotFound);
//
r=TheFs.RmDir(_L("\\"));
- test(r==KErrInUse);
+ test_Value(r, r == KErrInUse);
r=TheFs.RmDir(_L("\\PROG"));
- test(r==KErrInUse);
+ test_Value(r, r == KErrInUse);
r=TheFs.RmDir(_L("\\F32-TST\\"));
- test(r==KErrInUse);
+ test_Value(r, r == KErrInUse);
RDir dir;
r=dir.Open(TheFs,_L("V:\\asdf"),KEntryAttNormal);
- test(r==KErrNone || r==KErrNotReady || r==KErrNotFound);
+ test_Value(r, r == KErrNone || r==KErrNotReady || r==KErrNotFound);
if (r==KErrNone)
dir.Close();
r=dir.Open(TheFs,_L("L:\\asdf"),KEntryAttNormal);
- test(r==KErrNone || r==KErrNotReady || r==KErrNotFound);
+ test_Value(r, r == KErrNone || r==KErrNotReady || r==KErrNotFound);
dir.Close();
//
TEntry entry;
r=TheFs.Entry(_L("z:\\NOTEXiSTS\\file.txt"),entry);
- test(r==KErrPathNotFound);
+ test_Value(r, r == KErrPathNotFound);
r=TheFs.Entry(_L("z:\\NOTEXiSTS\\"),entry);
- test(r==KErrNotFound);
+ test_Value(r, r == KErrNotFound);
r=TheFs.Entry(_L("z:\\SYSTEM\\"),entry);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Entry(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)?_L("z:\\SYS\\BIN\\ESHELL.EXE"):_L("z:\\SYSTEM\\BIN\\ESHELL.EXE"),entry);
- test(r==KErrNone);
+ test_KErrNone(r);
r=dir.Open(TheFs,_L("\\*"),NULL);
- test(r==KErrNone);
+ test_KErrNone(r);
TEntry dirEntry;
r=dir.Read(dirEntry);
- test(r==KErrNone || r==KErrEof);
+ test_Value(r, r == KErrNone || r==KErrEof);
if (r==KErrNone)
test.Printf(_L("%S\n"),&dirEntry.iName);
dir.Close();
r=dir.Open(TheFs,_L("A:\\*"),NULL);
- test(r==KErrNotReady || r==KErrNone);
+ test_Value(r, r == KErrNotReady || r==KErrNone);
dir.Close();
}
@@ -181,13 +189,13 @@
{
RFile f;
r=f.Open(TheFs,KTFileCpp,EFileRead);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.Seek(ESeekAddress,pos);
TText8* ptrPos=*(TText8**)&pos;
- test(r==KErrNone);
+ test_KErrNone(r);
TBuf8<1024> readBuf;
r=f.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
TPtrC8 memBuf(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -195,10 +203,10 @@
ptrPos+=9913;
pos=9913;
r=f.Seek(ESeekStart,pos);
- test(r==KErrNone);
+ test_KErrNone(r);
readBuf.SetLength(0);
r=f.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
memBuf.Set(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -207,16 +215,16 @@
pos=10;
r=f2.Open(TheFs,KTFsrvCpp,EFileRead);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f2.Seek(ESeekAddress,pos);
ptrPos=*(TText8**)&pos;
- test(r==KErrNone);
+ test_KErrNone(r);
readBuf.SetLength(0);
pos=10;
r=f2.Seek(ESeekStart,pos);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f2.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
memBuf.Set(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -224,10 +232,10 @@
ptrPos+=2445;
pos=10+2445;
r=f2.Seek(ESeekStart,pos);
- test(r==KErrNone);
+ test_KErrNone(r);
readBuf.SetLength(0);
r=f2.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
memBuf.Set(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -235,13 +243,13 @@
pos=0;
r=f.Seek(ESeekAddress,pos);
ptrPos=*(TText8**)&pos;
- test(r==KErrNone);
+ test_KErrNone(r);
readBuf.SetLength(0);
pos=0;
r=f.Seek(ESeekStart,pos);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
memBuf.Set(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -249,10 +257,10 @@
ptrPos+=5245;
pos=5245;
r=f.Seek(ESeekStart,pos);
- test(r==KErrNone);
+ test_KErrNone(r);
readBuf.SetLength(0);
r=f.Read(readBuf);
- test(r==KErrNone);
+ test_KErrNone(r);
test(readBuf.Length()==readBuf.MaxLength());
memBuf.Set(ptrPos,readBuf.Length());
test(memBuf==readBuf);
@@ -271,14 +279,14 @@
RFile f;
TInt r=f.Replace(TheFs,_L("Z:\\Test\\T_Fsrv.Cpp"),EFileRead);
- test(r==KErrAccessDenied);
+ test_Value(r, r == KErrAccessDenied);
r=f.Create(TheFs,_L("Z:\\Test\\newT_Fsrv.Cpp"),EFileRead);
- test(r==KErrAccessDenied);
+ test_Value(r, r == KErrAccessDenied);
r=f.Open(TheFs,_L("Z:\\Test\\T_Fsrv.Cpp"),EFileRead);
- test(r==KErrNone);
+ test_KErrNone(r);
f.Close();
r=f.Open(TheFs,_L("Z:\\Test\\T_Fsrv.Cpp"),EFileRead|EFileWrite);
- test(r==KErrAccessDenied);
+ test_Value(r, r == KErrAccessDenied);
}
LOCAL_C void Test7()
@@ -295,7 +303,7 @@
TEntry entry;
TInt r=TheFs.Entry(file1,entry);
- test(r==KErrNone);
+ test_KErrNone(r);
test(entry.iType==uid1);
TUidType uid2(TUid::Uid(4),TUid::Uid(5),TUid::Uid(6));
@@ -303,19 +311,19 @@
TPtrC8 uidData((TUint8*)&checkedUid,sizeof(TCheckedUid));
RFile f;
r=f.Open(TheFs,file1,EFileRead|EFileWrite);
- test(r==KErrNone);
+ test_KErrNone(r);
r=f.Write(uidData);
- test(r==KErrNone);
+ test_KErrNone(r);
r = f.Flush();
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.Entry(file1,entry);
- test(r==KErrNone);
+ test_KErrNone(r);
test(entry.iType==uid2);
f.Close();
r=TheFs.Entry(file1,entry);
- test(r==KErrNone);
+ test_KErrNone(r);
test(entry.iType==uid2);
}
@@ -538,7 +546,7 @@
CFileMan* fMan=CFileMan::NewL(TheFs);
TInt r=fMan->Copy(_L("Z:\\TEST\\T_FILE.CPP"),_L("C:\\T_FILE.CPP"));
- test(r==KErrNone || r==KErrAccessDenied);
+ test_Value(r, r == KErrNone || r==KErrAccessDenied);
delete fMan;
TUint8* addr=TheFs.IsFileInRom(_L("C:\\ESHELL.EXE"));
test(addr==NULL);
@@ -567,7 +575,7 @@
for(i=0;i<KMaxDrives;i++)
{
TInt r=TheFs.GetDriveName(i,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
if (driveName.Length())
test.Printf(_L("Default name of %c: == %S\n"),'A'+i,&driveName);
}
@@ -577,32 +585,32 @@
TBuf<64> drive17=_L("Flibble");
TBuf<64> drive25=_L("RAMDRIVE");
TInt r=TheFs.SetDriveName(0,drive0);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(4,drive4);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(17,drive17);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(25,drive25);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.GetDriveName(0,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive0);
r=TheFs.GetDriveName(4,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive4);
r=TheFs.GetDriveName(17,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive17);
r=TheFs.GetDriveName(25,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive25);
drive0=_L("askdjflsdfourewoqiuroiuaksjdvx,cvsdhwjhjhalsjhfshfkjhslj");
r=TheFs.SetDriveName(0,drive0);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.GetDriveName(0,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive0);
// Test with illegal characters in drive name
@@ -612,13 +620,13 @@
drive25=_L("RAMD//RIVE");
r=TheFs.SetDriveName(0,drive0);
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
r=TheFs.SetDriveName(4,drive4);
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
r=TheFs.SetDriveName(17,drive17);
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
r=TheFs.SetDriveName(25,drive25);
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
// Test that it is OK to set the name to no characters
@@ -628,25 +636,25 @@
drive25=_L("");
r=TheFs.SetDriveName(0,drive0);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(4,drive4);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(17,drive17);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.SetDriveName(25,drive25);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.GetDriveName(0,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive0);
r=TheFs.GetDriveName(4,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive4);
r=TheFs.GetDriveName(17,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive17);
r=TheFs.GetDriveName(25,driveName);
- test(r==KErrNone);
+ test_KErrNone(r);
test(driveName==drive25);
@@ -662,11 +670,11 @@
TVolumeInfo vol;
TInt r=TheFs.Volume(vol);
test.Printf(_L("VolumeName = %S\n"),&vol.iName);
- test(r==KErrNone);
+ test_KErrNone(r);
r=TheFs.RmDir(_L("\\asdfasdf.\\"));
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
r=TheFs.MkDir(_L("\\asdfasdf.\\"));
- test(r==KErrBadName);
+ test_Value(r, r == KErrBadName);
}
LOCAL_C void Test12()
@@ -697,23 +705,23 @@
test.Next(_L("Test RFs::Volume"));
TVolumeInfo vol;
TInt r=TheFs.Volume(vol,EDriveB);
- test(r==KErrNotReady || r==KErrNone || KErrPathNotFound);
+ test_Value(r, r == KErrNotReady || r==KErrNone || r == KErrPathNotFound);
test.Printf(_L("RFs::Volume EDriveB returned %d\n"),r);
r=TheFs.Volume(vol,EDriveC);
- test(r==KErrNotReady || r==KErrNone || KErrPathNotFound);
+ test_Value(r, r == KErrNotReady || r==KErrNone || r == KErrPathNotFound);
test.Printf(_L("RFs::Volume EDriveC returned %d\n"),r);
r=TheFs.Volume(vol,EDriveD);
- test(r==KErrNotReady || r==KErrNone || KErrPathNotFound);
+ test_Value(r, r == KErrNotReady || r==KErrNone || r == KErrPathNotFound);
test.Printf(_L("RFs::Volume EDriveD returned %d\n"),r);
r=TheFs.Volume(vol,EDriveE);
- test(r==KErrNotReady || r==KErrNone || KErrPathNotFound);
+ test_Value(r, r == KErrNotReady || r==KErrNone || r == KErrPathNotFound);
test.Printf(_L("RFs::Volume EDriveE returned %d\n"),r);
r=TheFs.Volume(vol,EDriveF);
- test(r==KErrNotReady || r==KErrNone || KErrPathNotFound);
+ test_Value(r, r == KErrNotReady || r==KErrNone || r == KErrPathNotFound);
test.Printf(_L("RFs::Volume EDriveF returned %d\n"),r);
}
@@ -722,7 +730,9 @@
TInt CreateStuffedFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize);
TInt CreateEmptyFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize);
TBool CheckFileContents(RFs& aFs, const TDesC& aFileName);
+#ifndef __NFE_MEDIA_DRIVER_PRESENT__
TBool CheckBufferContents(const TDesC8& aBuffer, TUint aPrintBaseAddr=0);
+#endif
/**
Testing unallocated data initialization vulnerability in RFile
@@ -740,7 +750,7 @@
//-- 1. get drives list
nRes=TheFs.DriveList(driveList);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//-- 2. walk through all drives, performing the test only on suitable ones
for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
@@ -826,15 +836,17 @@
//-- 1. create an empty file
nRes = CreateEmptyFile(TheFs, fileName, KFileSize);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
+#ifndef __NFE_MEDIA_DRIVER_PRESENT__ // can't easily check for illegitimate information if drive is encrypted
//-- 1.1 check that this file doesn't contain illegitimate information.
nRes = CheckFileContents(TheFs, fileName);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
+#endif
//-- 1.2 delete the empty file
nRes = TheFs.Delete(fileName);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//==============================
//== Scenario 2.
@@ -847,18 +859,18 @@
//-- 2. create file filled with some data pattern
nRes = CreateStuffedFile(TheFs, fileName, KFileSize);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//-- 2.1 delete this file
TheFs.Delete(fileName);
//-- 2.1 create an empty file on the place of just deleted one (hopefully)
nRes = CreateEmptyFile(TheFs, fileName, KFileSize);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//-- 2.2 check that this file doesn't contain illegitimate information.
nRes = CheckFileContents(TheFs, fileName);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//-- 2.3 delete this file
TheFs.Delete(fileName);
@@ -1162,11 +1174,11 @@
test.Next(_L("Test RFs::GetMediaSerialNumber"));
TInt theDrive;
TInt r = TheFs.CharToDrive(gDriveToTest,theDrive);
- test(r == KErrNone);
+ test_KErrNone(r);
TMediaSerialNumber serNum;
r = TheFs.GetMediaSerialNumber(serNum, theDrive);
if (r) test.Printf(_L("RFs::GetMediaSerialNumber returned error %d"), r);
- test(r == KErrNotSupported || r == KErrNotReady || r == KErrNone);
+ test_Value(r, r == KErrNotSupported || r == KErrNotReady || r == KErrNone);
if (r == KErrNotSupported)
{
test.Printf(_L("MediaSerialNumber: Not Supported\n"));
@@ -1238,7 +1250,6 @@
RFile file;
//-- create a buffer with some data
- const TUint KBufLength = 0x100;
TBuf8<KBufLength> buffer;
buffer.SetLength(KBufLength);
@@ -1289,13 +1300,12 @@
TInt nRes = KErrNone;
RFile file;
- const TInt KBufLength = 0x100;
TBuf8<KBufLength> buffer;
buffer.SetLength(0);
//-- open the file
nRes = file.Open(aFs, aFileName, EFileRead);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
//-- check file contents
TUint nFilePos=0;
@@ -1303,7 +1313,7 @@
{
//-- read data from the file into the buffer
nRes = file.Read(buffer);
- test(nRes == KErrNone);
+ test_KErrNone(nRes);
if(buffer.Length() == 0)
{
@@ -1311,6 +1321,18 @@
break; //EOF
}
+#ifdef __NFE_MEDIA_DRIVER_PRESENT__
+ // check the buffer doesn't contain the same pattern written to it by CreateStuffedFile()
+ TUint i;
+ for(i = 0; i < KBufLength; i++)
+ if (buffer[i] != static_cast<TUint8> (i))
+ break;
+ if (i == KBufLength)
+ {
+ nRes = KErrCorrupt; //-- indicate that the read buffer contains illegitimate information
+ break; //-- comment this out if you need a full dump of the file
+ }
+#else
//-- check if the buffer contains only allowed data (RAM page initialisation data, etc. e.g. 0x00, 0xff, 0x03, 0xcc)
if(!CheckBufferContents(buffer, nFilePos))
{
@@ -1318,6 +1340,7 @@
nRes = KErrCorrupt; //-- indicate that the read buffer contains illegitimate information
break; //-- comment this out if you need a full dump of the file
}
+#endif
nFilePos+=buffer.Length();
}
--- a/userlibandfileserver/fileserver/group/release.txt Fri Apr 23 22:14:19 2010 +0100
+++ b/userlibandfileserver/fileserver/group/release.txt Fri Apr 23 22:20:31 2010 +0100
@@ -1,3 +1,12 @@
+Version 2.00.3031
+=================
+(Made by vfebvre 15/04/2010)
+
+1. migubarr
+ 1. REQ 415-7212 NFE drive encryption on Demand Paging-enabled device, kernelhwsrv/MCL
+ PackageReleaseID=453228 FeatureReleaseID=447937
+
+
Version 2.00.3030
=================
(Made by vfebvre 14/04/2010)
--- a/userlibandfileserver/fileserver/inc/f32ver.h Fri Apr 23 22:14:19 2010 +0100
+++ b/userlibandfileserver/fileserver/inc/f32ver.h Fri Apr 23 22:20:31 2010 +0100
@@ -58,6 +58,6 @@
@see TVersion
*/
-const TInt KF32BuildVersionNumber=3030;
+const TInt KF32BuildVersionNumber=3031;
//
#endif
--- a/userlibandfileserver/fileserver/sfile/sf_drv.cpp Fri Apr 23 22:14:19 2010 +0100
+++ b/userlibandfileserver/fileserver/sfile/sf_drv.cpp Fri Apr 23 22:20:31 2010 +0100
@@ -233,7 +233,7 @@
if (iReason==KErrNone && CurrentMount().LockStatus() > 0)
{
- //-- this meand that the mount has drive access objetcs opened (RFormat or RRawDisk)
+ //-- this means that the mount has drive access objects opened (RFormat or RRawDisk)
__PRINT1(_L("TDrive::CheckMount() Mount is locked! LockStaus:%d"), CurrentMount().LockStatus());
return KErrInUse;
}
@@ -547,6 +547,19 @@
TRAP(r,CurrentMount().FinaliseMountL(aOperation, aParam1, aParam2));
TRACERET1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFinaliseMount2Ret, EF32TraceUidFileSys, r);
+ // Pass FinaliseDrive notification down to media driver
+ TInt driveNumber = DriveNumber();
+ if (LocalDrives::IsValidDriveMapping(driveNumber) && !LocalDrives::IsProxyDrive(driveNumber))
+ {
+ TBusLocalDrive& drv = LocalDrives::GetLocalDrive(driveNumber);
+
+ TLocalDriveFinaliseInfoBuf finaliseBuf;
+ finaliseBuf().iMode = aOperation;
+
+ // notify local drive, ignore the error
+ drv.QueryDevice(RLocalDrive::EQueryFinaliseDrive, finaliseBuf);
+ }
+
return r;
}
@@ -815,7 +828,7 @@
// Check that the sharing rules are obeyed.
//
{
-
+ // Check the correct share modes are passed in
switch (aReqShare)
{
case EFileShareExclusive:
@@ -824,47 +837,46 @@
case EFileShareReadersOrWriters:
break;
default:
- return(KErrArgument);
+ return KErrArgument;
}
+
+ // Check the share mode of the file
switch (aFile.iShare)
{
case EFileShareExclusive:
- return(KErrInUse);
+ return KErrInUse;
case EFileShareReadersOnly:
case EFileShareAny:
if (aReqShare != aFile.iShare && aReqShare != EFileShareReadersOrWriters)
- return(KErrInUse);
+ {
+ return KErrInUse;
+ }
break;
case EFileShareReadersOrWriters:
- if (aReqShare==EFileShareExclusive)
- return(KErrInUse);
+ if (aReqShare == EFileShareExclusive)
+ {
+ return KErrInUse;
+ }
//
- // If the file is currently open as EFileShareReadersOrWriters then
+ // If the file is currently opened as EFileShareReadersOrWriters then
// promote the share to the requested share mode.
+ //
+ // If the requested share is EFileShareReadersOnly, verify that no
+ // other share has the file opened for writing.
//
- // If the requested share is EFileShareReadersOnly, verfiy that no
- // other share has the file open for writing.
- //
-
if (aReqShare == EFileShareReadersOnly)
{
- FileShares->Lock();
- TInt count = FileShares->Count();
- while(count--)
+ TDblQueIter<CFileShare> fileShareIter(aFile.FileShareList());
+ CFileShare* pFileShare;
+ while ((pFileShare = fileShareIter++) != NULL)
{
- CFileShare* share = (CFileShare*)(*FileShares)[count];
- if (&share->File() == &aFile)
+ if(pFileShare->iMode & EFileWrite)
{
- if(share->iMode & EFileWrite)
- {
- FileShares->Unlock();
- return KErrInUse;
- }
+ return KErrInUse;
}
}
- FileShares->Unlock();
}
break;
@@ -872,7 +884,8 @@
Fault(EDrvIllegalShareValue);
break;
}
- return(KErrNone);
+
+ return KErrNone;
}
void TDrive::DriveInfo(TDriveInfo& anInfo)
@@ -1332,88 +1345,90 @@
if ((aMode & EDeleteOnClose) && (anOpen!=EFileCreate))
User::Leave(KErrArgument);
- CFileCB* pF=LocateFile(aName);
+ CFileCB* pFile=LocateFile(aName);
CFileCache* pFileCache = NULL;
- TBool openFile=EFalse;
- if (pF!=NULL)
+ TBool openFile=EFalse; // True if file is being opened for the first time
+ if (pFile!=NULL) // File is already opened on the drive
{
- if (pF->iShare==EFileShareReadersOnly && (aMode&EFileWrite)!=0)
+ if (pFile->iShare==EFileShareReadersOnly && (aMode&EFileWrite))
User::Leave(KErrInUse);
if (anOpen==EFileCreate)
User::Leave(KErrAlreadyExists);
- TInt r=ValidateShare(*pF,share);
+ TInt r=ValidateShare(*pFile,share);
if (r!=KErrNone)
User::Leave(r);
- if ((r=pF->Open())!=KErrNone)
+ if ((r=pFile->Open())!=KErrNone)
User::Leave(r);
- aFileCB=pF;
- pFileCache = pF->FileCache();
+
+ aFileCB=pFile;
+ pFileCache = pFile->FileCache();
}
else
{
TRACE2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileL, EF32TraceUidFileSys, &FSys(), DriveNumber());
//-- construct CFileCB object, belonging to the corresponding mount
- pF = aFileCB = CurrentMount().NewFileL();
-
- TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileLRet, EF32TraceUidFileSys, r, pF);
+ pFile = aFileCB = CurrentMount().NewFileL();
+
+ TRACERET2(UTF::EBorder, UTraceModuleFileSys::ECFileSystemNewFileLRet, EF32TraceUidFileSys, r, pFile);
TDrive* createdDrive=!aRequest->SubstedDrive() ? this : aRequest->SubstedDrive();
HBufC* fileName = CreateFileNameL(aName);
- pF->InitL(this, createdDrive, fileName);
-
-
- pF->iShare = share;
+ pFile->InitL(this, createdDrive, fileName);
+
+ pFile->iShare = share;
+ pFile->SetSequentialMode(aMode & EFileSequential);
openFile=ETrue;
- CurrentMount().iMountQ.AddLast(*pF);
- Files->AddL(pF,ETrue);
+ CurrentMount().iMountQ.AddLast(*pFile);
+ Files->AddL(pFile,ETrue);
+ __PRINT1(_L("TDrive::FileOpenL - CFileCB->IsSequentialMode = %d"), pFile->IsSequentialMode());
}
- CFileShare* pS=aFileShare=new(ELeave) CFileShare(pF);
+ CFileShare* pFileShare=aFileShare=new(ELeave) CFileShare(pFile);
// We need to call CFileCB::PromoteShare immediately after the CFileShare
// instance is created since the destructor calls CFileCB::DemoteShare()
// which checks the share count is non-zero
- pS->iMode=aMode;
- pF->PromoteShare(pS);
-
- pS->InitL();
+ pFileShare->iMode=aMode;
+ pFile->PromoteShare(pFileShare);
+
+ pFileShare->InitL();
aFileCB=NULL;
- FileShares->AddL(pS,ETrue);
- aHandle=aRequest->Session()->Handles().AddL(pS,ETrue);
+ FileShares->AddL(pFileShare,ETrue);
+ aHandle=aRequest->Session()->Handles().AddL(pFileShare,ETrue);
if (openFile)
{
- TRACEMULT5(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenL, EF32TraceUidFileSys, DriveNumber(), aName, aMode, (TUint) anOpen, (TUint) pF);
- CurrentMount().FileOpenL(aName,aMode,anOpen,pF);
+ TRACEMULT5(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenL, EF32TraceUidFileSys, DriveNumber(), aName, aMode, (TUint) anOpen, (TUint) pFile);
+ CurrentMount().FileOpenL(aName,aMode,anOpen,pFile);
TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBFileOpenLRet, EF32TraceUidFileSys, KErrNone);
// Delete on close may now be safely flagged if required.
// The file did not exist on the media prior to the
// CMountCB::FileOpenL() call for the case of a create.
if ((aMode & EDeleteOnClose) && (anOpen==EFileCreate))
- pF->SetDeleteOnClose();
-
- TBool localBufferSuppport = (CurrentMount().LocalBufferSupport(pF) == KErrNone)?(TBool)ETrue:(TBool)EFalse;
- pF->SetLocalBufferSupport(localBufferSuppport);
+ pFile->SetDeleteOnClose();
+
+ TBool localBufferSuppport = (CurrentMount().LocalBufferSupport(pFile) == KErrNone)?(TBool)ETrue:(TBool)EFalse;
+ pFile->SetLocalBufferSupport(localBufferSuppport);
if (localBufferSuppport)
{
- // if file exists on closed queue resurrect it or discard it,
+ // If file exists on closed queue resurrect it or discard it,
// depending on the file open mode
pFileCache = LocateClosedFile(aName, anOpen == EFileOpen?(TBool)ETrue:(TBool)EFalse);
if (pFileCache)
{
- pFileCache = pFileCache->ReNewL(*pS); // NB may return NULL if caching not enabled
+ pFileCache = pFileCache->ReNewL(*pFileShare); // NB may return NULL if caching not enabled
}
else
{
- pFileCache = CFileCache::NewL(*pS); // NB may return NULL if caching not enabled
+ pFileCache = CFileCache::NewL(*pFileShare); // NB may return NULL if caching not enabled
}
if (pFileCache)
- // set the cached size to be the same as the uncached size
- pF->SetCachedSize64(pF->Size64());
+ // Set the cached size to be the same as the uncached size
+ pFile->SetCachedSize64(pFile->Size64());
}
else
{
@@ -1421,9 +1436,9 @@
}
}
- // initialize share mode flags
+ // Initialize share mode flags
if (pFileCache != NULL)
- pFileCache->Init(*pS);
+ pFileCache->Init(*pFileShare);
}
TInt TDrive::FileOpen(CFsRequest* aRequest,TInt& aHandle,const TDesC& aName,TUint aMode,TFileOpen anOpen)
@@ -1435,7 +1450,7 @@
CFileCB* pF=NULL;
CFileShare* pS=NULL;
aHandle=0;
- TRAPD(r,FileOpenL(aRequest,aHandle,aName,aMode,anOpen,pF,pS))
+ TRAPD(r,FileOpenL(aRequest,aHandle,aName,aMode,anOpen,pF,pS));
// Allow files > 2GB-1 to be opened only if EFileBigFile is specified in iMode
if (r == KErrNone && pS && ((TUint64)pS->File().Size64() > KMaxLegacyFileSize) && (!(pS->IsFileModeBig())))