diff -r 345b1ca54e88 -r 039a3e647356 kerneltest/e32test/mediaext/d_nfe.cpp --- a/kerneltest/e32test/mediaext/d_nfe.cpp Wed Sep 15 13:42:27 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1781 +0,0 @@ -// 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 -#include -#include -#include "nfe.h" - -#if defined(_DEBUG) -// #define TRACE_ENABLED -#define TRACE_ENABLED //*test* -#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= 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 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; iDoCreate(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; iDelete(); - 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; iAttach(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; iiDfcQ,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; iiLocalDriveNum)); - - __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: - 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 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; iiTimerDfc.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; - - aDi.iDriveFinalised = aFinalised; - - 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; instanceiNfeDfcQ,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 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; instanceiDriver; - __ASSERT_ALWAYS(mediaDriver, NFE_FAULT()); - - if (swapDriveInfo == NULL) - swapDriveInfo = mediaDriver->GetSwapDrive(); - - for (TInt i=0; iiInfo.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; - } - -