0
|
1 |
// Copyright (c) 1998-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 |
|
|
15 |
/**
|
|
16 |
@file
|
|
17 |
@internalTechnology
|
|
18 |
*/
|
|
19 |
|
|
20 |
#include <e32cmn.h>
|
|
21 |
#include <f32ver.h>
|
|
22 |
#include <u32std.h>
|
|
23 |
#include <f32file.h>
|
|
24 |
|
|
25 |
|
|
26 |
|
|
27 |
#include "filesystem_automounter.h"
|
|
28 |
#include "automounter.h"
|
|
29 |
|
|
30 |
|
|
31 |
//-----------------------------------------------------------------------------
|
|
32 |
|
|
33 |
void Fault(TFault aFault)
|
|
34 |
{
|
|
35 |
_LIT(KPanicName, "AutoMounter_fsy");
|
|
36 |
User::Panic(KPanicName, aFault);
|
|
37 |
}
|
|
38 |
|
|
39 |
|
|
40 |
//-----------------------------------------------------------------------------
|
|
41 |
|
|
42 |
/**
|
|
43 |
Factory function, Create a new object of this file system
|
|
44 |
*/
|
|
45 |
extern "C"
|
|
46 |
{
|
|
47 |
EXPORT_C CFileSystem* CreateFileSystem()
|
|
48 |
{
|
|
49 |
return CAutoMounterFileSystem::New();
|
|
50 |
}
|
|
51 |
}
|
|
52 |
|
|
53 |
|
|
54 |
//#######################################################################################################################################
|
|
55 |
//# CAutoMounterFileSystem class implementation
|
|
56 |
//#######################################################################################################################################
|
|
57 |
|
|
58 |
/**
|
|
59 |
Factory method
|
|
60 |
*/
|
|
61 |
CAutoMounterFileSystem* CAutoMounterFileSystem::New()
|
|
62 |
{
|
|
63 |
CAutoMounterFileSystem* pThis = new CAutoMounterFileSystem();
|
|
64 |
return pThis;
|
|
65 |
}
|
|
66 |
|
|
67 |
|
|
68 |
CAutoMounterFileSystem::CAutoMounterFileSystem()
|
|
69 |
{
|
|
70 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::CAutoMounterFileSystem() [0x%x]"), this);
|
|
71 |
|
|
72 |
SetState(EInvalid);
|
|
73 |
}
|
|
74 |
|
|
75 |
CAutoMounterFileSystem::~CAutoMounterFileSystem()
|
|
76 |
{
|
|
77 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::~CAutoMounterFileSystem() [0x%x]"), this);
|
|
78 |
}
|
|
79 |
|
|
80 |
//-----------------------------------------------------------------------------
|
|
81 |
|
|
82 |
/**
|
|
83 |
Install iand initialise file system.
|
|
84 |
*/
|
|
85 |
TInt CAutoMounterFileSystem::Install()
|
|
86 |
{
|
|
87 |
|
|
88 |
SetState(ENotInitialised);
|
|
89 |
|
|
90 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::Install() [0x%x]"), this);
|
|
91 |
|
|
92 |
iVersion=TVersion(KF32MajorVersionNumber,KF32MinorVersionNumber,KF32BuildVersionNumber);
|
|
93 |
|
|
94 |
InitialiseFileSystem();
|
|
95 |
|
|
96 |
return SetName(&KFileSystemName_AutoMounter);
|
|
97 |
}
|
|
98 |
|
|
99 |
|
|
100 |
//-----------------------------------------------------------------------------
|
|
101 |
/**
|
|
102 |
Create a new mount control block.
|
|
103 |
This method migh be called by the file server in some unusual cases, when the actual mount is needed only temporarily to get access to the
|
|
104 |
corresponding media driver. E.g. TDrive::ForceRemountDrive()
|
|
105 |
Produce the _default_ file system mount
|
|
106 |
*/
|
|
107 |
CMountCB* CAutoMounterFileSystem::NewMountL() const
|
|
108 |
{
|
|
109 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::NewMountL() [0x%x]"), this);
|
|
110 |
ASSERT(State() == EInitialised);
|
|
111 |
|
|
112 |
__PRINT1(_L("#<<- producing the _default_ filesystem:%S"), &iFSNames[KDefaultFSNo]);
|
|
113 |
|
|
114 |
CFileSystem* pFS = GetChildFileSystem(KDefaultFSNo);
|
|
115 |
ASSERT(pFS);
|
|
116 |
|
|
117 |
return pFS->NewMountL();
|
|
118 |
}
|
|
119 |
|
|
120 |
//-----------------------------------------------------------------------------
|
|
121 |
/**
|
|
122 |
Create a new file.
|
|
123 |
*/
|
|
124 |
CFileCB* CAutoMounterFileSystem::NewFileL() const
|
|
125 |
{
|
|
126 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::NewFileL() [0x%x]"), this);
|
|
127 |
Fault(EMustNotBeCalled);
|
|
128 |
return NULL;
|
|
129 |
}
|
|
130 |
|
|
131 |
//-----------------------------------------------------------------------------
|
|
132 |
/**
|
|
133 |
Create a new directory object
|
|
134 |
*/
|
|
135 |
CDirCB* CAutoMounterFileSystem::NewDirL() const
|
|
136 |
{
|
|
137 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::NewDirL() [0x%x]"), this);
|
|
138 |
Fault(EMustNotBeCalled);
|
|
139 |
return NULL;
|
|
140 |
}
|
|
141 |
|
|
142 |
//-----------------------------------------------------------------------------
|
|
143 |
/**
|
|
144 |
Create a new media formatter
|
|
145 |
*/
|
|
146 |
CFormatCB* CAutoMounterFileSystem::NewFormatL() const
|
|
147 |
{
|
|
148 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::NewFormatL() [0x%x]"), this);
|
|
149 |
Fault(EMustNotBeCalled);
|
|
150 |
return NULL;
|
|
151 |
}
|
|
152 |
|
|
153 |
|
|
154 |
//-----------------------------------------------------------------------------
|
|
155 |
|
|
156 |
#ifdef _DEBUG
|
|
157 |
/**
|
|
158 |
Called by File Server before deleting File System object.
|
|
159 |
*/
|
|
160 |
TInt CAutoMounterFileSystem::Remove()
|
|
161 |
{
|
|
162 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::Remove() [0x%x]"), this);
|
|
163 |
return CFileSystem::Remove();
|
|
164 |
}
|
|
165 |
|
|
166 |
//-----------------------------------------------------------------------------
|
|
167 |
|
|
168 |
/**
|
|
169 |
*/
|
|
170 |
TBool CAutoMounterFileSystem::QueryVersionSupported(const TVersion& aVer) const
|
|
171 |
{
|
|
172 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::QueryVersionSupported() [0x%x]"), this);
|
|
173 |
return CFileSystem::QueryVersionSupported(aVer);
|
|
174 |
}
|
|
175 |
|
|
176 |
#endif
|
|
177 |
|
|
178 |
//-----------------------------------------------------------------------------
|
|
179 |
|
|
180 |
/**
|
|
181 |
Find out if drive extensions are supported. In order to have consistent behaviour, _all_ child
|
|
182 |
file systems shall behave the same way.
|
|
183 |
|
|
184 |
@return ETrue if drive extensions are supported.
|
|
185 |
*/
|
|
186 |
TBool CAutoMounterFileSystem::IsExtensionSupported() const
|
|
187 |
{
|
|
188 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::IsExtensionSupported() [0x%x]"), this);
|
|
189 |
|
|
190 |
ASSERT(State() == EInitialised && iFSNames.Count() > 1);
|
|
191 |
|
|
192 |
|
|
193 |
//-- in debug mode check file systems compatibility: ALL childs must support this feature
|
|
194 |
for(TUint i=0; i<iFSNames.Count(); ++i)
|
|
195 |
{
|
|
196 |
if( !(GetChildFileSystem(i)->IsExtensionSupported()))
|
|
197 |
{
|
|
198 |
DBG_STATEMENT(Fault(EIncompatibleFileSystems));
|
|
199 |
__PRINT(_L("#<<- ::IsExtensionSupported(): Incompatible file sytems!"));
|
|
200 |
return EFalse;
|
|
201 |
}
|
|
202 |
}
|
|
203 |
|
|
204 |
|
|
205 |
return ETrue;
|
|
206 |
}
|
|
207 |
|
|
208 |
//-----------------------------------------------------------------------------
|
|
209 |
|
|
210 |
/**
|
|
211 |
Return the initial default path.
|
|
212 |
*/
|
|
213 |
TInt CAutoMounterFileSystem::DefaultPath(TDes& aPath) const
|
|
214 |
{
|
|
215 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::DefaultPath() [0x%x]"), this);
|
|
216 |
|
|
217 |
aPath=_L("?:\\");
|
|
218 |
aPath[0] = (TUint8) RFs::GetSystemDriveChar();
|
|
219 |
return KErrNone;
|
|
220 |
}
|
|
221 |
|
|
222 |
|
|
223 |
//-----------------------------------------------------------------------------
|
|
224 |
|
|
225 |
/**
|
|
226 |
Additional interfaces support.
|
|
227 |
*/
|
|
228 |
TInt CAutoMounterFileSystem::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput)
|
|
229 |
{
|
|
230 |
|
|
231 |
__PRINT2(_L("#<<- CAutoMounterFileSystem::GetInterface(id:%d) [0x%x]"), aInterfaceId, this);
|
|
232 |
|
|
233 |
switch(aInterfaceId)
|
|
234 |
{
|
|
235 |
//-- It is this filesystem private interface.
|
|
236 |
case EExtendedFunctionality:
|
|
237 |
aInterface = (CFileSystem::MFileSystemExtInterface*)this;
|
|
238 |
return KErrNone;
|
|
239 |
|
|
240 |
//-- a special case for child filesystems.
|
|
241 |
//-- ALL of them must respond to this interface query exactly the same way. I.e. It is impossible
|
|
242 |
//-- to have some of the child FS supporting it and some not.
|
|
243 |
case EProxyDriveSupport:
|
|
244 |
return DoProcessProxyDriveSupport();
|
|
245 |
|
|
246 |
|
|
247 |
default:
|
|
248 |
//-- This is the request to other (child file system) from the file server
|
|
249 |
//-- Actually, this part must never be called. File Server shall query the file system interfaces _after_ mounting the concrete FS
|
|
250 |
//-- calling TDrive::iCurrentMount->FileSystem().GetInterface()
|
|
251 |
ASSERT(0);
|
|
252 |
return CFileSystem::GetInterface(aInterfaceId, aInterface, aInput);
|
|
253 |
|
|
254 |
}
|
|
255 |
}
|
|
256 |
|
|
257 |
|
|
258 |
//-----------------------------------------------------------------------------
|
|
259 |
|
|
260 |
/**
|
|
261 |
Find out if _all_ child file systems support the proxy drive. All childs shall behave exactly the same way.
|
|
262 |
@return KErrNone if all child file systems support proxy drives, or KErrNotSupported if all of them do not.
|
|
263 |
*/
|
|
264 |
TInt CAutoMounterFileSystem::DoProcessProxyDriveSupport()
|
|
265 |
{
|
|
266 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::DoProcessProxyDriveSupport[0x%x]"), this);
|
|
267 |
ASSERT(State() == EInitialised);
|
|
268 |
|
|
269 |
const TUint cnt = iFSNames.Count();
|
|
270 |
ASSERT(cnt > 1);
|
|
271 |
|
|
272 |
|
|
273 |
//-- query the default filesystem #0
|
|
274 |
const TBool bRes = GetChildFileSystem(KDefaultFSNo)->IsProxyDriveSupported();
|
|
275 |
|
|
276 |
//-- query the rest of child filesystems
|
|
277 |
for(TUint i=1; i<cnt; ++i)
|
|
278 |
{
|
|
279 |
const TBool b = GetChildFileSystem(i)->IsProxyDriveSupported();
|
|
280 |
|
|
281 |
if(BoolXOR(b, bRes))
|
|
282 |
Fault(EIncompatibleFileSystems);
|
|
283 |
}
|
|
284 |
|
|
285 |
|
|
286 |
return bRes ? KErrNone : KErrNotSupported;
|
|
287 |
}
|
|
288 |
|
|
289 |
//-----------------------------------------------------------------------------
|
|
290 |
/**
|
|
291 |
Get the child file system name by its index (enumerator).
|
|
292 |
|
|
293 |
@param aFsNumber index of the child FS 0...KMaxTInt
|
|
294 |
@param aFsName on success the child file system name will be placed into this buffer
|
|
295 |
|
|
296 |
@return KErrNone if there is a child FS name with index 'aFsNumber' (child FS 'aFsNumber' is supported by automounter)
|
|
297 |
KErrNotFound if child FS 'aFsNumber' is not supported
|
|
298 |
*/
|
|
299 |
TInt CAutoMounterFileSystem::GetSupportedFileSystemName(TInt aFsNumber, TDes& aFsName) const
|
|
300 |
{
|
|
301 |
__PRINT2(_L("#<<- CAutoMounterFileSystem::GetSupportedFileSystemName[0x%x](%d)"), this, aFsNumber);
|
|
302 |
|
|
303 |
if(aFsNumber == RFs::KRootFileSystem)
|
|
304 |
{//-- this is a name query for "root filesystem" or automounter
|
|
305 |
aFsName = Name(); //-- ourselves
|
|
306 |
return KErrNone;
|
|
307 |
}
|
|
308 |
|
|
309 |
//-- this is a query for one of the child filesystems
|
|
310 |
if((TUint)aFsNumber < iFSNames.Count())
|
|
311 |
{
|
|
312 |
aFsName = iFSNames[aFsNumber];
|
|
313 |
return KErrNone;
|
|
314 |
}
|
|
315 |
|
|
316 |
|
|
317 |
return KErrNotFound;
|
|
318 |
}
|
|
319 |
|
|
320 |
|
|
321 |
//-----------------------------------------------------------------------------
|
|
322 |
/**
|
|
323 |
This is the only factory method that can be called by file server for this file system.
|
|
324 |
In this method the automounter sequentially tries to mount every child and on success produces the corresponding CMountCB object.
|
|
325 |
|
|
326 |
@param apDrive pointer to the TDrive, child FS will need this to access media.
|
|
327 |
@param apFileSystem on return will contain the pointer to the CFileSystem that has produced the proped CMountCB if
|
|
328 |
one of the child file system has recognised the volume.
|
|
329 |
@param aForceMount if ETrue the appropriate child FS (designated by aFsNameHash) will be forcedly mounted on the volume. for volume formatting purposes.
|
|
330 |
@param aFsNameHash if !=0 specifies the file system name, see TVolFormatParam::CalcFSNameHash(). 0 means "file system name is not specified"
|
|
331 |
|
|
332 |
@return pointer to the constructed CMountCB by one of the child file systems (and pointer to this child FS in apFileSystem)
|
|
333 |
NULL if it was impossible to produce proper CMountCB object.
|
|
334 |
|
|
335 |
*/
|
|
336 |
CMountCB* CAutoMounterFileSystem::NewMountExL(TDrive* apDrive, CFileSystem** apFileSystem, TBool aForceMount, TUint32 aFsNameHash)
|
|
337 |
{
|
|
338 |
__PRINT4(_L("#<<- CAutoMounterFileSystem::NewMountExL[0x%x] drv:%d, ForceMount:%d, FSNameHash:0x%x"), this, apDrive->DriveNumber(), aForceMount, aFsNameHash);
|
|
339 |
|
|
340 |
ASSERT(State() == EInitialised && apDrive);
|
|
341 |
|
|
342 |
//-- This method is usually called from the appropriate drive thread; this file system is intended to be bound to
|
|
343 |
//-- removable drives. Having removable drive runnind in the main file server thread means that something is terribly wrongly configured.
|
|
344 |
if(apDrive->IsSynchronous())
|
|
345 |
Fault(EWrongDriveAttributes);
|
|
346 |
|
|
347 |
if(iFSNames.Count() < 2)
|
|
348 |
Fault(EWrongConfiguration);
|
|
349 |
|
|
350 |
|
|
351 |
//-- if aForceMount is true, this means that the TDrive tries mount the filesystem by force for formatting because normal mounting has failed before.
|
|
352 |
//-- in our case it means that the file system on the volume hadn't been recognised by any child FS.
|
|
353 |
//-- aFsNameHash shall designate the file system to be forcedly mounted. Depending on this the appropriat CMounCB object will be produced.
|
|
354 |
//-- if aFsNameHash is 0, i.e. not provided, this method will fail with KErrNotFound because it is impossible to select appropriat child FS.
|
|
355 |
if(aForceMount)
|
|
356 |
{
|
|
357 |
if(aFsNameHash == 0)
|
|
358 |
{//-- the file system to mount forcedly is not specified
|
|
359 |
__PRINT(_L("#<<- Unable to select appropriate child FS for formatting!"));
|
|
360 |
User::Leave(KErrNotFound);
|
|
361 |
}
|
|
362 |
else
|
|
363 |
{//-- try to find appropriate child FS by its name hash
|
|
364 |
CFileSystem *pFS = GetChildFileSysteByNameHash(aFsNameHash);
|
|
365 |
if(!pFS)
|
|
366 |
{
|
|
367 |
__PRINT(_L("#<<- no child FS found by its name hash!"));
|
|
368 |
ASSERT(0);
|
|
369 |
User::Leave(KErrNotFound);
|
|
370 |
}
|
|
371 |
|
|
372 |
CMountCB* pMount = pFS->NewMountL();
|
|
373 |
ASSERT(pMount);
|
|
374 |
|
|
375 |
*apFileSystem = pFS;
|
|
376 |
return pMount;
|
|
377 |
}
|
|
378 |
}//if(aForceMount)
|
|
379 |
|
|
380 |
|
|
381 |
|
|
382 |
//-- try instantiate a new CMountCB depending on the file system on the media
|
|
383 |
|
|
384 |
CMountCB* pMatchedMount;
|
|
385 |
TInt nRes = TryMountFilesystem(apDrive, &pMatchedMount, apFileSystem);
|
|
386 |
|
|
387 |
if(nRes == KErrNone)
|
|
388 |
{
|
|
389 |
ASSERT(pMatchedMount);
|
|
390 |
return pMatchedMount;
|
|
391 |
}
|
|
392 |
|
|
393 |
|
|
394 |
|
|
395 |
User::Leave(nRes);
|
|
396 |
return NULL;
|
|
397 |
}
|
|
398 |
|
|
399 |
//-----------------------------------------------------------------------------
|
|
400 |
/**
|
|
401 |
Initialise this file system. Reads and processes configuration, fills in file system names container, etc.
|
|
402 |
*/
|
|
403 |
void CAutoMounterFileSystem::InitialiseFileSystem()
|
|
404 |
{
|
|
405 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::InitialiseFileSystem() [0x%x]"), this);
|
|
406 |
|
|
407 |
ASSERT(State() == ENotInitialised);
|
|
408 |
|
|
409 |
TInt nRes;
|
|
410 |
|
|
411 |
|
|
412 |
//-- 1. initialise the array of file system names. These names shall be listed in a config string.
|
|
413 |
//-- the config string is taken from estart.txt usually and its format is like this:
|
|
414 |
//-- section: [AutoMounter] and property "FSNames fat,exfat"
|
|
415 |
//-- in debug version a special text property can override the config string. This allows controlling automounter from
|
|
416 |
//-- the test environment.
|
|
417 |
|
|
418 |
TBuf8<0x100> buf(0);
|
|
419 |
TBuf<0x100> fsName;
|
|
420 |
|
|
421 |
|
|
422 |
#ifdef _DEBUG
|
|
423 |
const TUid KSID_Test1={0x10210EB3}; //-- SID of the test that will define and set test property to control volume mounting
|
|
424 |
const TUint KPropKey = 0; //-- property key
|
|
425 |
|
|
426 |
//-- in debug mode the property will override the estart.txt config
|
|
427 |
if(RProperty::Get(KSID_Test1, KPropKey, buf) == KErrNone)
|
|
428 |
{
|
|
429 |
__PRINT(_L("#<<- reading config from the debug propery..."));
|
|
430 |
}
|
|
431 |
else
|
|
432 |
#endif
|
|
433 |
{
|
|
434 |
__PRINT(_L("#<<- reading config from estart.txt..."));
|
|
435 |
_LIT8(KSection, "AutoMounter");
|
|
436 |
_LIT8(KProperty, "FSNames");
|
|
437 |
|
|
438 |
nRes = F32Properties::GetString(KSection, KProperty, buf);
|
|
439 |
if(!nRes)
|
|
440 |
Fault(EPluginInitialise);
|
|
441 |
}
|
|
442 |
|
|
443 |
|
|
444 |
fsName.Copy(buf);
|
|
445 |
__PRINT1(_L("#<<- config:'%S'"), &fsName);
|
|
446 |
|
|
447 |
//-- parse CSV config line and fill in the file system names array
|
|
448 |
const TChar chDelim = ','; //-- token delimiter, comma
|
|
449 |
buf.Trim();
|
|
450 |
TPtrC8 ptrCurrLine(buf);
|
|
451 |
for(TInt i=0; ;++i)
|
|
452 |
{
|
|
453 |
const TInt delimPos = ptrCurrLine.Locate(chDelim);
|
|
454 |
if(delimPos <= 0)
|
|
455 |
{
|
|
456 |
fsName.Copy(ptrCurrLine);
|
|
457 |
}
|
|
458 |
else
|
|
459 |
{
|
|
460 |
TPtrC8 temp(ptrCurrLine.Ptr(), delimPos);
|
|
461 |
fsName.Copy(temp);
|
|
462 |
}
|
|
463 |
|
|
464 |
fsName.Trim();
|
|
465 |
__PRINT2(_L("#<<- child FS[%d]: '%S'"), i, &fsName);
|
|
466 |
|
|
467 |
|
|
468 |
if(fsName.Length() <= 0)
|
|
469 |
Fault(EPluginInitialise);
|
|
470 |
|
|
471 |
//-- check if the FS name being appended is unique
|
|
472 |
for(TUint j=0; j<iFSNames.Count(); ++j)
|
|
473 |
{
|
|
474 |
if(iFSNames[j] == fsName)
|
|
475 |
{
|
|
476 |
Fault(EPluginInitialise);
|
|
477 |
}
|
|
478 |
}
|
|
479 |
|
|
480 |
|
|
481 |
nRes = iFSNames.Append(fsName);
|
|
482 |
ASSERT(nRes ==KErrNone);
|
|
483 |
|
|
484 |
if(delimPos <=0 )
|
|
485 |
break;
|
|
486 |
|
|
487 |
ptrCurrLine.Set(ptrCurrLine.Ptr()+delimPos+1, ptrCurrLine.Length()-delimPos-1);
|
|
488 |
}
|
|
489 |
|
|
490 |
|
|
491 |
SetState(EInitialised);
|
|
492 |
|
|
493 |
//-- 2. check that the file server has all filesystems we need instantiated and stored in a global container
|
|
494 |
TUint cnt = iFSNames.Count();
|
|
495 |
if(cnt < 2)
|
|
496 |
{
|
|
497 |
__PRINT(_L("#<<- ::InitialiseFileSystem(): too few File Systems bound!"));
|
|
498 |
Fault(EPluginInitialise);
|
|
499 |
}
|
|
500 |
|
|
501 |
while(cnt--)
|
|
502 |
{
|
|
503 |
GetChildFileSystem(cnt);
|
|
504 |
}
|
|
505 |
|
|
506 |
|
|
507 |
}
|
|
508 |
|
|
509 |
|
|
510 |
|
|
511 |
//-----------------------------------------------------------------------------
|
|
512 |
/**
|
|
513 |
Tries to find out if some of the child file systems can be mounted on the given volume.
|
|
514 |
|
|
515 |
@param apDrive pointer to the TDrive, child FS will need this to access media.
|
|
516 |
@param on return will contain the pointer to the CMountCB object if some of the childs has decided that it can be mounted.
|
|
517 |
@param apFS on return will contain the pointer to the CFileSystem that has produced the proped CMountCB if
|
|
518 |
|
|
519 |
@return KErrNone on success, otherwise standard error code.
|
|
520 |
|
|
521 |
*/
|
|
522 |
TInt CAutoMounterFileSystem::TryMountFilesystem(TDrive* apDrive, CMountCB** apMount, CFileSystem** apFS)
|
|
523 |
{
|
|
524 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::TryMountFilesystem()[0x%x]"), this);
|
|
525 |
|
|
526 |
const TInt KNumFS = iFSNames.Count();
|
|
527 |
|
|
528 |
ASSERT(State() == EInitialised && (KNumFS >1));
|
|
529 |
|
|
530 |
|
|
531 |
*apMount = NULL;
|
|
532 |
*apFS = NULL;
|
|
533 |
|
|
534 |
|
|
535 |
TInt nRes;
|
|
536 |
TInt cntFS;
|
|
537 |
CMountCB* pMountCB = NULL;
|
|
538 |
CFileSystem* pMatchedFS = NULL;
|
|
539 |
|
|
540 |
for(cntFS=0; cntFS < KNumFS; ++cntFS)
|
|
541 |
{
|
|
542 |
|
|
543 |
__PRINT2(_L("#<<-@@ trying FS[%d]:%S"), cntFS, &iFSNames[cntFS]);
|
|
544 |
|
|
545 |
CFileSystem* pFS = GetChildFileSystem(cntFS); //-- Find current filesystem object in the FileServer's global container
|
|
546 |
|
|
547 |
//-- 2. create CMountCB instance and set it up
|
|
548 |
pMountCB = NULL;
|
|
549 |
|
|
550 |
TRAP(nRes, pMountCB = pFS->NewMountL());
|
|
551 |
if(nRes != KErrNone)
|
|
552 |
{
|
|
553 |
return KErrNoMemory;
|
|
554 |
}
|
|
555 |
|
|
556 |
ASSERT(pMountCB);
|
|
557 |
pMountCB->SetDrive(apDrive);
|
|
558 |
|
|
559 |
|
|
560 |
//-- 2.1 Firstly try using special CMountCB interface to find out if current FS can be mounted on this media
|
|
561 |
nRes = pMountCB->CheckFileSystemMountable();
|
|
562 |
if(nRes == KErrNotSupported)
|
|
563 |
{
|
|
564 |
//-- file system doesn't support this feature,
|
|
565 |
//-- 2.2 try to check the file system by mounting and dismounting later. It can result in some long activity, like FAT scanning etc.
|
|
566 |
TRAP(nRes, pMountCB->MountL(EFalse));
|
|
567 |
pMountCB->Dismounted(); //-- dismount the mountCB, it will be required in dismounted state anyway
|
|
568 |
}
|
|
569 |
|
|
570 |
//-- 2.3 analyse the result of mounting
|
|
571 |
if(nRes != KErrNone)
|
|
572 |
{
|
|
573 |
if(nRes == KErrLocked)
|
|
574 |
{//-- this is a special case; The media (SD card for example) is locked.
|
|
575 |
//-- Pretend that everything is OK and return CMountCB instance that is produced by the _default_ file system.
|
|
576 |
//-- locked media case will be handled by the file server later.
|
|
577 |
ASSERT(cntFS == KDefaultFSNo); //-- the default FS is tried first and must detect the locked media
|
|
578 |
pMatchedFS = pFS;
|
|
579 |
__PRINT(_L("#<<-@@ The media is LOCKED !"));
|
|
580 |
break;
|
|
581 |
}
|
|
582 |
|
|
583 |
//-- failed to mount the file system, most likey it is not recognised
|
|
584 |
pMountCB->Close(); //-- this is a self-destructing object!
|
|
585 |
pMountCB = NULL;
|
|
586 |
__PRINT(_L("#<<-@@ Mount FAILED !"));
|
|
587 |
}
|
|
588 |
else
|
|
589 |
{
|
|
590 |
//-- mounted OK, the file system is recognised
|
|
591 |
__PRINT(_L("#<<-@@ Mount OK!"));
|
|
592 |
|
|
593 |
pMatchedFS = pFS;
|
|
594 |
break;
|
|
595 |
}
|
|
596 |
|
|
597 |
}//for(cntFS=0; cntFS<KNumFS; ++cntFS)
|
|
598 |
|
|
599 |
if(cntFS >= KNumFS)
|
|
600 |
{//-- no one from the FS factories recognised the file system
|
|
601 |
__PRINT1(_L("#<<- ::TryMountFilesystem()[0x%x] No file system recognised!"), this);
|
|
602 |
|
|
603 |
SetName(&KFileSystemName_AutoMounter);
|
|
604 |
return KErrCorrupt;
|
|
605 |
}
|
|
606 |
|
|
607 |
ASSERT(pMountCB && pMatchedFS);
|
|
608 |
*apMount = pMountCB;
|
|
609 |
*apFS = pMatchedFS;
|
|
610 |
|
|
611 |
//-- set this FS name to the name of recognised FS. In this case the automounter "pretends" to be one of the child file systems on
|
|
612 |
//-- successful mounting. This behaviour was considered to be incorrect.
|
|
613 |
//TPtrC fsName = pMatchedFS->Name();
|
|
614 |
//SetName(&fsName);
|
|
615 |
|
|
616 |
return KErrNone;
|
|
617 |
|
|
618 |
}
|
|
619 |
|
|
620 |
//-----------------------------------------------------------------------------
|
|
621 |
/**
|
|
622 |
get the child file system object by the index in file child system names container
|
|
623 |
|
|
624 |
@param aIndex index in the iFSNames
|
|
625 |
@return pointer to the FS object if it is found, NULL otherwise
|
|
626 |
*/
|
|
627 |
CFileSystem* CAutoMounterFileSystem::GetChildFileSystem(TUint aIndex) const
|
|
628 |
{
|
|
629 |
ASSERT(State() == EInitialised && (iFSNames.Count() >1) && aIndex < iFSNames.Count());
|
|
630 |
|
|
631 |
const TDesC& fsName = iFSNames[aIndex]; //-- registered child file system name
|
|
632 |
CFileSystem* pFS = GetFileSystem(fsName); //-- Find filesystem object in the FileServer's global container
|
|
633 |
|
|
634 |
if(!pFS)
|
|
635 |
{
|
|
636 |
__PRINT1(_L("#<<- CAutoMounterFileSystem::GetChildFileSystem() FileServer doesn't have FS:%S Added!"), &fsName);
|
|
637 |
Fault(EFileSysNotAdded);
|
|
638 |
}
|
|
639 |
|
|
640 |
return pFS;
|
|
641 |
}
|
|
642 |
|
|
643 |
//-----------------------------------------------------------------------------
|
|
644 |
/**
|
|
645 |
Find the child file system object by the file system name name hash.
|
|
646 |
@param aFsNameHash FS name hash
|
|
647 |
@return pointer to the FS object if it is found, NULL otherwise
|
|
648 |
*/
|
|
649 |
CFileSystem* CAutoMounterFileSystem::GetChildFileSysteByNameHash(TUint32 aFsNameHash) const
|
|
650 |
{
|
|
651 |
ASSERT(State() == EInitialised && (iFSNames.Count() >1) && aFsNameHash);
|
|
652 |
|
|
653 |
for(TUint i=0; i<iFSNames.Count(); ++i)
|
|
654 |
{
|
|
655 |
if(aFsNameHash == iFSNames.GetStringHash(i))
|
|
656 |
{
|
|
657 |
const TDesC& fsName = iFSNames[i]; //-- registered child file system name
|
|
658 |
__PRINT2(_L("#<<- ::GetChildFileSysteByNameHash() found FsName:%S by hash:0x%x"), &fsName, aFsNameHash);
|
|
659 |
CFileSystem* pFS = GetFileSystem(fsName); //-- Find filesystem object in the FileServer's global container
|
|
660 |
ASSERT(pFS);
|
|
661 |
return pFS;
|
|
662 |
}
|
|
663 |
|
|
664 |
}
|
|
665 |
|
|
666 |
__PRINT1(_L("#<<- ::GetChildFileSysteByNameHash() No FS name found by hash:0x%x"), aFsNameHash);
|
|
667 |
|
|
668 |
return NULL;
|
|
669 |
}
|
|
670 |
|
|
671 |
|
|
672 |
|
|
673 |
|
|
674 |
//#######################################################################################################################################
|
|
675 |
//# XStringArray implementation
|
|
676 |
//#######################################################################################################################################
|
|
677 |
|
|
678 |
XStringArray::XStringArray()
|
|
679 |
{
|
|
680 |
}
|
|
681 |
|
|
682 |
XStringArray::~XStringArray()
|
|
683 |
{
|
|
684 |
Reset();
|
|
685 |
iStrings.Close();
|
|
686 |
}
|
|
687 |
|
|
688 |
//-----------------------------------------------------------------------------
|
|
689 |
void XStringArray::Reset()
|
|
690 |
{
|
|
691 |
iStrings.ResetAndDestroy();
|
|
692 |
}
|
|
693 |
|
|
694 |
//-----------------------------------------------------------------------------
|
|
695 |
const TDesC& XStringArray::operator[](TUint aIndex) const
|
|
696 |
{
|
|
697 |
if(aIndex >= (TUint)iStrings.Count())
|
|
698 |
Panic(EIndexOutOfRange);
|
|
699 |
|
|
700 |
HBufC* des=iStrings[aIndex];
|
|
701 |
return *des;
|
|
702 |
}
|
|
703 |
|
|
704 |
//-----------------------------------------------------------------------------
|
|
705 |
/**
|
|
706 |
Append file system name to the container. The name is converted to upper case.
|
|
707 |
@param aString name descriptor.
|
|
708 |
@return standard error code
|
|
709 |
*/
|
|
710 |
TInt XStringArray::Append(const TDesC& aString)
|
|
711 |
{
|
|
712 |
HBufC* pBuf = aString.Alloc();
|
|
713 |
if(!pBuf)
|
|
714 |
return KErrNoMemory;
|
|
715 |
|
|
716 |
//-- string being appended shall be unique
|
|
717 |
for(TUint i=0; i<Count(); ++i)
|
|
718 |
{
|
|
719 |
if(operator[](i).CompareF(aString) == 0)
|
|
720 |
{
|
|
721 |
ASSERT(0);
|
|
722 |
return KErrNone;
|
|
723 |
}
|
|
724 |
}
|
|
725 |
|
|
726 |
pBuf->Des().UpperCase(); //-- convert the FS name to upper-case in order to correctly calculate hash later
|
|
727 |
return iStrings.Append(pBuf);
|
|
728 |
}
|
|
729 |
|
|
730 |
|
|
731 |
//-----------------------------------------------------------------------------
|
|
732 |
/**
|
|
733 |
Get child FS name hash by index in the names container.
|
|
734 |
@param aIndex name index in the container
|
|
735 |
@return file system name hash (crc32)
|
|
736 |
*/
|
|
737 |
TUint32 XStringArray::GetStringHash(TUint aIndex) const
|
|
738 |
{
|
|
739 |
const TDesC& des = operator[](aIndex);
|
|
740 |
return TVolFormatParam::CalcFSNameHash(des);
|
|
741 |
}
|
|
742 |
|
|
743 |
|
|
744 |
|
|
745 |
void XStringArray::Panic(TPanicCode aPanicCode) const
|
|
746 |
{
|
|
747 |
_LIT(KPanicCat,"XStringArray");
|
|
748 |
User::Panic(KPanicCat, aPanicCode);
|
|
749 |
}
|
|
750 |
|
|
751 |
|
|
752 |
|
|
753 |
|
|
754 |
|
|
755 |
|
|
756 |
|
|
757 |
|
|
758 |
|
|
759 |
|
|
760 |
|
|
761 |
|
|
762 |
|
|
763 |
|
|
764 |
|
|
765 |
|
|
766 |
|
|
767 |
|
|
768 |
|
|
769 |
|
|
770 |
|
|
771 |
|
|
772 |
|
|
773 |
|
|
774 |
|
|
775 |
|
|
776 |
|
|
777 |
|
|
778 |
|
|
779 |
|
|
780 |
|
|
781 |
|