userlibandfileserver/fileserver/shostmassstorage/msproxy/hostusbmsproxy.cpp
changeset 0 a41df078684a
child 33 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}