os/kernelhwsrv/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/cmassstoragefilesystem.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // CMassStorageFileSystem implementation.
    15 // 
    16 //
    17 
    18 
    19 
    20 /**
    21  @file
    22  @internalTechnology
    23 */
    24 
    25 #include <e32def.h>
    26 #include <f32ver.h>
    27 #include <f32fsys.h>
    28 
    29 #include "usbmsshared.h"
    30 #include "mstypes.h"
    31 #include "msctypes.h"
    32 #include "mserverprotocol.h"
    33 #include "cusbmassstoragecontroller.h"
    34 #include "cmassstoragefilesystem.h"
    35 #include "cmassstoragemountcb.h"
    36 #include "debug.h"
    37 #include "msdebug.h"
    38 #include "massstorage.h"
    39 
    40 _LIT(KMsFsyName, "MassStorageFileSystem");
    41 _LIT(KMsThreadName, "MassStorageThread");
    42 _LIT(KMsDeadThreadName, "MassStorageDeadThread");
    43 _LIT(KMsFsysSemName, "MassStorageSemaphore");
    44 LOCAL_D const TInt KMsFsyMajorVersionNumber=1;
    45 LOCAL_D const TInt KMsFsyMinorVersionNumber=0;
    46 
    47 CMassStorageFileSystem::CMassStorageFileSystem()
    48 	{
    49     __MSFNLOG
    50 	}
    51 
    52 CMassStorageFileSystem::~CMassStorageFileSystem()
    53 	{
    54     __MSFNLOG
    55 	//Kill the controller thread if it exists
    56 	delete iMassStorageController;
    57 	iMediaChangedStatusList.Close();
    58 	RThread thread;
    59 	TInt err = thread.Open(KMsThreadName);
    60 	if (err == KErrNone)
    61 		{
    62 		thread.Kill(1); //Parameter is irrelevant
    63 		}
    64 	thread.Close();
    65 	iDriveMap.Close();
    66 	}
    67 
    68 CMassStorageFileSystem* CMassStorageFileSystem::NewL()
    69 	{
    70     __MSFNSLOG
    71 	CMassStorageFileSystem*  self = new (ELeave) CMassStorageFileSystem();
    72 	CleanupStack::PushL(self);
    73 	self->ConstructL();
    74 	CleanupStack::Pop(self);
    75 	return self;
    76 	}
    77 
    78 void CMassStorageFileSystem::ConstructL()
    79 	{
    80     __MSFNLOG
    81 	}
    82 
    83 /**
    84 Set the file system version and name
    85 
    86 @return Any of the standard Symbian error codes.
    87 */
    88 TInt CMassStorageFileSystem::Install()
    89 	{
    90     __MSFNLOG
    91 	iVersion=TVersion(KMsFsyMajorVersionNumber, KMsFsyMinorVersionNumber, KF32BuildVersionNumber);
    92 	TInt err = SetName(&KMsFsyName);
    93 	return err;
    94 	}
    95 
    96 TInt CMassStorageFileSystem::Remove()
    97 	{
    98     __MSFNLOG
    99 	TInt err = KErrNone;
   100 	if (iInstalled)
   101 		{
   102 		// Try connecting to the server to send a shutdown message.
   103 		// - If the class controller has a session in use, this will return KErrInUse
   104 		RUsbMassStorage usbMs;
   105 		err = usbMs.Connect();
   106 		if(err == KErrNone)
   107 			{
   108 			err = usbMs.Shutdown();
   109 			usbMs.Close();
   110 
   111 			if(err == KErrNone)
   112 				{
   113 				User::WaitForRequest(iThreadStat);
   114 				err = iThreadStat.Int();
   115 				}
   116 			else
   117 				{
   118 				__PRINT1(_L("CMassStorageFileSystem::Remove Shutdown Error %d\n"),err);
   119 				}
   120 			}
   121 		else
   122 			{
   123 			__PRINT1(_L("CMassStorageFileSystem::Remove Connect Error %d\n"),err);
   124 			}
   125 		}
   126 	return(err);
   127 	}
   128 
   129 /**
   130 Creates a new Mass Storage mount object.
   131 
   132 @return A new CMassStorageMountCB
   133 @leave KErrNotReady if the Mass Storage controller is not running.
   134 */
   135 CMountCB* CMassStorageFileSystem::NewMountL() const
   136 	{
   137     __MSFNSLOG
   138 	if (!iRunning)
   139 		{
   140 		User::Leave(KErrNotReady);
   141 		}
   142 	return CMassStorageMountCB::NewL(iDriveMap);
   143 	}
   144 
   145 /**
   146 Sets the media attributes and type in the aInfo parameter to those of the specified drive.
   147 
   148 @param anInfo TDriveInfo object to store the drive information.
   149 @param aDriveNumber The number of the drive to get the information from.
   150 */
   151 void CMassStorageFileSystem::DriveInfo(TDriveInfo& aInfo, TInt aDriveNumber) const
   152 	{
   153     __MSFNSLOG
   154 	TLocalDriveCapsV2Buf caps;
   155 	if (!IsValidLocalDriveMapping(aDriveNumber))
   156 		{
   157 		return;
   158 		}
   159 	GetLocalDrive(aDriveNumber).Caps(caps);
   160 	aInfo.iMediaAtt=caps().iMediaAtt;
   161     aInfo.iType = ::EMediaNotPresent;  // Media is not available to the file system
   162 	aInfo.iDriveAtt=caps().iDriveAtt;
   163 	}
   164 
   165 /**
   166 Returns a reference to the Mass Storage controller.
   167 
   168 @return Reference to the Mass Storage controller.
   169 */
   170 CUsbMassStorageController& CMassStorageFileSystem::Controller()
   171 	{
   172     __MSFNLOG
   173 	return *iMassStorageController;
   174 	}
   175 
   176 /**
   177 Fill iMsDrives with a mapping of lun->drive number for supported mass storage drives
   178 
   179 */
   180 TInt CMassStorageFileSystem::EnumerateMsDrivesL()
   181 	{
   182     __MSFNLOG
   183 	iDriveMap.Reset();
   184 	TInt driveCount = 0;
   185 
   186 	TLocalDriveCapsV2Buf caps;
   187 
   188 	for (TInt i = EDriveC; i < KMaxDrives; i++)
   189 		{
   190 		caps.FillZ();
   191 
   192 		if (IsValidLocalDriveMapping(i))
   193 			{
   194 			TInt err = GetLocalDrive(i).Caps(caps);
   195 			TInt locDrvNum = DriveNumberToLocalDriveNumber(i);
   196 			__PRINT2(_L("Caps: err=%d, att=%d\n"), err, caps().iDriveAtt);
   197 
   198 			TBool isRemovable = err==KErrNotReady || (caps().iDriveAtt & KDriveAttRemovable);
   199 			__PRINT2(_L("EnumerateMsDrives: Drive %c: is %sremovable\n"),
   200 							'A'+i-EDriveA,
   201 							isRemovable?_S(""):_S("NOT "));
   202 
   203 			if (isRemovable)
   204 				{
   205 				//
   206 				// STF: Connect to the local drive here.  This gives us the media changed flag, and
   207 				//		our own TBusLocalDrive object for use by the proxy drive and controller.
   208                 //
   209 
   210                 TMediaChangedStatus mediaChanged;
   211                 iMediaChangedStatusList.AppendL(mediaChanged);
   212 
   213                 TBool& mediaChangedRef = iMediaChangedStatusList[driveCount].iMediaChanged;
   214 				TInt err = iMediaChangedStatusList[driveCount].iLocalDrive.Connect(locDrvNum, mediaChangedRef);
   215 				if (err == KErrNone)
   216 					{
   217 					iDriveMap.Append(static_cast <TDriveNumber>(i));
   218 					}
   219 				driveCount++;
   220 				}
   221 			}
   222 		}
   223 
   224 	__PRINT1(_L("EnumerateMsDrives Out, %d MS drives found\n"), driveCount);
   225 	return driveCount;
   226 	}
   227 
   228 TBool CMassStorageFileSystem::IsExtensionSupported() const
   229 	{
   230     __MSFNSLOG
   231 	return ETrue;
   232 	}
   233 
   234 /**
   235 Creates a TrapCleanup and ActiveScheduler and initializes the Mass Storage controller.
   236 Start the ActiveScheduler.
   237 
   238 @return Any of the standard Symbian error codes.
   239 */
   240 TInt CMassStorageFileSystem::InitThread()
   241 	{
   242     __MSFNLOG
   243 
   244 	//Give the thread a name so we can kill it later
   245 	User::RenameThread(KMsThreadName);
   246 
   247 	CTrapCleanup* cleanup = CTrapCleanup::New();
   248 	if (cleanup == NULL)
   249 		{
   250 		return KErrNoMemory;
   251 		}
   252 
   253 	TRAPD(err, InitThreadL());
   254 
   255 	delete cleanup;
   256 
   257 	__PRINT1(_L("CMassStorageFileSystem::InitThread Out, error=%d\n"), err);
   258 	return err;
   259 	}
   260 
   261 TInt CMassStorageFileSystem::InitThreadL()
   262 	{
   263     __MSFNLOG
   264 	RSemaphore gSemThreadReady;
   265 	gSemThreadReady.OpenGlobal(KMsFsysSemName);
   266 
   267 	// Determine which drives are available for Mass Storage.
   268 	// (this also creates a local TBusLocalDrive for use by the drive controller)
   269 	EnumerateMsDrivesL();
   270 
   271 	CActiveScheduler* sched = new (ELeave) CActiveScheduler;
   272 	if (sched == NULL)
   273 		{
   274 		gSemThreadReady.Signal();
   275 		User::Leave(KErrNoMemory);
   276 		}
   277 	CleanupStack::PushL(sched);
   278 	CActiveScheduler::Install(sched);
   279 
   280 	iMassStorageController = CUsbMassStorageController::NewL();
   281 	if (iMassStorageController == NULL)
   282 		{
   283 		gSemThreadReady.Signal();
   284 		User::Leave(KErrNoMemory);
   285 		}
   286 
   287 	__PRINT(_L("CMassStorageFileSystem::InitThread: Creating Mass Storage Controller\n"));
   288 	TRAPD(err, iMassStorageController->CreateL(iDriveMap));
   289 	if (err != KErrNone)
   290 		{
   291 		gSemThreadReady.Signal();
   292 		CActiveScheduler::Install(NULL);
   293 		User::Leave(err);
   294 		}
   295 
   296 	CleanupStack::Pop(sched);
   297 
   298 	iRunning = ETrue;
   299 	gSemThreadReady.Signal();
   300 	gSemThreadReady.Close();
   301 	CActiveScheduler::Start();
   302 
   303 //========= stop thread ================
   304 	delete iMassStorageController;
   305 	iMassStorageController = NULL;
   306 
   307 	for (TInt i=0; i < iMediaChangedStatusList.Count(); i++)
   308 		{
   309         iMediaChangedStatusList[i].iLocalDrive.Disconnect();
   310 		}
   311 	iMediaChangedStatusList.Reset();
   312 
   313 	delete sched;
   314 	iRunning = EFalse;
   315 	return KErrNone;
   316 	}
   317 
   318 /**
   319 Not supported in Mass Storage file system.
   320 
   321 @leave KErrNotReady
   322 */
   323 CFileCB* CMassStorageFileSystem::NewFileL() const
   324 	{
   325     __MSFNSLOG
   326 	User::Leave(KErrNotReady);
   327 	return NULL;
   328 	}
   329 
   330 /**
   331 Not supported in Mass Storage file system.
   332 
   333 @leave KErrNotReady
   334 */
   335 CDirCB* CMassStorageFileSystem::NewDirL() const
   336 	{
   337     __MSFNSLOG
   338 	User::Leave(KErrNotReady);
   339 	return NULL;
   340 	}
   341 
   342 /**
   343 Not supported in Mass Storage file system.
   344 
   345 @leave KErrNotReady
   346 */
   347 CFormatCB* CMassStorageFileSystem::NewFormatL() const
   348 	{
   349     __MSFNSLOG
   350 	User::Leave(KErrNotReady);
   351 	return NULL;
   352 	}
   353 
   354 /**
   355 Not supported in Mass Storage file system.
   356 
   357 @return KErrNotSupported
   358 */
   359 TInt CMassStorageFileSystem::DefaultPath(TDes& /*aPath*/) const
   360 	{
   361     __MSFNSLOG
   362 	return KErrNotSupported;
   363 	}
   364 
   365 /**
   366 Not supported in Mass Storage file system.
   367 
   368 @return KErrNotSupported
   369 */
   370 TInt CMassStorageFileSystem::DriveList(TDriveList& /*aList*/) const
   371 	{
   372     __MSFNSLOG
   373 	return KErrNotSupported;
   374 	}
   375 
   376 /**
   377 Thread entry point.
   378 */
   379 LOCAL_C TInt MsInitThreadFn(TAny* aPtr)
   380 	{
   381 	User::SetCritical(User::ESystemCritical);
   382 	((CMassStorageFileSystem*)aPtr)->InitThread();
   383 	//Rename the thread so we can create a new one with the same original name later
   384 	User::RenameThread(KMsDeadThreadName);
   385 	return KErrNone;
   386 	}
   387 
   388 /**
   389 Standard entry point for file systems.
   390 Creates a new file system object and starts a new thread for the Mass Storage controller.
   391 */
   392 extern "C" EXPORT_C CFileSystem* CreateFileSystem()
   393 	{
   394 	__PRINT(_L("CMassStorageFileSystem::CreateFileSystem In\n"));
   395 	RSemaphore gSemThreadReady;
   396 	TInt err = gSemThreadReady.CreateGlobal(KMsFsysSemName, 0);
   397 	if (err != KErrNone)
   398 		{
   399 		__PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out Semaphore Error %d\n"),err);
   400 		return NULL;
   401 		}
   402 
   403 	CFileSystem* msFsys = NULL;
   404 	TRAP(err,  msFsys = CMassStorageFileSystem::NewL());
   405 	if (err != KErrNone)
   406 		{
   407 		__PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out MSFS Error %d\n"),err);
   408 		gSemThreadReady.Close();
   409 		return NULL;
   410 		}
   411 
   412 	RThread msThread;
   413 	__PRINT(_L("CMassStorageFileSystem::CreateFileSystem: Creating Mass Storage thread\n"));
   414 	err = msThread.Create(KMsThreadName, MsInitThreadFn, KDefaultStackSize, NULL, msFsys);
   415 	if (err != KErrNone)
   416 		{
   417 		__PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out Thread Error %d\n"),err);
   418 		gSemThreadReady.Close();
   419 		return msFsys;
   420 		}
   421 	((CMassStorageFileSystem*)msFsys)->iInstalled=ETrue;
   422 
   423 
   424 	msThread.Logon(((CMassStorageFileSystem*)msFsys)->iThreadStat);
   425 	msThread.Resume();
   426 	gSemThreadReady.Wait();
   427 	gSemThreadReady.Close();
   428 	msThread.Close();
   429 
   430 	__PRINT(_L("CMassStorageFileSystem::CreateFileSystem Out Clean\n"));
   431 
   432 	return msFsys;
   433 	}