|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 // |
|
18 // hostusbmsproxy.cpp |
|
19 // |
|
20 // This file system extension provides a way to access a drive on the MS system in "raw format". |
|
21 // It can be used to test large files / drives |
|
22 // |
|
23 |
|
24 /** @file |
|
25 @internalTechnology |
|
26 */ |
|
27 |
|
28 #include <f32fsys.h> |
|
29 |
|
30 #include "hostusbmsproxy.h" |
|
31 #include "debug.h" |
|
32 |
|
33 |
|
34 CUsbHostMsProxyDrive::CUsbHostMsProxyDrive(CMountCB* aMount, CExtProxyDriveFactory* aDevice) |
|
35 : CExtProxyDrive(aMount,aDevice) |
|
36 { |
|
37 __MSFNSLOG |
|
38 } |
|
39 |
|
40 CUsbHostMsProxyDrive::~CUsbHostMsProxyDrive() |
|
41 { |
|
42 __MSFNSLOG |
|
43 iUsbHostMsLun.UnInitialise(); |
|
44 } |
|
45 |
|
46 TInt CUsbHostMsProxyDrive::InitialiseOffset(TCapsInfo& aCapsInfo) |
|
47 { |
|
48 __MSFNSLOG |
|
49 const TInt KPartitionInfoSize = TMsDataMemMap::KSectorSize; |
|
50 TBuf8<KPartitionInfoSize> partitionInfo; |
|
51 TInt r; |
|
52 |
|
53 r = iUsbHostMsLun.Read(0 , KPartitionInfoSize, (TDes8 &) partitionInfo); |
|
54 if (r != KErrNone) |
|
55 { |
|
56 __PXYPRINT1(_L("!! Reading medium failed with %d !!"), r); |
|
57 return r; |
|
58 } |
|
59 TUint8 *iIntBuf = (TUint8 *) partitionInfo.Ptr(); |
|
60 |
|
61 // Read of the first sector successful so check for a Master Boot Record |
|
62 if (*(TUint16*)(&iIntBuf[KMBRSignatureOffset])!= KMBRSignature) |
|
63 { |
|
64 __PXYPRINT(_L("MBR not present")); |
|
65 iMsDataMemMap.Reset(); |
|
66 } |
|
67 else |
|
68 { |
|
69 // Move the partition entries to a 4 byte boundary |
|
70 memcpy(&iIntBuf[0],&iIntBuf[KMBRFirstPartitionOffset],(sizeof(TMBRPartitionEntry)<<2)); |
|
71 // Search for a x86 default boot partition - let this be the first |
|
72 TMBRPartitionEntry* pe = (TMBRPartitionEntry*)(&iIntBuf[0]); |
|
73 |
|
74 TInt firstValidPartitionCount = -1; |
|
75 TInt defaultPartitionNumber = -1; |
|
76 TInt partitionCount = 0; |
|
77 for (TInt i = 0; i < KMBRMaxPrimaryPartitions; i++, pe++) |
|
78 { |
|
79 if (pe->IsValidDosPartition() || pe->IsValidFAT32Partition()) |
|
80 { |
|
81 __PXYPRINT(_L("Found a Valid Partition")); |
|
82 partitionCount++; |
|
83 |
|
84 if (firstValidPartitionCount < 0) |
|
85 firstValidPartitionCount = i; |
|
86 |
|
87 if (pe->iX86BootIndicator == KBootIndicatorBootable) |
|
88 { |
|
89 defaultPartitionNumber = i; |
|
90 break; |
|
91 } |
|
92 } |
|
93 else |
|
94 { |
|
95 __PXYPRINT(_L("!! Invalid Partition !!")); |
|
96 } |
|
97 } |
|
98 |
|
99 // Check the validity of the partition address boundaries |
|
100 if (partitionCount > 0) |
|
101 { |
|
102 __PXYPRINT1(_L("Using Partition %d"), partitionCount); |
|
103 pe = (TMBRPartitionEntry*)(&iIntBuf[0]); |
|
104 TInt partitionIndex = firstValidPartitionCount; |
|
105 if (defaultPartitionNumber > 0) |
|
106 { |
|
107 partitionIndex = defaultPartitionNumber; |
|
108 } |
|
109 |
|
110 TMBRPartitionEntry& partitionEntry = pe[partitionIndex]; |
|
111 |
|
112 iMsDataMemMap.InitDataArea(partitionEntry.iFirstSector, |
|
113 partitionEntry.iNumSectors); |
|
114 __PXYPRINT2(_L("paritioncount = %d defaultpartition = %d"), |
|
115 partitionCount, partitionIndex); |
|
116 __PXYPRINT2(_L("iFirstSector = x%x iNumSectors = x%x"), |
|
117 partitionEntry.iFirstSector, |
|
118 partitionEntry.iNumSectors); |
|
119 } |
|
120 else |
|
121 { |
|
122 __PXYPRINT(_L("No partition found")); |
|
123 iMsDataMemMap.InitDataArea(0, aCapsInfo.iNumberOfBlocks); |
|
124 __PXYPRINT2(_L("iFirstSector = x%x iNumSectors = x%x"), |
|
125 0, aCapsInfo.iNumberOfBlocks); |
|
126 } |
|
127 } |
|
128 return KErrNone; |
|
129 } |
|
130 |
|
131 /** |
|
132 Initialise the proxy drive. |
|
133 @return system wide error code. |
|
134 */ |
|
135 TInt CUsbHostMsProxyDrive::Initialise() |
|
136 { |
|
137 __MSFNSLOG |
|
138 __HOSTPRINT(_L(">>> CUsbHostMsProxyDrive::Initialise()")); |
|
139 |
|
140 if(Mount()) |
|
141 { |
|
142 // as we can't currently handle remounting devices that have |
|
143 // been removed by unplugging the USB cable, disable critical notifiers |
|
144 // as there's no point in asking the user to re-insert the disk. |
|
145 Mount()->SetNotifyOff(); |
|
146 } |
|
147 |
|
148 // Check for media presence |
|
149 TCapsInfo capsInfo; |
|
150 TInt err = iUsbHostMsLun.Caps(capsInfo); |
|
151 |
|
152 if (err == KErrNone) |
|
153 { |
|
154 err = InitialiseOffset(capsInfo); |
|
155 } |
|
156 |
|
157 __HOSTPRINT1(_L("<<< CUsbHostMsProxyDrive::Initialise() err = %d"), err); |
|
158 return err; |
|
159 } |
|
160 |
|
161 TInt CUsbHostMsProxyDrive::SetInfo(const RMessage2 &msg, TAny* aMessageParam2, TAny* aMessageParam3) |
|
162 { |
|
163 __MSFNSLOG |
|
164 __HOSTPRINT(_L(">>> CUsbHostMsProxyDrive::SetInfo()")); |
|
165 TMassStorageUnitInfo iUnitInfo; |
|
166 TPckg<TMassStorageUnitInfo> infoPckg(iUnitInfo); |
|
167 TRAPD(err, msg.ReadL(2, infoPckg)); |
|
168 |
|
169 if(err != KErrNone) |
|
170 { |
|
171 __PXYPRINT1(_L("Cant read from the RMessage %d"), err); |
|
172 __HOSTPRINT1(_L("<<< CUsbHostMsProxyDrive::SetInfo() err = %d"), err); |
|
173 return err; |
|
174 } |
|
175 |
|
176 err = iUsbHostMsLun.Initialise(msg, 3, iUnitInfo.iLunID); |
|
177 if(err != KErrNone) |
|
178 { |
|
179 __PXYPRINT1(_L("Initialising logical unit failed %d"), err); |
|
180 __HOSTPRINT1(_L("<<< CUsbHostMsProxyDrive::SetInfo() err = %d"), err); |
|
181 return err; |
|
182 } |
|
183 |
|
184 __HOSTPRINT1(_L("<<< CUsbHostMsProxyDrive::SetInfo() err = %d"), err); |
|
185 return err; |
|
186 } |
|
187 |
|
188 TInt CUsbHostMsProxyDrive::Dismounted() |
|
189 { |
|
190 __MSFNSLOG |
|
191 return KErrNone; |
|
192 } |
|
193 |
|
194 TInt CUsbHostMsProxyDrive::Enlarge(TInt /*aLength*/) |
|
195 { |
|
196 __MSFNSLOG |
|
197 return KErrNotSupported; |
|
198 } |
|
199 |
|
200 |
|
201 TInt CUsbHostMsProxyDrive::ReduceSize(TInt /*aPos*/, TInt /*aLength*/) |
|
202 { |
|
203 __MSFNSLOG |
|
204 return KErrNotSupported; |
|
205 } |
|
206 |
|
207 #define GetIndex(msg, aAddress, aIndex) \ |
|
208 aIndex = msg.Ptr0() == aAddress ? 0 : \ |
|
209 msg.Ptr1() == aAddress ? 1 : \ |
|
210 msg.Ptr1() == aAddress ? 2 : \ |
|
211 msg.Ptr1() == aAddress ? 3 : -1; |
|
212 |
|
213 /** |
|
214 Read from the proxy drive. |
|
215 |
|
216 @param aPos The address from where the read begins. |
|
217 @param aLength The length of the read. |
|
218 @param aTrg A descriptor of the memory buffer from which to read. |
|
219 @param aThreadHandle The handle-number representing the drive thread. |
|
220 @param aOffset Offset into aTrg to read the data from. |
|
221 |
|
222 @return system wide error code. |
|
223 */ |
|
224 TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, |
|
225 const TAny* aTrg, TInt aThreadHandle, TInt aOffset) |
|
226 { |
|
227 __MSFNSLOG |
|
228 __HOSTPRINT4(_L("\n>>> HOST Read Pos=0x%lx LBA=0x%lx 0x%x 0x%x"), |
|
229 aPos, aPos/KBlockSize, aLength, aOffset); |
|
230 |
|
231 TBool localMessage = (aThreadHandle == KLocalMessageHandle); |
|
232 |
|
233 // |
|
234 // Set file position to where we want to read... |
|
235 // |
|
236 if(!localMessage) |
|
237 { |
|
238 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
239 localMessage = (msg.Handle() == KLocalMessageHandle); |
|
240 } |
|
241 |
|
242 TInt index = 0; |
|
243 if (!localMessage) |
|
244 { |
|
245 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
246 GetIndex(msg, aTrg, index); |
|
247 |
|
248 if (index < 0) |
|
249 { |
|
250 __HOSTPRINT1(_L("<<< HOST Read ret=%d"), KErrArgument); |
|
251 return KErrArgument; |
|
252 } |
|
253 } |
|
254 |
|
255 /* Calculate the end position */ |
|
256 TInt64 end = aPos + static_cast<TInt64>(aLength); |
|
257 |
|
258 /* check whether there is enough source data to write to the destination descriptor */ |
|
259 TInt64 truncate; |
|
260 if(localMessage) |
|
261 { |
|
262 truncate = aLength - (((TPtr8* )aTrg)->MaxLength() - aOffset); |
|
263 __PXYPRINT1(_L("Descriptor length: %08x"), ((TPtr8* )aTrg)->MaxLength()); |
|
264 } |
|
265 else |
|
266 { |
|
267 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
268 truncate = aLength - (msg.GetDesMaxLength(index) - aOffset); |
|
269 __PXYPRINT1(_L("Descriptor length: %08x"), msg.GetDesMaxLength(index)); |
|
270 } |
|
271 |
|
272 __PXYPRINT1(_L("Offset: %08x"), aOffset); |
|
273 __PXYPRINT1(_L("Truncate: 0x%lx"), truncate); |
|
274 |
|
275 if (truncate > 0) |
|
276 { |
|
277 end -= truncate; |
|
278 } |
|
279 |
|
280 iBuf.SetMax(); |
|
281 TInt r; |
|
282 TInt64 mediaPos; |
|
283 while (aPos < end) |
|
284 { |
|
285 TInt len = end - aPos; |
|
286 mediaPos = aPos; |
|
287 r = iMsDataMemMap.CheckBlockInRange(mediaPos, len); |
|
288 if (r != KErrNone) |
|
289 { |
|
290 __HOSTPRINT1(_L("<<< HOST Read ret=%d"), r); |
|
291 return r; |
|
292 } |
|
293 |
|
294 if (localMessage) |
|
295 { |
|
296 TPtr8* pTrgPtr = (TPtr8*)aTrg; |
|
297 TPtr8 trgDes((TUint8*)(pTrgPtr->MidTPtr(aOffset).Ptr()), pTrgPtr->MaxLength() - aOffset); |
|
298 r = iUsbHostMsLun.Read(mediaPos, len, trgDes); |
|
299 if (r != KErrNone) |
|
300 return r; |
|
301 pTrgPtr->SetLength(aOffset + trgDes.Length()); |
|
302 } |
|
303 else |
|
304 { |
|
305 if (len > iBuf.MaxLength()) |
|
306 len = iBuf.MaxLength(); |
|
307 |
|
308 r = iUsbHostMsLun.Read(mediaPos, len, iBuf); |
|
309 if (r != KErrNone) |
|
310 { |
|
311 __HOSTPRINT1(_L("<<< HOST Read ret=%d"), r); |
|
312 return r; |
|
313 } |
|
314 |
|
315 iBuf.SetLength(len); |
|
316 |
|
317 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
318 r = msg.Write(index, iBuf, aOffset); |
|
319 if (r != KErrNone) |
|
320 { |
|
321 __HOSTPRINT1(_L("<<< HOST Read ret=%d"), r); |
|
322 return r; |
|
323 } |
|
324 } |
|
325 |
|
326 aPos += len; |
|
327 aOffset += len; |
|
328 } |
|
329 |
|
330 __HOSTPRINT1(_L("<<< HOST Read ret=%d"), KErrNone); |
|
331 return KErrNone; |
|
332 } |
|
333 |
|
334 |
|
335 /** |
|
336 Read from the proxy drive, and pass flags to driver. |
|
337 |
|
338 @param aPos The address from where the read begins. |
|
339 @param aLength The length of the read. |
|
340 @param aTrg A descriptor of the memory buffer from which to read. |
|
341 @param aThreadHandle The handle-number representing the drive thread. |
|
342 @param aOffset Offset into aTrg to read the data from. |
|
343 @param aFlags Flags to be passed into the driver. |
|
344 |
|
345 @return system wide error code. |
|
346 */ |
|
347 TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, |
|
348 const TAny* aTrg, TInt aThreadHandle, TInt aOffset, TInt /* aFlags */) |
|
349 { |
|
350 __MSFNSLOG |
|
351 return Read(aPos, aLength, aTrg, aThreadHandle, aOffset); |
|
352 } |
|
353 |
|
354 /** |
|
355 Read from the proxy drive. |
|
356 |
|
357 @param aPos The address from where the read begins. |
|
358 @param aLength The length of the read. |
|
359 @param aTrg A descriptor of the memory buffer from which to read. |
|
360 |
|
361 @return system wide error code. |
|
362 */ |
|
363 TInt CUsbHostMsProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg) |
|
364 { |
|
365 __MSFNSLOG |
|
366 __HOSTPRINT3(_L("\n>>> HOST Read Pos=0x%lx LBA=0x%lx 0x%x"), |
|
367 aPos, aPos/KBlockSize, aLength); |
|
368 return iUsbHostMsLun.Read(iMsDataMemMap.GetDataPos(aPos), aLength, aTrg); |
|
369 } |
|
370 |
|
371 /** |
|
372 Write to the proxy drive. |
|
373 |
|
374 @param aPos The address from where the write begins. |
|
375 @param aLength The length of the write. |
|
376 @param aSrc A descriptor of the memory buffer from which to write. |
|
377 @param aThreadHandle The handle-number representing the drive thread. |
|
378 @param aOffset Offset into aSrc to write the data to. |
|
379 |
|
380 @return system wide error code. |
|
381 */ |
|
382 TInt CUsbHostMsProxyDrive::Write(TInt64 aPos, TInt aLength, |
|
383 const TAny* aSrc, TInt aThreadHandle, TInt aOffset) |
|
384 { |
|
385 // |
|
386 // Set file position to where we want to write... |
|
387 // |
|
388 __MSFNSLOG |
|
389 __HOSTPRINT4(_L("\n>>> HOST Write Pos=0x%lx LBA=0%lx 0x%x 0x%x"), |
|
390 aPos, aPos/KBlockSize, aLength, aOffset); |
|
391 |
|
392 TBool localMessage = (aThreadHandle == KLocalMessageHandle); |
|
393 |
|
394 if(!localMessage) |
|
395 { |
|
396 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
397 localMessage = (msg.Handle() == KLocalMessageHandle); |
|
398 } |
|
399 |
|
400 TInt index = 0; |
|
401 if(!localMessage) |
|
402 { |
|
403 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
404 GetIndex(msg, aSrc, index); |
|
405 |
|
406 if (index < 0) |
|
407 return KErrArgument; |
|
408 } |
|
409 |
|
410 /* Calculate the end position */ |
|
411 TInt64 end = aPos + static_cast<TInt64>(aLength); |
|
412 /* check whether there is enough source data to read */ |
|
413 TInt64 truncate; |
|
414 if (localMessage) |
|
415 { |
|
416 truncate = aLength - (((TPtr8* )aSrc)->Length() - aOffset); |
|
417 __PXYPRINT1(_L("Descriptor length: %08x"), ((TPtr8* )aSrc)->Length()); |
|
418 } |
|
419 else |
|
420 { |
|
421 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
422 truncate = aLength - (msg.GetDesLength(index) - aOffset); |
|
423 __PXYPRINT1(_L("Descriptor length: %08x"), msg.GetDesLength(index)); |
|
424 } |
|
425 |
|
426 __PXYPRINT1(_L("Offset: %08x"), aOffset); |
|
427 __PXYPRINT1(_L("Truncate: 0x%lx"), truncate); |
|
428 |
|
429 /* if truncate is > 0 we are short of source data as claimed by the aLength. Hence adjust the 'end' */ |
|
430 if (truncate > 0) |
|
431 { |
|
432 end -= truncate; |
|
433 } |
|
434 |
|
435 iBuf.SetMax(); |
|
436 |
|
437 TInt r; |
|
438 TInt64 mediaPos; |
|
439 while (aPos < end) |
|
440 { |
|
441 TInt len = end - aPos; |
|
442 mediaPos = aPos; |
|
443 r = iMsDataMemMap.CheckBlockInRange(mediaPos, len); |
|
444 if (r != KErrNone) |
|
445 { |
|
446 __HOSTPRINT1(_L("<<< HOST Write ret=%d"), r); |
|
447 return r; |
|
448 } |
|
449 |
|
450 if (localMessage) |
|
451 { |
|
452 r = iUsbHostMsLun.Write(mediaPos, len, ((TPtr8*)aSrc)->MidTPtr(aOffset)); |
|
453 |
|
454 if (r != KErrNone) |
|
455 { |
|
456 __HOSTPRINT1(_L("<<< HOST Write ret=%d"), r); |
|
457 return r; |
|
458 } |
|
459 } |
|
460 else |
|
461 { |
|
462 if (len > iBuf.Length()) |
|
463 len = iBuf.Length(); |
|
464 |
|
465 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle); |
|
466 r = msg.Read(index, iBuf, aOffset); |
|
467 if (r != KErrNone) |
|
468 { |
|
469 __HOSTPRINT1(_L("<<< HOST Write ret=%d"), r); |
|
470 return r; |
|
471 } |
|
472 |
|
473 r = iUsbHostMsLun.Write(mediaPos, len, iBuf); |
|
474 if (r != KErrNone) |
|
475 { |
|
476 __HOSTPRINT1(_L("<<< HOST Write ret=%d"), r); |
|
477 return r; |
|
478 } |
|
479 } |
|
480 |
|
481 aPos += len; |
|
482 aOffset += len; |
|
483 } |
|
484 |
|
485 __HOSTPRINT1(_L("<<< HOST Write ret=%d"), KErrNone); |
|
486 return KErrNone; |
|
487 } |
|
488 |
|
489 /** |
|
490 Write to the proxy drive and pass flags to driver |
|
491 |
|
492 @param aPos The address from where the write begins. |
|
493 @param aLength The length of the write. |
|
494 @param aSrc A descriptor of the memory buffer from which to write. |
|
495 @param aThreadHandle The handle-number representing the drive thread. |
|
496 @param aOffset Offset into aSrc to write the data to. |
|
497 @param aFlags Flags to be passed into the driver. |
|
498 |
|
499 @return system wide error code. |
|
500 */ |
|
501 TInt CUsbHostMsProxyDrive::Write(TInt64 aPos, TInt aLength, |
|
502 const TAny* aSrc, TInt aThreadHandle, TInt aOffset, TInt /* aFlags */) |
|
503 { |
|
504 __MSFNSLOG |
|
505 return Write(aPos, aLength, aSrc, aThreadHandle, aOffset); |
|
506 } |
|
507 |
|
508 /** |
|
509 Write to the proxy drive. |
|
510 |
|
511 @param aPos The address from where the write begins. |
|
512 @param aSrc A descriptor of the memory buffer from which to write. |
|
513 |
|
514 @return system wide error code. |
|
515 */ |
|
516 TInt CUsbHostMsProxyDrive::Write(TInt64 aPos,const TDesC8& aSrc) |
|
517 { |
|
518 __MSFNSLOG |
|
519 __HOSTPRINT3(_L("\n>>> HOST Write Pos=0x%lx LBA=0x%lx 0x%x"), |
|
520 aPos, aPos/KBlockSize, aSrc.Length()); |
|
521 return iUsbHostMsLun.Write(iMsDataMemMap.GetDataPos(aPos), aSrc.Length(), aSrc); |
|
522 } |
|
523 |
|
524 /** |
|
525 Get the proxy drive's capabilities information. |
|
526 |
|
527 @param anInfo A descriptor of the connected drives capabilities. |
|
528 |
|
529 @return system wide error code |
|
530 */ |
|
531 TInt CUsbHostMsProxyDrive::Caps(TDes8& anInfo) |
|
532 { |
|
533 __MSFNSLOG |
|
534 __HOSTPRINT(_L("\n>>> HOST Caps")); |
|
535 TLocalDriveCapsV6Buf caps; |
|
536 caps.FillZ(); |
|
537 |
|
538 caps().iType = EMediaHardDisk; |
|
539 caps().iBattery = EBatNotSupported; |
|
540 caps().iDriveAtt = KDriveAttLocal | KDriveAttRemovable; |
|
541 caps().iMediaAtt = KMediaAttFormattable; |
|
542 caps().iFileSystemId = KDriveFileSysFAT; |
|
543 caps().iExtraInfo = EFalse; |
|
544 |
|
545 TCapsInfo capsInfo; |
|
546 TInt r = iUsbHostMsLun.Caps(capsInfo); |
|
547 if (KErrNone == r) |
|
548 { |
|
549 caps().iBlockSize = capsInfo.iBlockLength; |
|
550 TUint64 size = iMsDataMemMap.DataSize(); |
|
551 if (size == 0) |
|
552 { |
|
553 // No valid partitions so specify the size of the disk |
|
554 size = static_cast<TUint64>(capsInfo.iNumberOfBlocks) * capsInfo.iBlockLength; |
|
555 } |
|
556 caps().iSize = size; |
|
557 |
|
558 caps().iEraseBlockSize = 0; |
|
559 |
|
560 if (capsInfo.iWriteProtect) |
|
561 { |
|
562 caps().iMediaAtt |= KMediaAttWriteProtected; |
|
563 } |
|
564 __HOSTPRINT4(_L("<<< HOST Caps Block[num=0x%x size=0x%x] Media[size=0x%lx WP=0x%x]"), |
|
565 capsInfo.iNumberOfBlocks, capsInfo.iBlockLength, |
|
566 caps().iSize, caps().iMediaAtt); |
|
567 } |
|
568 else |
|
569 { |
|
570 __HOSTPRINT(_L("<<< HOST Caps Media Not Present")); |
|
571 caps().iType = EMediaNotPresent; |
|
572 if(r != KErrNotReady) |
|
573 r = KErrUnknown; |
|
574 } |
|
575 anInfo = caps.Left(Min(caps.Length(),anInfo.MaxLength())); |
|
576 return r; |
|
577 } |
|
578 |
|
579 |
|
580 |
|
581 /** |
|
582 Format the proxy drive. The drive is assumed to be a single partition. The |
|
583 partition size is equivalent to the size of the media. |
|
584 |
|
585 @param aPos The position of the data which is being formatted. |
|
586 @param aLength [IN] The length of the data which is being formatted. [OUT] The |
|
587 length of data formatted, truncated when end of drive is reached. |
|
588 |
|
589 @return system wide error code. |
|
590 */ |
|
591 TInt CUsbHostMsProxyDrive::Erase(TInt64 aPos, TInt& aLength) |
|
592 { |
|
593 __MSFNSLOG |
|
594 __HOSTPRINT3(_L("\n HOST Erase Pos=0x%lx LBA=0x%lx 0x%x"), |
|
595 aPos, aPos/KBlockSize, aLength); |
|
596 TInt err = iMsDataMemMap.TranslateDataPos(aPos, aLength); |
|
597 |
|
598 if (err) |
|
599 return err; |
|
600 |
|
601 err = iUsbHostMsLun.Erase(aPos, aLength); |
|
602 return err; |
|
603 } |
|
604 |
|
605 |
|
606 /** |
|
607 Format the proxy drive. |
|
608 |
|
609 @param aPos The position of the data which is being formatted. |
|
610 @param aLength The length of the data which is being formatted. |
|
611 |
|
612 @return system wide error code. |
|
613 */ |
|
614 TInt CUsbHostMsProxyDrive::Format(TInt64 aPos, TInt aLength) |
|
615 { |
|
616 __MSFNSLOG |
|
617 return Erase(aPos, aLength); |
|
618 } |
|
619 |
|
620 |
|
621 /** |
|
622 Format the connected drive. |
|
623 |
|
624 @param anInfo Device specific format information. |
|
625 |
|
626 @return system wide error code. |
|
627 */ |
|
628 TInt CUsbHostMsProxyDrive::Format(TFormatInfo& aInfo) |
|
629 { |
|
630 __MSFNSLOG |
|
631 |
|
632 const TInt KDefaultMaxBytesPerFormat = 0x100 * TMsDataMemMap::KSectorSize; // 128K |
|
633 |
|
634 if (aInfo.i512ByteSectorsFormatted < 0) |
|
635 return KErrArgument; |
|
636 |
|
637 if (!aInfo.iFormatIsCurrent) |
|
638 { |
|
639 aInfo.iFormatIsCurrent = ETrue; |
|
640 aInfo.i512ByteSectorsFormatted = 0; |
|
641 aInfo.iMaxBytesPerFormat = KDefaultMaxBytesPerFormat; |
|
642 |
|
643 TLocalDriveCapsV6Buf caps; |
|
644 TInt r = Caps(caps); |
|
645 if (r != KErrNone) |
|
646 return r; |
|
647 |
|
648 iMsDataMemMap.InitDataArea(caps().iSize); |
|
649 } |
|
650 |
|
651 TInt64 pos = static_cast<TInt64>(aInfo.i512ByteSectorsFormatted) << TMsDataMemMap::KFormatSectorShift; |
|
652 TInt length = aInfo.iMaxBytesPerFormat; |
|
653 TInt r = Erase(pos, length); |
|
654 |
|
655 if (r == KErrNone) |
|
656 { |
|
657 length += TMsDataMemMap::KSectorSize - 1; |
|
658 length >>= TMsDataMemMap::KFormatSectorShift; |
|
659 aInfo.i512ByteSectorsFormatted += length; |
|
660 } |
|
661 |
|
662 return r; |
|
663 } |
|
664 |
|
665 |
|
666 TInt CUsbHostMsProxyDrive::NotifyChange(TDes8 &aChanged,TRequestStatus* aStatus) |
|
667 { |
|
668 __MSFNSLOG |
|
669 iUsbHostMsLun.NotifyChange(aChanged, *aStatus); |
|
670 |
|
671 if(*aStatus != KRequestPending) |
|
672 return KErrUnknown; |
|
673 |
|
674 return KErrNone; |
|
675 } |
|
676 |
|
677 void CUsbHostMsProxyDrive::NotifyChangeCancel() |
|
678 { |
|
679 __MSFNSLOG |
|
680 iUsbHostMsLun.NotifyChangeCancel(); |
|
681 } |
|
682 |
|
683 TInt CUsbHostMsProxyDrive::SetMountInfo(const TDesC8* /*aMountInfo*/,TInt /*aMountInfoThreadHandle=KCurrentThreadHandle*/) |
|
684 { |
|
685 __MSFNSLOG |
|
686 return KErrNone; |
|
687 } |
|
688 |
|
689 TInt CUsbHostMsProxyDrive::ForceRemount(TUint aFlags) |
|
690 { |
|
691 __MSFNSLOG |
|
692 iUsbHostMsLun.ForceRemount(aFlags); |
|
693 return KErrNone; |
|
694 } |
|
695 |
|
696 TInt CUsbHostMsProxyDrive::Unlock(TMediaPassword& /*aPassword*/, TBool /*aStorePassword*/) |
|
697 { |
|
698 __MSFNSLOG |
|
699 return KErrNotSupported; |
|
700 } |
|
701 |
|
702 TInt CUsbHostMsProxyDrive::Lock(TMediaPassword& /*aOldPassword*/, TMediaPassword& /*aNewPassword*/, TBool /*aStorePassword*/) |
|
703 { |
|
704 __MSFNSLOG |
|
705 return KErrNotSupported; |
|
706 } |
|
707 |
|
708 TInt CUsbHostMsProxyDrive::Clear(TMediaPassword& /*aPassword*/) |
|
709 { |
|
710 __MSFNSLOG |
|
711 return KErrNotSupported; |
|
712 } |
|
713 |
|
714 TInt CUsbHostMsProxyDrive::ErasePassword() |
|
715 { |
|
716 __MSFNSLOG |
|
717 return KErrNotSupported; |
|
718 } |
|
719 |
|
720 TInt CUsbHostMsProxyDrive::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
|
721 { |
|
722 switch(aInterfaceId) |
|
723 { |
|
724 case ELocalBufferSupport: |
|
725 return KErrNone; |
|
726 case EFinalised: |
|
727 { |
|
728 TBool isFinalised = (TBool)aInput; |
|
729 if(isFinalised) |
|
730 { |
|
731 iUsbHostMsLun.SuspendLun(); |
|
732 } |
|
733 } |
|
734 return KErrNone; |
|
735 default: |
|
736 return KErrNotSupported; |
|
737 } |
|
738 } |