diff -r 819e59dfc032 -r 2d9cac8919d3 utilityapps/filebrowser/fileopserver/src/FBDrivePartitioner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilityapps/filebrowser/fileopserver/src/FBDrivePartitioner.cpp Mon Oct 18 16:30:05 2010 +0300 @@ -0,0 +1,454 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include + +#include "FBDrivePartitioner.h" + + +// copied from coreapplicationuisdomainpskeys.h +const TUid KPSUidCoreApplicationUIs = { 0x101F8767 }; +const TUint32 KCoreAppUIsMmcRemovedWithoutEject = 0x00000109; +enum TCoreAppUIsMmcRemovedWithoutEject + { + ECoreAppUIsEjectCommandUsedUninitialized = 0, + ECoreAppUIsEjectCommandNotUsed, + ECoreAppUIsEjectCommandUsed, + ECoreAppUIsEjectCommandUsedToDrive // Low 16-bits contain this value and high 16-bits TDriveNumber to eject + }; + + +// trace macros +#define TRACE(a) {_LIT( KMsg, a ); RDebug::Print(KMsg);} +#define TRACE1(a,b) {_LIT( KMsg, a ); RDebug::Print(KMsg,b);} +#define TRACE2(a,b,c) {_LIT( KMsg, a ); RDebug::Print(KMsg,b,c);} + + +// Set the partition alignment boundary +const TInt KPartitionAlignment = 0x1000; // 4kB +const TInt KMBRSize = 512; +const TInt KSectorSize = 512; +const TInt KMBRPartitionInfoOffset = 0x1BE; +const TInt KLargeFAT16Partition = 0x2000000; // 32MB +const TInt KPartitionEntrySize = 16; + +// Set for the iX86BootIndicator +//const TInt KPartitionBootable = 0x80; +const TInt KPartitionNonBootable = 0x0; + + +class TMBRPartition + { +public: + TUint8 iX86BootIndicator; + TUint8 iStartHead; + TUint8 iStartSector; + TUint8 iStartCylinder; + TUint8 iPartitionType; + TUint8 iEndHead; + TUint8 iEndSector; + TUint8 iEndCylinder; + TUint32 iFirstSector; + TUint32 iNumSectors; + }; + + +// -------------------------------------------------------------------------------------------- + +TInt FBDrivePartioner::FindLocalDriveNumber(RFs& aFs, TInt aDriveNumber, TInt& aLocalDriveNum) + { + TRACE1( "FBDrivePartitioner::FindLocalDriveNumber: start aDriveNumber=%d", aDriveNumber ); + + TInt err(KErrNone); + + TDriveInfo driveInfo; + err = aFs.Drive(driveInfo, aDriveNumber); + + TRACE1( "FBDrivePartitioner::FindLocalDriveNumber: get DriveInfo err=%d", err ); + + + TVolumeInfo vi; + err = aFs.Volume(vi, aDriveNumber); + + TRACE1( "FBDrivePartitioner::FindLocalDriveNumber: get VolumeInfo err=%d", err ); + + + TMediaSerialNumber serialNum; + err = aFs.GetMediaSerialNumber(serialNum, aDriveNumber); + + TRACE1( "FBDrivePartitioner::FindLocalDriveNumber: get MediaSerialNumber err=%d", err ); + + + TInt len = serialNum.Length(); + TInt n(0); + for (n=0; n buf; + for (TInt m=n; m hexBuf; + hexBuf.Format(_L("%02X "),serialNum[m]); + buf.Append(hexBuf); + } + buf.Append(_L("\n")); + } + + TBusLocalDrive drv; + TBool chg(EFalse); + aLocalDriveNum = -1; + for (n=0; n mbrBuf; + mbrBuf.Fill(0, mbrBuf.MaxLength()); + +/* + // write the next 16 sectors with the buffer. Usually you only write the first one, but this one should erase any following invalid sectors + for (TInt i=0; i<16; i++) + { + err = drv.Write(i*KMBRSize, KMBRSize, &mbrBuf, -1 , 0, 0x40000000); // RLocalDrive::ELocDrvWholeMedia==0x40000000 + TRACE2("FBDrivePartitioner::EraseMBR: sector %d, write returns %d", i+1, err); + } +*/ + + // erase the MBR + err = drv.Write(0, KMBRSize, &mbrBuf, -1 , 0, 0x40000000); // RLocalDrive::ELocDrvWholeMedia==0x40000000 + TRACE1("FBDrivePartitioner::EraseMBR: write returns %d", err); + + drv.Disconnect(); + + // force a remount, if this is the protected area, then it will have to be remounted + TRACE1( "FBDrivePartitioner::EraseMBR: Remounting drive number %d", aDriveNumber ); + TInt err2 = aFs.RemountDrive(aDriveNumber, NULL, 0); + TRACE1( "FBDrivePartitioner::EraseMBR: RemountDrive err2=%d", err2 ); + + TRACE1( "FBDrivePartitioner::EraseMBR: returns %d", err ); + return err; + } + +// -------------------------------------------------------------------------------------------- + +TInt FBDrivePartioner::CreatePartitions(RFs& aFs, TInt aDriveNumber, TInt aPartCount) + { + TRACE2( "FBDrivePartitioner::CreatePartitions: start aDriveNumber=%d aPartCount=%d", aDriveNumber, aPartCount ); + TInt err(KErrNone); + + TUint8 MBRPartitionInfo[ KPartitionEntrySize*KMBRMaxPrimaryPartitions ]; + + // Prevent SysAp shutting down applications + RProperty::Set( + KPSUidCoreApplicationUIs, + KCoreAppUIsMmcRemovedWithoutEject, + ECoreAppUIsEjectCommandUsed ); + + // Force the system to read the memory card erased MBR + err = aFs.RemountDrive( aDriveNumber ); + TRACE1( "FBDrivePartitioner::CreatePartitions: Remount result %d", err ); + + // Get the number of partitions from user + TUint8 partitionCount(aPartCount); + TBool change = EFalse; + TInt mcDriveNbr(2); + TLocalDriveCapsV4 dc; + TInt64 diskSpace(0); + +/* + err = FindLocalDriveNumber(aFs, aDriveNumber, mcDriveNbr); + + if (err != KErrNone) + { + TRACE1("FBDrivePartitioner::CreatePartitions: FindLocalDriveNumber err=%d returning", err); + return err; + } +*/ + + // Seek through the system drives to find memory card drive + for (TInt i = 0; i < KMaxLocalDrives; ++i) + { + RLocalDrive d; + change = EFalse; + err = d.Connect(i, change); + if (err == KErrNone) + { + TPckg capsPack(dc); + + if (d.Caps(capsPack) == KErrNone) + { + if (dc.iType == EMediaHardDisk) + { + mcDriveNbr = i; + diskSpace = dc.iSize; + TRACE1( "FBDrivePartitioner::CreatePartitions: found hard drive %d:", mcDriveNbr ); + } + } + d.Close(); + } + } + + // Connect to the local drive we found + RLocalDrive localDrive; + change = EFalse; + err = localDrive.Connect( mcDriveNbr, change ); + TRACE2( "FBDrivePartitioner::CreatePartitions: localDrive.Connect %d: %d", mcDriveNbr, err ); + TRACE1( "FBDrivePartitioner::CreatePartitions: diskSpace in sectors 0x%x, %d", diskSpace / KSectorSize ); + + // Let's read the MBR by using RLocalDrive + TUint8 data[KMBRSize]; + TPtr8 buf( &data[0], KMBRSize ); + err = localDrive.Read( 0, KMBRSize, buf ); + TRACE1( "FBDrivePartitioner::CreatePartitions: localDrive.Read %d", err ); + // Let's check the current drive layout here + memcpy( MBRPartitionInfo, &data[KMBRPartitionInfoOffset],(sizeof(TMBRPartition)<<2)); + TMBRPartition *partitionInfo = (TMBRPartition*) MBRPartitionInfo; + + // Clean the rest of the MBR buffer + buf.FillZ(); + + // Print out the partition info + for( TInt i = 0; i 0) + { + err = fmt.Next(count); + if (err != KErrNone) + { + TRACE1( "FBDrivePartitioner::FormatPartitions: Format error=%d", err ); + break; + } + } + fmt.Close(); + TRACE1( "FBDrivePartitioner::FormatPartitions: Format %S end", &name ); + } + + TRACE1("FBDrivePartitioner::FormatPartitions returns %d", err); + + return err; + } + +// --------------------------------------------------------------------------------------------