userlibandfileserver/fileserver/sfile/sf_debug.cpp
changeset 0 a41df078684a
child 19 4a8fed1c0ef6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_debug.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,600 @@
+// Copyright (c) 1996-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:
+// f32\sfile\sf_debug.cpp
+// 
+//
+
+#include "sf_std.h"
+#include <f32dbg.h>
+#include "f32image.h"
+#include <F32plugin.h>
+#include "sf_file_cache.h"
+
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+
+//
+// ONLY INCLUDED IN DEBUG BUILDS
+//
+
+void PrintHeapSize(const TDesC& aMessage)
+//
+// Display the total memory available
+//
+	{
+
+	TInt biggest;
+	TInt heapSize = User::Allocator().Available(biggest);
+	RDebug::Print(_L("%S size=0x%x largest cell=0x%x"),&aMessage,heapSize,biggest);
+	}
+
+static void SetAllocFailure(const RMessage2* aMessage)
+//
+// Set alloc failure after allocCount allocations
+//
+	{
+
+	UserHeapAllocFailCount=aMessage->Int1();
+	KernHeapAllocFailCount=UserHeapAllocFailCount;
+	if (UserHeapAllocFailCount>=0)
+		{
+		__UHEAP_FAILNEXT(UserHeapAllocFailCount);
+		__KHEAP_FAILNEXT(KernHeapAllocFailCount);
+		}
+	else
+		{
+		__UHEAP_RESET;
+		__KHEAP_RESET;
+		}	
+	}
+
+TInt FsDebugFunction(CFsRequest* aRequest)
+//
+// SetAllocFailure - Set alloc failure after allocCount allocations
+// SetErrorCondition - Set simulated error failure
+// SetDebugRegister - Trigger tracing output
+// DebugNotify - Request notification of a file server event - .FSY specific
+//
+	{
+
+	TInt r=KErrNone;
+	const RMessage2* message=&(aRequest->Message());
+	switch (message->Int0())
+		{
+	case EFsSetAllocFailure: 
+		SetAllocFailure(message); 
+		break;
+	case EFsSetErrorCondition:
+		ErrorCondition=message->Int1();
+		ErrorCount=message->Int2();
+		break;
+	case EFsSetDebugRegister:
+		DebugReg=message->Int1();
+		break;
+	case EFsDebugNotify:
+		{
+		TUint notifyType=(aRequest->Message().Int2())&KDebugNotifyMask;
+		if (notifyType)
+			{
+			CDebugChangeInfo* info=new CDebugChangeInfo;
+			if(!info)
+				return(KErrNoMemory);
+			const RMessage2& m=aRequest->Message();
+			info->Initialise(notifyType,(TRequestStatus*)m.Ptr3(),m,aRequest->Session());
+			r=FsNotify::AddDebug(info);
+			if(r!=KErrNone)
+				delete(info);
+			else
+				aRequest->SetCompleted(EFalse);
+			}
+		else
+			r=KErrArgument;
+		break;
+		}
+	default:
+		break;
+		};
+	return(r);
+	}
+
+TBool SimulateError(const RMessage2* aMessage)
+//
+// Return an error message if ErrorCount<=0
+//
+	{
+	TInt function = aMessage->Function() & KIpcFunctionMask;
+	
+	if (ErrorCondition!=KErrNone && 
+		(
+		function!=EFsDebugFunction || aMessage->Int0()!=EFsSetErrorCondition) &&
+		function!=EFsNotifyChangeCancel &&
+		function!=EFsNotifyChangeCancelEx &&
+		function!=EFsNotifyDiskSpaceCancel &&
+		function!=EFsFormatSubClose && 
+		function!=EFsDirSubClose  && 
+		function!=EFsFileSubClose && 
+		function!=EFsRawSubClose &&
+		function!=EFsUnclamp &&
+
+        //-- this operation must not fail. It can only fail if the client's thread has died.
+        //-- in this case whole session will be cleaned up.
+		function!=EFsFileAdopt 
+        )
+		{
+		if (ErrorCount<=0)
+			return(ETrue);
+		ErrorCount--;
+		}
+	return(EFalse);
+	}
+
+
+TPtrC GetFunctionName(TInt aFunction)
+//
+// Print number of alloc fails to complete a given function
+//
+	{
+
+	switch (aFunction)
+		{
+	case EFsDebugFunction: return _L("EFsDebugFunction");
+	case EFsAddFileSystem: return _L("EFsAddFileSystem");
+	case EFsRemoveFileSystem: return _L("EFsRemoveFileSystem");
+	case EFsMountFileSystem: return _L("EFsMountFileSystem");
+	case EFsNotifyChange: return _L("EFsNotifyChange");
+	case EFsNotifyChangeCancel: return _L("EFsNotifyChangeCancel");
+	case EFsDriveList: return _L("EFsDriveList");
+	case EFsDrive: return _L("EFsDrive");
+	case EFsVolume: return _L("EFsVolume");
+	case EFsSetVolume: return _L("EFsSetVolume");
+	case EFsSubst: return _L("EFsSubst");
+	case EFsSetSubst: return _L("EFsSetSubst");
+	case EFsRealName: return _L("EFsRealName");
+	case EFsDefaultPath: return _L("EFsDefaultPath");
+	case EFsSetDefaultPath: return _L("EFsSetDefaultPath");
+	case EFsSessionPath: return _L("EFsSessionPath");
+	case EFsSetSessionPath: return _L("EFsSetSessionPath");
+	case EFsMkDir: return _L("EFsMkDir");
+	case EFsRmDir: return _L("EFsRmDir");
+	case EFsParse: return _L("EFsParse");
+	case EFsDelete: return _L("EFsDelete");
+	case EFsRename: return _L("EFsRename");
+	case EFsReplace: return _L("EFsReplace");
+	case EFsEntry: return _L("EFsEntry");
+	case EFsSetEntry: return _L("EFsSetEntry");
+	case EFsGetDriveName: return _L("EFsGetDriveName");
+	case EFsSetDriveName: return _L("EFsSetDriveName");
+	case EFsFormatSubClose: return _L("EFsFormatSubClose");
+	case EFsDirSubClose: return _L("EFsDirSubClose");
+	case EFsFileSubClose: return _L("EFsFileSubClose");
+	case EFsRawSubClose: return _L("EFsRawSubClose");
+	case EFsFileOpen: return _L("EFsFileOpen");
+	case EFsFileCreate: return _L("EFsFileCreate");
+	case EFsFileReplace: return _L("EFsFileReplace");
+	case EFsFileTemp: return _L("EFsFileTemp");
+	case EFsFileRead: return _L("EFsFileRead");
+	case EFsFileWrite: return _L("EFsFileWrite");
+	case EFsFileLock: return _L("EFsFileLock");
+	case EFsFileUnLock: return _L("EFsFileUnLock");
+	case EFsFileSeek: return _L("EFsFileSeek");
+	case EFsFileFlush: return _L("EFsFileFlush");
+	case EFsFileSize: return _L("EFsFileSize");
+	case EFsFileSetSize: return _L("EFsFileSetSize");
+	case EFsFileAtt: return _L("EFsFileAtt");
+	case EFsFileSetAtt: return _L("EFsFileSetAtt");
+	case EFsFileModified: return _L("EFsFileModified");
+	case EFsFileSetModified: return _L("EFsFileSetModified");
+	case EFsFileSet: return _L("EFsFileSet");
+	case EFsFileChangeMode: return _L("EFsFileChangeMode");
+	case EFsFileRename: return _L("EFsFileRename");
+	case EFsDirOpen: return _L("EFsDirOpen");
+	case EFsDirReadOne: return _L("EFsDirReadOne");
+	case EFsDirReadPacked: return _L("EFsDirReadPacked");
+	case EFsFormatOpen: return _L("EFsFormatOpen");
+	case EFsFormatNext: return _L("EFsFormatNext");
+	case EFsRawDiskOpen: return _L("EFsRawDiskOpen");
+	case EFsRawDiskRead: return _L("EFsRawDiskRead");
+	case EFsRawDiskWrite: return _L("EFsRawDiskWrite");
+	case EFsResourceCountMarkStart: return _L("EFsResourceCountMarkStart");
+	case EFsResourceCountMarkEnd: return _L("EFsResourceCountMarkEnd");
+	case EFsResourceCount: return _L("EFsResourceCount");
+	case EFsCheckDisk: return _L("EFsCheckDisk");
+	case EFsGetShortName: return _L("EFsGetShortName");
+	case EFsGetLongName: return _L("EFsGetLongName");
+	case EFsIsFileOpen: return _L("EFsIsFileOpen");
+	case EFsListOpenFiles: return _L("EFsListOpenFiles");
+	case EFsSetNotifyUser: return _L("EFsSetNotifyUser");
+	case EFsIsFileInRom: return _L("EFsIsFileInRom");
+	case EFsGetNotifyUser: return _L("EFsGetNotifyUser");
+	case EFsIsValidName: return _L("EFsIsValidName");
+	case EFsReadFileSection: return _L("EFsReadFileSection");
+	case EFsNotifyChangeEx: return _L("EFsNotifyChangeEx");
+	case EFsNotifyChangeCancelEx: return _L("EFsNotifyChangeCancelEx");
+	case EFsDismountFileSystem: return _L("EFsDismountFileSystem");
+	case EFsFileSystemName: return _L("EFsFileSystemName");
+	case EFsScanDrive: return _L("EFsScanDrive");
+	case EFsControlIo: return _L("EFsControlIo");
+	case EFsLockDrive: return _L("EFsLockDrive");
+	case EFsUnlockDrive: return _L("EFsUnlockDrive");
+	case EFsClearPassword: return _L("EFsClearPassword");
+	case EFsNotifyDiskSpace: return _L("EFsNotifyDiskSpace");
+	case EFsNotifyDiskSpaceCancel: return _L("EFsNotifyDiskSpaceCancel");
+	case EFsMountFileSystemScan: return _L("EFsMountFileSystemScan");
+	case EFsSessionToPrivate: return _L("EFsSessionToPrivate");
+	case EFsPrivatePath: return _L("EFsPrivatePath");
+	case EFsCreatePrivatePath: return _L("EFsCreatePrivatePath");
+	case EFsFileDrive: return _L("EFsFileDrive");
+	case EFsRemountDrive: return _L("EFsRemountDrive");
+	case EFsAddExtension: return _L("EFsAddExtension");
+	case EFsMountExtension: return _L("EFsMountExtension");
+	case EFsDismountExtension: return _L("EFsDismountExtension");
+	case EFsRemoveExtension: return _L("EFsRemoveExtension");
+	case EFsExtensionName: return _L("EFsExtensionName");
+	case EFsStartupInitComplete: return _L("EFsStartupInitComplete");
+	case EFsSetLocalDriveMapping: return _L("EFsSetLocalDriveMapping");
+	case EFsFileDuplicate: return _L("EFsFileDuplicate");
+	case EFsFileAdopt: return _L("EFsFileAdopt");
+	case EFsFinaliseDrive: return _L("EFsFinaliseDrive");
+	case EFsSwapFileSystem: return _L("EFsSwapFileSystem");
+	case EFsErasePassword: return _L("EFsErasePassword");
+	case EFsReserveDriveSpace: return _L("EFsReserveDriveSpace");
+	case EFsGetReserveAccess: return _L("EFsGetReserveAccess");
+	case EFsReleaseReserveAccess: return _L("EFsReleaseReserveAccess");
+	case EFsFileName: return _L("EFsFileName");
+    case EFsGetMediaSerialNumber: return _L("EFsGetMediaSerialNumber");
+	case EFsFileFullName: return _L("EFsFileFullName");
+	case EFsAddPlugin: return _L("EFsAddPlugin");
+	case EFsRemovePlugin: return _L("EFsRemovePlugin");
+	case EFsMountPlugin: return _L("EFsMountPlugin");
+	case EFsDismountPlugin: return _L("EFsDismountPlugin");
+	case EFsPluginName: return _L("EFsPluginName");
+	case EFsPluginOpen: return _L("EFsPluginOpen");
+	case EFsPluginSubClose: return _L("EFsPluginSubClose");
+	case EFsPluginDoRequest: return _L("EFsPluginDoRequest");
+	case EFsPluginDoControl: return _L("EFsPluginDoControl");
+	case EFsPluginDoCancel: return _L("EFsPluginDoCancel");
+	case EFsNotifyDismount: return _L("EFsNotifyDismount");
+	case EFsNotifyDismountCancel: return _L("EFsNotifyDismountCancel");
+	case EFsAllowDismount: return _L("EFsAllowDismount");
+	case EFsSetStartupConfiguration: return _L("EFsSetStartupConfiguration");
+	case EFsFileReadCancel: return _L("EFsFileReadCancel");
+	case EFsAddCompositeMount: return _L("EFsAddCompositeMount");
+	case EFsSetSessionFlags: return _L("EFsSetSessionFlags");
+	case EFsSetSystemDrive: return _L("EFsSetSystemDrive");
+	case EFsBlockMap: return _L("EFsBlockMap");
+	case EFsUnclamp: return _L("EFsUnclamp");
+	case EFsFileClamp: return _L("EFsFileClamp");
+	case EFsQueryVolumeInfoExt: return _L("EFsQueryVolumeInfoExt");
+	case EFsInitialisePropertiesFile: return _L("EFsInitialisePropertiesFile");
+	case EFsFileWriteDirty: return _L("EFsFileWriteDirty");
+	case EFsSynchroniseDriveThread: return _L("EFsSynchroniseDriveThread");
+	case EFsAddProxyDrive: return _L("EFsAddProxyDrive");
+	case EFsRemoveProxyDrive: return _L("EFsRemoveProxyDrive");
+	case EFsMountProxyDrive: return _L("EFsMountProxyDrive");
+	case EFsDismountProxyDrive:  return _L("EFsDismountProxyDrive");
+	case EFsNotificationAdd : return _L("EFsNotificationAdd"); 
+	case EFsNotificationBuffer : return _L("EFsNotificationBuffer");
+	case EFsNotificationCancel : return _L("EFsNotificationCancel");
+	case EFsNotificationOpen : return _L("EFsNotificationOpen");
+	case EFsNotificationRemove : return _L("EFsNotificationRemove");
+	case EFsNotificationRequest : return _L("EFsNotificationRequest");
+	case EFsNotificationSubClose : return _L("EFsNotificationSubClose");
+	case EFsLoadCodePage: return _L("EFsLoadCodePage");
+	default:
+		return _L("Error unknown function");
+		}
+	}
+
+
+void PrintStartUpReason(TMachineStartupType aReason)
+//
+// Print the reason the machine is booting up
+//
+	{
+
+	TBuf<64> nameBuf;
+	switch (aReason)
+		{
+	case EStartupCold: nameBuf=_L("EStartupCold"); break;
+	case EStartupColdReset: nameBuf=_L("EStartupColdReset"); break;
+	case EStartupNewOs: nameBuf=_L("EStartupNewOs"); break;
+	case EStartupPowerFail: nameBuf=_L("StartupPowerFail"); break;
+	case EStartupWarmReset: nameBuf=_L("EStartupWarmReset"); break;
+	case EStartupKernelFault: nameBuf=_L("EStartupKernelFault"); break;
+	case EStartupSafeReset: nameBuf=_L("EStartupSafeReset"); break;
+	default:
+		nameBuf=_L("Error unknown startup type");
+		}
+	__PRINT1(_L("Machine startup - %S"),&nameBuf);
+	};
+
+LOCAL_C void AllocPrint(TInt aFunction)
+//
+// Print number of alloc fails to complete a given function
+//
+	{
+	if (UserHeapAllocFailCount || KernHeapAllocFailCount)
+		{	
+		TPtrC funcName=GetFunctionName(aFunction);
+			{
+			__PRINTALLOC(_L("Function %S UserAllocs %d KernAllocs %d"),&funcName,UserHeapAllocFailCount,KernHeapAllocFailCount);
+			}
+		}
+	}
+
+void SimulateAllocFailure(TInt aFunctionReturnValue,TInt aFunction)
+//
+// Simulate alloc failure
+//
+	{
+
+	
+	if (UserHeapAllocFailCount>=0 && (aFunctionReturnValue==KErrDiskFull || aFunctionReturnValue==KErrNoMemory))
+		{
+		if (KernHeapAllocFailCount<20)
+			{
+			__KHEAP_FAILNEXT(++KernHeapAllocFailCount);
+			__UHEAP_FAILNEXT(UserHeapAllocFailCount);
+			}
+		else
+			{
+			KernHeapAllocFailCount=0;
+			__UHEAP_FAILNEXT(++UserHeapAllocFailCount);
+			__KHEAP_FAILNEXT(KernHeapAllocFailCount);
+			}
+		if (UserHeapAllocFailCount<100)
+			return;
+		}
+	if (UserHeapAllocFailCount>=0)
+		{
+		AllocPrint(aFunction);
+		UserHeapAllocFailCount=0;
+		KernHeapAllocFailCount=0;
+		__UHEAP_FAILNEXT(UserHeapAllocFailCount);
+		__KHEAP_FAILNEXT(KernHeapAllocFailCount);
+		}
+	}
+
+#else
+TInt FsDebugFunction(CFsRequest* /*aRequest*/)
+//
+// Not in the release build
+//
+	{
+	return KErrNotSupported;
+	}
+#endif
+
+TInt TFsDebugFunc::DoRequestL(CFsRequest* aRequest)
+//
+// Not in the release build
+//
+	{
+	return FsDebugFunction(aRequest);
+	}
+
+TInt TFsDebugFunc::Initialise(CFsRequest* /*aRequest*/)
+//
+// Not in the release build
+//
+	{
+	return KErrNone;
+	}
+
+TInt TFsControlIo::DoRequestL(CFsRequest* aRequest)
+//
+// General purpose test interface - .FSY specific.
+// Not in the release build
+//
+	{
+	TInt command=aRequest->Message().Int1();
+	TAny* param1=(TAny*)aRequest->Message().Ptr2();
+	TAny* param2=(TAny*)aRequest->Message().Ptr3();
+
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+	switch(command)
+		{	//These are non-drive commands
+		case KControlIoGetCorruptLogRecord:
+			{
+			// number of the log record to be retrieved (1-based)
+			TInt logRecNum=(TInt)param2;
+			TFsDebugCorruptLogRecordBuf logBuf;
+			TInt r=TCorruptLogRec::GetLogRecord(logBuf,logRecNum);
+			if(r!=KErrNone)
+				return r;
+			r=aRequest->Write(2,logBuf,0);
+			return r;
+			}
+		case KControlIoGetNumberOfCorruptLogRecords:
+			{
+			TPtrC8 ptrHits((TUint8*)&gNumberOfCorruptHits,sizeof(gNumberOfCorruptHits));
+			TInt r=aRequest->Write(2,ptrHits,0);
+
+			return r;
+			}
+		case KControlIoGetCorruptListFile:
+			{
+			// Get name of file that contains the filenames nominated as "corrupt"
+			TBuf8<KMaxFileName> fileName8;
+			if(gCorruptFileNamesListFile)
+				{
+				fileName8.Copy(*gCorruptFileNamesListFile);
+				}
+			else
+				{
+				fileName8.SetLength(0);
+				}
+			TInt r=aRequest->Write(2,fileName8,0);
+			return r;
+			}
+		case KControlIoCorruptLogRecordReset:
+			{
+			TCorruptLogRec::DestroyList();
+			TCorruptNameRec::ResetListConsumed();
+			return KErrNone;
+			}
+		case KControlIoCacheCount:
+			{
+			TIOCacheValues cacheValues;
+			cacheValues.iCloseCount= RequestAllocator::CloseCount();
+			cacheValues.iFreeCount= RequestAllocator::FreeCount();
+			cacheValues.iAllocated=	RequestAllocator::AllocatedCount();
+			cacheValues.iTotalCount= RequestAllocator::TotalCount();
+			TPckgBuf<TIOCacheValues> pkgBuf(cacheValues);
+
+			// ensure we only write what the client buffer can hold -
+			// this allows TIOCacheValues to increase in size without breaking BC
+			pkgBuf.SetLength(Min(pkgBuf.MaxLength(), aRequest->Message().GetDesMaxLengthL(2)));
+			
+			TInt r=aRequest->Write(2,pkgBuf);
+			return r;
+			}
+		case KControlIoGetLocalDriveNumber:
+			{
+			return DriveNumberToLocalDriveNumber(aRequest->Drive()->DriveNumber());
+			}
+		case KControlIoCancelDeferredDismount:
+			{
+			// Cancel and clear deferred dismount information
+			aRequest->Drive()->ClearDeferredDismount();
+			return KErrNone;
+			}
+		case KControlIoFileCacheStats:
+			{
+			CCacheManager* manager = CCacheManagerFactory::CacheManager();
+			if (manager == NULL)
+				return KErrNotSupported;
+
+			TFileCacheStats& stats = manager->Stats();
+
+			TPckgBuf<TFileCacheStats> pkgBuf(stats);
+			TInt r=aRequest->Write(2,pkgBuf);
+			return r;
+			}
+		case KControlIoFileCacheConfig:
+			{
+			TInt driveNumber = aRequest->Drive()->DriveNumber();
+
+			TFileCacheSettings::TFileCacheConfig* driveConfig = NULL;
+			TInt r = TFileCacheSettings::GetFileCacheConfig(driveNumber, driveConfig);
+			if (( r != KErrNone) || (driveConfig == NULL))
+				return KErrNotSupported;
+
+			TFileCacheConfig config;
+			config.iDrive = driveConfig->iDrive;
+			config.iFlags = driveConfig->iFlags;
+			config.iFileCacheReadAsync = driveConfig->iFileCacheReadAsync;
+			config.iFairSchedulingLen = driveConfig->iFairSchedulingLen;
+			config.iCacheSize = driveConfig->iCacheSize;
+			config.iMaxReadAheadLen = driveConfig->iMaxReadAheadLen;
+			config.iClosedFileKeepAliveTime = driveConfig->iClosedFileKeepAliveTime;
+			config.iDirtyDataFlushTime = driveConfig->iDirtyDataFlushTime;
+
+			TPckgBuf<TFileCacheConfig> pkgBuf(config);
+			r=aRequest->Write(2,pkgBuf);
+			return r;
+			}
+		case KControlIoFileCacheFlagsWrite:
+			{
+			TInt drive = aRequest->Message().Int0();
+
+			TPckgBuf<TFileCacheFlags> driveFlagsPkg;
+			TFileCacheFlags& driveFlags = driveFlagsPkg();
+
+			TInt r = aRequest->Read(2, driveFlagsPkg);
+			if (r != KErrNone)
+				return r;
+
+			__CACHE_PRINT2(_L("CACHE: TFileCacheFlags %x on drive %d"), driveFlags, drive);
+			TFileCacheSettings::SetFlags(drive, driveFlags);
+
+			return r;
+			}
+		case KControlIoFlushClosedFiles:
+			{
+			TClosedFileUtils::Remove();
+			return KErrNone;
+			}
+		case KControlIoSimulateLockFailureMode:
+			{
+			TPckgBuf<TBool> enabledPkg;
+			TInt r = aRequest->Read(2, enabledPkg);
+			if (r != KErrNone)
+				return r;
+
+			CCacheManager* manager = CCacheManagerFactory::CacheManager();
+			if (manager == NULL)
+				return KErrNotSupported;
+			manager->SimulateLockFailureMode(enabledPkg());
+			return KErrNone;
+			}
+		case KControlIoSimulateFileCacheWriteFailure:
+			{
+			CCacheManager* manager = CCacheManagerFactory::CacheManager();
+			if (manager == NULL)
+				return KErrNotSupported;
+			manager->SimulateWriteFailure();
+			return KErrNone;
+			}
+		case KControlIoFileCacheDump:
+			{
+			CCacheManager* manager = CCacheManagerFactory::CacheManager();
+			if (manager == NULL)
+				return KErrNotSupported;
+			manager->DumpCache();
+			return KErrNone;
+			}
+		case KControlIoAllocateMaxSegments:
+			{
+			TPckgBuf<TBool> enabledPkg;
+			TInt r = aRequest->Read(2, enabledPkg);
+			if (r != KErrNone)
+				return r;
+
+			CCacheManager* manager = CCacheManagerFactory::CacheManager();
+			if (manager == NULL)
+				return KErrNotSupported;
+			manager->AllocateMaxSegments(enabledPkg());
+			return KErrNone;
+			}
+		case KControlIoDisableFatUtilityFunctions:
+			{
+			EnableFatUtilityFunctions = EFalse;
+			return KErrNone;
+			}
+		case KControlIoEnableFatUtilityFunctions:
+			{
+			EnableFatUtilityFunctions = ETrue;
+			return KErrNone;
+			}
+		}
+#endif
+
+	return(aRequest->Drive()->ControlIO(aRequest->Message(),command,param1,param2));
+	}
+
+TInt TFsControlIo::Initialise(CFsRequest* aRequest)
+//
+// General purpose test interface - .FSY specific.
+// Not in the release build
+//
+	{
+	TInt driveNumber=aRequest->Message().Int0();
+	if(driveNumber<0||driveNumber>=KMaxDrives)
+		return(KErrArgument);
+	ValidateDriveDoSubst(driveNumber,aRequest);
+	return KErrNone;
+	}
+