123
|
1 |
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
2 |
// All rights reserved.
|
|
3 |
// This component and the accompanying materials are made available
|
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
// e32test\mediext\d_nfe.cpp
|
|
15 |
//
|
|
16 |
//
|
|
17 |
|
|
18 |
#include <drivers/locmedia.h>
|
|
19 |
#include <platform.h>
|
|
20 |
#include <variantmediadef.h>
|
|
21 |
#include "nfe.h"
|
|
22 |
|
|
23 |
#if defined(_DEBUG)
|
134
|
24 |
// #define TRACE_ENABLED
|
123
|
25 |
#else
|
|
26 |
#endif
|
|
27 |
|
|
28 |
#if defined(TRACE_ENABLED)
|
|
29 |
#define __KTRACE_PRINT(p) {p;}
|
|
30 |
#else
|
|
31 |
#define __KTRACE_PRINT(p)
|
|
32 |
#endif
|
|
33 |
|
|
34 |
|
|
35 |
|
|
36 |
|
|
37 |
// Variant parameters for test Media Extension Driver
|
|
38 |
|
|
39 |
|
|
40 |
const TInt KNfeThreadPriority = 24; // same as file server
|
|
41 |
const TInt KNfeDiskOpReady = 100; //100%
|
|
42 |
//const TInt KNfeDiskOpStart = 0; //0%
|
|
43 |
|
|
44 |
_LIT(KPddName, "Media.NFE");
|
|
45 |
#define NFE_DRIVENAME "NFE"
|
|
46 |
#define NFE_NUMMEDIA 1
|
|
47 |
|
|
48 |
// Define the array of local drives which we're attaching to
|
|
49 |
__ASSERT_COMPILE(sizeof(TNfeDeviceInfo) <= 256); // KMaxQueryDeviceLength
|
|
50 |
|
|
51 |
// Define the array of local code-paging drives which we're attaching to
|
|
52 |
#ifdef __DEMAND_PAGING__
|
|
53 |
__ASSERT_COMPILE(NFE_PAGEDRIVECOUNT <= TNfeDeviceInfo::ENfeMaxPartitionEntries);
|
|
54 |
__ASSERT_COMPILE(NFE_DRIVECOUNT >= NFE_PAGEDRIVECOUNT);
|
|
55 |
#define SECTOR_SHIFT 9
|
|
56 |
#endif // #ifdef __DEMAND_PAGING__
|
|
57 |
|
|
58 |
|
|
59 |
|
|
60 |
|
|
61 |
class DPrimaryMediaExt : public DPrimaryMediaBase
|
|
62 |
{
|
|
63 |
public:
|
|
64 |
DPrimaryMediaExt(TInt aInstance);
|
|
65 |
public:
|
|
66 |
TInt iInstance;
|
|
67 |
TDfcQue iNfeDfcQ;
|
|
68 |
};
|
|
69 |
|
|
70 |
|
|
71 |
|
|
72 |
// Get the number of drives in the drive array belonging to this instance
|
|
73 |
TInt DriveCount(TInt aInstance)
|
|
74 |
{
|
|
75 |
static const TInt NfeInstanceDriveCounts[NFE_INSTANCE_COUNT]={NFE_INSTANCE_DRIVE_COUNTS};
|
|
76 |
return NfeInstanceDriveCounts[aInstance];
|
|
77 |
}
|
|
78 |
|
|
79 |
// Get a pointer to the first drive in the drive array belonging to this instance
|
|
80 |
const TInt* DriveList(TInt aInstance)
|
|
81 |
{
|
|
82 |
static const TInt NfeDriveNumbers[NFE_DRIVECOUNT]={NFE_DRIVELIST};
|
|
83 |
TInt driveListOffset = 0;
|
|
84 |
for (TInt n=0; n<aInstance; n++)
|
|
85 |
driveListOffset+= DriveCount(n);
|
|
86 |
return NfeDriveNumbers + driveListOffset;
|
|
87 |
}
|
|
88 |
|
|
89 |
const TInt* DriveLetterList(TInt aInstance)
|
|
90 |
{
|
|
91 |
static const TInt NfeDriveLetters[NFE_DRIVECOUNT]={NFE_DRIVELETTERLIST};
|
|
92 |
TInt driveListOffset = 0;
|
|
93 |
for (TInt n=0; n<aInstance; n++)
|
|
94 |
driveListOffset+= DriveCount(n);
|
|
95 |
return NfeDriveLetters + driveListOffset;
|
|
96 |
}
|
|
97 |
|
|
98 |
TInt DriveLetter(TInt aIndex)
|
|
99 |
{
|
|
100 |
static const TInt NfeDriveLetters[NFE_DRIVECOUNT]={NFE_DRIVELETTERLIST};
|
|
101 |
return NfeDriveLetters[aIndex];
|
|
102 |
}
|
|
103 |
|
|
104 |
TChar DriveLetterToAscii(TInt aDriveLetter)
|
|
105 |
{
|
|
106 |
return aDriveLetter >= 0 && aDriveLetter <= 25 ? aDriveLetter +'A' : '?';
|
|
107 |
}
|
|
108 |
|
|
109 |
#ifdef __DEMAND_PAGING__
|
|
110 |
// Get the number of drives in the paged drive array belonging to this instance
|
|
111 |
TInt PageDriveCount(TInt aInstance)
|
|
112 |
{
|
|
113 |
#if NFE_PAGEDRIVECOUNT > 0
|
|
114 |
static const TInt NfeInstancePageDriveCounts[NFE_INSTANCE_COUNT]={NFE_INSTANCE_PAGEDRIVE_COUNTS};
|
|
115 |
return NfeInstancePageDriveCounts[aInstance];
|
|
116 |
#else
|
|
117 |
return 0;
|
|
118 |
#endif
|
|
119 |
}
|
|
120 |
|
|
121 |
// Get a pointer to the first drive in the paged drive array belonging to this instance
|
|
122 |
const TInt* PageDriveList(TInt aInstance)
|
|
123 |
{
|
|
124 |
#if NFE_PAGEDRIVECOUNT > 0
|
|
125 |
static const TInt NfePageDriveNumbers[NFE_PAGEDRIVECOUNT]={NFE_PAGEDRIVELIST};
|
|
126 |
TInt driveListOffset = 0;
|
|
127 |
for (TInt n=0; n<aInstance; n++)
|
|
128 |
driveListOffset+= PageDriveCount(n);
|
|
129 |
return NfePageDriveNumbers + driveListOffset;
|
|
130 |
#else
|
|
131 |
return NULL;
|
|
132 |
#endif
|
|
133 |
}
|
|
134 |
|
|
135 |
// Get the number of paging type belonging to this instance
|
|
136 |
TInt PagingType(TInt aInstance)
|
|
137 |
{
|
|
138 |
#if NFE_PAGEDRIVECOUNT > 0
|
|
139 |
static const TInt NfeInstancePagingType[NFE_INSTANCE_COUNT]={NFE_INSTANCE_PAGING_TYPE};
|
|
140 |
return NfeInstancePagingType[aInstance];
|
|
141 |
#else
|
|
142 |
return 0;
|
|
143 |
#endif
|
|
144 |
}
|
|
145 |
|
|
146 |
// get the instance of the swap drive
|
|
147 |
TInt SwapInstance()
|
|
148 |
{
|
|
149 |
for (TInt i=0; i<NFE_INSTANCE_COUNT; i++)
|
|
150 |
if (PagingType(i) & DPagingDevice::EData)
|
|
151 |
return i;
|
|
152 |
return KErrNotFound;
|
|
153 |
}
|
|
154 |
#endif // #ifdef __DEMAND_PAGING__
|
|
155 |
|
|
156 |
|
|
157 |
const char* DriveStatus(TNfeDiskStatus aStatus)
|
|
158 |
{
|
|
159 |
const char* KNfeUnmounted = "Unmounted";
|
|
160 |
const char* KNfeDecrypted = "Decrypted";
|
|
161 |
const char* KNfeDecrypting = "Decrypting";
|
|
162 |
const char* KNfeEncrypted = "Encrypted";
|
|
163 |
const char* KNfeEncrypting = "Encrypting";
|
|
164 |
const char* KNfeWiping = "Wiping";
|
|
165 |
const char* KNfeCorrupted = "Corrupted";
|
|
166 |
const char* KNfeUnrecognised = "Unrecognised";
|
|
167 |
|
|
168 |
switch(aStatus)
|
|
169 |
{
|
|
170 |
case ENfeUnmounted:
|
|
171 |
return KNfeUnmounted;
|
|
172 |
case ENfeDecrypted:
|
|
173 |
return KNfeDecrypted;
|
|
174 |
case ENfeDecrypting:
|
|
175 |
return KNfeDecrypting;
|
|
176 |
case ENfeEncrypted:
|
|
177 |
return KNfeEncrypted;
|
|
178 |
case ENfeEncrypting:
|
|
179 |
return KNfeEncrypting;
|
|
180 |
case ENfeWiping:
|
|
181 |
return KNfeWiping;
|
|
182 |
case ENfeCorrupted:
|
|
183 |
return KNfeCorrupted;
|
|
184 |
default:
|
|
185 |
return KNfeUnrecognised;
|
|
186 |
|
|
187 |
}
|
|
188 |
}
|
|
189 |
|
|
190 |
|
|
191 |
DPrimaryMediaExt::DPrimaryMediaExt(TInt aInstance) : iInstance(aInstance)
|
|
192 |
{
|
|
193 |
}
|
|
194 |
|
|
195 |
|
|
196 |
#define NFE_FAULT() Kern::Fault("NFEMEDIA",__LINE__)
|
|
197 |
|
|
198 |
// disk encryption/decryption/wiping is only performed after the following period of inactivity
|
|
199 |
// NB USB Mass Storage tends to 'poll' the media driver by sending ECaps every second or so, so we need
|
|
200 |
// to ensure this timeout period is significantly less to ensure the timer DFC thread gets a chance to run...
|
|
201 |
const TInt KNotBusyInterval = 200; // 200 mS
|
|
202 |
|
|
203 |
|
|
204 |
|
|
205 |
class DPhysicalDeviceMediaNFE : public DPhysicalDevice
|
|
206 |
{
|
|
207 |
public:
|
|
208 |
DPhysicalDeviceMediaNFE();
|
|
209 |
virtual TInt Install();
|
|
210 |
virtual void GetCaps(TDes8& aDes) const;
|
|
211 |
virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* anInfo, const TVersion& aVer);
|
|
212 |
virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
|
|
213 |
virtual TInt Info(TInt aFunction, TAny* a1);
|
|
214 |
};
|
|
215 |
|
|
216 |
|
|
217 |
class DMediaDriverNFE : public DMediaDriverExtension
|
|
218 |
{
|
|
219 |
public:
|
|
220 |
class TPropertyObserver
|
|
221 |
{
|
|
222 |
public:
|
|
223 |
void Close();
|
|
224 |
static void PropertySubsCompleteFn(TAny* aPtr, TInt aReason);
|
|
225 |
public:
|
|
226 |
TInt iDriveIndex;
|
|
227 |
DMediaDriverNFE* iMediaExt;
|
|
228 |
RPropertyRef iProperty;
|
|
229 |
TPropertySubsRequest* iPropertySubsRequest;
|
|
230 |
TDfc* iPropertyDfc; // N.B. subscription call backs don't occur in our thread context, hence the need for this DFC
|
|
231 |
TInt iValue;
|
|
232 |
};
|
|
233 |
|
|
234 |
public:
|
|
235 |
DMediaDriverNFE(TInt aMediaId);
|
|
236 |
~DMediaDriverNFE();
|
|
237 |
|
|
238 |
// replacing pure virtual
|
|
239 |
virtual TInt Request(TLocDrvRequest& aRequest);
|
|
240 |
virtual TInt PartitionInfo(TPartitionInfo &anInfo);
|
|
241 |
|
|
242 |
TInt DoCreate(TInt aMediaId);
|
|
243 |
void Close();
|
|
244 |
|
|
245 |
TNfeDriveInfo* GetSwapDrive();
|
|
246 |
|
|
247 |
private:
|
|
248 |
TInt HandleRead(TLocDrvRequest& aRequest);
|
|
249 |
TInt HandleWrite(TLocDrvRequest& aRequest);
|
|
250 |
TInt HandleFormat(TLocDrvRequest& aRequest);
|
|
251 |
TInt HandleCaps(TLocDrvRequest& aReq);
|
|
252 |
|
|
253 |
|
|
254 |
void EncryptBuffer(TDes8& aBuffer);
|
|
255 |
void DecryptBuffer(TDes8& aBuffer);
|
|
256 |
|
|
257 |
inline TUint8 EncryptByte(TUint8 aByte) {return (TUint8) (aByte ^ 0xDD);}
|
|
258 |
inline TUint8 DecryptByte(TUint8 aByte) {return (TUint8) (aByte ^ 0xDD);}
|
|
259 |
inline TInt DriveIndex(TInt aDriveNum) {return iDriveNumToIndex[aDriveNum];}
|
|
260 |
|
|
261 |
static void IdleTimerCallBack(TAny* aMediaDriver);
|
|
262 |
static void TimerDfcFunction(TAny* aMediaDriver);
|
|
263 |
|
|
264 |
// Publish & Subscribe stuff - used to listen to requests from UI
|
|
265 |
static void FromUiPropertyDfcFunction(TAny* aObserver);
|
|
266 |
void FromUiPropertyDfc(TPropertyObserver& aObserver);
|
|
267 |
|
|
268 |
// Publish & Subscribe stuff - used to listen to status setting from other NFE drives
|
|
269 |
static void StatusToUiPropertyDfcFunction(TAny* aObserver);
|
|
270 |
void StatusToUiPropertyDfc(TPropertyObserver& aObserver);
|
|
271 |
|
|
272 |
void StartEncrypting();
|
|
273 |
void StartDecrypting();
|
|
274 |
|
|
275 |
TInt HandleDiskContent(); // called from idle timer DFC
|
|
276 |
|
|
277 |
TNfeDriveInfo* NextDrive();
|
|
278 |
|
|
279 |
TBool AdjustRequest(TNfeDriveInfo*& aDriveInfo, TInt64& aCurrentPos, TInt64& aCurrentLen);
|
|
280 |
|
|
281 |
void SetStatus(TNfeDriveInfo& aDi, TNfeDiskStatus aStatus);
|
|
282 |
|
|
283 |
TBool ValidBootSector(TUint8* aBuffer);
|
|
284 |
TUint32 VolumeId(TUint8* aBuffer);
|
|
285 |
void CheckBootSector(TNfeDriveInfo &aDriveInfo);
|
|
286 |
TInt WriteEncryptionStatusToBootSector(TNfeDriveInfo &aDi, TBool aFinalised = EFalse);
|
|
287 |
|
|
288 |
private:
|
|
289 |
TInt iInstance; // media drive instance
|
|
290 |
|
|
291 |
// A local buffer use for encryting / decrypting
|
|
292 |
// For paging requests we need this to be page aligned, so allocate enough to cater for
|
|
293 |
// the worst case of up to 4K being wasted at the start of the buffer and the end
|
|
294 |
enum {KSectorSize = 512, KPageSize = 4096, KBufSize = 65536};
|
|
295 |
TUint8 iNonPageAlignedBuffer[KBufSize + KPageSize*2];
|
|
296 |
// a pointer to the start of the first page in iNonPageAlignedBuffer
|
|
297 |
TUint8* iBuffer;
|
|
298 |
|
|
299 |
|
|
300 |
// Idle timer & DFC for kicking an encryption pass
|
|
301 |
NTimer iIdleTimer;
|
|
302 |
TDfc iTimerDfc;
|
|
303 |
|
|
304 |
TInt iDriveIndex; // index of local drive number currently being encrypted
|
|
305 |
TInt iDriveNumToIndex[KMaxPartitionEntries]; // maps drive numbers to index
|
|
306 |
|
|
307 |
TBool iBusy;
|
|
308 |
|
|
309 |
const TInt* iDriveList; // pointer into the drives in NFE_DRIVELIST belonging to this media driver
|
|
310 |
const TInt* iDriveLetterList; // pointer into the drive letter in NFE_DRIVELETTERLIST belonging to this media driver
|
|
311 |
|
|
312 |
// Publish & subscribe stuff which handles drive command notification events from the UI
|
|
313 |
TPropertyObserver iFromUiPropertyObserver[NFE_DRIVECOUNT];
|
|
314 |
|
|
315 |
// Publish & subscribe stuff which handles drive status notification events from the other NFE drives
|
|
316 |
TPropertyObserver iStatusToUiPropertyObserver[NFE_DRIVECOUNT];
|
|
317 |
|
|
318 |
TBool iDriveFinalised;
|
|
319 |
|
|
320 |
public:
|
|
321 |
// Partition information etc for drives this driver is attached to
|
|
322 |
TNfeDeviceInfo iInfo;
|
|
323 |
};
|
|
324 |
|
|
325 |
|
|
326 |
|
|
327 |
class TBootSectorStatus
|
|
328 |
{
|
|
329 |
public:
|
|
330 |
TUint8 iFatBootSectorData[128];
|
|
331 |
|
|
332 |
enum {ENfeBootSectorSignature = 0x2045464E}; // 'NFE '
|
|
333 |
TUint32 iSignature;
|
|
334 |
|
|
335 |
TNfeDiskStatus iStatus;
|
|
336 |
TBool iFinalised;
|
|
337 |
TInt64 iEncryptEndPos; // position of the last encrypted byte +1. Only written when device is powered down
|
|
338 |
};
|
|
339 |
|
|
340 |
|
|
341 |
DPhysicalDeviceMediaNFE::DPhysicalDeviceMediaNFE()
|
|
342 |
{
|
|
343 |
__KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::DPhysicalDeviceMediaNFE()"));
|
|
344 |
iUnitsMask=0x1;
|
|
345 |
iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
|
|
346 |
}
|
|
347 |
|
|
348 |
/**
|
|
349 |
Install the Internal NFE PDD.
|
|
350 |
*/
|
|
351 |
TInt DPhysicalDeviceMediaNFE::Install()
|
|
352 |
{
|
|
353 |
__KTRACE_PRINT(Kern::Printf(": TInt DPhysicalDeviceMediaNFE::Install()"));
|
|
354 |
|
|
355 |
return SetName(&KPddName);
|
|
356 |
}
|
|
357 |
|
|
358 |
void DPhysicalDeviceMediaNFE::GetCaps(TDes8& /*aDes*/) const
|
|
359 |
{
|
|
360 |
}
|
|
361 |
|
|
362 |
/**
|
|
363 |
Create an NFE media driver.
|
|
364 |
*/
|
|
365 |
TInt DPhysicalDeviceMediaNFE::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
|
|
366 |
{
|
|
367 |
__KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::Create()"));
|
|
368 |
|
|
369 |
if (!Kern::QueryVersionSupported(iVersion,aVer))
|
|
370 |
return KErrNotSupported;
|
|
371 |
|
|
372 |
TInt r=KErrNoMemory;
|
|
373 |
|
|
374 |
DMediaDriverNFE* pD = new DMediaDriverNFE(aMediaId);
|
|
375 |
aChannel=pD;
|
|
376 |
if (pD)
|
|
377 |
r=pD->DoCreate(aMediaId);
|
|
378 |
|
|
379 |
if (r == KErrNone)
|
|
380 |
pD->OpenMediaDriverComplete(KErrNone);
|
|
381 |
|
|
382 |
return r;
|
|
383 |
}
|
|
384 |
|
|
385 |
TInt DPhysicalDeviceMediaNFE::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
|
|
386 |
{
|
|
387 |
TInt r;
|
|
388 |
if (!Kern::QueryVersionSupported(iVersion,aVer))
|
|
389 |
r = KErrNotSupported;
|
|
390 |
else if (aDeviceType == MEDIA_DEVICE_NFE)
|
|
391 |
return r = KErrNone;
|
|
392 |
else
|
|
393 |
r = KErrNotSupported;
|
|
394 |
|
|
395 |
// __KTRACE_PRINT(Kern::Printf("DPhysicalDeviceMediaNFE::Validate() aDeviceType %d NfeDeviceType %d r %d", aDeviceType, MEDIA_DEVICE_NFE, r));
|
|
396 |
return r;
|
|
397 |
}
|
|
398 |
|
|
399 |
TInt DPhysicalDeviceMediaNFE::Info(TInt aFunction, TAny*)
|
|
400 |
//
|
|
401 |
// Return the priority of this media driver
|
|
402 |
//
|
|
403 |
{
|
|
404 |
// __KTRACE_PRINT(Kern::Printf(": DPhysicalDeviceMediaNFE::Info()"));
|
|
405 |
|
|
406 |
if (aFunction==EPriority)
|
|
407 |
return KMediaDriverPriorityNormal;
|
|
408 |
|
|
409 |
if (aFunction==EMediaDriverPersistent)
|
|
410 |
return KErrNone;
|
|
411 |
|
|
412 |
return KErrNotSupported;
|
|
413 |
}
|
|
414 |
|
|
415 |
DMediaDriverNFE::DMediaDriverNFE(TInt aMediaId) :
|
|
416 |
DMediaDriverExtension(aMediaId),
|
|
417 |
iInstance(((DPrimaryMediaExt*) iPrimaryMedia)->iInstance),
|
|
418 |
iIdleTimer(IdleTimerCallBack,this),
|
|
419 |
iTimerDfc(TimerDfcFunction,this,2),
|
|
420 |
iDriveList (DriveList(iInstance)),
|
|
421 |
iDriveLetterList (DriveLetterList(iInstance))
|
|
422 |
{
|
|
423 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::DMediaDriverNFE()", iInstance));
|
|
424 |
iInfo.iDriveCount = DriveCount(iInstance);
|
|
425 |
|
|
426 |
__ASSERT_ALWAYS(Kern::RoundToPageSize(1) == KPageSize, NFE_FAULT());
|
|
427 |
|
|
428 |
// Align the buffer to a page boundary to improve efficiency for paging requests
|
|
429 |
iBuffer = &iNonPageAlignedBuffer[0];
|
|
430 |
iBuffer = (TUint8*) ((((TUint32) &iNonPageAlignedBuffer[0]) + KPageSize-1) & ~(KPageSize-1));
|
|
431 |
}
|
|
432 |
|
|
433 |
DMediaDriverNFE::~DMediaDriverNFE()
|
|
434 |
//
|
|
435 |
// Destructor.
|
|
436 |
//
|
|
437 |
{
|
|
438 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::~DMediaDriverNFE()", iInstance));
|
|
439 |
|
|
440 |
TInt i;
|
|
441 |
for (i=0; i<TNfeDeviceInfo::ENfeMaxPartitionEntries; i++)
|
|
442 |
{
|
|
443 |
RPropertyRef* property = (RPropertyRef*) iInfo.iDrives[i].iStatusToUiProperty;
|
|
444 |
if (property)
|
|
445 |
{
|
|
446 |
property->Delete();
|
|
447 |
delete property;
|
|
448 |
}
|
|
449 |
property = (RPropertyRef*) iInfo.iDrives[i].iToUiProperty;
|
|
450 |
if (property)
|
|
451 |
{
|
|
452 |
property->Delete();
|
|
453 |
delete property;
|
|
454 |
}
|
|
455 |
property = (RPropertyRef*) iInfo.iDrives[i].iProgressToUiProperty;
|
|
456 |
if (property)
|
|
457 |
{
|
|
458 |
property->Delete();
|
|
459 |
delete property;
|
|
460 |
}
|
|
461 |
}
|
|
462 |
|
|
463 |
for (i=0; i<NFE_DRIVECOUNT; i++)
|
|
464 |
{
|
|
465 |
iFromUiPropertyObserver[i].Close();
|
|
466 |
iStatusToUiPropertyObserver[i].Close();
|
|
467 |
}
|
|
468 |
}
|
|
469 |
|
|
470 |
|
|
471 |
TInt CreateKey(RPropertyRef*& aProperty, TUint aKey)
|
|
472 |
{
|
|
473 |
aProperty = new RPropertyRef;
|
|
474 |
if (aProperty == NULL)
|
|
475 |
return KErrNoMemory;
|
|
476 |
TInt r = aProperty->Attach(KNfeUID, aKey);
|
|
477 |
if (r != KErrNone)
|
|
478 |
return r;
|
|
479 |
|
|
480 |
static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
|
|
481 |
r = aProperty->Define( RProperty::EInt, KPassPolicy, KPassPolicy );
|
|
482 |
if (r != KErrNone && r != KErrAlreadyExists)
|
|
483 |
return r;
|
|
484 |
return KErrNone;
|
|
485 |
}
|
|
486 |
|
|
487 |
TInt DMediaDriverNFE::DoCreate(TInt /*aMediaId*/)
|
|
488 |
//
|
|
489 |
// Create the media driver.
|
|
490 |
//
|
|
491 |
{
|
|
492 |
__KTRACE_PRINT(Kern::Printf("NFE%d: TInt DMediaDriverNFE::DoCreate()", iInstance));
|
|
493 |
|
|
494 |
// Associate the idle timer DFC with our thread
|
|
495 |
iTimerDfc.SetDfcQ(iPrimaryMedia->iDfcQ);
|
|
496 |
|
|
497 |
// Publish & Subscribe stuff - used to initiate an encryption pass from the test app
|
|
498 |
static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
|
|
499 |
TInt r;
|
|
500 |
TInt i;
|
|
501 |
|
|
502 |
TInt swapInstance = KErrNotFound;
|
|
503 |
#if defined (__DEMAND_PAGING__)
|
|
504 |
swapInstance = SwapInstance();
|
|
505 |
#endif
|
|
506 |
|
|
507 |
// **************************************************************************************
|
|
508 |
// Set up P&S publishers so we can publish the status for our drives
|
|
509 |
// **************************************************************************************
|
|
510 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Setting up StatusToUi, ToUi, ProgressToUi P&S publisher & FromUi P&S observer", iInstance));
|
|
511 |
|
|
512 |
for (i = 0; i<DriveCount(iInstance); i++)
|
|
513 |
{
|
|
514 |
__KTRACE_PRINT(Kern::Printf("NFE%d:drive index %d", iInstance, i));
|
|
515 |
TInt driveLetter = iDriveLetterList[i];
|
|
516 |
__KTRACE_PRINT(Kern::Printf("NFE%d:drive letter %c", iInstance, (TInt) DriveLetterToAscii(driveLetter)));
|
|
517 |
|
|
518 |
// no point setting up P&S for the swap drive
|
|
519 |
if (driveLetter == -1)
|
|
520 |
{
|
|
521 |
__KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Skipping P&S for swap partition", iInstance, i));
|
|
522 |
continue;
|
|
523 |
}
|
|
524 |
|
|
525 |
r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iStatusToUiProperty, NFE_KEY(driveLetter, KNfeStatusToUiKey));
|
|
526 |
if (r != KErrNone)
|
|
527 |
return r;
|
|
528 |
|
|
529 |
r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iToUiProperty, NFE_KEY(driveLetter, KNfeToUiKey));
|
|
530 |
if (r != KErrNone)
|
|
531 |
return r;
|
|
532 |
|
|
533 |
r = CreateKey((RPropertyRef*&) iInfo.iDrives[i].iProgressToUiProperty, NFE_KEY(driveLetter, KNfeProgressToUiKey));
|
|
534 |
if (r != KErrNone)
|
|
535 |
return r;
|
|
536 |
|
|
537 |
TPropertyObserver& observer = iFromUiPropertyObserver[i];
|
|
538 |
observer.iDriveIndex = i;
|
|
539 |
observer.iMediaExt = this;
|
|
540 |
observer.iPropertySubsRequest = new TPropertySubsRequest(TPropertyObserver::PropertySubsCompleteFn, &observer);
|
|
541 |
if (observer.iPropertySubsRequest == NULL)
|
|
542 |
return KErrNoMemory;
|
|
543 |
|
|
544 |
observer.iPropertyDfc = new TDfc(FromUiPropertyDfcFunction,&observer,iPrimaryMedia->iDfcQ,2);
|
|
545 |
if (observer.iPropertyDfc == NULL)
|
|
546 |
return KErrNoMemory;
|
|
547 |
|
|
548 |
r = observer.iProperty.Attach(KNfeUID, NFE_KEY(driveLetter, KNfeToThreadKey));
|
|
549 |
if (r != KErrNone)
|
|
550 |
return r;
|
|
551 |
r = observer.iProperty.Define(
|
|
552 |
RProperty::EInt,
|
|
553 |
KPassPolicy,
|
|
554 |
KPassPolicy);
|
|
555 |
if (r != KErrNone && r != KErrAlreadyExists)
|
|
556 |
return r;
|
|
557 |
|
|
558 |
r = observer.iProperty.Subscribe(*observer.iPropertySubsRequest);
|
|
559 |
if (r != KErrNone)
|
|
560 |
return r;
|
|
561 |
}
|
|
562 |
|
|
563 |
// **************************************************************************************
|
|
564 |
// If this instance owns the swap partition,
|
|
565 |
// set up P&S listeners so we can get status notification events from the other drives
|
|
566 |
// **************************************************************************************
|
|
567 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Setting up StatusToUi P&S observer", iInstance));
|
|
568 |
|
|
569 |
for (i = 0; i < (iInstance == swapInstance ? NFE_DRIVECOUNT : -1); i++)
|
|
570 |
{
|
|
571 |
__KTRACE_PRINT(Kern::Printf("NFE%d:drive index %d", iInstance, i));
|
|
572 |
__KTRACE_PRINT(Kern::Printf("NFE%d:drive letter %c", iInstance, (TInt) DriveLetterToAscii(DriveLetter(i))));
|
|
573 |
|
|
574 |
// no point setting up P&S for the swap drive
|
|
575 |
if (DriveLetter(i) == -1)
|
|
576 |
{
|
|
577 |
__KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Skipping StatusToUi P&S observer for swap partition", iInstance, i));
|
|
578 |
continue;
|
|
579 |
}
|
|
580 |
|
|
581 |
__KTRACE_PRINT(Kern::Printf("NFE%d: i %d, Setting up StatusToUi P&S observer for drive %c", iInstance, i, (TInt) DriveLetterToAscii(DriveLetter(i))));
|
|
582 |
TPropertyObserver& observer = iStatusToUiPropertyObserver[i];
|
|
583 |
observer.iDriveIndex = i;
|
|
584 |
observer.iMediaExt = this;
|
|
585 |
observer.iPropertySubsRequest = new TPropertySubsRequest(TPropertyObserver::PropertySubsCompleteFn, &observer);
|
|
586 |
if (observer.iPropertySubsRequest == NULL)
|
|
587 |
return KErrNoMemory;
|
|
588 |
|
|
589 |
observer.iPropertyDfc = new TDfc(StatusToUiPropertyDfcFunction,&observer,iPrimaryMedia->iDfcQ,2);
|
|
590 |
if (observer.iPropertyDfc == NULL)
|
|
591 |
return KErrNoMemory;
|
|
592 |
|
|
593 |
r = observer.iProperty.Attach(KNfeUID, NFE_KEY(DriveLetter(i), KNfeStatusToUiKey));
|
|
594 |
if (r != KErrNone)
|
|
595 |
return r;
|
|
596 |
r = observer.iProperty.Define(
|
|
597 |
RProperty::EInt,
|
|
598 |
KPassPolicy,
|
|
599 |
KPassPolicy);
|
|
600 |
if (r != KErrNone && r != KErrAlreadyExists)
|
|
601 |
return r;
|
|
602 |
|
|
603 |
r = observer.iProperty.Subscribe(*observer.iPropertySubsRequest);
|
|
604 |
if (r != KErrNone)
|
|
605 |
return r;
|
|
606 |
}
|
|
607 |
|
|
608 |
return(KErrNone);
|
|
609 |
}
|
|
610 |
|
|
611 |
void DMediaDriverNFE::TPropertyObserver::Close()
|
|
612 |
{
|
|
613 |
iProperty.Close();
|
|
614 |
delete iPropertyDfc;
|
|
615 |
iPropertyDfc = NULL;
|
|
616 |
delete iPropertySubsRequest;
|
|
617 |
iPropertySubsRequest = NULL;
|
|
618 |
}
|
|
619 |
|
|
620 |
void DMediaDriverNFE::TPropertyObserver::PropertySubsCompleteFn(TAny* aPtr, TInt /*aReason*/)
|
|
621 |
{
|
|
622 |
TPropertyObserver* self = (TPropertyObserver*) aPtr;
|
|
623 |
// Queue a DFC to ensure we're running in the correct thread
|
|
624 |
self->iPropertyDfc->Enque();
|
|
625 |
}
|
|
626 |
|
|
627 |
void DMediaDriverNFE::FromUiPropertyDfcFunction(TAny* aObserver)
|
|
628 |
{
|
|
629 |
TPropertyObserver& observer = *(TPropertyObserver*) aObserver;
|
|
630 |
observer.iMediaExt->FromUiPropertyDfc(observer);
|
|
631 |
}
|
|
632 |
|
|
633 |
void DMediaDriverNFE::FromUiPropertyDfc(TPropertyObserver& aObserver)
|
|
634 |
{
|
|
635 |
// Get the value of request from the UI
|
|
636 |
TInt err = aObserver.iProperty.Get(aObserver.iValue);
|
|
637 |
|
|
638 |
TInt r = aObserver.iProperty.Subscribe(*aObserver.iPropertySubsRequest);
|
|
639 |
__ASSERT_ALWAYS(r == KErrNone, NFE_FAULT());
|
|
640 |
|
|
641 |
TInt driveLetter = iDriveLetterList[aObserver.iDriveIndex];
|
|
642 |
|
|
643 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::FromUiPropertyDfc() cmd %d driveLetter %c",
|
|
644 |
iInstance, aObserver.iValue, (TInt) DriveLetterToAscii(driveLetter)));
|
|
645 |
|
|
646 |
// is this our drive letter ?
|
|
647 |
TInt driveCount = DriveCount(iInstance);
|
|
648 |
TNfeDriveInfo* driveInfo = NULL;
|
|
649 |
|
|
650 |
for (TInt i=0; i<driveCount; i++)
|
|
651 |
{
|
|
652 |
TInt myDriveLetter = iDriveLetterList[i];
|
|
653 |
|
|
654 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Comparing drive %c with myDrive %c", iInstance, (TInt) DriveLetterToAscii(driveLetter), (TInt) DriveLetterToAscii(myDriveLetter)));
|
|
655 |
|
|
656 |
if (myDriveLetter == driveLetter)
|
|
657 |
{
|
|
658 |
TInt driveNumber = iDriveList[i];
|
|
659 |
driveInfo = &iInfo.iDrives[iDriveNumToIndex[driveNumber]];
|
|
660 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Drive Match found driveNumber %d", iInstance, driveInfo->iLocalDriveNum));
|
|
661 |
|
|
662 |
__ASSERT_ALWAYS(driveInfo->iProgressToUiProperty, NFE_FAULT());
|
|
663 |
((RPropertyRef*) (driveInfo->iProgressToUiProperty))->Set(0);
|
|
664 |
// Wake up the possibly waiting client, whether or not the request
|
|
665 |
// was successfull.
|
|
666 |
((RPropertyRef*) (driveInfo->iToUiProperty))->Set( err ); // Return value ignored
|
|
667 |
break;
|
|
668 |
}
|
|
669 |
}
|
|
670 |
|
|
671 |
|
|
672 |
__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));
|
|
673 |
|
|
674 |
if (err == KErrNone && aObserver.iValue == ENfeEncryptDisk && driveInfo != NULL)
|
|
675 |
{
|
|
676 |
if (driveInfo->Status() == ENfeDecrypted)
|
|
677 |
{
|
|
678 |
SetStatus(*driveInfo, ENfeEncrypting);
|
|
679 |
StartEncrypting();
|
|
680 |
}
|
|
681 |
}
|
|
682 |
if (err == KErrNone && aObserver.iValue == ENfeDecryptDisk && driveInfo != NULL)
|
|
683 |
{
|
|
684 |
if (driveInfo->Status() == ENfeEncrypted)
|
|
685 |
{
|
|
686 |
SetStatus(*driveInfo, ENfeDecrypting);
|
|
687 |
StartDecrypting();
|
|
688 |
}
|
|
689 |
}
|
|
690 |
}
|
|
691 |
|
|
692 |
|
|
693 |
void DMediaDriverNFE::StatusToUiPropertyDfcFunction(TAny* aObserver)
|
|
694 |
{
|
|
695 |
TPropertyObserver& observer = *(TPropertyObserver*) aObserver;
|
|
696 |
observer.iMediaExt->StatusToUiPropertyDfc(observer);
|
|
697 |
}
|
|
698 |
|
|
699 |
void DMediaDriverNFE::StatusToUiPropertyDfc(TPropertyObserver& aObserver)
|
|
700 |
{
|
|
701 |
// Get the value of request from the UI
|
|
702 |
TInt err = aObserver.iProperty.Get(aObserver.iValue);
|
|
703 |
|
|
704 |
TInt r = aObserver.iProperty.Subscribe(*aObserver.iPropertySubsRequest);
|
|
705 |
__ASSERT_ALWAYS(r == KErrNone, NFE_FAULT());
|
|
706 |
|
|
707 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::StatusToUiPropertyDfc() status %d driveLetter %c",
|
|
708 |
iInstance, aObserver.iValue, DriveLetter(aObserver.iDriveIndex) >=0 ? DriveLetter(aObserver.iDriveIndex)+'A' : '?'));
|
|
709 |
|
|
710 |
|
|
711 |
__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));
|
|
712 |
|
|
713 |
if (err == KErrNone && (aObserver.iValue == ENfeEncrypted || aObserver.iValue == ENfeEncrypting))
|
|
714 |
{
|
|
715 |
// If any drive is being or is already encrypted then we have to encrypt the swap partition...
|
|
716 |
TNfeDriveInfo* diSwap = GetSwapDrive();
|
|
717 |
if (diSwap != NULL && diSwap->Status() == ENfeDecrypted)
|
|
718 |
{
|
|
719 |
SetStatus(*diSwap, ENfeEncrypting);
|
|
720 |
StartEncrypting();
|
|
721 |
}
|
|
722 |
}
|
|
723 |
}
|
|
724 |
|
|
725 |
|
|
726 |
void DMediaDriverNFE::Close()
|
|
727 |
{
|
|
728 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::Close()", iInstance));
|
|
729 |
DMediaDriverExtension::Close();
|
|
730 |
}
|
|
731 |
|
|
732 |
|
|
733 |
void DMediaDriverNFE::SetStatus(TNfeDriveInfo& aDi, TNfeDiskStatus aStatus)
|
|
734 |
{
|
|
735 |
if (aStatus != aDi.Status())
|
|
736 |
{
|
|
737 |
aDi.SetStatus(aStatus);
|
|
738 |
__KTRACE_PRINT(Kern::Printf("NFE%d: SetStatus = %s", iInstance, DriveStatus(aDi.Status())));
|
|
739 |
}
|
|
740 |
}
|
|
741 |
|
|
742 |
void TNfeDriveInfo::SetStatus(TNfeDiskStatus aStatus)
|
|
743 |
{
|
|
744 |
iStatus = aStatus;
|
|
745 |
if (IsUDADrive())
|
|
746 |
{
|
|
747 |
// Update the status pub&sub variable for UI
|
|
748 |
__ASSERT_ALWAYS(iStatusToUiProperty, NFE_FAULT());
|
|
749 |
((RPropertyRef*) iStatusToUiProperty)->Set(aStatus);
|
|
750 |
}
|
|
751 |
}
|
|
752 |
|
|
753 |
|
|
754 |
|
|
755 |
|
|
756 |
TInt DMediaDriverNFE::Request(TLocDrvRequest& aReq)
|
|
757 |
{
|
|
758 |
// __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()));
|
|
759 |
|
|
760 |
TInt r = KErrNotSupported;
|
|
761 |
|
|
762 |
TInt reqId = aReq.Id();
|
|
763 |
TNfeDriveInfo& di = iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
|
|
764 |
|
|
765 |
switch (reqId)
|
|
766 |
{
|
|
767 |
#if defined(__DEMAND_PAGING__)
|
|
768 |
case DMediaPagingDevice::ERomPageInRequest:
|
|
769 |
BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_NFE,&aReq);
|
|
770 |
r=HandleRead(aReq);
|
|
771 |
break;
|
|
772 |
|
|
773 |
case DMediaPagingDevice::ECodePageInRequest:
|
|
774 |
BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_NFE,&aReq);
|
|
775 |
r=HandleRead(aReq);
|
|
776 |
break;
|
|
777 |
|
|
778 |
#endif // __DEMAND_PAGING__
|
|
779 |
|
|
780 |
case DLocalDrive::ERead:
|
|
781 |
r=HandleRead(aReq);
|
|
782 |
break;
|
|
783 |
|
|
784 |
case DLocalDrive::EWrite:
|
|
785 |
r=HandleWrite(aReq);
|
|
786 |
break;
|
|
787 |
|
|
788 |
case DLocalDrive::ECaps:
|
|
789 |
r = HandleCaps(aReq);
|
|
790 |
break;
|
|
791 |
|
|
792 |
case DLocalDrive::EFormat:
|
|
793 |
r = HandleFormat(aReq);
|
|
794 |
break;
|
|
795 |
|
|
796 |
// API used by T_NFE to query state etc.
|
|
797 |
case DLocalDrive::EQueryDevice:
|
|
798 |
switch((TInt) aReq.iArg[0])
|
|
799 |
{
|
|
800 |
case EQueryNfeDeviceInfo:
|
|
801 |
{
|
|
802 |
TNfeDeviceInfo& deviceInfo = *(TNfeDeviceInfo*) aReq.RemoteDes();
|
|
803 |
iInfo.iMediaSizeInBytes = iTotalSizeInBytes;
|
|
804 |
deviceInfo = iInfo;
|
|
805 |
|
|
806 |
r = KErrCompletion;
|
|
807 |
break;
|
|
808 |
}
|
|
809 |
case RLocalDrive::EQueryFinaliseDrive:
|
|
810 |
{
|
|
811 |
// TLocalDriveFinaliseInfo& finaliseInfo = *(TLocalDriveFinaliseInfo*) aReq.RemoteDes();
|
|
812 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: EQueryFinaliseDrive iMode %d", iInstance, finaliseInfo.iMode));
|
|
813 |
|
|
814 |
// write to boot sector to indicate that the drive has ben finalised
|
|
815 |
WriteEncryptionStatusToBootSector(di, ETrue);
|
|
816 |
}
|
|
817 |
default:
|
|
818 |
r = KErrNotSupported;
|
|
819 |
break;
|
|
820 |
}
|
|
821 |
break;
|
|
822 |
|
|
823 |
default:
|
|
824 |
r = ForwardRequest(aReq);
|
|
825 |
break;
|
|
826 |
}
|
|
827 |
|
|
828 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::DoRequest() : ret: %d", iInstance, r));
|
|
829 |
|
|
830 |
if (!di.iDriveFinalised && iBusy)
|
|
831 |
{
|
|
832 |
// Restart the idle timer after processing a request
|
|
833 |
iIdleTimer.Cancel();
|
|
834 |
iTimerDfc.Cancel();
|
|
835 |
iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
|
|
836 |
}
|
|
837 |
|
|
838 |
return r;
|
|
839 |
}
|
|
840 |
|
|
841 |
/**
|
|
842 |
PartitionInfo()
|
|
843 |
|
|
844 |
Reads the partition information from the attached drive(s).
|
|
845 |
Note: this method is also called when a removable card is removed, so can
|
|
846 |
be used to detect a memory card insertions/removals. Assumes the swap
|
|
847 |
partition is encrypted if any encrypted FAT drives are found
|
|
848 |
*/
|
|
849 |
TInt DMediaDriverNFE::PartitionInfo(TPartitionInfo& aInfo)
|
|
850 |
{
|
|
851 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DMediaDriverNFE::PartitionInfo()", iInstance));
|
|
852 |
|
|
853 |
TInt r = DoDrivePartitionInfo(aInfo);
|
|
854 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DoDrivePartitionInfo() r %d", iInstance, r));
|
|
855 |
if (r != KErrNone)
|
|
856 |
return r;
|
|
857 |
|
|
858 |
__KTRACE_PRINT(Kern::Printf("NFE%d: *** Slave drives partition info ***", iInstance));
|
|
859 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iMediaSizeInBytes %lx", iInstance, aInfo.iMediaSizeInBytes));
|
|
860 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionCount %d", iInstance, aInfo.iPartitionCount));
|
|
861 |
__KTRACE_PRINT(Kern::Printf("NFE%d: ", iInstance));
|
|
862 |
|
|
863 |
TInt i;
|
|
864 |
|
|
865 |
__ASSERT_DEBUG(aInfo.iPartitionCount <= TNfeDeviceInfo::ENfeMaxPartitionEntries, NFE_FAULT());
|
|
866 |
for (i=0; i<aInfo.iPartitionCount; i++)
|
|
867 |
{
|
|
868 |
TInt driveNum = iDriveList[i];
|
|
869 |
iDriveNumToIndex[driveNum] = i;
|
|
870 |
|
|
871 |
TNfeDriveInfo& di = iInfo.iDrives[i];
|
|
872 |
|
|
873 |
di.iDriveFinalised = EFalse; // a remount clears the finalised state
|
|
874 |
|
126
|
875 |
// Make sure we haven't lost the swap partition
|
|
876 |
__ASSERT_ALWAYS(!(di.iEntry.iPartitionType == KPartitionTypePagedData && aInfo.iEntry[i].iPartitionType != KPartitionTypePagedData), NFE_FAULT());
|
|
877 |
|
123
|
878 |
// Make a copy of the TPartitionEntry
|
|
879 |
di.iEntry = aInfo.iEntry[i];
|
|
880 |
|
|
881 |
|
|
882 |
// save the local drive number
|
|
883 |
di.iLocalDriveNum = driveNum;
|
|
884 |
di.iDriveLetter = iDriveLetterList[i];
|
|
885 |
|
|
886 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DriveNum %d", iInstance, driveNum));
|
|
887 |
__KTRACE_PRINT(Kern::Printf("NFE%d: DriveLetter %c", iInstance, (TInt) DriveLetterToAscii(di.iDriveLetter)));
|
|
888 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionBaseAddr %lX", iInstance, di.iEntry.iPartitionBaseAddr));
|
|
889 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionLen %lx", iInstance, di.iEntry.iPartitionLen));
|
|
890 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iPartitionType %x", iInstance, di.iEntry.iPartitionType));
|
|
891 |
|
|
892 |
|
|
893 |
// If the drive was removed, reset it's state
|
|
894 |
if (di.iEntry.iPartitionType == KPartitionTypeEmpty)
|
|
895 |
{
|
|
896 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Empty Partition, setting state to ENfeUnmounted", iInstance));
|
|
897 |
SetStatus(di, ENfeUnmounted);
|
|
898 |
}
|
|
899 |
|
|
900 |
// Is this an unencrypted FAT partition ?
|
|
901 |
if (di.IsUDADrive())
|
|
902 |
{
|
|
903 |
r = Read(di.iLocalDriveNum, di.iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
|
|
904 |
if (r != KErrNone)
|
|
905 |
return r;
|
|
906 |
CheckBootSector(di);
|
|
907 |
}
|
|
908 |
|
|
909 |
|
|
910 |
__KTRACE_PRINT(Kern::Printf("NFE%d: status = %s", iInstance, DriveStatus(di.Status())));
|
|
911 |
|
|
912 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iEncryptStartPos %lX", iInstance, di.iEncryptStartPos));
|
|
913 |
__KTRACE_PRINT(Kern::Printf("NFE%d: iEncryptEndPos %lX", iInstance, di.iEncryptEndPos));
|
|
914 |
__KTRACE_PRINT(Kern::Printf("NFE%d: ", iInstance));
|
|
915 |
}
|
|
916 |
|
|
917 |
|
|
918 |
|
|
919 |
#ifdef COMPOSITE_DRIVES
|
|
920 |
// Accumulate the sizes of consecutive FAT drives & report the accumulated size back in the first FAT partition
|
|
921 |
for (i=0; i<aInfo.iPartitionCount; i++)
|
|
922 |
{
|
|
923 |
aInfo.iEntry[i] = iInfo.iDrives[i].iEntry;
|
|
924 |
|
|
925 |
if (iInfo.iDrives[i].IsUDADrive())
|
|
926 |
{
|
|
927 |
aInfo.iEntry[i].iPartitionLen = 0;
|
|
928 |
for (TInt j=i; j<aInfo.iPartitionCount; j++)
|
|
929 |
{
|
|
930 |
if (iInfo.iDrives[j].IsUDADrive())
|
|
931 |
{
|
|
932 |
aInfo.iEntry[i].iPartitionLen+= iInfo.iDrives[j].iEntry.iPartitionLen;
|
|
933 |
}
|
|
934 |
}
|
|
935 |
iInfo.iDrives[i].iCompositeSize = aInfo.iEntry[i].iPartitionLen;
|
|
936 |
i = j;
|
|
937 |
}
|
|
938 |
}
|
|
939 |
#endif
|
|
940 |
|
|
941 |
|
|
942 |
SetTotalSizeInBytes(aInfo.iMediaSizeInBytes);
|
|
943 |
|
|
944 |
|
|
945 |
return KErrCompletion; // synchronous completion
|
|
946 |
}
|
|
947 |
|
|
948 |
/**
|
|
949 |
HandleCaps() -
|
|
950 |
|
|
951 |
Return the Caps for a particular drive
|
|
952 |
|
|
953 |
Queries the caps from the attached drive, ORs in appropriate paging flags & returns
|
|
954 |
*/
|
|
955 |
TInt DMediaDriverNFE::HandleCaps(TLocDrvRequest& aReq)
|
|
956 |
{
|
|
957 |
// Get caps from slave drive
|
|
958 |
// NB if we didn't want to alter anything then we could just call ForwardRequest(aReq);
|
|
959 |
TBuf8<sizeof(TLocalDriveCapsV6)> slaveCapsBuf;
|
|
960 |
TLocalDriveCapsV6& slaveCaps = *(TLocalDriveCapsV6*) slaveCapsBuf.Ptr();
|
|
961 |
slaveCapsBuf.SetMax();
|
|
962 |
slaveCapsBuf.FillZ();
|
|
963 |
TInt r = Caps(aReq.Drive()->iDriveNumber, slaveCapsBuf);
|
|
964 |
if (r != KErrNone)
|
|
965 |
return r;
|
|
966 |
|
|
967 |
#ifdef COMPOSITE_DRIVES
|
|
968 |
TInt driveNum = aReq.Drive()->iDriveNumber;
|
|
969 |
TInt driveIndex = DriveIndex(driveNum);
|
|
970 |
if (iInfo.iDrives[driveIndex].iCompositeSize)
|
|
971 |
slaveCaps.iSize = iInfo.iDrives[driveIndex].iCompositeSize;
|
|
972 |
#endif
|
|
973 |
|
|
974 |
// copy slave caps to returned caps
|
|
975 |
TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)aReq.RemoteDes();
|
|
976 |
caps = slaveCaps;
|
|
977 |
|
|
978 |
// set the paging flags
|
|
979 |
#ifdef __DEMAND_PAGING__
|
|
980 |
TLocDrv& drive = *aReq.Drive();
|
|
981 |
if (drive.iPrimaryMedia->iPagingMedia)
|
|
982 |
caps.iMediaAtt|=KMediaAttPageable;
|
|
983 |
if (drive.iPagingDrv)
|
|
984 |
caps.iDriveAtt|=KDriveAttPageable;
|
|
985 |
#endif // __DEMAND_PAGING__
|
|
986 |
|
|
987 |
return KErrCompletion;
|
|
988 |
}
|
|
989 |
|
|
990 |
|
|
991 |
/**
|
|
992 |
AdjustRequest() -
|
|
993 |
|
|
994 |
Adjusts position & length if a request crosses these boundaries:
|
|
995 |
- the start of the partition (if RLocalDrive::ELocDrvWholeMedia set)
|
|
996 |
- the current encrytion point (iEncryptEndPos) N.B. this will point to the end of the partition
|
|
997 |
if the drive is fully encrypted
|
|
998 |
|
|
999 |
For composite drives, it also adjusts the position, length & drive number as appropriate to cater for
|
|
1000 |
crossing partition boundaries
|
|
1001 |
|
|
1002 |
returns ETrue if buffer needs encrypting/decrypting
|
|
1003 |
*/
|
|
1004 |
|
|
1005 |
TBool DMediaDriverNFE::AdjustRequest(TNfeDriveInfo*& aDriveInfo, TInt64& aCurrentPos, TInt64& aCurrentLen)
|
|
1006 |
{
|
|
1007 |
#ifdef COMPOSITE_DRIVES
|
|
1008 |
while (aCurrentPos >= aDriveInfo->iEntry.iPartitionLen)
|
|
1009 |
{
|
|
1010 |
aCurrentPos-= aDriveInfo->iEntry.iPartitionLen;
|
|
1011 |
aDriveInfo++;
|
|
1012 |
}
|
|
1013 |
if (aCurrentPos + aCurrentLen > aDriveInfo->iEntry.iPartitionLen)
|
|
1014 |
aCurrentLen = aDriveInfo->iEntry.iPartitionLen - aCurrentPos;
|
|
1015 |
#endif
|
|
1016 |
|
|
1017 |
// do we need to encrypt/decrypt this buffer ?
|
|
1018 |
TBool encodeBuffer = EFalse;
|
|
1019 |
|
|
1020 |
if ((aDriveInfo->Status() == ENfeEncrypted) || aDriveInfo->Status() == ENfeEncrypting)
|
|
1021 |
{
|
|
1022 |
// __ASSERT_DEBUG(aDriveInfo->iEncryptEndPos <= aDriveInfo->iEntry.iPartitionBaseAddr + aDriveInfo->iEntry.iPartitionLen, NFE_FAULT());
|
|
1023 |
|
|
1024 |
if (aCurrentPos < aDriveInfo->iEncryptStartPos)
|
|
1025 |
{
|
|
1026 |
aCurrentLen = Min(aCurrentLen, aDriveInfo->iEncryptStartPos - aCurrentPos);
|
|
1027 |
encodeBuffer = EFalse;
|
|
1028 |
}
|
|
1029 |
else if (aCurrentPos < aDriveInfo->iEncryptEndPos)
|
|
1030 |
{
|
|
1031 |
aCurrentLen = Min(aCurrentLen, aDriveInfo->iEncryptEndPos - aCurrentPos);
|
|
1032 |
encodeBuffer = ETrue;
|
|
1033 |
}
|
|
1034 |
else
|
|
1035 |
{
|
|
1036 |
encodeBuffer = EFalse;
|
|
1037 |
}
|
|
1038 |
}
|
|
1039 |
|
|
1040 |
return encodeBuffer;
|
|
1041 |
}
|
|
1042 |
|
|
1043 |
|
|
1044 |
TInt DMediaDriverNFE::HandleRead(TLocDrvRequest& aReq)
|
|
1045 |
{
|
|
1046 |
TInt r = KErrNone;
|
|
1047 |
TInt64 currentPos = aReq.Pos();
|
|
1048 |
TInt64 remainingLength = aReq.Length();
|
|
1049 |
TInt desPos = 0;
|
|
1050 |
TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
|
|
1051 |
|
|
1052 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleRead pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
|
|
1053 |
|
|
1054 |
|
|
1055 |
di->iReadRequestCount++;
|
|
1056 |
|
|
1057 |
if (aReq.Flags() & TLocDrvRequest::ECodePaging)
|
|
1058 |
di->iCodePagingRequesCount++;
|
|
1059 |
if (aReq.Flags() & TLocDrvRequest::EDataPaging)
|
|
1060 |
di->iDataPagingReadRequestCount++;
|
|
1061 |
|
|
1062 |
|
|
1063 |
// just forward the request if the drive is not encrypted
|
|
1064 |
if (di->Status() == ENfeDecrypted)
|
|
1065 |
return ForwardRequest(aReq);
|
|
1066 |
|
|
1067 |
|
|
1068 |
while(remainingLength)
|
|
1069 |
{
|
|
1070 |
TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
|
|
1071 |
|
|
1072 |
TBool decryptBuffer = AdjustRequest(di, currentPos, currentLength);
|
|
1073 |
|
|
1074 |
// Read from attached drive
|
|
1075 |
#ifdef __DEMAND_PAGING__
|
|
1076 |
if (DMediaPagingDevice::PagingRequest(aReq))
|
|
1077 |
r = ReadPaged(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
|
|
1078 |
else
|
|
1079 |
#endif
|
|
1080 |
r = Read(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
|
|
1081 |
if(r != KErrNone)
|
|
1082 |
break;
|
|
1083 |
|
|
1084 |
TPtr8 des(iBuffer, I64LOW(currentLength), I64LOW(currentLength));
|
|
1085 |
|
|
1086 |
// decrypt buffer
|
|
1087 |
if (decryptBuffer)
|
|
1088 |
DecryptBuffer(des);
|
|
1089 |
|
|
1090 |
// write back to user
|
|
1091 |
r = aReq.WriteRemote(&des, desPos);
|
|
1092 |
if(r != KErrNone)
|
|
1093 |
break;
|
|
1094 |
|
|
1095 |
remainingLength-= currentLength;
|
|
1096 |
currentPos+= currentLength;
|
|
1097 |
desPos+= I64LOW(currentLength);
|
|
1098 |
}
|
|
1099 |
|
|
1100 |
return r == KErrNone ? KErrCompletion : r;
|
|
1101 |
}
|
|
1102 |
|
|
1103 |
TInt DMediaDriverNFE::HandleWrite(TLocDrvRequest& aReq)
|
|
1104 |
{
|
|
1105 |
TInt r = KErrNone;
|
|
1106 |
TInt64 currentPos = aReq.Pos();
|
|
1107 |
TInt64 remainingLength = aReq.Length();
|
|
1108 |
TInt desPos = 0;
|
|
1109 |
TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
|
|
1110 |
|
|
1111 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleWrite pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
|
|
1112 |
|
|
1113 |
|
|
1114 |
di->iWriteRequestCount++;
|
|
1115 |
if (aReq.Flags() & TLocDrvRequest::EDataPaging)
|
|
1116 |
di->iDataPagingWriteRequestCount++;
|
|
1117 |
|
|
1118 |
|
|
1119 |
// just forward the request if the drive is not encrypted
|
|
1120 |
if (di->Status() == ENfeDecrypted)
|
|
1121 |
return ForwardRequest(aReq);
|
|
1122 |
|
|
1123 |
while(remainingLength)
|
|
1124 |
{
|
|
1125 |
TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
|
|
1126 |
|
|
1127 |
TBool encryptBuffer = AdjustRequest(di, currentPos, currentLength);
|
|
1128 |
|
|
1129 |
// read from user
|
|
1130 |
TPtr8 des(iBuffer,0,I64LOW(currentLength));
|
|
1131 |
r = aReq.ReadRemote(&des, desPos);
|
|
1132 |
if(r != KErrNone)
|
|
1133 |
break;
|
|
1134 |
|
|
1135 |
// get the length of data read from the user in case user's
|
|
1136 |
// descriptor is shorter than advertised
|
|
1137 |
currentLength = des.Length();
|
|
1138 |
if (currentLength == 0)
|
|
1139 |
break;
|
|
1140 |
|
|
1141 |
// writing to sector zero ?
|
|
1142 |
if (currentPos >= di->iEntry.iPartitionBaseAddr &&
|
|
1143 |
currentPos < di->iEntry.iPartitionBaseAddr + KSectorSize &&
|
|
1144 |
di->IsUDADrive())
|
|
1145 |
{
|
|
1146 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Write to sector #0 detected", iInstance));
|
|
1147 |
|
|
1148 |
|
|
1149 |
TUint8* bootSector = iBuffer;
|
|
1150 |
TUint8 bootSectorBuffer[KSectorSize];
|
|
1151 |
// writing partial sector ?
|
|
1152 |
if (currentPos > di->iEntry.iPartitionBaseAddr || currentLength < KSectorSize)
|
|
1153 |
{
|
|
1154 |
bootSector = bootSectorBuffer;
|
|
1155 |
r = Read(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) bootSector, KSectorSize);
|
|
1156 |
if(r != KErrNone)
|
|
1157 |
break;
|
|
1158 |
TInt64 readLen = KSectorSize;
|
|
1159 |
TBool encryptBuffer = AdjustRequest(di, di->iEntry.iPartitionBaseAddr, readLen);
|
|
1160 |
if (encryptBuffer)
|
|
1161 |
{
|
|
1162 |
TPtr8 des(bootSectorBuffer,KSectorSize,KSectorSize);
|
|
1163 |
DecryptBuffer(des);
|
|
1164 |
}
|
|
1165 |
TInt sectorOffset = (TInt) (currentPos - di->iEntry.iPartitionBaseAddr);
|
|
1166 |
TInt64 copyLen = currentLength;
|
|
1167 |
if (copyLen > KSectorSize-sectorOffset)
|
|
1168 |
copyLen = KSectorSize-sectorOffset;
|
|
1169 |
memcpy(bootSectorBuffer+sectorOffset, iBuffer, (TInt) copyLen);
|
|
1170 |
}
|
|
1171 |
|
|
1172 |
if ((di->Status() == ENfeUnmounted || di->Status() == ENfeCorrupted) &&
|
|
1173 |
ValidBootSector(bootSector))
|
|
1174 |
{
|
|
1175 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Setting status to ENfeDecrypted", iInstance ));
|
|
1176 |
di->SetStatus(ENfeDecrypted);
|
|
1177 |
}
|
|
1178 |
di->iUniqueID = VolumeId(bootSector); // update the Volume ID
|
|
1179 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Setting Volume ID to %08X", iInstance, di->iUniqueID ));
|
|
1180 |
TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
|
|
1181 |
if (di->Status() == ENfeEncrypting || di->Status() == ENfeDecrypting)
|
|
1182 |
{
|
|
1183 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Adding NFE status record to boot sector", iInstance ));
|
|
1184 |
bootSectorStatus->iSignature = TBootSectorStatus::ENfeBootSectorSignature;
|
|
1185 |
bootSectorStatus->iEncryptEndPos = di->iEncryptEndPos;
|
|
1186 |
bootSectorStatus->iStatus = di->Status();
|
|
1187 |
bootSectorStatus->iFinalised = EFalse;
|
|
1188 |
}
|
|
1189 |
}
|
|
1190 |
|
|
1191 |
// encrypt the buffer
|
|
1192 |
if (encryptBuffer)
|
|
1193 |
EncryptBuffer(des);
|
|
1194 |
|
|
1195 |
// write the data to the attached drive
|
|
1196 |
#ifdef __DEMAND_PAGING__
|
|
1197 |
if (DMediaPagingDevice::PagingRequest(aReq))
|
|
1198 |
r = WritePaged(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
|
|
1199 |
else
|
|
1200 |
#endif
|
|
1201 |
r = Write(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
|
|
1202 |
if(r != KErrNone)
|
|
1203 |
break;
|
|
1204 |
|
|
1205 |
remainingLength-= currentLength;
|
|
1206 |
currentPos+= currentLength;
|
|
1207 |
desPos+= I64LOW(currentLength);
|
|
1208 |
}
|
|
1209 |
|
|
1210 |
return r == KErrNone ? KErrCompletion : r;
|
|
1211 |
}
|
|
1212 |
|
|
1213 |
TInt DMediaDriverNFE::HandleFormat(TLocDrvRequest& aReq)
|
|
1214 |
{
|
|
1215 |
TInt r = KErrNone;
|
|
1216 |
TInt64 currentPos = aReq.Pos();
|
|
1217 |
TInt64 remainingLength = aReq.Length();
|
|
1218 |
TNfeDriveInfo* di = &iInfo.iDrives[DriveIndex(aReq.Drive()->iDriveNumber)];
|
|
1219 |
|
|
1220 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: HandleFormat pos %lx len %lx status %d", iInstance, currentPos, remainingLength, di->Status()));
|
|
1221 |
|
|
1222 |
|
|
1223 |
// just forward the request if the drive is not encrypted
|
|
1224 |
if (di->Status() == ENfeDecrypted)
|
|
1225 |
return ForwardRequest(aReq);
|
|
1226 |
|
|
1227 |
// otherwise create a buffer containing NULLs, encrypt it and write that to the attached drive
|
|
1228 |
while(remainingLength && r == KErrNone)
|
|
1229 |
{
|
|
1230 |
TInt64 currentLength = (remainingLength <= KBufSize ? remainingLength : KBufSize);
|
|
1231 |
|
|
1232 |
TBool encryptBuffer = AdjustRequest(di, currentPos, currentLength);
|
|
1233 |
|
|
1234 |
memclr(iBuffer, KBufSize);
|
|
1235 |
TPtr8 des(iBuffer,KBufSize,KBufSize);
|
|
1236 |
|
|
1237 |
if (encryptBuffer)
|
|
1238 |
EncryptBuffer(des);
|
|
1239 |
|
|
1240 |
r = Write(di->iLocalDriveNum, currentPos, (TLinAddr) iBuffer, I64LOW(currentLength));
|
|
1241 |
if(r != KErrNone)
|
|
1242 |
break;
|
|
1243 |
|
|
1244 |
remainingLength-= currentLength;
|
|
1245 |
currentPos+= currentLength;
|
|
1246 |
}
|
|
1247 |
|
|
1248 |
return r == KErrNone ? KErrCompletion : r;
|
|
1249 |
}
|
|
1250 |
|
|
1251 |
|
|
1252 |
void DMediaDriverNFE::EncryptBuffer(TDes8& aBuffer)
|
|
1253 |
{
|
|
1254 |
TInt len = aBuffer.Length();
|
|
1255 |
for(TInt i=0; i<len; i++)
|
|
1256 |
aBuffer[i] = EncryptByte(aBuffer[i]);
|
|
1257 |
}
|
|
1258 |
|
|
1259 |
void DMediaDriverNFE::DecryptBuffer(TDes8& aBuffer)
|
|
1260 |
{
|
|
1261 |
TInt len = aBuffer.Length();
|
|
1262 |
for(TInt i=0; i<len; i++)
|
|
1263 |
aBuffer[i] = DecryptByte(aBuffer[i]);
|
|
1264 |
}
|
|
1265 |
|
|
1266 |
|
|
1267 |
TNfeDriveInfo* DMediaDriverNFE::GetSwapDrive()
|
|
1268 |
{
|
|
1269 |
for (TInt i=0; i<iInfo.iDriveCount; i++)
|
|
1270 |
{
|
|
1271 |
TNfeDriveInfo& di = iInfo.iDrives[i];
|
|
1272 |
if (di.iEntry.iPartitionType == KPartitionTypePagedData)
|
|
1273 |
{
|
|
1274 |
return &di;
|
|
1275 |
}
|
|
1276 |
}
|
|
1277 |
return NULL; // swap drive not found
|
|
1278 |
}
|
|
1279 |
|
|
1280 |
/**
|
|
1281 |
Get the first/next drive to encrypt
|
|
1282 |
*/
|
|
1283 |
|
|
1284 |
TNfeDriveInfo* DMediaDriverNFE::NextDrive()
|
|
1285 |
{
|
|
1286 |
for (iDriveIndex = 0; iDriveIndex<iInfo.iDriveCount; iDriveIndex++)
|
|
1287 |
{
|
|
1288 |
TNfeDriveInfo& di = iInfo.iDrives[iDriveIndex];
|
|
1289 |
TNfeDiskStatus status = iInfo.iDrives[iDriveIndex].Status();
|
|
1290 |
if (status == ENfeEncrypting || status == ENfeDecrypting)
|
|
1291 |
{
|
|
1292 |
di.iEncryptStartPos = di.iEncryptEndPos = di.iEntry.iPartitionBaseAddr;
|
|
1293 |
|
|
1294 |
// write to boot sector to indicate we are encrypting/decrypting this drive
|
|
1295 |
WriteEncryptionStatusToBootSector(di);
|
|
1296 |
|
|
1297 |
return &di;
|
|
1298 |
}
|
|
1299 |
}
|
|
1300 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Finished encrypting / decrypting", iInstance));
|
|
1301 |
iBusy = EFalse;
|
|
1302 |
return NULL;
|
|
1303 |
}
|
|
1304 |
|
|
1305 |
|
|
1306 |
/**
|
|
1307 |
Finds the first unencrypted drive & kicks off the idle timer -
|
|
1308 |
when this expires the encryption of the drive will start
|
|
1309 |
*/
|
|
1310 |
void DMediaDriverNFE::StartEncrypting()
|
|
1311 |
{
|
|
1312 |
// start encrypting if not already doing so
|
|
1313 |
if (!iBusy)
|
|
1314 |
{
|
|
1315 |
iBusy = ETrue;
|
|
1316 |
TNfeDriveInfo* di = NextDrive();
|
|
1317 |
if (di)
|
|
1318 |
{
|
|
1319 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Start encrypting drive %d...", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
|
|
1320 |
iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
|
|
1321 |
}
|
|
1322 |
}
|
|
1323 |
}
|
|
1324 |
|
|
1325 |
/**
|
|
1326 |
Finds the first unencrypted drive & kicks off the idle timer -
|
|
1327 |
when this expires the encryption of the drive will start
|
|
1328 |
*/
|
|
1329 |
void DMediaDriverNFE::StartDecrypting()
|
|
1330 |
{
|
|
1331 |
// start encrypting if not already doing so
|
|
1332 |
if (!iBusy)
|
|
1333 |
{
|
|
1334 |
iBusy = ETrue;
|
|
1335 |
TNfeDriveInfo* di = NextDrive();
|
|
1336 |
if (di)
|
|
1337 |
{
|
|
1338 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Start decrypting drive %d...", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
|
|
1339 |
iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
|
|
1340 |
}
|
|
1341 |
}
|
|
1342 |
}
|
|
1343 |
|
|
1344 |
/**
|
|
1345 |
Idle timer callback
|
|
1346 |
Kicks off a DFC to ensure we are running in the correct thread
|
|
1347 |
*/
|
|
1348 |
void DMediaDriverNFE::IdleTimerCallBack(TAny* aMediaDriver)
|
|
1349 |
{
|
|
1350 |
((DMediaDriverNFE*)aMediaDriver)->iTimerDfc.Add();
|
|
1351 |
}
|
|
1352 |
|
|
1353 |
/**
|
|
1354 |
Idle timer DFC
|
|
1355 |
*/
|
|
1356 |
void DMediaDriverNFE::TimerDfcFunction(TAny* aMediaDriver)
|
|
1357 |
{
|
|
1358 |
((DMediaDriverNFE*) aMediaDriver)->HandleDiskContent();
|
|
1359 |
}
|
|
1360 |
|
|
1361 |
|
|
1362 |
TBool DMediaDriverNFE::ValidBootSector(TUint8* aBuffer)
|
|
1363 |
{
|
|
1364 |
if (aBuffer[0] == 0xEB || aBuffer[0] == 0xE9)
|
|
1365 |
return ETrue;
|
|
1366 |
else
|
|
1367 |
return EFalse;
|
|
1368 |
}
|
|
1369 |
|
|
1370 |
|
|
1371 |
TUint32 DMediaDriverNFE::VolumeId(TUint8* aBuffer)
|
|
1372 |
{
|
|
1373 |
TUint16 rootDirEntries;
|
|
1374 |
TUint32 uniqueID;
|
|
1375 |
memcpy(&rootDirEntries,&aBuffer[17], 2); // 17 TUint16 iRootDirEntries
|
|
1376 |
TBool fat32 = rootDirEntries == 0;
|
|
1377 |
TInt pos = fat32 ? 67 : 39; // get position of VolumeID
|
|
1378 |
memcpy(&uniqueID,&aBuffer[pos],4);
|
|
1379 |
return uniqueID;
|
|
1380 |
}
|
|
1381 |
|
|
1382 |
void DMediaDriverNFE::CheckBootSector(TNfeDriveInfo &aDi)
|
|
1383 |
{
|
|
1384 |
TNfeDiskStatus fatBootSectorStatus = ENfeDecrypted;
|
|
1385 |
|
|
1386 |
// Try to determine whether the FAT boot sector is encypted
|
|
1387 |
if (ValidBootSector(iBuffer))
|
|
1388 |
{
|
|
1389 |
fatBootSectorStatus = ENfeDecrypted;
|
|
1390 |
__KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is decrypted", iInstance));
|
|
1391 |
}
|
|
1392 |
else
|
|
1393 |
{
|
|
1394 |
TPtr8 des(iBuffer, KSectorSize, KSectorSize);
|
|
1395 |
DecryptBuffer(des);
|
|
1396 |
if (ValidBootSector(iBuffer))
|
|
1397 |
{
|
|
1398 |
__KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is encrypted", iInstance));
|
|
1399 |
fatBootSectorStatus = ENfeEncrypted;
|
|
1400 |
}
|
|
1401 |
else
|
|
1402 |
{
|
|
1403 |
__KTRACE_PRINT(Kern::Printf("NFE%d: FAT Boot sector is corrupted", iInstance));
|
|
1404 |
fatBootSectorStatus = ENfeCorrupted;
|
|
1405 |
}
|
|
1406 |
}
|
|
1407 |
|
|
1408 |
__KTRACE_PRINT(Kern::Printf("NFE%d: fatBootSectorStatus %d", iInstance, fatBootSectorStatus));
|
|
1409 |
|
|
1410 |
// Find out whether the volume has changed
|
|
1411 |
TUint32 uniqueID = VolumeId(iBuffer);
|
|
1412 |
TBool volumeChanged = uniqueID != aDi.iUniqueID;
|
|
1413 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Old Volume ID %08X", iInstance, aDi.iUniqueID));
|
|
1414 |
__KTRACE_PRINT(Kern::Printf("NFE%d: New Volume ID %08X", iInstance, uniqueID));
|
|
1415 |
__KTRACE_PRINT(Kern::Printf("NFE%d: volumeChanged %d", iInstance, volumeChanged));
|
|
1416 |
aDi.iUniqueID = uniqueID;
|
|
1417 |
|
|
1418 |
|
|
1419 |
|
|
1420 |
TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
|
|
1421 |
|
|
1422 |
__KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iSignature %08X", iInstance, bootSectorStatus->iSignature));
|
|
1423 |
__KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iStatus %d", iInstance, bootSectorStatus->iStatus));
|
|
1424 |
__KTRACE_PRINT(Kern::Printf("NFE%d: CheckBootSector, iEncryptEndPos %lx", iInstance, bootSectorStatus->iEncryptEndPos));
|
|
1425 |
|
|
1426 |
|
|
1427 |
/*
|
|
1428 |
If there IS NFE info in the boot sector, restore the encryption settings -
|
|
1429 |
unless the 'finalised' flag is clear which indicates that the media was removed or power was lost
|
|
1430 |
while encrypting the device...
|
|
1431 |
|
|
1432 |
If there is no NFE info in the boot sector and there has been a volume change, then we can decide
|
|
1433 |
whether the drive is encrypted/decrypted/corrupt by examining the boot sector
|
|
1434 |
*/
|
|
1435 |
if (volumeChanged &&
|
|
1436 |
fatBootSectorStatus != ENfeCorrupted &&
|
|
1437 |
bootSectorStatus->iSignature == TBootSectorStatus::ENfeBootSectorSignature &&
|
|
1438 |
!bootSectorStatus->iFinalised)
|
|
1439 |
{
|
|
1440 |
SetStatus(aDi, ENfeCorrupted);
|
|
1441 |
}
|
|
1442 |
else if (volumeChanged &&
|
|
1443 |
fatBootSectorStatus != ENfeCorrupted &&
|
|
1444 |
bootSectorStatus->iFinalised &&
|
|
1445 |
bootSectorStatus->iSignature == TBootSectorStatus::ENfeBootSectorSignature &&
|
|
1446 |
(bootSectorStatus->iStatus == ENfeDecrypting || bootSectorStatus->iStatus == ENfeEncrypting))
|
|
1447 |
{
|
|
1448 |
SetStatus(aDi, bootSectorStatus->iStatus);
|
|
1449 |
aDi.iEncryptEndPos = bootSectorStatus->iEncryptEndPos;
|
|
1450 |
|
|
1451 |
// write to boot sector to indicate we are no longer finalised
|
|
1452 |
WriteEncryptionStatusToBootSector(aDi, EFalse);
|
|
1453 |
|
|
1454 |
iBusy = ETrue;
|
|
1455 |
}
|
|
1456 |
else if (volumeChanged || aDi.Status() == ENfeUnmounted)
|
|
1457 |
{
|
|
1458 |
SetStatus(aDi, fatBootSectorStatus);
|
|
1459 |
if (aDi.Status() == ENfeEncrypted)
|
|
1460 |
{
|
|
1461 |
aDi.iEncryptStartPos = aDi.iEntry.iPartitionBaseAddr;
|
|
1462 |
aDi.iEncryptEndPos = aDi.iEntry.iPartitionBaseAddr + aDi.iEntry.iPartitionLen;
|
|
1463 |
}
|
|
1464 |
}
|
|
1465 |
}
|
|
1466 |
|
|
1467 |
|
|
1468 |
TInt DMediaDriverNFE::WriteEncryptionStatusToBootSector(TNfeDriveInfo &aDi, TBool aFinalised)
|
|
1469 |
{
|
|
1470 |
if (!aDi.IsUDADrive())
|
|
1471 |
return KErrNone;
|
|
1472 |
|
134
|
1473 |
aDi.iDriveFinalised = aFinalised;
|
123
|
1474 |
|
|
1475 |
TNfeDiskStatus status = aDi.Status();
|
|
1476 |
|
|
1477 |
TInt64 currentPos = aDi.iEntry.iPartitionBaseAddr;
|
|
1478 |
TInt64 currentLen = KSectorSize;
|
|
1479 |
TNfeDriveInfo* di = &aDi;
|
|
1480 |
TBool encodeBuffer = EFalse;
|
|
1481 |
|
|
1482 |
if (status == ENfeEncrypting || status == ENfeEncrypted || status == ENfeDecrypting)
|
|
1483 |
encodeBuffer = AdjustRequest(di, currentPos, currentLen);
|
|
1484 |
|
|
1485 |
|
|
1486 |
TInt r = Read(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
|
|
1487 |
if (r != KErrNone)
|
|
1488 |
return r;
|
|
1489 |
TPtr8 des(iBuffer, I64LOW(currentLen), I64LOW(currentLen));
|
|
1490 |
|
|
1491 |
if (encodeBuffer)
|
|
1492 |
DecryptBuffer(des);
|
|
1493 |
|
|
1494 |
|
|
1495 |
TBootSectorStatus* bootSectorStatus = (TBootSectorStatus*) iBuffer;
|
|
1496 |
|
|
1497 |
if (status == ENfeEncrypting || status == ENfeDecrypting)
|
|
1498 |
{
|
|
1499 |
bootSectorStatus->iSignature = TBootSectorStatus::ENfeBootSectorSignature;
|
|
1500 |
bootSectorStatus->iEncryptEndPos = di->iEncryptEndPos;
|
|
1501 |
bootSectorStatus->iStatus = status;
|
|
1502 |
bootSectorStatus->iFinalised = aFinalised;
|
|
1503 |
}
|
|
1504 |
else
|
|
1505 |
{
|
|
1506 |
bootSectorStatus->iSignature = 0;
|
|
1507 |
bootSectorStatus->iEncryptEndPos = 0;
|
|
1508 |
bootSectorStatus->iStatus = ENfeUnmounted;
|
|
1509 |
bootSectorStatus->iFinalised = EFalse;
|
|
1510 |
}
|
|
1511 |
|
|
1512 |
if (encodeBuffer)
|
|
1513 |
EncryptBuffer(des);
|
|
1514 |
|
|
1515 |
|
|
1516 |
r = Write(di->iLocalDriveNum, di->iEntry.iPartitionBaseAddr, (TLinAddr) iBuffer, KSectorSize);
|
|
1517 |
return r;
|
|
1518 |
}
|
|
1519 |
|
|
1520 |
|
|
1521 |
/**
|
|
1522 |
HandleDiskContent -
|
|
1523 |
|
|
1524 |
Called from Idle timer DFC
|
|
1525 |
|
|
1526 |
Starts encrypting the current drive (iDrives[iDriveIndex]) from the current encryption position (iEncryptEndPos)
|
|
1527 |
*/
|
|
1528 |
TInt DMediaDriverNFE::HandleDiskContent()
|
|
1529 |
{
|
|
1530 |
TNfeDriveInfo* di = &iInfo.iDrives[iDriveIndex];
|
|
1531 |
|
|
1532 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Starting to encrypt Drive %d at pos %lx", iInstance, di->iLocalDriveNum, di->iEncryptEndPos));
|
|
1533 |
|
|
1534 |
if (di->iDriveFinalised)
|
|
1535 |
{
|
|
1536 |
__KTRACE_PRINT(Kern::Printf("HandleDiskContent aborting as drive has been finalised", iInstance));
|
|
1537 |
return KErrNone;
|
|
1538 |
}
|
|
1539 |
|
|
1540 |
// TInt KBackgroundPriority = 7; //*test*
|
|
1541 |
// Kern::SetThreadPriority(KBackgroundPriority); //*test*
|
|
1542 |
|
|
1543 |
TInt r = KErrNone;
|
|
1544 |
for (;;)
|
|
1545 |
{
|
|
1546 |
// If we've finished encryting this drive, change the state and move on to the next drive
|
|
1547 |
if (r != KErrNone || di->iEncryptEndPos >= di->iEntry.iPartitionBaseAddr + di->iEntry.iPartitionLen)
|
|
1548 |
{
|
|
1549 |
if (di->Status() == ENfeEncrypting)
|
|
1550 |
{
|
|
1551 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Finished encrypting Drive %d r %d", iInstance, di->iLocalDriveNum, r));
|
|
1552 |
SetStatus(*di, r == KErrNone ? ENfeEncrypted : ENfeCorrupted);
|
|
1553 |
}
|
|
1554 |
if (di->Status() == ENfeDecrypting)
|
|
1555 |
{
|
|
1556 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Finished decrypting Drive %d r %d", iInstance, di->iLocalDriveNum, r));
|
|
1557 |
SetStatus(*di, r == KErrNone ? ENfeDecrypted : ENfeCorrupted);
|
|
1558 |
}
|
|
1559 |
|
|
1560 |
// write to boot sector to indicate we have finished encrypting/decrypting this drive
|
|
1561 |
r = WriteEncryptionStatusToBootSector(*di);
|
|
1562 |
|
|
1563 |
di = NextDrive();
|
|
1564 |
if (di == NULL)
|
|
1565 |
{
|
|
1566 |
r = KErrCompletion;
|
|
1567 |
break;
|
|
1568 |
}
|
|
1569 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Starting to encrypt Drive %d", iInstance, iInfo.iDrives[iDriveIndex].iLocalDriveNum));
|
|
1570 |
}
|
|
1571 |
|
|
1572 |
// If this media or any of the attached media are busy, stop encrypting & wait for the next idle timeout
|
|
1573 |
if (MediaBusy(di->iLocalDriveNum))
|
|
1574 |
{
|
|
1575 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Media is busy !!!", iInstance));
|
|
1576 |
r = KErrNone; // goto sleep & wait for another timer event
|
|
1577 |
break;
|
|
1578 |
}
|
|
1579 |
|
|
1580 |
TInt64& pos = di->iEncryptEndPos;
|
|
1581 |
TInt64 partitionEnd = di->iEntry.iPartitionBaseAddr + di->iEntry.iPartitionLen;
|
|
1582 |
TInt len = (TInt) Min (partitionEnd - pos, KBufSize);
|
|
1583 |
|
|
1584 |
#if defined(TRACE_ENABLED)
|
|
1585 |
// print position every 1/16 of the partition size
|
|
1586 |
TInt64 printPos = Max((di->iEntry.iPartitionLen >> 4) & ~(KBufSize-1), KBufSize);
|
|
1587 |
if (((di->iEncryptEndPos - di->iEncryptStartPos)% printPos) == 0)
|
|
1588 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Encrypting drive %d from %lx to %lx end %lx", iInstance, di->iLocalDriveNum, pos, pos + len, partitionEnd));
|
|
1589 |
#endif
|
|
1590 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: Encrypting drive %d from %lx to %lx end %lx", iInstance, di->iLocalDriveNum, pos, pos + len, partitionEnd));
|
|
1591 |
|
|
1592 |
|
|
1593 |
// Read a buffer, encrypt it, and then write it back
|
|
1594 |
// retry in case of media change
|
|
1595 |
const TInt KRetries = 5;
|
|
1596 |
r = KErrNotReady;
|
|
1597 |
for (TInt i=0; r == KErrNotReady && i < KRetries; i++)
|
|
1598 |
{
|
|
1599 |
r = Read(di->iLocalDriveNum, pos, (TLinAddr) iBuffer, len);
|
|
1600 |
if (r != KErrNone)
|
|
1601 |
continue;
|
|
1602 |
|
|
1603 |
TPtr8 des(iBuffer,len,len);
|
|
1604 |
if (di->Status() == ENfeEncrypting)
|
|
1605 |
EncryptBuffer(des);
|
|
1606 |
else
|
|
1607 |
DecryptBuffer(des);
|
|
1608 |
|
|
1609 |
r = Write(di->iLocalDriveNum, pos, (TLinAddr) iBuffer, len);
|
|
1610 |
}
|
|
1611 |
|
|
1612 |
if (r == KErrNone)
|
|
1613 |
pos+= len;
|
|
1614 |
|
|
1615 |
if (di->iProgressToUiProperty) // no iProgressToUiProperty for swap drive
|
|
1616 |
{
|
|
1617 |
TInt progress = (TInt) (KNfeDiskOpReady * (pos - di->iEntry.iPartitionBaseAddr) / di->iEntry.iPartitionLen);
|
|
1618 |
// __KTRACE_PRINT(Kern::Printf("NFE%d: Progess %d ", progress));
|
|
1619 |
((RPropertyRef*) (di->iProgressToUiProperty))->Set( progress ); // Return value ignored
|
|
1620 |
}
|
|
1621 |
}
|
|
1622 |
|
|
1623 |
__KTRACE_PRINT(Kern::Printf("NFE%d: HandleDiskContent returned %d", iInstance, r));
|
|
1624 |
|
|
1625 |
// If not completed, start the idle timer & try again later
|
|
1626 |
if (r != KErrCompletion)
|
|
1627 |
iIdleTimer.OneShot(NKern::TimerTicks(KNotBusyInterval));
|
|
1628 |
|
|
1629 |
// Kern::SetThreadPriority(KNfeThreadPriority); //*test*
|
|
1630 |
|
|
1631 |
return r;
|
|
1632 |
}
|
|
1633 |
|
|
1634 |
|
|
1635 |
|
|
1636 |
DECLARE_EXTENSION_PDD()
|
|
1637 |
{
|
|
1638 |
__KTRACE_PRINT(Kern::Printf("DECLARE_EXTENSION_PDD()"));
|
|
1639 |
return new DPhysicalDeviceMediaNFE;
|
|
1640 |
}
|
|
1641 |
|
|
1642 |
DECLARE_STANDARD_EXTENSION()
|
|
1643 |
{
|
|
1644 |
__KTRACE_PRINT(Kern::Printf("DECLARE_STANDARD_EXTENSION()"));
|
|
1645 |
|
|
1646 |
|
|
1647 |
// Create the media driver factory object and register this with the kernel
|
|
1648 |
__KTRACE_PRINT(Kern::Printf("Creating NFE PDD"));
|
|
1649 |
DPhysicalDeviceMediaNFE* device = new DPhysicalDeviceMediaNFE;
|
|
1650 |
if (device == NULL)
|
|
1651 |
return KErrNoMemory;
|
|
1652 |
TInt r = Kern::InstallPhysicalDevice(device);
|
|
1653 |
__KTRACE_PRINT(Kern::Printf("Installing NFE PDD in extension init - name %s r:%d", NFE_DRIVENAME, r));
|
|
1654 |
if (r != KErrNone)
|
|
1655 |
return r;
|
|
1656 |
|
|
1657 |
TInt swapInstance = KErrNotFound;
|
|
1658 |
#if defined (__DEMAND_PAGING__)
|
|
1659 |
swapInstance = SwapInstance();
|
|
1660 |
#endif
|
|
1661 |
|
|
1662 |
DPrimaryMediaExt* primaryMedia[NFE_INSTANCE_COUNT];
|
|
1663 |
TInt instance;
|
|
1664 |
|
|
1665 |
for (instance=0; instance<NFE_INSTANCE_COUNT; instance++)
|
|
1666 |
{
|
|
1667 |
// Register this media device & define which drives we want to attach to.
|
|
1668 |
// These drives must already be registered with the local media subsystem
|
|
1669 |
// i.e. this media's kernel extension must be defined AFTER any attached
|
|
1670 |
// media's kernel extension in the appropriate .IBY file
|
|
1671 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Creating NFE primary media", instance));
|
|
1672 |
DPrimaryMediaExt* pM = new DPrimaryMediaExt(instance);
|
|
1673 |
if (pM == NULL)
|
|
1674 |
return KErrNoMemory;
|
|
1675 |
primaryMedia[instance] = pM;
|
|
1676 |
|
|
1677 |
_LIT(KMediaThreadName,"NfeThread?");
|
|
1678 |
HBuf* pMediaThreadName = HBuf::New(KMediaThreadName);
|
|
1679 |
(*pMediaThreadName)[9] = (TUint8) ('0' + (TUint8) instance);
|
|
1680 |
|
|
1681 |
TInt r = Kern::DfcQInit(&pM->iNfeDfcQ,KNfeThreadPriority,pMediaThreadName);
|
|
1682 |
if (r != KErrNone)
|
|
1683 |
return r;
|
|
1684 |
|
|
1685 |
#ifdef CPU_AFFINITY_ANY
|
|
1686 |
NKern::ThreadSetCpuAffinity((NThread*)(pM->iNfeDfcQ.iThread), KCpuAffinityAny);
|
|
1687 |
#endif
|
|
1688 |
|
|
1689 |
|
|
1690 |
pM->iDfcQ = &pM->iNfeDfcQ;
|
|
1691 |
pM->iMsgQ.Receive();
|
|
1692 |
|
|
1693 |
|
|
1694 |
const TInt* driveList = DriveList(instance);
|
|
1695 |
TInt driveCount = DriveCount(instance);
|
|
1696 |
|
|
1697 |
TBuf<4> driveName(_L("NFE?"));
|
|
1698 |
driveName[3] = (TUint8) ('0' + (TUint8) instance);
|
|
1699 |
|
|
1700 |
|
|
1701 |
r = LocDrv::RegisterMediaDevice(
|
|
1702 |
MEDIA_DEVICE_NFE,
|
|
1703 |
driveCount, driveList,
|
|
1704 |
pM, NFE_NUMMEDIA, driveName);
|
|
1705 |
if (r != KErrNone)
|
|
1706 |
return r;
|
|
1707 |
|
|
1708 |
|
|
1709 |
#if defined (__DEMAND_PAGING__)
|
|
1710 |
if (PagingType(instance))
|
|
1711 |
{
|
|
1712 |
// Define which of the drives we have already attached to have code or data paging enabled
|
|
1713 |
const TInt* pageDriveList = PageDriveList(instance);
|
|
1714 |
TInt pageDriveCount = PageDriveCount(instance);
|
|
1715 |
|
|
1716 |
r = LocDrv::RegisterPagingDevice(pM,pageDriveList,pageDriveCount,PagingType(instance),SECTOR_SHIFT,NFE_NUM_PAGES);
|
|
1717 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Installing NFE PagingDevice in extension init - r:%d", pM->iInstance, r));
|
|
1718 |
// Ignore error if demand paging not supported by kernel
|
|
1719 |
if (r == KErrNotSupported)
|
|
1720 |
r = KErrNone;
|
|
1721 |
if (r != KErrNone)
|
|
1722 |
return r;
|
|
1723 |
}
|
|
1724 |
|
|
1725 |
|
|
1726 |
#endif // __NAND_DEMAND_PAGING__
|
|
1727 |
|
|
1728 |
/*
|
|
1729 |
If there is a swap partition we need to make sure all instances have their PartitionInfo() called
|
|
1730 |
so that we can flag the swap partition as 'encrypted' if there are any encrypted drives at all
|
|
1731 |
*/
|
|
1732 |
if (swapInstance != KErrNotFound)
|
|
1733 |
{
|
|
1734 |
TBuf8<sizeof(TLocalDriveCapsV6)> capsBuf;
|
|
1735 |
capsBuf.SetMax();
|
|
1736 |
capsBuf.FillZ();
|
|
1737 |
DLocalDrive::Caps(driveList[0], capsBuf);
|
|
1738 |
}
|
|
1739 |
}
|
|
1740 |
|
|
1741 |
|
|
1742 |
// If we encounter an encrypted drive belonging to ANY NFE instance, then assume the swap partition is
|
|
1743 |
// encrypted too. We need to do this because the swap partition has no equivalent of the boot sector
|
|
1744 |
if (swapInstance != KErrNotFound)
|
|
1745 |
{
|
|
1746 |
__KTRACE_PRINT(Kern::Printf("NFE: Searching for encrypted drives to determine whether swap partition should be encrypted..."));
|
|
1747 |
TBool encryptedDriveFound = EFalse;
|
|
1748 |
TNfeDriveInfo* swapDriveInfo = NULL;
|
|
1749 |
for (instance=0; instance<NFE_INSTANCE_COUNT; instance++)
|
|
1750 |
{
|
|
1751 |
DPrimaryMediaExt* pM = primaryMedia[instance];
|
|
1752 |
DMediaDriverNFE* mediaDriver = (DMediaDriverNFE*) pM->iDriver;
|
|
1753 |
__ASSERT_ALWAYS(mediaDriver, NFE_FAULT());
|
|
1754 |
|
|
1755 |
if (swapDriveInfo == NULL)
|
|
1756 |
swapDriveInfo = mediaDriver->GetSwapDrive();
|
|
1757 |
|
|
1758 |
for (TInt i=0; i<mediaDriver->iInfo.iDriveCount; i++)
|
|
1759 |
{
|
|
1760 |
TNfeDriveInfo& di = mediaDriver->iInfo.iDrives[i];
|
|
1761 |
__KTRACE_PRINT(Kern::Printf("NFE%d: Testing drive %d DriveLetter %c status %s",
|
|
1762 |
instance, di.iLocalDriveNum, (TInt) DriveLetterToAscii(di.iDriveLetter), DriveStatus(di.Status()) ));
|
|
1763 |
if (di.Status() == ENfeEncrypted || di.Status() == ENfeEncrypting)
|
|
1764 |
encryptedDriveFound = ETrue;
|
|
1765 |
}
|
|
1766 |
}
|
|
1767 |
if (swapDriveInfo)
|
|
1768 |
{
|
|
1769 |
swapDriveInfo->SetStatus(encryptedDriveFound ? ENfeEncrypted : ENfeDecrypted);
|
|
1770 |
swapDriveInfo->iEncryptEndPos = swapDriveInfo->iEntry.iPartitionBaseAddr + swapDriveInfo->iEntry.iPartitionLen;
|
|
1771 |
|
|
1772 |
__KTRACE_PRINT(Kern::Printf("NFE: Setting swap partition state to %s...", DriveStatus(swapDriveInfo->Status())));
|
|
1773 |
}
|
|
1774 |
}
|
|
1775 |
|
|
1776 |
|
|
1777 |
return r;
|
|
1778 |
}
|
|
1779 |
|
|
1780 |
|