os/kernelhwsrv/userlibandfileserver/fileserver/smassstorage/cmassstoragefilesystem.cpp
First public contribution.
1 // Copyright (c) 2004-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // CMassStorageFileSystem implementation.
24 #include "cmassstoragefilesystem.h"
25 #include "cmassstoragemountcb.h"
26 #include "massstoragedebug.h"
27 #include "massstorage.h"
29 _LIT(KMsFsyName, "MassStorageFileSystem");
30 _LIT(KMsThreadName, "MassStorageThread");
31 _LIT(KMsDeadThreadName, "MassStorageDeadThread");
32 _LIT(KMsFsysSemName, "MassStorageSemaphore");
33 LOCAL_D const TInt KMsFsyMajorVersionNumber=1;
34 LOCAL_D const TInt KMsFsyMinorVersionNumber=0;
36 CMassStorageFileSystem::CMassStorageFileSystem()
40 CMassStorageFileSystem::~CMassStorageFileSystem()
42 //Kill the controller thread if it exists
43 delete iMassStorageController;
46 TInt err = thread.Open(KMsThreadName);
49 thread.Kill(1); //Parameter is irrelevant
55 CMassStorageFileSystem* CMassStorageFileSystem::NewL()
57 CMassStorageFileSystem* self = new (ELeave) CMassStorageFileSystem();
58 CleanupStack::PushL(self);
60 CleanupStack::Pop(self);
64 void CMassStorageFileSystem::ConstructL()
66 iMediaChanged = new(ELeave) CArrayFixFlat<TBool>(KMaxDrives);
70 Set the file system version and name
72 @return Any of the standard Symbian error codes.
74 TInt CMassStorageFileSystem::Install()
76 __PRINT(_L("CMassStorageFileSystem::Install In\n"));
77 iVersion=TVersion(KMsFsyMajorVersionNumber, KMsFsyMinorVersionNumber, KF32BuildVersionNumber);
78 TInt err = SetName(&KMsFsyName);
79 __PRINT(_L("CMassStorageFileSystem::Install Out\n"));
83 TInt CMassStorageFileSystem::Remove()
85 __PRINT(_L("CMassStorageFileSystem::Remove In\n"));
89 // Try connecting to the server to send a shutdown message.
90 // - If the class controller has a session in use, this will return KErrInUse
91 RUsbMassStorage usbMs;
92 err = usbMs.Connect();
95 err = usbMs.Shutdown();
100 User::WaitForRequest(iThreadStat);
101 err = iThreadStat.Int();
105 __PRINT1(_L("CMassStorageFileSystem::Remove Shutdown Error %d\n"),err);
110 __PRINT1(_L("CMassStorageFileSystem::Remove Connect Error %d\n"),err);
113 __PRINT(_L("CMassStorageFileSystem::Remove Out\n"));
118 Creates a new Mass Storage mount object.
120 @return A new CMassStorageMountCB
121 @leave KErrNotReady if the Mass Storage controller is not running.
123 CMountCB* CMassStorageFileSystem::NewMountL() const
127 User::Leave(KErrNotReady);
129 return CMassStorageMountCB::NewL(iMsDrives);
133 Sets the media attributes and type in the aInfo parameter to those of the specified drive.
135 @param anInfo TDriveInfo object to store the drive information.
136 @param aDriveNumber The number of the drive to get the information from.
138 void CMassStorageFileSystem::DriveInfo(TDriveInfo& aInfo, TInt aDriveNumber) const
140 __PRINT(_L("CMassStorageFileSystem::DriveInfo In\n"));
141 TLocalDriveCapsV2Buf caps;
142 if (!IsValidLocalDriveMapping(aDriveNumber))
146 (void)GetLocalDrive(aDriveNumber).Caps(caps);
147 // error ignored as Caps always returns valid Media and Drive attributes
148 aInfo.iMediaAtt=caps().iMediaAtt;
149 aInfo.iType = ::EMediaNotPresent; // Media is not available to the file system
150 aInfo.iDriveAtt=caps().iDriveAtt;
151 __PRINT(_L("CMassStorageFileSystem::DriveInfo Out\n"));
155 Returns a reference to the Mass Storage controller.
157 @return Reference to the Mass Storage controller.
159 CUsbMassStorageController& CMassStorageFileSystem::Controller()
161 return *iMassStorageController;
165 Fill iMsDrives with a mapping of lun->drive number for supported mass storage drives
168 TInt CMassStorageFileSystem::EnumerateMsDrivesL()
170 __PRINT(_L("CMassStorageFileSystem::EnumerateMsDrives In\n"));
174 TLocalDriveCapsV2Buf caps;
175 for (TInt i = EDriveC; i < KMaxDrives; i++)
179 if (IsValidLocalDriveMapping(i))
181 TInt err = GetLocalDrive(i).Caps(caps);
182 TInt locDrvNum = DriveNumberToLocalDriveNumber(i);
183 __PRINT2(_L("Caps: err=%d, att=%d\n"), err, caps().iDriveAtt);
185 TBool isRemovable = err==KErrNotReady || (caps().iDriveAtt & KDriveAttRemovable);
186 __PRINT2(_L("EnumerateMsDrives: Drive %c: is %sremovable\n"),
188 isRemovable?_S(""):_S("NOT "));
193 // STF: Connect to the local drive here. This gives us the media changed flag, and
194 // our own TBusLocalDrive object for use by the proxy drive and controller.
196 TBool& mediaChanged = (*iMediaChanged).ExtendL();
197 mediaChanged = EFalse;
198 TBusLocalDrive* localDrive = new(ELeave) TBusLocalDrive;
199 iLocalDriveForMediaFlag.Append(*localDrive);
201 TInt err=iLocalDriveForMediaFlag[driveCount].Connect(locDrvNum, mediaChanged);
211 __PRINT1(_L("CMassStorageFileSystem::EnumerateMsDrives Out, %d MS drives found\n"), driveCount);
215 TBool CMassStorageFileSystem::IsExtensionSupported() const
221 Creates a TrapCleanup and ActiveScheduler and initializes the Mass Storage controller.
222 Start the ActiveScheduler.
224 @return Any of the standard Symbian error codes.
226 TInt CMassStorageFileSystem::InitThread()
228 __PRINT(_L("CMassStorageFileSystem::InitThread In\n"));
230 //Give the thread a name so we can kill it later
231 User::RenameThread(KMsThreadName);
233 CTrapCleanup* cleanup = CTrapCleanup::New();
239 TRAPD(err, InitThreadL());
243 __PRINT1(_L("CMassStorageFileSystem::InitThread Out, error=%d\n"), err);
247 TInt CMassStorageFileSystem::InitThreadL()
249 __PRINT(_L("CMassStorageFileSystem::InitThreadL In\n"));
251 RSemaphore gSemThreadReady;
253 TInt ret = gSemThreadReady.OpenGlobal(KMsFsysSemName);
255 if (ret != KErrNone && ret != KErrAlreadyExists)
260 // Determine which drives are available for Mass Storage.
261 // (this also creates a local TBusLocalDrive for use by the drive controller)
262 EnumerateMsDrivesL();
264 CActiveScheduler* sched = new CActiveScheduler;
267 gSemThreadReady.Signal();
268 User::Leave(KErrNoMemory);
270 CleanupStack::PushL(sched);
271 CActiveScheduler::Install(sched);
273 iMassStorageController = new CUsbMassStorageController;
274 if (iMassStorageController == NULL)
276 gSemThreadReady.Signal();
277 User::Leave(KErrNoMemory);
280 __PRINT(_L("CMassStorageFileSystem::InitThread: Creating Mass Storage Controller\n"));
281 TRAPD(err, iMassStorageController->CreateL(iMsDrives));
284 gSemThreadReady.Signal();
285 CActiveScheduler::Install(NULL);
289 CleanupStack::Pop(sched);
292 gSemThreadReady.Signal();
293 gSemThreadReady.Close();
294 CActiveScheduler::Start();
296 //========= stop thread ================
297 delete iMassStorageController;
298 iMassStorageController = NULL;
300 for (;i<iLocalDriveForMediaFlag.Count();i++)
302 iLocalDriveForMediaFlag[i].Disconnect();
304 iLocalDriveForMediaFlag.Reset();
305 (*iMediaChanged).Reset();
309 __PRINT(_L("CMassStorageFileSystem::InitThread Out\n"));
314 Not supported in Mass Storage file system.
318 CFileCB* CMassStorageFileSystem::NewFileL() const
320 __PRINT(_L("CMassStorageFileSystem::NewFileL In\n"));
321 User::Leave(KErrNotReady);
326 Not supported in Mass Storage file system.
330 CDirCB* CMassStorageFileSystem::NewDirL() const
332 User::Leave(KErrNotReady);
337 Not supported in Mass Storage file system.
341 CFormatCB* CMassStorageFileSystem::NewFormatL() const
343 User::Leave(KErrNotReady);
348 Not supported in Mass Storage file system.
350 @return KErrNotSupported
352 TInt CMassStorageFileSystem::DefaultPath(TDes& /*aPath*/) const
354 return KErrNotSupported;
358 Not supported in Mass Storage file system.
360 @return KErrNotSupported
362 TInt CMassStorageFileSystem::DriveList(TDriveList& /*aList*/) const
364 return KErrNotSupported;
370 LOCAL_C TInt MsInitThreadFn(TAny* aPtr)
372 User::SetCritical(User::ESystemCritical);
373 ((CMassStorageFileSystem*)aPtr)->InitThread();
374 //Rename the thread so we can create a new one with the same original name later
375 User::RenameThread(KMsDeadThreadName);
380 Standard entry point for file systems.
381 Creates a new file system object and starts a new thread for the Mass Storage controller.
383 extern "C" EXPORT_C CFileSystem* CreateFileSystem()
385 __PRINT(_L("CMassStorageFileSystem::CreateFileSystem In\n"));
386 RSemaphore gSemThreadReady;
387 TInt err = gSemThreadReady.CreateGlobal(KMsFsysSemName, 0);
390 __PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out Semaphore Error %d\n"),err);
394 CFileSystem* msFsys = NULL;
395 TRAP(err, msFsys = CMassStorageFileSystem::NewL());
398 __PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out MSFS Error %d\n"),err);
399 gSemThreadReady.Close();
404 __PRINT(_L("CMassStorageFileSystem::CreateFileSystem: Creating Mass Storage thread\n"));
405 err = msThread.Create(KMsThreadName, MsInitThreadFn, KDefaultStackSize, NULL, msFsys);
408 __PRINT1(_L("CMassStorageFileSystem::CreateFileSystem Out Thread Error %d\n"),err);
409 gSemThreadReady.Close();
412 ((CMassStorageFileSystem*)msFsys)->iInstalled=ETrue;
415 msThread.Logon(((CMassStorageFileSystem*)msFsys)->iThreadStat);
417 gSemThreadReady.Wait();
418 gSemThreadReady.Close();
421 __PRINT(_L("CMassStorageFileSystem::CreateFileSystem Out Clean\n"));