os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/msproxy/hostusbmsproxy.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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     TLocalDriveCapsV6& c = caps();
   539 
   540 	c.iType = EMediaHardDisk;
   541     c.iConnectionBusType = EConnectionBusUsb;
   542 	c.iDriveAtt = KDriveAttLocal | KDriveAttRemovable | KDriveAttExternal;
   543 	c.iMediaAtt = KMediaAttFormattable;
   544 	c.iFileSystemId = KDriveFileSysFAT;
   545 
   546 	TCapsInfo capsInfo;
   547 	TInt r = iUsbHostMsLun.Caps(capsInfo);
   548 	if (KErrNone == r)
   549 		{
   550         c.iBlockSize = capsInfo.iBlockLength;
   551         TUint64 size = iMsDataMemMap.DataSize();
   552         if (size == 0)
   553             {
   554             // No valid partitions so specify the size of the disk
   555             size = static_cast<TUint64>(capsInfo.iNumberOfBlocks) * capsInfo.iBlockLength;
   556             }
   557         c.iSize = size;
   558 
   559         c.iEraseBlockSize = 0;
   560 
   561         if (capsInfo.iWriteProtect)
   562             {
   563             c.iMediaAtt |= KMediaAttWriteProtected;
   564             }
   565         __HOSTPRINT4(_L("<<< HOST Caps Block[num=0x%x size=0x%x] Media[size=0x%lx WP=0x%x]"),
   566                     capsInfo.iNumberOfBlocks, capsInfo.iBlockLength,
   567 		            caps().iSize, caps().iMediaAtt);
   568 		}
   569 	else
   570         {
   571         __HOSTPRINT(_L("<<< HOST Caps Media Not Present"));
   572 		c.iType = EMediaNotPresent;
   573 		if(r != KErrNotReady)
   574 			r = KErrUnknown;
   575         }
   576 	anInfo = caps.Left(Min(caps.Length(),anInfo.MaxLength()));
   577 	return r;
   578 	}
   579 
   580 
   581 
   582 /**
   583 Format the proxy drive. The drive is assumed to be a single partition. The
   584 partition size is equivalent to the size of the media.
   585 
   586 @param aPos    The position of the data which is being formatted.
   587 @param aLength [IN] The length of the data which is being formatted. [OUT] The
   588 length of data formatted, truncated when end of drive is reached.
   589 
   590 @return system wide error code.
   591 */
   592 TInt CUsbHostMsProxyDrive::Erase(TInt64 aPos, TInt& aLength)
   593 	{
   594 	__MSFNSLOG
   595     __HOSTPRINT3(_L("\n HOST Erase Pos=0x%lx LBA=0x%lx 0x%x"),
   596                  aPos, aPos/KBlockSize, aLength);
   597     TInt err = iMsDataMemMap.TranslateDataPos(aPos, aLength);
   598 
   599     if (err)
   600         return err;
   601 
   602     err = iUsbHostMsLun.Erase(aPos, aLength);
   603     return err;
   604 	}
   605 
   606 
   607 /**
   608 Format the proxy drive.
   609 
   610 @param aPos    The position of the data which is being formatted.
   611 @param aLength The length of the data which is being formatted.
   612 
   613 @return system wide error code.
   614 */
   615 TInt CUsbHostMsProxyDrive::Format(TInt64 aPos, TInt aLength)
   616 	{
   617 	__MSFNSLOG
   618     return Erase(aPos, aLength);
   619 	}
   620 
   621 
   622 /**
   623 Format the connected drive.
   624 
   625 @param anInfo Device specific format information.
   626 
   627 @return system wide error code.
   628 */
   629 TInt CUsbHostMsProxyDrive::Format(TFormatInfo& aInfo)
   630 	{
   631 	__MSFNSLOG
   632 
   633     const TInt KDefaultMaxBytesPerFormat = 0x100 * TMsDataMemMap::KSectorSize;  // 128K
   634 
   635     if (aInfo.i512ByteSectorsFormatted < 0)
   636         return KErrArgument;
   637 
   638     if (!aInfo.iFormatIsCurrent)
   639         {
   640         aInfo.iFormatIsCurrent = ETrue;
   641         aInfo.i512ByteSectorsFormatted = 0;
   642         aInfo.iMaxBytesPerFormat = KDefaultMaxBytesPerFormat;
   643 
   644 		TLocalDriveCapsV6Buf caps;
   645 		TInt r = Caps(caps);
   646 		if (r != KErrNone)
   647 			return r;
   648 
   649         iMsDataMemMap.InitDataArea(caps().iSize);
   650         }
   651 
   652     TInt64 pos = static_cast<TInt64>(aInfo.i512ByteSectorsFormatted) << TMsDataMemMap::KFormatSectorShift;
   653     TInt length = aInfo.iMaxBytesPerFormat;
   654     TInt r = Erase(pos, length);
   655 
   656     if (r == KErrNone)
   657         {
   658         length += TMsDataMemMap::KSectorSize - 1;
   659         length >>= TMsDataMemMap::KFormatSectorShift;
   660         aInfo.i512ByteSectorsFormatted += length;
   661         }
   662 
   663     return r;
   664     }
   665 
   666 
   667 TInt CUsbHostMsProxyDrive::NotifyChange(TDes8 &aChanged,TRequestStatus* aStatus)
   668 	{
   669 	__MSFNSLOG
   670 	iUsbHostMsLun.NotifyChange(aChanged, *aStatus);
   671 
   672 	if(*aStatus != KRequestPending)
   673 		return KErrUnknown;
   674 
   675 	return KErrNone;
   676 	}
   677 
   678 void CUsbHostMsProxyDrive::NotifyChangeCancel()
   679 	{
   680 	__MSFNSLOG
   681 	iUsbHostMsLun.NotifyChangeCancel();
   682 	}
   683 
   684 TInt CUsbHostMsProxyDrive::SetMountInfo(const TDesC8* /*aMountInfo*/,TInt /*aMountInfoThreadHandle=KCurrentThreadHandle*/)
   685     {
   686 	__MSFNSLOG
   687     return KErrNone;
   688     }
   689 
   690 TInt CUsbHostMsProxyDrive::ForceRemount(TUint aFlags)
   691     {
   692 	__MSFNSLOG
   693     iUsbHostMsLun.ForceRemount(aFlags);
   694     return KErrNone;
   695     }
   696 
   697 TInt CUsbHostMsProxyDrive::Unlock(TMediaPassword& /*aPassword*/, TBool /*aStorePassword*/)
   698     {
   699 	__MSFNSLOG
   700     return KErrNotSupported;
   701     }
   702 
   703 TInt CUsbHostMsProxyDrive::Lock(TMediaPassword& /*aOldPassword*/, TMediaPassword& /*aNewPassword*/, TBool /*aStorePassword*/)
   704     {
   705 	__MSFNSLOG
   706     return KErrNotSupported;
   707     }
   708 
   709 TInt CUsbHostMsProxyDrive::Clear(TMediaPassword& /*aPassword*/)
   710     {
   711 	__MSFNSLOG
   712     return KErrNotSupported;
   713     }
   714 
   715 TInt CUsbHostMsProxyDrive::ErasePassword()
   716     {
   717 	__MSFNSLOG
   718     return KErrNotSupported;
   719     }
   720 
   721 TInt CUsbHostMsProxyDrive::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   722 	{
   723 	switch(aInterfaceId)
   724 		{
   725 		case ELocalBufferSupport:
   726 			return KErrNone;
   727 		case EFinalised:
   728 			{
   729 			TBool isFinalised = (TBool)aInput;
   730 			if(isFinalised)
   731 				{
   732 				iUsbHostMsLun.SuspendLun();
   733 				}
   734 			}
   735 			return KErrNone;
   736 		default:
   737 			return KErrNotSupported;
   738 		}
   739 	}