--- 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 <drivers/locmedia.h>
-#include <platform.h>
-#include <variantmediadef.h>
-#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<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:
- 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 sure we haven't lost the swap partition
- __ASSERT_ALWAYS(!(di.iEntry.iPartitionType == KPartitionTypePagedData && aInfo.iEntry[i].iPartitionType != KPartitionTypePagedData), NFE_FAULT());
-
- // 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;
-
- 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; 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;
- }
-
-