kerneltest/f32test/server/t_blockmap.cpp
changeset 0 a41df078684a
child 33 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/server/t_blockmap.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1404 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// Tests for the blockmap API. The blockmap API enumerates the resources
+// used by a file depending upon the type of media on which the file
+// resides.
+// 002 Test Initialise error checking
+// 003 Test processing of user-side block map into extent list
+// 004 Test processing of user-side block map into extent list, block size > read unit size
+// 005 Test Read error checking
+// 006 Test Read
+// Test BlockMap API functionality.
+// 
+//
+
+//! @SYMTestCaseID			KBASE-T_BLOCKMAP-0337
+//! @SYMTestType			UT
+//! @SYMPREQ				PREQ1110
+//! @SYMTestCaseDesc		Demand Paging Blockmap tests
+//! @SYMTestActions			001 Unit tests the TKernBlockMap class
+//! @SYMTestExpectedResults All tests should pass.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+
+
+#include <e32test.h>
+#include <f32file.h>
+#include <e32math.h>
+#include <hal.h>
+#include "t_server.h"
+
+RTest test( _L("T_BLOCKMAP") );
+
+const TInt KReadBufferSize = 1024;
+const TInt KMaxFragmentSize = 400;
+const TInt KMaxFileSize = 10000;
+
+TInt RamFatDrive = -1;
+TInt RemovableFatDrive = -1;
+TInt InternalRemovableFatDrive = -1;
+TInt NandDrive = -1;
+TBool Pageable = EFalse;
+TBool Finished = EFalse;
+
+enum DriveType
+	{
+	EDriveNand,
+	EDriveRam,
+	EDriveRemovable,
+	EDriveInternalRemovable
+	};
+
+_LIT( KTestFile, "Z:\\TEST\\T_FILE.CPP");
+_LIT( KTestFileFAT, "Z:\\Multiple\\T_file.cpp");
+_LIT( KTestFileName, "T_FILE.CPP");
+_LIT( KFragmentedFileName1, "FRAG1.TXT");
+_LIT( KFragmentedFileName2, "FRAG2.TXT");
+_LIT( KDriveBase, " :\\" );
+
+LOCAL_C TInt TestBlockMapNandFATUserData(TInt64 aStartPos, TInt64 aEndPos)
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	name[0] = TText('A' + NandDrive);
+	name.Append( KTestFileName );
+
+	TInt r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	r = fMan->Delete(name);
+
+	r = fMan->Copy(KTestFile, name);
+	test( r == KErrNone );
+
+	TInt localDriveNum = 0;
+	RFile testFile;
+	r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+			test( r == KErrNone );
+			r = fMan->Delete(name);
+			test( r == KErrNone );
+			delete fMan;
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	UserSvr::UnlockRamDrive();
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt remainder = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+
+	const TInt KTotalSegments = totalSegments;
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+		
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			if ( c2 == KTotalSegments && aEndPos%map[c].iBlockGranularity != 0 )
+				remainder = map[c].iBlockGranularity - aEndPos%map[c].iBlockGranularity;
+			else
+				remainder = 0;
+			miniLength = map[c].iBlockGranularity*myBlockMapEntry->iNumberOfBlocks - remainder - (c2 == 1?map[c].iBlockStartOffset:0);
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength);
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+
+	testFile.Close();
+	r=fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	test( r == KErrNone );
+	r = fMan->Delete(name);
+	test( r == KErrNone );
+	delete fMan;
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapNandFAT(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on NAND FAT.
+//
+	{
+	TInt localDriveNum = 0;
+	RFile testFile;
+	TInt r = testFile.Open( TheFs, KTestFileFAT, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, Pageable?EBlockMapUsagePaging:ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt remainder = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+
+	const TInt KTotalSegments = totalSegments;
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			if ( c2 == KTotalSegments && aEndPos%map[c].iBlockGranularity != 0 )
+				remainder = map[c].iBlockGranularity - aEndPos%map[c].iBlockGranularity;
+			else
+				remainder = 0;
+			miniLength = map[c].iBlockGranularity*myBlockMapEntry->iNumberOfBlocks - remainder - (c2 == 1?map[c].iBlockStartOffset:0);
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength);
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+	testFile.Close();
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapNandROFS(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on NAND ROFS.
+//
+	{
+	TInt localDriveNum = 0;
+	RFile testFile;
+	TInt r = testFile.Open( TheFs, KTestFile, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, Pageable?EBlockMapUsagePaging:ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+		
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			miniLength = length;
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength);
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+
+	testFile.Close();
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapRamFAT(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on RAM FAT.
+//
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	name[0] = TText('A' + RamFatDrive);
+	name.Append( KTestFileName );
+
+	TInt r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	r = fMan->Delete(name);
+
+	r = fMan->Copy(KTestFile, name);
+	test( r == KErrNone  || r == KErrAlreadyExists);
+
+	TInt localDriveNum = 0;
+	RFile testFile;
+	r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+			test( r == KErrNone );
+			r = fMan->Delete(name);
+			test( r == KErrNone );
+			delete fMan;
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	UserSvr::UnlockRamDrive();
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt remainder = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+
+	const TInt KTotalSegments = totalSegments;
+
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+	
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			if ( c2 == KTotalSegments && aEndPos%map[c].iBlockGranularity != 0 )
+				remainder = map[c].iBlockGranularity - aEndPos%map[c].iBlockGranularity;
+			else
+				remainder = 0;
+			miniLength = map[c].iBlockGranularity*myBlockMapEntry->iNumberOfBlocks - remainder - (c2 == 1?map[c].iBlockStartOffset:0);
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength);
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+
+	testFile.Close();
+	r=fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	test( r == KErrNone );
+	r = fMan->Delete(name);
+	test( r == KErrNone );
+	delete fMan;
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapRamFAT2(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on Ram FAT.
+//
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	name[0] = TText('A' + RamFatDrive);
+	name.Append( KTestFileName );
+
+	TInt r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	r = fMan->Delete(name);
+
+	r = fMan->Copy(KTestFile, name);
+	test( r == KErrNone  || r == KErrAlreadyExists);
+
+	RFile testFile;
+	r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+
+	TInt bmErr;
+	bmErr = testFile.BlockMap(info, aStartPos, aEndPos, EBlockMapUsagePaging);
+
+	map.Close();
+
+	testFile.Close();
+	r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	test( r == KErrNone );
+	r = fMan->Delete(name);
+	test( r == KErrNone );
+	delete fMan;
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapRemovableFAT(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on Removable FAT.
+//
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	name[0] = TText('A' + RemovableFatDrive);
+	name.Append( KTestFileName );
+
+	TInt r=fMan->Copy(KTestFile, name);
+	test( r == KErrNone  || r == KErrAlreadyExists);
+
+	RFile testFile;
+	r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt bmErr = testFile.BlockMap(info, aStartPos, aEndPos, Pageable?EBlockMapUsagePaging:ETestDebug);
+	map.Close();
+
+	testFile.Close();
+	r=fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	test( r == KErrNone );
+	r = fMan->Delete(name);
+	test( r == KErrNone );
+	delete fMan;
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapInternalRemovableFAT(TInt64 aStartPos, TInt64 aEndPos)
+//
+// Test BlockMap retrieval on internal removable FAT.
+//
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	name[0] = TText('A' + RamFatDrive);
+	name.Append( KTestFileName );
+
+	TInt r=fMan->Copy(KTestFile, name);
+	test( r == KErrNone  || r == KErrAlreadyExists);
+
+	TInt localDriveNum = 0;
+	RFile testFile;
+	r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+			test( r == KErrNone );
+			r = fMan->Delete(name);
+			test( r == KErrNone );
+			delete fMan;
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	UserSvr::UnlockRamDrive();
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt remainder = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+
+	const TInt KTotalSegments = totalSegments;
+
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+		
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			if ( c2 == KTotalSegments && aEndPos%map[c].iBlockGranularity != 0 )
+				remainder = map[c].iBlockGranularity - aEndPos%map[c].iBlockGranularity;
+			else
+				remainder = 0;
+			miniLength = map[c].iBlockGranularity*myBlockMapEntry->iNumberOfBlocks - remainder - (c2 == 1?map[c].iBlockStartOffset:0);
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength);
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+
+	testFile.Close();
+	r=fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+	test( r == KErrNone );
+	r = fMan->Delete(name);
+	test( r == KErrNone );
+	delete fMan;
+	return bmErr;
+	}
+
+LOCAL_C TInt TestBlockMapFragmented(DriveType aDriveType, TInt64 aStartPos, TInt64 aEndPos)
+	{
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	TFileName name(KDriveBase);
+	if (aDriveType==EDriveRam)
+		name[0] = TText('A' + RamFatDrive);
+	else if (aDriveType==EDriveRemovable)
+		name[0] = TText('A' + RemovableFatDrive);
+	else if (aDriveType==EDriveNand)
+		name[0] = TText('A' + NandDrive);
+	else 
+		name[0] = TText('A' + InternalRemovableFatDrive);
+	name.Append( KFragmentedFileName1 );
+	TInt localDriveNum = 0;
+	RFile testFile;
+	TInt r = testFile.Open( TheFs, name, EFileRead );
+	test( r == KErrNone );
+	RArray<SBlockMapInfo> map;	// From RArray<TBlockMapEntry> map; to RArray<SBlockMapInfo> map;
+	SBlockMapInfo info;
+	TInt counter = 0;
+	TInt startPos = aStartPos;
+	TInt bmErr;
+
+	// Store SBlockMapInfo objects in map:RArray until KErrCompletion is returned.
+	do
+		{
+		bmErr = testFile.BlockMap(info, aStartPos, aEndPos, ETestDebug);
+		if (bmErr != 0 && bmErr != KErrCompletion)
+			{
+			map.Close();
+			testFile.Close();
+			if ( Finished )
+				{
+				r = fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+				test( r == KErrNone );
+				r = fMan->Delete(name);
+				test( r == KErrNone );
+				}
+			delete fMan;
+			return bmErr;
+			}
+		map.Append(info); 
+		if (counter++ == 0)
+			localDriveNum = info.iLocalDriveNumber;
+		} while ( bmErr == 0 && bmErr != KErrCompletion );
+	test( bmErr == KErrCompletion );
+	TInt granularity;
+	TInt size;
+	r = testFile.Size(size);
+	test( r == KErrNone );
+
+	TBuf8<KReadBufferSize> buf1;
+	TBuf8<KReadBufferSize> buf2;
+	
+	TBool changed;	
+	TBusLocalDrive localDrive;
+
+	UserSvr::UnlockRamDrive();
+
+	TBlockMapEntry* myBlockMapEntry;
+	TInt myCounter = 0;
+	TInt totalSegments = 0;
+	TInt remainder = 0;
+	TInt miniLength = 0;
+	TInt amountRead = 0;
+
+	TInt c;
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+		totalSegments += granularity;
+		}
+
+	const TInt KTotalSegments = totalSegments;
+	r = localDrive.Connect( localDriveNum, changed );
+	test( r == KErrNone );
+
+//	For each SBlockMapInfo object in RArray map
+	for ( c = 0; c < map.Count(); c++ )
+		{
+		myBlockMapEntry = (TBlockMapEntry*) map[c].iMap.Ptr();
+		granularity = map[c].iMap.Size()/sizeof(TBlockMapEntry);
+
+		TInt length;
+		if ( aEndPos == -1 )
+			{
+			length = size - startPos;
+			aEndPos = size;
+			}
+		else
+			length = aEndPos - startPos;
+		
+		for ( TInt c2 = 1; c2 <= granularity; c2++)
+			{
+			myCounter = 0;
+			if ( c2 == KTotalSegments && aEndPos%map[c].iBlockGranularity != 0 )
+				remainder = map[c].iBlockGranularity - aEndPos%map[c].iBlockGranularity;
+			else
+				remainder = 0;
+			miniLength = map[c].iBlockGranularity*myBlockMapEntry->iNumberOfBlocks - remainder - (c2 == 1?map[c].iBlockStartOffset:0);
+			do
+				{
+				if ( miniLength >= KReadBufferSize )
+					{
+					testFile.Read( startPos + amountRead, buf1, KReadBufferSize );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, KReadBufferSize, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					buf1.Zero();
+					buf2.Zero();
+					myCounter++;
+					miniLength -= KReadBufferSize;
+					length -= KReadBufferSize;
+					amountRead += KReadBufferSize;
+					}
+				else
+					{
+					testFile.Read(startPos + amountRead, buf1, miniLength );
+					localDrive.Read( map[c].iStartBlockAddress + myBlockMapEntry->iStartBlock * map[c].iBlockGranularity + (c2 == 1?map[c].iBlockStartOffset:0) + myCounter*KReadBufferSize, miniLength, buf2);
+					r = buf1.Compare( buf2 );
+					test( r == 0 );
+					amountRead += miniLength;
+					length -= miniLength;
+					miniLength = 0;
+					}
+				} while ( miniLength != 0 && length != 0);
+			myBlockMapEntry++;
+			}
+		}
+	map.Close();
+
+	testFile.Close();
+	if ( Finished )
+		{
+		r=fMan->Attribs(name, 0, KEntryAttReadOnly, 0);
+		test( r == KErrNone );
+		r = fMan->Delete(name);
+		test( r == KErrNone );
+		}
+	delete fMan;
+	return bmErr;	
+	}
+
+LOCAL_C void GenerateFragmentedFiles(DriveType aDriveType)
+	{
+	TInt r;
+	TFileName name1(KDriveBase);
+	if (aDriveType==EDriveRam)
+		name1[0] = TText('A' + RamFatDrive);
+	else if (aDriveType==EDriveRemovable)
+		name1[0] = TText('A' + RemovableFatDrive);
+	else if (aDriveType==EDriveNand)
+		name1[0] = TText('A' + NandDrive);
+	else 
+		name1[0] = TText('A' + InternalRemovableFatDrive);
+	name1.Append( KFragmentedFileName1 );
+	RFile file1;
+	r = file1.Create(TheFs, name1, EFileWrite);
+	test( r == KErrNone );
+	file1.Close();
+
+	TFileName name2(KDriveBase);
+	if (aDriveType==EDriveRam)
+		name2[0] = TText('A' + RamFatDrive);
+	else if (aDriveType==EDriveRemovable)
+		name2[0] = TText('A' + RemovableFatDrive);
+	else if (aDriveType==EDriveNand)
+		name2[0] = TText('A' + NandDrive);
+	else 
+		name2[0] = TText('A' + InternalRemovableFatDrive);
+	name2.Append( KFragmentedFileName2 );
+	RFile file2;
+	r = file2.Create(TheFs, name2, EFileWrite);
+	test( r == KErrNone );
+	file2.Close();
+	TInt64 randomSeed;
+	TBuf8<KMaxFragmentSize> tempBuf;	
+	TUint8 *buf;
+	TInt fileSize = 0;
+	TInt fragmentSize;
+	TInt randomLength;
+	TInt pos1;
+	TInt pos2;
+	TInt mycount = 0;
+	do	
+		{
+		fragmentSize = 0;
+		pos1 = 0;
+		pos2 = 0;
+		buf = (TUint8*) tempBuf.Ptr();
+		tempBuf.Zero();
+		randomLength = Math::Random() % KMaxFragmentSize;
+		randomSeed = Math::Random();
+		tempBuf.SetLength(randomLength);
+
+		while (randomLength-- && fragmentSize++ < KMaxFragmentSize && fileSize++ < KMaxFileSize)
+			{
+			*buf++ = (TUint8)('A' + (Math::Rand(randomSeed) % ('Z' - 'A')));
+			}
+		r = file1.Open( TheFs, name1, EFileWrite );
+		test( r == KErrNone );
+		r = file1.Seek( ESeekEnd, pos1 );
+		test( r == KErrNone );
+		r = file1.Write( pos1, tempBuf );
+		test( r == KErrNone );
+		r = file1.Flush();
+		test( r == KErrNone );		
+		file1.Close();
+		if ( mycount++ < 6 )
+			{
+			r = file2.Open( TheFs, name2, EFileWrite );
+			test( r == KErrNone );
+			r = file2.Seek( ESeekEnd, pos2 );
+			test( r == KErrNone );
+			r = file2.Write( pos2, tempBuf );
+			test( r == KErrNone );
+			r = file2.Flush();
+			test( r == KErrNone );
+			file2.Close();
+			}
+		} while ( fileSize < KMaxFileSize );
+	CFileMan* fMan=CFileMan::NewL(TheFs);
+	test(fMan!=NULL);
+	r = fMan->Delete(name2);
+	test( r == KErrNone );
+	delete fMan;
+	}
+
+LOCAL_C void FindDrive(DriveType aDriveType)
+	{
+	TInt i;
+	TInt c = 0;
+	for( i = EDriveA; i < EDriveZ; i++ )
+		{
+		TDriveInfo info;
+		TInt r = TheFs.Drive(info, i);
+		if ( r != KErrNone )
+			continue;
+		test( r == KErrNone );
+		if ( aDriveType == EDriveNand )	
+			{
+			c++ == 0 ? test.Printf( _L("Searching for NAND drive.")) : test.Printf( _L("."));
+			if ( info.iType == EMediaNANDFlash && ((info.iMediaAtt & KMediaAttWriteProtected) == 0) )
+				{
+				if ( info.iDriveAtt & KDriveAttPageable )
+					Pageable = ETrue;
+				NandDrive = i;
+				test.Printf( _L("Found NAND drive: %d\n"), NandDrive );
+				break;
+				}
+			}
+		else if ( aDriveType == EDriveRam )
+			{
+			c++ == 0 ? test.Printf( _L("Searching for RAM FAT drive.")) : test.Printf( _L("."));
+			if ( (info.iType == EMediaRam) && ( info.iDriveAtt == (KDriveAttLocal|KDriveAttInternal) ) && ( info.iMediaAtt == (KMediaAttVariableSize|KMediaAttFormattable) ) )
+				{
+				if ( info.iDriveAtt & KDriveAttPageable )
+					Pageable = ETrue;
+				RamFatDrive = i;
+				test.Printf( _L("Found RAM FAT drive: %d\n"), RamFatDrive );
+				break;
+				}
+			}
+		else if ( aDriveType == EDriveRemovable )
+			{
+			c++ == 0 ? test.Printf( _L("Searching for removable FAT drive.")) : test.Printf( _L("."));
+			if ( info.iType == EMediaHardDisk && ( info.iDriveAtt == (KDriveAttLocal|KDriveAttRemovable) ) )
+				{
+				if ( info.iDriveAtt & KDriveAttPageable )
+					Pageable = ETrue;
+				RemovableFatDrive = i;
+				test.Printf( _L("Found removable FAT drive: %d\n"), RemovableFatDrive );
+				break;
+				}
+			}
+		else if ( aDriveType == EDriveInternalRemovable )
+			{
+			c++ == 0 ? test.Printf( _L("Searching for internal removable FAT drive.")) : test.Printf( _L("."));
+			if ( info.iType == EMediaHardDisk && ( info.iDriveAtt == (KDriveAttLocal|KDriveAttInternal) ) )
+				{
+				if ( info.iDriveAtt & KDriveAttPageable )
+					Pageable = ETrue;
+				InternalRemovableFatDrive = i;
+				test.Printf( _L("Found internal removable FAT drive: %d\n"), InternalRemovableFatDrive );
+				break;
+				}
+			}
+		}
+		if ( i == EDriveZ )
+			{
+			switch(aDriveType)
+				{
+				case EDriveNand:
+					test.Printf( _L("NAND drive not found.\n") );
+					break;
+				case EDriveRam:
+					test.Printf( _L("RAM FAT drive not found.\n") );
+					break;
+				case EDriveRemovable:
+					test.Printf( _L("Removable FAT drive not found.\n") );
+					break;
+				case EDriveInternalRemovable:
+					test.Printf( _L("Internal removable FAT drive not found.\n") );
+					break;
+				default:
+					test.Printf( _L("Drive not found.\n") );
+				}			
+			}
+	}
+
+//************************
+// Entry point
+
+GLDEF_C void CallTestsL(void)
+	{
+	test.Title(); 
+	test.Start( _L("BlockMap Test\n") );
+
+	TInt testFileSize = 0;
+	RFile testFile;
+	TInt r = testFile.Open(TheFs, KTestFile, EFileRead);
+	test(r==KErrNone);
+	r = testFile.Size(testFileSize);
+	test(r==KErrNone);
+	test(testFileSize>16384);
+	testFile.Close();
+
+	if ( gDriveToTest == 'C' )
+		{
+		TInt value;
+		r = HAL::Get( HAL::EMachineUid, value );
+		test( r == KErrNone );
+		if ( value != HAL::EMachineUid_Lubbock )	// Lubbock cannot run FindDrive as it doesn't support the NAND API
+			{
+			test.Next(_L("Test BlockMap retrieval on NAND FAT."));
+			FindDrive(EDriveNand);
+			if ( NandDrive > -1 )	// not finding a NAND drive isn't an error as only NAND builds have one
+				{
+				r = TestBlockMapNandFATUserData(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(1024, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(-5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(-5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFATUserData(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(2000, 2000);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFATUserData(2048, 2048);
+				test( r == KErrArgument );
+				test.Printf(_L("Generating Fragmented File..."));
+				GenerateFragmentedFiles(EDriveNand);
+				test.Printf(_L("Done!\n"));
+				test.Next(_L("Test BlockMap retrieval on NAND FAT (User area) (fragmented)."));	
+				r = TestBlockMapFragmented(EDriveNand, 0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 1024, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, -5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, -5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, 0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, 0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveNand, 0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveNand, 2000, 2000);
+				test( r == KErrArgument );
+				Finished = ETrue;
+				r = TestBlockMapFragmented(EDriveNand, 2048, 2048);
+				test( r == KErrArgument );
+				test.Next(_L("Test BlockMap retrieval on NAND FAT."));	
+				r = TestBlockMapNandFAT(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(1024, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(-5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(-5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandFAT(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(2000, 2000);
+				test( r == KErrArgument );
+				r = TestBlockMapNandFAT(2048, 2048);
+				test( r == KErrArgument );
+				test.Next(_L("Test BlockMap retrieval on NAND ROFS."));
+				r = TestBlockMapNandROFS(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(1024, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(-5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(-5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapNandROFS(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(2000, 2000);
+				test( r == KErrArgument );
+				r = TestBlockMapNandROFS(2048, 2048);
+				test( r == KErrArgument );
+				test.Next(_L("Test BlockMap retrieval on RAM FAT."));
+				FindDrive(EDriveRam);
+				test( RamFatDrive > -1 );
+				r = TestBlockMapRamFAT(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(1024, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(-5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(-5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapRamFAT(0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(2000, 2000);
+				test( r == KErrArgument );
+				r = TestBlockMapRamFAT(2048, 2048);
+				test( r == KErrArgument ); 
+				test.Next(_L("Test BlockMap retrieval on Ram FAT (2)."));
+				r = TestBlockMapRamFAT2(0, -1);
+				test( r == KErrNotSupported );
+				FindDrive(EDriveRemovable);
+				if ( RemovableFatDrive > -1)
+					{
+					test.Next(_L("Test BlockMap retrieval on removable FAT."));
+					r = TestBlockMapRemovableFAT(0, -1);
+					Pageable?test( r == KErrNotSupported ):test( r == KErrCompletion );
+					}
+				else
+					{
+					test.Next(_L("Test BlockMap retrieval on internal removable FAT."));
+					FindDrive(EDriveInternalRemovable);
+					test( InternalRemovableFatDrive > -1);
+					r = TestBlockMapInternalRemovableFAT(0, -1);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(1024, 4096);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(1020, 4100);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(1024, 4100);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(1020, 4096);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(1025, 1200);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(0, testFileSize+100);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(-5, -1);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(-5, testFileSize+100);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(0, 0);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(testFileSize, -1);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(0, -1);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(2000, 2001);
+					test( r == KErrCompletion );
+					r = TestBlockMapInternalRemovableFAT(0, 0);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(2000, 2000);
+					test( r == KErrArgument );
+					r = TestBlockMapInternalRemovableFAT(2048, 2048);
+					test( r == KErrArgument );
+					}
+				test.Next(_L("Test BlockMap retrieval on Ram FAT (fragmented)."));	
+				test.Printf(_L("Generating Fragmented File..."));
+				GenerateFragmentedFiles(EDriveRam);
+				test.Printf(_L("Done!\n"));
+				Finished = EFalse;
+				r = TestBlockMapFragmented(EDriveRam, 0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 1020, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 2049, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 1024, 4100);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 1020, 4096);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 1025, 1200);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 0, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, -5, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, -5, testFileSize+100);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, 0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, testFileSize, -1);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, 0, -1);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 2000, 2001);
+				test( r == KErrCompletion );
+				r = TestBlockMapFragmented(EDriveRam, 0, 0);
+				test( r == KErrArgument );
+				r = TestBlockMapFragmented(EDriveRam, 2000, 2000);
+				test( r == KErrArgument );
+				Finished = ETrue;
+				r = TestBlockMapFragmented(EDriveRam, 2048, 2048);
+				test( r == KErrArgument );
+				}
+			else
+				{
+				test.Printf( _L("NAND drive not found, skipping test.\n") );
+				}
+			}
+		}
+	test.End();
+	test.Close();
+	}