Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\estart\estart.cpp
15 // Generic startup code run by the fileserver on boot
20 #include <e32std_private.h>
21 #include <e32def_private.h>
24 #include <f32file_private.h>
26 #ifndef SYMBIAN_EXCLUDE_ESTART_DOMAIN_MANAGER
27 #include <domainmanager.h>
30 #include <e32property.h>
40 //-- define this macro in order to have system start time measurement (SYSSTATEMGR.EXE process life time)
41 //#define SYMBIAN_ESTART_OUTPUT_BOOT_TIME
44 TInt LoadCodePageDll();
45 /** Maximum Codepage Dll name length. */
46 const TInt KMaxCodepageDllName=16;
50 TBool DebugTraceEnabled()
55 return UserSvr::DebugMask() & 2;
60 _LIT(KEStartPanicCatagory, "ESTART");
64 ELitNoDM = 1, // No Domain Manager
65 ELitDMInitFail, // Domain Manager init fail
66 ELitHALFail, // HAL init fail
67 ELitConnectFsFail1, // Connect fs 1 fail
68 ELitInitLocalPwStoreFail, // Init PwStore fail
69 ELitLocaleInitialisationFail, // Initialisation of locale properties failed
70 ELitFSInitDriveInfoFail, // FS Init DriveInfo fail
71 ELitCreateTrapHandlerFail, // Create trap handler fail
72 ELitLoadSysLddsFail, // Load sys ldds fail
73 ELitLocalDriveMappingFail, // Local drive mapping fail
74 ELitDriveMappingFileFail, // Drive mapping file not found
75 ELitSwapMappingFailArrayInconsistent, // Swap mappings fail - array inconsistent
76 ELitFsSwapMappingFail, // Swap mappings fail - Fs request failed
77 EPropertyError, // RProperty return error
78 ECompMountFsFail, // Failed comp fs mount
79 EFsNameFail, // File system name on Z: failed
81 EStartupModeFail, // Get startup mode failed
82 ESysAgentFail, // Fail to launch system agent
83 ESetSystemDriveFail // Fail to set System Drive
86 inline void Panic(TEStartPanic aPanic, TInt aReason)
88 TBuf<10> panic(KEStartPanicCatagory);
89 panic.AppendFormat(_L("_%d"), aPanic);
90 User::Panic(panic, aReason);
93 _LIT(KRofs,"erofs.fsy");
94 _LIT(KCompfs,"ecomp.fsy");
96 _LIT(KServerPathSysBin, "0:\\Sys\\Bin\\");
97 _LIT(KSystemAgentName, "z:\\sys\\bin\\SysAgt2Svr.exe");
98 _LIT(KLitLocaleData,"?:\\System\\Data\\LOCALE.D");
99 _LIT(KLocaleDllNameBase, "ELOCL");
100 _LIT(KLocalDriveMappingFile,"Z:\\SYS\\DATA\\ESTART.TXT");
101 _LIT(KWindowServerRootName1,"EWSRV.EXE");
102 _LIT(KSystemStarterName, "z:\\sys\\bin\\SYSSTART.EXE");
103 _LIT(KSystemStateManager, "z:\\sys\\bin\\SYSSTATEMGR.EXE");
105 //const TInt KPatchLddUidValue=0x100000cc; // patch ldds should specify this as their third uid
107 GLDEF_D TBool gMountRofsAlone=ETrue;
108 GLDEF_D TBool gMountComposite=EFalse;
110 enum TCompositeMountSate
117 LOCAL_D TCompositeMountSate gCompositeMountState=ENoMounts;
119 #if !defined(AUTODETECT_DISABLE)
120 LOCAL_D TInt gNCompositeMounts=0;
123 #if defined(__EPOC32__) && defined(__X86__)
124 LOCAL_D TInt gNFloppies=0;
128 ASCII text file reader constructor
130 TText8FileReader::TText8FileReader()
139 ASCII text file reader desctructor
141 TText8FileReader::~TText8FileReader()
144 delete[] iFileDataBuf;
148 Supply an ASCII text file for the file reader.
149 This function reads the entire contents of this file into a buffer, converting to
150 unicode / folding each character. Subsequent parsing of the file data is all done from this
152 @param aFile The file to be read. Must already be opened for read access in EFileStreamText mode.
153 @return KErrNone if no error.
155 TInt TText8FileReader::Set(RFile& aFile)
162 // Read the size of the file
163 TInt r=iFile.Size(iFileSize);
164 if (r!=KErrNone || !iFileSize)
167 // Allocate a buffer to read in the file
168 iFileDataBuf=new TText[iFileSize+1]; // +1 in case need to NULL terminate the end of the last string
169 if (iFileDataBuf==NULL)
170 return(KErrNoMemory);
172 // Read the entire contents of the file into the buffer
175 r=iFile.Seek(ESeekStart,pos);
176 while (pos<iFileSize)
178 if ((r=iFile.Read(iBuf))!=KErrNone)
180 fdata.Set((iFileDataBuf+pos),0,iBuf.Length());
189 Return the next record from the text file.
190 @param aPtr A TPtr which is setup with the address and length of the next record, referencing
191 the data in the reader's buffer.
192 @return KErrNone if a record is successfully loaded into the buffer, KErrEof if the end of the
193 file is encountered, KErrGeneral if a file hasn't been set.
195 TInt TText8FileReader::Read(TPtr& aPtr)
198 // Check that Set() has been called.
202 // Check if we have run into the end of the file
203 TInt bufRemainder=(iFileSize-iBufPos);
207 // Setup the descriptor passed with the next record - don't include the record terminator
208 // The line terminators are CR + LF for DOS
209 // whereas only LF for Unix line endings
210 aPtr.Set((iFileDataBuf+iBufPos),bufRemainder,bufRemainder);
211 TInt len=aPtr.Locate('\n');
212 if (len != KErrNotFound)
215 // Check for DOS line ending to support both DOS and Unix formats
216 if ((len != 0) && (iFileDataBuf[iBufPos-1] == '\r'))
225 // Point iBufPos to the next non-empty line
226 while (iBufPos<iFileSize && (iFileDataBuf[iBufPos]=='\n' || iFileDataBuf[iBufPos]=='\r'))
231 const TInt DefaultLocalDrives[KMaxLocalDrives]=
251 Return the default drive letter for the specified local drive.
252 To alter the default mapping scheme on auto-configuration, override this function.
254 @param aLocalDrive The number of the local drive (0-15).
256 @return The default drive number associated with this local drive.
258 TInt TFSStartup::DefaultLocalDrive(TInt aLocalDrive)
261 return(DefaultLocalDrives[aLocalDrive]);
264 //typedef TInt TLocalDriveList[KMaxLocalDrives];
266 Write the local drive mapping data to the file server. If there is no potential of a drive swap then also commit it.
267 Once committed, the setting cannot be changed.
269 @panic ESTART_10 Error_Code; If unable to set local drive mapping in the file server.
270 Error_Code is the error code returned by RFs::SetLocalDriveMapping()
273 void TFSStartup::SetFServLocalDriveMapping()
276 DEBUGPRINT("SetFServLocalDriveMapping");
277 TLocalDriveMappingInfoBuf mBuf;
278 TLocalDriveMappingInfo& ldmi=mBuf();
279 Mem::Copy(&ldmi.iDriveMapping[0],&iLocalDriveList[0],(KMaxLocalDrives*sizeof(TInt)));
281 // Can't set the mapping yet - if there is the potential of a drive swap .
282 ldmi.iOperation = (iDriveSwapCount) ? TLocalDriveMappingInfo::EWriteMappingsNoSet : TLocalDriveMappingInfo::EWriteMappingsAndSet;
284 TInt r=iFs.SetLocalDriveMapping(mBuf);
285 __ASSERT_ALWAYS(r==KErrNone,Panic(ELitLocalDriveMappingFail, r));
289 Swap and commit the file server's local drive mapping data. Change the local drive mapping info already set with the file server.
291 @param aFirstDrive First Drive number to be swapped.
292 @param aSecondDrive Second Drive number to be swapped.
294 @panic ESTART_13 Error_Code; if unable to set the local drive mapping to file server.
295 Error_Code is the error code returned by RFs::SetLocalDriveMapping()
297 void TFSStartup::SwapFServLocalDriveMapping(TInt aFirstDrive,TInt aSecondDrive)
300 DEBUGPRINT("SwapFServLocalDriveMapping");
301 TLocalDriveMappingInfoBuf mBuf;
302 TLocalDriveMappingInfo& ldmi=mBuf();
303 ldmi.iDriveMapping[0]=aFirstDrive;
304 ldmi.iDriveMapping[1]=aSecondDrive;
305 ldmi.iOperation=TLocalDriveMappingInfo::ESwapIntMappingAndSet;
306 TInt r=iFs.SetLocalDriveMapping(mBuf);
307 __ASSERT_ALWAYS(r==KErrNone,Panic(ELitFsSwapMappingFail,r));
312 // Warning - File format changes must be replicated in EikSrv.
316 TCurrencySymbol iCurrency;
320 Attempt to open the locale data file from system drive. If found, read the
321 locale and currency symbol data from this file and transfer it to 'the system'.
323 @return KErrNone if successful.
325 TInt TFSStartup::LoadLocale()
327 // Append the language index to the standard locale filename.
328 TFileName filename(KLitLocaleData);
329 filename[0] = (TUint8) RFs::GetSystemDriveChar();
331 if (HAL::Get(HAL::ELanguageIndex,lang) == KErrNone)
333 filename.AppendNumFixedWidth(lang,EDecimal,2);
334 HAL::Set(HAL::ELocaleLoaded, lang);
337 // Attempt to open the file, read/set the data.
339 if (file.Open(iFs,filename,EFileRead) == KErrNone)
341 TPckgBuf<TLocData> data;
342 if( file.Read(data) == KErrNone && data.Size()==sizeof(TLocData))
344 data().iLocale.Set();
345 TInt offset = data().iLocale.UniversalTimeOffset().Int();
346 if (data().iLocale.QueryHomeHasDaylightSavingOn())
348 User::SetUTCOffset(offset);
349 User::SetCurrencySymbol(data().iCurrency);
359 @return KErrNone if successful.
360 KErrNotFound if locale DLL not found.
361 Or other system wide error code.
365 TBuf<16> localeDllName;
368 TInt error=HAL::Get(HALData::ELanguageIndex,languageIndex);
370 error = KErrNotFound;
373 TBuf<6> extension; // Dot plus five digit locale
374 _LIT(KExtension,".%u");
375 extension.Format(KExtension, languageIndex);
376 if (extension.Length()<3) // Padd ".1" to ".01" for compatibility.
379 extension.Insert(1,KPadding);
381 localeDllName=KLocaleDllNameBase;
382 localeDllName.Append(extension);
383 error = UserSvr::ChangeLocale(localeDllName);
385 if (error==KErrNotFound)
387 // Try default locale
388 _LIT(KLocaleDllNameExtension, ".LOC");
389 localeDllName=KLocaleDllNameBase;
390 localeDllName.Append(KLocaleDllNameExtension);
391 error = UserSvr::ChangeLocale(localeDllName);
393 if (error == KErrNone)
400 Search for a saved HAL file - containing a series of saved HAL attributes.
401 If found, initialise each attribute saved.
403 @return KErrNone if successful; KErrGeneral if the exe panicked.
405 TInt TFSStartup::InitialiseHAL()
408 TInt result = process.Create(_L("HALSettings.exe"), _L("INITIALISE"));
409 if(result != KErrNone)
411 TRequestStatus status;
412 process.Logon(status);
413 if (status != KRequestPending)
414 process.Kill(0); // abort
416 process.Resume(); // logon OK
417 User::WaitForRequest(status);
419 // Special case to ensure the nonsecure clock offset set function gets called
421 result = HAL::Get(HAL::ETimeNonSecureOffset,nsc_offset);
422 if (result == KErrNone)
424 HAL::Set(HAL::ETimeNonSecureOffset,nsc_offset); // this will only succeed when hal.dat is missing and the function wasnt called by halsettings.exe
428 // we can't use the 'exit reason' if the exe panicked as this
429 // is the panic 'reason' and may be '0' which cannot be distinguished
431 result = process.ExitType() == EExitPanic ? KErrGeneral : status.Int();
437 Create and resume a server. Start without specifying a path.
438 If this fails, then systematically try to start it from
439 each valid drive in turn (Y: - A:, then Z:).
440 The second phase is to handle the sitation where a version
441 of the executable is found on a drive early in the search order
442 (e.g. C:) - that fails to load. Rather than failing the load
443 on the 1st error, this function keeps going through all the valid drives.
445 @param aDrives The drive list, to determine which are valid.
446 @param aRootName The root name of the executable.
448 @return ETrue if the server was eventually created successfully, EFalse if not.
450 TBool TFSStartup::CreateServer(const TDriveList& aDrives, const TDesC& aRootName)
453 TInt r=ws.Create(aRootName, KNullDesC);
457 name = KServerPathSysBin();
462 i= (i==0) ? EDriveZ : i-1;
463 if (aDrives[i]!=KDriveAbsent) // Got a valid drive
465 name[0]=(TText)('A'+i); // Set the drive letter
466 r=ws.Create(name,KNullDesC);
480 _LIT(KProfilerName,"profiler.exe");
481 _LIT(KProfilerCmd,"start");
485 void TFSStartup::StartProfiler()
488 TInt r=p.Create(KProfilerName,KProfilerCmd);
497 #if !defined(AUTODETECT_DISABLE)
499 FSY detection function for the local FSY (assumed to be FAT). This will return success for MMC,
500 ATA, Floppy and IRAM devices that are FAT formatted. Will also return success for any drive
501 (other than those designated for CD ROMs) which isn't ready - assuming these to be removable FAT
502 formatted devices. For floppy devices detected on the X86 build, we need to change the drive
503 mapping so that these are mounted on drives A: or B:.
505 GLDEF_C TInt DetectELocal(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
510 if (cr==KErrNotReady && caps.iType != EMediaCdRom)
512 #if defined(__EPOC32__) && defined(__X86__)
513 // For FDD iEraseBlockSize top 16 bits is sectors per track
514 if (caps.iType==EMediaFloppy && (caps.iEraseBlockSize>>16))
519 // Change the default mapping to A: or B:
520 TInt ret = gNFloppies ? EDriveB : EDriveA;
522 return KFsDetectMappingChangeReturnOffset + ret;
527 return KErrNone; // Removable and not ready - assume fat
529 if(cr == KErrCorrupt && ld.IsRemovable(socknum)) // Removable and media corrupt - assume fat
533 if (caps.iType!=EMediaFloppy && caps.iType!=EMediaHardDisk)
535 if (cr==KErrNone && (PartitionIsFAT32(caps.iPartitionType) || PartitionIsFAT(caps.iPartitionType)) )
537 #if defined(__EPOC32__) && defined(__X86__)
538 if (cr!=KErrNotSupported && caps.iType==EMediaFloppy && (caps.iEraseBlockSize>>16))
547 FSY detection function for the local FSY (assumed to be FAT) running over internal RAM. This will
548 return success for any drive containing RAM media which reports a FAT16 partition type.
550 GLDEF_C TInt DetectIRam(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
554 if (caps.iType==EMediaRam && caps.iPartitionType==KPartitionTypeFAT16)
560 FSY detection function for the local FSY (assumed to be FAT) running over a NAND FTL. This will
561 return success for any drive containing NAND media which reports a FAT16 partition type.
563 GLDEF_C TInt DetectFtl(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
567 if (caps.iType==EMediaNANDFlash && caps.iPartitionType==KPartitionTypeFAT16)
573 FSY detection function for the ROFS FSY. This will return success for any drive containing NAND
574 media which reports a ROFS partition type as long as the ROFS FSY is present - but not the Composite FSY
576 GLDEF_C TInt DetectRofs(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
580 if ((caps.iType==EMediaNANDFlash) && caps.iPartitionType==KPartitionTypeRofs && gMountRofsAlone)
586 FSY detection function for the Composite FSY. This will return success for the 1st drive containing NAND
587 media which reports a ROFS partition type as long as both the ROFS and Composite FSYs are present. We
588 change the DRIVE mapping so that this is mounted on drive Z:. Any subsequent ROFS partitions detected
589 can be mounted as ROFS.
591 GLDEF_C TInt DetectComposite(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
595 if ((caps.iType==EMediaNANDFlash) && caps.iPartitionType==KPartitionTypeRofs && gMountComposite)
597 if (!gNCompositeMounts)
600 gMountRofsAlone=ETrue; // Any further ROFS drives found can be mounted as such
601 return(KFsDetectMappingChangeReturnOffset+EDriveZ);
608 FSY detection function for the LFFS FSY. This will return success for any drive containing NOR
609 media which reports an LFFS partition type.
611 GLDEF_C TInt DetectEneaLFFS(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
615 if (caps.iType==EMediaFlash && caps.iPartitionType==KPartitionTypeEneaLFFS)
621 FSY detection function for the ISO 9660 FSY (X86 only). This will return success for CD ROM
624 GLDEF_C TInt DetectIso9660(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
628 if (caps.iType == EMediaCdRom)
634 FSY detection function for the NTFS FSY (X86 only). This will return success for any drive
635 containing a hard disk device which reports an NTFS partition type.
637 GLDEF_C TInt DetectNtfs(RLocalDrive ld, TInt cr, TLocalDriveCapsV2& caps)
641 if (caps.iType==EMediaHardDisk && PartitionIsNTFS(caps.iPartitionType))
650 @param aDrive The number of the drive to be formatted (0-25).
652 @return KErrNone if no error otherwise one of the other system wide error codes.
654 TInt TFSStartup::FormatDrive(TInt aDrive)
656 TBuf<2> driveName(_S("A:"));
657 driveName[0] = (TText)(aDrive+'A');
660 TInt d = format.Open(iFs, driveName, EHighDensity, count);
661 DEBUGPRINT2("FormatOpen %S -> %d", &driveName, d);
664 ShowFormatProgress(count, aDrive);
668 while (d==KErrNone && count)
671 if (lastCount != count)
672 DEBUGPRINT1("Format count %d", count);
675 d=format.Next(count);
676 ShowFormatProgress(count, aDrive);
679 DEBUGPRINT1("Format complete %d", d);
684 Set System Drive if defined either in ESTART.TXT or in HALData::ESystemDrive
686 void TFSStartup::SetSystemDrive()
688 DEBUGPRINT("TFSStartup::SetSystemDrive");
689 for(TInt i=0; i<iMapCount; i++)
691 if(iDriveMappingInfo[i].iFsInfo.iFlags&FS_SYSTEM_DRIVE)
693 TInt err = iFs.SetSystemDrive((TDriveNumber)iDriveMappingInfo[i].iDriveNumber);
694 DEBUGPRINT3("SetSystemDrive from FILE [%d], %d, err:%d", i, iDriveMappingInfo[i].iDriveNumber, err);
695 __ASSERT_ALWAYS(err==KErrNone, Panic(ESetSystemDriveFail, err));
699 TInt drive = KErrNotFound;
700 TInt err = HAL::Get(HAL::ESystemDrive, drive);
701 if(err == KErrNone && drive >= EDriveA && drive <= EDriveZ)
703 err = iFs.SetSystemDrive((TDriveNumber)drive);
704 DEBUGPRINT2("SetSystemDrive from HAL %d, err:%d", drive, err);
705 __ASSERT_ALWAYS(err==KErrNone || err==KErrAlreadyExists, Panic(ESetSystemDriveFail, err));
711 Parse the flags field of a drive mapping record that has been read from the drive mapping file.
712 The flags field text is expected to contain one or more flags, each delimited with a "," char.
713 Override this function to support custom drive configuation flags.
715 @param aFlagDesc Non-modifiable descriptor holding the flags record text to be parsed.
716 @param aFlagVar An integer to hold the returned flag settings.
717 @param aSpare An integer to hold any additional info returned.
719 @return Always returns KErrNone (but derived version may not).
721 TInt TFSStartup::ParseMappingFileFlags(const TPtrC& aFlagDesc,TUint32& aFlagVar,TInt& aSpare)
728 TBool endOfFlagDesc=EFalse;
730 while (!endOfFlagDesc && r==KErrNone)
732 ptr.Set(aFlagDesc.Mid(pos));
734 if (len==KErrNotFound)
738 ptr.Set(ptr.Left(len));
741 if (ptr.MatchF(_L("FS_FORMAT_ALWAYS"))!=KErrNotFound)
742 aFlagVar|=FS_FORMAT_ALWAYS;
743 else if (ptr.MatchF(_L("FS_FORMAT_COLD"))!=KErrNotFound)
744 aFlagVar|=FS_FORMAT_COLD;
745 else if (ptr.MatchF(_L("FS_FORMAT_CORRUPT"))!=KErrNotFound)
746 aFlagVar|=FS_FORMAT_CORRUPT;
747 else if (ptr.MatchF(_L("FS_DISMNT_CORRUPT"))!=KErrNotFound)
748 aFlagVar|=FS_DISMNT_CORRUPT;
749 else if (ptr.MatchF(_L("FS_SWAP_CORRUPT*"))!=KErrNotFound)
752 if (iFs.CharToDrive(ptr[len+1],aSpare)==KErrNone && iDriveSwapCount==0) // We only allow one swap
754 aFlagVar|=FS_SWAP_CORRUPT;
758 else if (ptr.MatchF(_L("FS_SYNC_DRIVE"))!=KErrNotFound)
759 aFlagVar|=FS_SYNC_DRIVE;
760 else if (ptr.MatchF(_L("FS_SCANDRIVE"))!=KErrNotFound)
761 aFlagVar|=FS_SCANDRIVE;
762 else if (ptr.MatchF(_L("FS_COMPOSITE"))!=KErrNotFound)
763 aFlagVar|=FS_COMPOSITE;
764 else if (ptr.MatchF(_L("FS_NO_MOUNT"))!=KErrNotFound)
765 aFlagVar|=FS_NO_MOUNT;
766 else if (ptr.MatchF(_L("FS_ALLOW_REM_ACC"))!=KErrNotFound)
767 aFlagVar|=FS_ALLOW_REM_ACC;
768 else if (ptr.MatchF(_L("FS_NOT_RUGGED")) != KErrNotFound)
769 aFlagVar |= FS_NOT_RUGGED;
770 else if (ptr.MatchF(_L("FS_SYSTEM_DRIVE")) != KErrNotFound)
771 aFlagVar |= FS_SYSTEM_DRIVE;
773 r=ParseCustomMountFlags(&ptr,aFlagVar,aSpare);
779 Parse for custom mount flags - default implementation.
780 In either the auto-configuration scheme or the drive mapping file scheme,
781 to add support for additional mount flags, this function needs to be override.
783 @param aFlagPtr The flag text.
784 @param aFlags An integer to hold the returned mount flag settings
785 @param aSpare An integer to hold any additional info returned.
787 @return KErrNone if no error.
789 TInt TFSStartup::ParseCustomMountFlags(TPtrC* /*aFlagPtr*/,TUint32& /*aFlags*/,TInt& /*aSpare*/)
796 Process any custom mount flags - default implementation.
797 In either the auto-configuration scheme or the drive mapping file scheme,
798 to add support for additional mount flags, this function needs to be override.
800 @param aMountRet The value returned when attempting to mount the drive.
801 @param aFlags The mount flags.
802 @param aSpare An integer containing any additional info associated with the flags.
803 @param aDrive The drive number.
805 @return KErrNone if no error.
807 TInt TFSStartup::HandleCustomMountFlags(TInt& /*aMountRet*/,TInt& /*aFlags*/,TInt& /*aSpare*/,TInt /*aDrive*/)
814 Process the local drive field of a drive mapping record
816 @param aDriveDesc The comma seperated local drives
817 @param aDrives An array of drive numbers (return reference)
818 @param aCount The number of local drives found.
820 @return KErrNone if no error, otherwise a System-wide error code.
822 TInt TFSStartup::ParseMappingFileLocalDrive(const TPtrC& aDriveDesc,TUint32 (&aDrives)[KMaxLocalDrives],TInt& aCount)
828 TBool endOfDriveDesc=EFalse;
831 while (!endOfDriveDesc)
833 ptr.Set(aDriveDesc.Mid(pos));
835 if (len==KErrNotFound)
836 endOfDriveDesc=ETrue;
839 ptr.Set(ptr.Left(len));
847 if (lex.BoundedVal(locDrvNum,EDecimal,(KMaxLocalDrives-1))!=KErrNone)
848 return(KErrArgument);
850 if(aCount >= KMaxLocalDrives)
852 aDrives[aCount]=locDrvNum;
860 Parse a drive mapping record that has been read from the drive mapping file.
862 @param aTextLine Modifiable ptr descriptor holding the mapping record text
863 to be parsed. Note that this function will null-terminate
864 any FSY or extension names it detects. This will generally
865 result in the over-writing of the field separator or end of
866 record delimitor but consideration is required where a
867 mapping file ends with such a string.
868 @param anInfo A stucture to hold the returned mapping settings,
869 FSY/ext name string pointers and mounting flags.
871 @return KErrNone if record is successfully parsed and 'anInfo' contains
872 mapping info to be applied.
873 KErrNotFound if the record is a comment line.
874 KErrArgument if the syntax of record is incorrect.
876 TInt TFSStartup::ParseMappingRecord(TPtr& aTextLine,SLocalDriveMappingInfo& anInfo)
881 TInt driveNumber = KDriveInvalid;
882 TUint32 localDriveNums[KMaxLocalDrives];
883 const TText* fsyName = NULL;
884 const TText* objName = NULL;
885 const TText* extName = NULL;
889 // Get all of the above Attributes.
892 token.Set(lex.NextToken());
893 if (token.Length() <= 1 || token[0]=='#') // Blank line or comment line
894 return(KErrNotFound);
897 if (token[1]!=':' || iFs.CharToDrive(token[0],driveNumber)!=KErrNone)
898 return(KErrArgument);
900 // Local drive number(s)
902 token.Set(lex.NextToken());
903 TInt localDriveCount = 0;
904 TInt err = ParseMappingFileLocalDrive(token,localDriveNums,localDriveCount);
909 if(localDriveCount==0)
915 TPtr fileName(NULL,0);
916 TBool endOfRecord = EFalse;
919 token.Set(lex.NextToken());
920 if (!endOfRecord && (token.Length()==0 || token[0]=='#'))
926 tokLen=token.Length();
927 fileName.Set((TUint16*)token.Ptr(),tokLen,tokLen+1);
928 token.Set(lex.NextToken());
929 fsyName=fileName.PtrZ();
933 token.Set(lex.NextToken());
937 // Object name of .FSY
938 if (!endOfRecord && (token.Length()==0 || token[0]=='#'))
946 tokLen=token.Length();
947 fileName.Set((TUint16*)token.Ptr(),tokLen,tokLen+1);
948 token.Set(lex.NextToken());
949 objName=fileName.PtrZ();
953 token.Set(lex.NextToken());
958 if (!endOfRecord && (token.Length()==0 || token[0]=='#'))
962 else // Get extension
966 tokLen=token.Length();
967 fileName.Set((TUint16*)token.Ptr(),tokLen,tokLen+1);
968 token.Set(lex.NextToken());
969 extName=fileName.PtrZ();
973 token.Set(lex.NextToken());
978 if (!endOfRecord && (token.Length()==0 || token[0]=='#'))
986 TInt r=ParseMappingFileFlags(token,flags,spare);
993 // For every local drive
995 SLocalDriveMappingInfo* mappingInfo = &anInfo;
996 for(TInt i = 0; i<localDriveCount; i++)
998 if(iMapCount >= KMaxLocalDrives)
1000 Mem::FillZ(mappingInfo,sizeof(SLocalDriveMappingInfo));
1002 mappingInfo->iDriveNumber = driveNumber;
1003 mappingInfo->iLocalDriveNumber = localDriveNums[i];
1004 mappingInfo->iFsInfo.iExtName = extName;
1005 mappingInfo->iFsInfo.iFsyName = fsyName;
1006 mappingInfo->iFsInfo.iObjName = objName;
1007 mappingInfo->iSpare = spare;
1008 mappingInfo->iFsInfo.iFlags = flags;
1010 // If there was more than 1 local drive number (multi-slot device)
1011 // then increase iMapCount so that the mappingInfo doesn't get
1012 // clobbered next time this function is called.
1013 if(i>=1 && ((TInt)localDriveNums[i])!=KDriveInvalid)
1016 DEBUGPRINT2("Alternative Entry found for registered ldrive:%d -> %c:",localDriveNums[i],(mappingInfo->iDriveNumber+'A'));
1024 This is only called if a mapping configuration has specified "FS_SWAP_CORRUPT".
1025 If it is necessary to implement the drive swap then it is required that
1026 the entry for the second drive involved in the swap (ie the one specified
1027 in "FS_SWAP_CORRUPT-<drv>") occurs later in the mapping array than the one
1028 specifying the swap. This functions checks whether the ordering is OK and
1029 swaps the entries for the two drives if necessary.
1031 @param aTotalEntries The total number of valid entries in the mapping array.
1033 void TFSStartup::CheckAndReOrderArrayForSwapping(TInt aTotalEntries)
1036 // Find the swapper - and determine its entry number
1038 for (i=0;i<aTotalEntries;i++)
1040 if (iDriveMappingInfo[i].iFsInfo.iFlags & FS_SWAP_CORRUPT)
1043 if (i==aTotalEntries)
1045 TInt swapperEntryNo=i;
1046 TInt swappeeDrvNo=iDriveMappingInfo[i].iSpare;
1048 // Now find the swappee and determine its entry number
1049 for (i=0;i<aTotalEntries;i++)
1051 if (iDriveMappingInfo[i].iDriveNumber == swappeeDrvNo)
1054 if (i==aTotalEntries)
1056 TInt swappeeEntryNo=i;
1058 // If swappee comes before swapper then we need to switch then around
1059 if (swapperEntryNo>swappeeEntryNo)
1061 SLocalDriveMappingInfo tmp;
1062 tmp=iDriveMappingInfo[swapperEntryNo];
1063 iDriveMappingInfo[swapperEntryNo]=iDriveMappingInfo[swappeeEntryNo];
1064 iDriveMappingInfo[swappeeEntryNo]=tmp;
1069 Swap the local drive mappings of two entries in the mapping array. Also, update the local drive mapping previously
1070 written to the file server.
1072 @param aCurrentEntry The position in the mapping array of the next mapping to be applied.
1073 This coincides with the drive which has 'requested' the swap.
1074 (The other mapping involved in the swap is guarenteed to be later
1075 in the list and therefore not yet applied).
1076 @param aTotalEntries The total number of valid entries in the mapping array.
1078 @panic ESTART_12 0; If swap mapping file array is inconsistent.
1080 void TFSStartup::SwapDriveMappings(TInt aCurrentEntry,TInt aTotalEntries)
1082 DEBUGPRINT1("TFSStartup::SwapDriveMappings - Index %d",aCurrentEntry);
1083 TInt firstDrive=iDriveMappingInfo[aCurrentEntry].iDriveNumber;
1084 TInt secondDrive=iDriveMappingInfo[aCurrentEntry].iSpare;
1086 // Find the entry for the other mapping that we need to swap with
1088 for (secondEntry=aCurrentEntry ; secondEntry<aTotalEntries ; secondEntry++)
1090 if (iDriveMappingInfo[secondEntry].iDriveNumber==secondDrive)
1093 if (secondEntry==aTotalEntries)
1094 Panic(ELitSwapMappingFailArrayInconsistent,0);
1096 // Swap the entries over in the list of mappings still to be applied
1097 iDriveMappingInfo[aCurrentEntry].iDriveNumber=secondDrive;
1098 iDriveMappingInfo[secondEntry].iDriveNumber=firstDrive;
1100 // If second drive is replacing one that is corrupt then we always want to mount it
1101 iDriveMappingInfo[secondEntry].iFsInfo.iFlags&=~FS_NO_MOUNT;
1103 // Change the local drive mapping info already set with the file server
1104 SwapFServLocalDriveMapping(firstDrive,secondDrive);
1105 iDriveSwapCount=0; // Swap now handled and the FS local drive mapping is set
1109 Return the filename of the drive mapping file. If it is required to vary
1110 the local drive mapping for a given platform, depending on a particular platform
1111 specific setting (e.g. state of a switch or jumper setting, detection of
1112 a particular h/w feature etc) then it is still possible to use the map file scheme.
1113 In this situation, the ROM can be built with more than one mapping file.
1114 A custom version of ESTART should then override this virtual function to detect
1115 the current setting and return the name of the appropriate map file.
1117 @return A non-modifiable ptr descriptor containing the path and filename of the mapping file.
1119 TPtrC TFSStartup::LocalDriveMappingFileName()
1122 return(KLocalDriveMappingFile());
1126 Open the drive mapping file, and process each mapping record it contains.
1127 For each record, this involves updating the local drive list, adding the FSY and
1128 any extension specified and then mounting these on the drive in question -
1129 processing any mounting flags in the process. The local drive mapping is also
1130 written to the File Server.
1132 Calls InitCompositeFileSystem but carries on should this fail.
1134 @return KErrNone if no error.
1136 TInt TFSStartup::ProcessLocalDriveMappingFile()
1139 DEBUGPRINT("ProcessLocalDriveMappingFile");
1141 TInt r = InitCompositeFileSystem();
1142 __ASSERT_ALWAYS(r==KErrNone || r==KErrNotFound || r==KErrAlreadyExists,User::Panic(_L("EStart init composite fs failed"),r));
1144 // Following block of code tries to initialise the reading facilities of
1146 // Note: RFs::InitialisePropertiesFile() MUST always be called even there
1147 // is no estart.txt file. It is for the default construction of File
1148 // Cache Manager and Global Cache Memory Manager.
1150 TPtrC mappingFileName(LocalDriveMappingFileName());
1151 r=f.Open(iFs,mappingFileName,EFileShareExclusive|EFileStreamText|EFileRead);
1152 DEBUGPRINT2("Opening mapping file %S -> %d", &mappingFileName, r);
1155 // pass ROM address of estart.txt file to file server to allow it to support
1156 // reading of ".ini file" - style parameters
1157 TInt romAddress = 0;
1158 r = f.Seek(ESeekAddress, romAddress);
1167 TPtrC8 ptr((TUint8*)romAddress, size);
1168 iFs.InitialisePropertiesFile(ptr);
1177 // If any error detected found, the default version of RFs::InitialisePropertiesFile()
1178 // will be called before exiting.
1182 iFs.InitialisePropertiesFile(ptr);
1188 // Create a mapping file reader and pass it the file object. This will also result in the copying of the contents of
1189 // the file into reader's buffer. Mapping information read from the file will include pointers to text strings in
1190 // this buffer and so the reader object must not be deleted until processing is complete.
1191 iMapFile = new TText8FileReader;
1195 return(KErrNoMemory);
1198 DEBUGPRINT1("Reading map file returns %d",r);
1199 f.Close(); // Can't leave file on Z: open too long because can't mount composite FSY on Z: in this sitaution
1203 // Parse each drive mapping record in turn, saving the information in an array of mapping structures - one for
1204 // each valid record.
1206 TPtr linePtr(NULL,0);
1208 SLocalDriveMappingInfo* infoPtr;
1209 while ((r=iMapFile->Read(linePtr))==KErrNone && iMapCount<KMaxLocalDrives)
1211 infoPtr=&iDriveMappingInfo[iMapCount];
1212 if (ParseMappingRecord(linePtr,*infoPtr)==KErrNone)
1214 // Valid mapping record found
1215 TInt localDriveNumber=infoPtr->iLocalDriveNumber;
1216 __ASSERT_DEBUG(localDriveNumber >=0 && localDriveNumber < KMaxLocalDrives, User::Invariant());
1217 if (iLocalDriveList[localDriveNumber]!=KDriveInvalid)
1219 DEBUGPRINT2("Entry found for registered ldrive:%d -> %c:",localDriveNumber,(infoPtr->iDriveNumber+'A'));
1224 DEBUGPRINT1("Invalid LocalDriveNumber : %d",localDriveNumber);
1229 infoPtr->iLocalDriveNumber = KDriveInvalid; // reset all local drives
1235 return((r==KErrNone)?KErrGeneral:r); // Error reading the records, or too many records in mapping file
1238 // If there is the potential of a drive swap then check that the order of the entries in the mapping array
1239 // are consitent for this - re-order if necessary
1240 if (iDriveSwapCount)
1241 CheckAndReOrderArrayForSwapping(iMapCount);
1243 // Scan through the array of valid mappings - updating the the local drive list. Once, complete, write the list
1244 // to the File Server. (Apart from swapping internal drives, this can only be written once).
1247 // first clear default mappings for all local drives not listed on mapping file
1249 for(i=0;i<KMaxLocalDrives;i++)
1250 iLocalDriveList[i]=KDriveInvalid;
1252 // then map non composite local drives
1253 for (i=0;i<iMapCount;i++)
1255 if (iDriveMappingInfo[i].iFsInfo.iFlags & FS_COMPOSITE)
1257 iLocalDriveList[iDriveMappingInfo[i].iLocalDriveNumber]=iDriveMappingInfo[i].iDriveNumber;
1260 // finally map composite drives: the first is mapped to the drive letter specifed on the mapping file, the following
1261 // are mapped to unused drive letters. Later when they are added to the compsite mount their mappings are invalidated
1262 TInt drvNumber=EDriveA-1;
1263 for(i=0;i<iMapCount;i++)
1265 if (iDriveMappingInfo[i].iFsInfo.iFlags & FS_COMPOSITE)
1269 firstComp=iDriveMappingInfo[i].iDriveNumber;
1270 iLocalDriveList[iDriveMappingInfo[i].iLocalDriveNumber]=iDriveMappingInfo[i].iDriveNumber;
1274 r=SearchForUnusedDriveNumber(drvNumber);
1275 __ASSERT_ALWAYS(r==KErrNone, Panic(ELitLocalDriveMappingFail,r));
1276 iLocalDriveList[iDriveMappingInfo[i].iLocalDriveNumber]=drvNumber;
1281 SetFServLocalDriveMapping();
1284 // Scan through the array of valid mappings again - adding the FSY and any extension specified and then mounting
1285 // these on the drive in question.
1286 // Now that the mapping is written to the file server - we can't auto-detect file systems any more. Hence, don't
1287 // return an error if a drive fails to mount, just keep going.
1288 for (i=0;i<iMapCount;i++)
1290 // Record removable drives for later mount
1291 TLocalDriveCapsBuf caps;
1292 TBusLocalDrive drive;
1294 SLocalDriveMappingInfo* infoPtr = &iDriveMappingInfo[i];
1295 infoPtr->iRemovable = EFalse;
1296 r = drive.Connect(iDriveMappingInfo[i].iLocalDriveNumber, changed);
1299 infoPtr->iCapsRetCode = r = drive.Caps(caps);
1300 if (r==KErrNone && caps().iDriveAtt&KDriveAttRemovable)
1302 infoPtr->iRemovable = ETrue;
1309 r=MountFileSystem(iDriveMappingInfo[i]);
1310 if (r==KErrDisMounted)
1312 // We have encountered a corrupt internal drive which should be swapped with another internal drive
1313 SwapDriveMappings(i,iMapCount);
1314 i--; // Re-attempt to mount the same drive now that the mappings are swapped
1317 // If the drive is pageable, search for a ROM image file name and if found clamp it
1318 // so that nothing can overwrite it
1319 DEBUGPRINT3("Testing if Drive %c is pageable, r %d att %08X", 'A' + iDriveMappingInfo[i].iDriveNumber, r, caps().iMediaAtt);
1320 if (r == KErrNone && (caps().iMediaAtt & KMediaAttPageable))
1323 RArray<TPtrC> sysFiles;
1324 r = SysFileNames(sysFiles);
1325 TInt sysFilesCount = sysFiles.Count();
1327 for (TInt n=0; n< sysFilesCount; n++)
1329 TFileName romFilePath;
1330 romFilePath.Append( (TText) ('A'+iDriveMappingInfo[i].iDriveNumber) );
1331 romFilePath.Append(':');
1332 romFilePath.Append(sysFiles[n]);
1334 DEBUGPRINT1("Drive %c is pageable", 'A' + iDriveMappingInfo[i].iDriveNumber);
1336 r = file.Open(iFs, romFilePath, EFileRead);
1337 DEBUGPRINT2("Opening %S returned %d", &romFilePath, r);
1341 r = handle.Clamp(file);
1342 DEBUGPRINT2("Clamping %S returned %d", &romFilePath, r);
1350 if (gCompositeMountState==1)
1351 LoadCompositeFileSystem(firstComp);
1358 Return the filenames of any "System" files on a writable drive (e.g internal MMC).
1359 If the files are found, then they are clamped (and never unclamped) to prevent them from being overridden.
1360 This function should be overriden by the variant if needed.
1362 @return KErrNotSupported, by default if the function is not overridden.
1364 TInt TFSStartup::SysFileNames(RArray<TPtrC>& /*aFileNames*/)
1366 return KErrNotSupported;
1370 Search for any unused drive number that has not been added to the list.
1372 @param aDrvNum Drive number to be checked, if used or not.
1374 @return KErrNone if found one unused drive; KErrOverflow if all drives are used.
1376 TInt TFSStartup::SearchForUnusedDriveNumber(TInt& aDrvNum)
1379 while(++aDrvNum<=(TInt)EDriveZ)
1381 for(i=0;i<KMaxLocalDrives;i++)
1383 if(iLocalDriveList[i]==aDrvNum)
1386 if(i==KMaxLocalDrives) // found one
1389 return KErrOverflow; // all used up??
1394 Mount a file system on a drive. Adds the FSY and any extension specified and
1395 then mounts these on the specified drive. Also, processes any mount flags specified.
1397 @param anInfo A stucture holding the drive number, the details of the FSY/ext to be mounted on it and the mount flags.
1399 @return KErrNone if no error, KErrDisMounted if this needs to be mounted on an alternative drive.
1401 TInt TFSStartup::MountFileSystem(SLocalDriveMappingInfo& anInfo)
1407 TInt flags=anInfo.iFsInfo.iFlags;
1408 TInt drive=anInfo.iDriveNumber;
1412 // If an FSY is specified, mount this on the drive in question.
1413 if (anInfo.iFsInfo.iFsyName && !(flags & (FS_NO_MOUNT | FS_COMPOSITE)))
1415 fsyname.Set(anInfo.iFsInfo.iFsyName);
1416 r=iFs.AddFileSystem(fsyname);
1417 DEBUGPRINT2("AddFileSystem(%S) -> %d",&fsyname,r);
1418 if (r!=KErrNone && r!=KErrAlreadyExists)
1421 if (flags & FS_NOT_RUGGED)
1423 r = iFs.SetStartupConfiguration(ESetRugged, (TAny*)drive, (TAny*)EFalse);
1424 iRuggedFileSystem = 0;
1427 objname.Set((anInfo.iFsInfo.iObjName) ? anInfo.iFsInfo.iObjName : anInfo.iFsInfo.iFsyName);
1428 TBool isSync=(flags & FS_SYNC_DRIVE);
1429 if (anInfo.iFsInfo.iExtName)
1431 TPtrC extname(anInfo.iFsInfo.iExtName);
1432 r=iFs.AddExtension(extname);
1433 if (r==KErrNone || r==KErrAlreadyExists)
1434 r=iFs.MountFileSystem(objname,extname,drive,isSync);
1437 r=iFs.MountFileSystem(objname,drive,isSync);
1439 DEBUGPRINT4("MountFileSystem(%S) on drive %c: -> %d (sync=%d)",&objname,(drive+'A'),r,isSync);
1440 iUnmountedDriveBitmask&=~(0x01<<(anInfo.iLocalDriveNumber));
1443 // Process the mount flags
1444 DEBUGPRINT1("FSI flags %08x",flags);
1446 if ((cf=HandleCustomMountFlags(r,flags,anInfo.iSpare,drive))!=KErrNone)
1449 if (flags & FS_COMPOSITE)
1450 if (anInfo.iFsInfo.iFsyName && TPtrC(anInfo.iFsInfo.iFsyName).CompareF(KEcomp))
1451 LoadCompositeFileSystem(anInfo);
1453 LoadCompositeFileSystem(drive);
1454 // Handle format related flags
1455 if (flags & FS_FORMAT_ALWAYS)
1456 r=FormatDrive(drive);
1457 if ((flags & FS_FORMAT_COLD) && iColdStart)
1458 r=FormatDrive(drive);
1459 if (r==KErrCorrupt && (flags & FS_FORMAT_CORRUPT))
1460 r=FormatDrive(drive);
1463 //-- running ScanDrive on Rugged FAT volumes. "Rugged FAT" and "ScanDrive" are counterparts.
1464 //-- 1. Having "Rugged FAT" volume and not running ScanDrive on it doesn't make any sense and dangerous because "Rugged FAT" mechanisms imply using ScanDrive
1465 //-- 2. Vice versa, running ScanDrive on "non-rugged FAT" doesn't make any sense, it is jsut waste of time.
1466 //-- Thus: if the volume is detected as "Rugged FAT", force running ScanDrive on it; otherwise ignore FS_SCANDRIVE flag
1467 #if !defined(__X86__)
1470 TText driveLetter=(TText)(drive+'A');
1471 TBuf<3> driveDes=_L("?:\\");
1472 driveDes[0]=driveLetter;
1474 if(iRuggedFileSystem)
1475 {//-- the volume has rugged FAT, force ScanDrive
1477 if(!(flags & FS_SCANDRIVE))
1478 {//-- no FS_SCANDRIVE flag, this is obvious misconfiguration
1479 if(objname.CompareF(_L("FAT")) == 0)
1481 DEBUGPRINT1("### !!!! WARNING!!! Drive %S has RuggedFAT, but no FS_SCANDRIVE flag in estart.txt", &driveDes);
1482 DEBUGPRINT( "### !!!! Forcing ScanDrive. Check that the drive is configured properly !!!");
1486 iFs.ScanDrive(driveDes);
1489 {//-- the volume doesn't have rugged FAT
1490 if(flags & FS_SCANDRIVE)
1491 {//-- FS_SCANDRIVE flag is set for non-rugged-FAT drive. don't run ScanDrive
1492 DEBUGPRINT1("### !!!! WARNING!!! Drive %S has NON-Rugged FAT, but FS_SCANDRIVE flag is set in estart.txt", &driveDes);
1493 DEBUGPRINT( "### !!!! SKipping ScanDrive. Check that the drive is configured properly !!!");
1500 // Handle swap on corrupt or dismount on corrupt
1501 if (r==KErrCorrupt && ((flags & FS_DISMNT_CORRUPT) || (flags & FS_SWAP_CORRUPT)))
1502 // if (((flags & FS_DISMNT_CORRUPT) || (flags & FS_SWAP_CORRUPT))) // Testing swap mode - always swaps
1505 iFs.DismountFileSystem(objname,drive);
1507 if (flags & FS_SWAP_CORRUPT)
1509 anInfo.iFsInfo.iFlags&=~FS_SWAP_CORRUPT; // Mustn't try to swap again the next time
1510 r=KErrDisMounted; // Signal that this needs to be re-mounted on another drive
1516 #if !defined(AUTODETECT_DISABLE)
1517 const TInt KMaxFSInfoTableEntries=8;
1519 Standard file system info. array - used when auto-detecting an appropraite FSY for a local drive. In this scheme, the local
1520 drive capabilities and partition type information is examined to determine an appropraite FSY for the drive. Each entry
1521 contains an FSY detection function together with the corresponding information for that particular FSY configuration. This
1522 information includes the FSY/ext name string pointers and mounting flags. Each detection function should uniquely identify
1523 its associated FSY configuration.
1525 LOCAL_D const SFileSystemInfo FileSystems[KMaxFSInfoTableEntries] =
1527 {DetectELocal, {_S("elocal"), _S("fat"), 0, FS_SCANDRIVE}},
1528 {DetectIRam, {_S("elocal"), _S("fat"), 0, FS_FORMAT_COLD|FS_SYNC_DRIVE}},
1529 {DetectFtl, {_S("elocal"), _S("fat"), 0, FS_FORMAT_CORRUPT|FS_SCANDRIVE}},
1530 {DetectRofs, {_S("erofs"), _S("rofs"), 0, FS_DISMNT_CORRUPT}},
1531 {DetectComposite, {0, 0, 0, FS_COMPOSITE}},
1532 {DetectEneaLFFS, {_S("elffs"), _S("lffs"), 0, FS_FORMAT_CORRUPT}},
1533 {DetectIso9660, {_S("iso9660"), 0, 0, 0}},
1534 {DetectNtfs, {_S("ntfs"), 0, 0, 0}},
1538 Return the next entry from the standard file system info array - used when auto-detecting an FSY for a local drive.
1539 Override this function when altering or extending the standard file system info. array.
1541 @param anInfo Address of a pointer to a stucture to hold the returned mapping settings,
1542 FSY/ext name string pointers and mounting flags.
1543 @param aPos The current position within the array. The caller is responsible to
1544 initializing and incrementing this.
1546 @return KErrNone if no error, KErrNotFound if the end of the array is reached.
1548 TInt TFSStartup::GetNextStandardFSInfoEntry(const SFileSystemInfo** anEntry,TInt aPos)
1551 if (aPos<KMaxFSInfoTableEntries)
1553 *anEntry=&FileSystems[aPos];
1557 return(KErrNotFound);
1561 Detect the appropraite FSY configuration for a particular local drive. This is
1562 achieved by reading the drives capabilities and partition information and using
1563 this to determine an appropraite config.
1565 @param aLocalDriveNumber The number of the local drive .
1566 @param anInfo A stucture to hold the returned mapping settings,
1567 FSY/ext name string pointers and mounting flags.
1569 @return KErrNone if successful, KErrNotFound if an appropriate file system isn't found or any other error.
1571 TInt TFSStartup::DetectFileSystem(TInt aLocalDriveNumber,SLocalDriveMappingInfo& anInfo)
1574 DEBUGPRINT1("DetectFileSystem ldrive:%d",aLocalDriveNumber);
1575 TLocalDriveCapsV2 caps;
1576 TPckg<TLocalDriveCapsV2> capsBuf(caps);
1579 TInt r = ld.Connect(aLocalDriveNumber, changed);
1580 DEBUGPRINT1("Connect -> %d", r);
1583 TInt cr=ld.Caps(capsBuf);
1584 DEBUGPRINT1("Caps -> %d", cr);
1585 const SFileSystemInfo* fsi=NULL;
1586 for (TInt i=0 ; (r=GetNextStandardFSInfoEntry(&fsi,i))==KErrNone ; i++)
1588 TInt d=(*fsi->iDetect)(ld,cr,caps);
1589 DEBUGPRINT2("FS:%d Detect -> %d",i,d);
1594 d-=KFsDetectMappingChangeReturnOffset;
1595 if (d>=EDriveA && d<=EDriveZ)
1596 iLocalDriveList[aLocalDriveNumber]=d;
1598 TInt drive=iLocalDriveList[aLocalDriveNumber];
1599 anInfo.iDriveNumber=drive;
1600 anInfo.iLocalDriveNumber=aLocalDriveNumber;
1601 anInfo.iFsInfo=fsi->iFsInfo;
1610 For each registered local drive on the system detect an appropriate FSY configuration
1611 and attempt to mount this on the drive concerned.
1613 @return Always returns KErrNone.
1615 TInt TFSStartup::DetectAndMountFileSystems()
1618 InitCompositeFileSystem();
1620 // Determine an appropriate FSY configuration for each registered local drive
1622 DEBUGPRINT("DetectAndMountFileSystems");
1624 SLocalDriveMappingInfo* infoPtr;
1625 for (i=0;i<KMaxLocalDrives;++i)
1627 if(iLocalDriveList[i]!=KDriveInvalid)
1629 infoPtr=&iDriveMappingInfo[iMapCount];
1630 if (DetectFileSystem(i,*infoPtr)==KErrNone)
1632 DEBUGPRINT3("Entry found for registered ldrive: %2d->%c: (%s)",i,(infoPtr->iDriveNumber+'A'),infoPtr->iFsInfo.iFsyName);
1638 // Scan through the array of valid mappings - updating the the local drive list. Once, complete, write the list
1639 // to the File Server (can only be written once).
1640 for (i=0;i<iMapCount;i++)
1641 iLocalDriveList[iDriveMappingInfo[i].iLocalDriveNumber]=iDriveMappingInfo[i].iDriveNumber;
1642 SetFServLocalDriveMapping();
1644 // Scan through the array of valid mappings again - adding the FSY and any extension specified and then mounting
1645 // these on the drive in question
1646 for (i=0;i<iMapCount;i++)
1648 // Record removable drives for later mount
1649 TLocalDriveCapsBuf caps;
1650 TBusLocalDrive drive;
1652 SLocalDriveMappingInfo* infoPtr = &iDriveMappingInfo[i];
1653 infoPtr->iRemovable = EFalse;
1654 TInt r = drive.Connect(iDriveMappingInfo[i].iLocalDriveNumber, changed);
1657 infoPtr->iCapsRetCode = r = drive.Caps(caps);
1659 if (r==KErrNone && (caps().iDriveAtt&KDriveAttRemovable || drive.IsRemovable(sockNum)))
1661 infoPtr->iRemovable = ETrue;
1668 r=MountFileSystem(iDriveMappingInfo[i]);
1669 if (r==KErrDisMounted)
1671 // We have encountered a corrupt internal drive which should be swapped with another internal drive
1672 SwapDriveMappings(i,iMapCount);
1673 i--; // Re-attempt to mount the same drive now that the mappings are swapped
1681 #if defined(_LOCKABLE_MEDIA)
1683 Initialise the local media password store with contents of a file.
1685 @param aFile The file used to initialize the store. Must already be opened for
1686 read access in EFileStreamText mode.
1688 @return KErrNone if successful, KErrNoMemory if heap is full, otherwise one of the other system-wide error codes.
1690 TInt TFSStartup::WriteLocalPwStore(RFile& aFile)
1692 // Initialise local media password store with contents of aFile
1696 DEBUGPRINT("WriteLocalPwStore");
1699 TInt r=aFile.Size(size);
1700 if(r!=KErrNone || size==0)
1702 HBufC8* hBuf=HBufC8::New(size);
1704 return(KErrNoMemory);
1705 TPtr8 pBuf=hBuf->Des();
1709 TBusLocalDrive TBLD;
1710 TBool TBLDChangedFlag;
1712 for (TInt i=0; i<iMapCount; i++)
1714 SLocalDriveMappingInfo* infoPtr = &iDriveMappingInfo[i];
1715 DEBUGPRINT3("drive %d: removable %d capsret %d", i, infoPtr->iRemovable, infoPtr->iCapsRetCode);
1716 if (infoPtr->iRemovable || infoPtr->iCapsRetCode == KErrNotReady)
1718 r = TBLD.Connect(iDriveMappingInfo[i].iLocalDriveNumber, TBLDChangedFlag);
1721 r = TBLD.WritePasswordData(pBuf);
1722 DEBUGPRINT2("WritePasswordData on drive %d returned %d", i, r);
1724 // ignore error if media not ready (it MAY not be a removable drive)
1725 if (r != KErrNone && infoPtr->iCapsRetCode == KErrNotReady)
1736 Attempt to initilise the local media password store. This allows locked media devices
1737 (e.g. password protected MMC cards) to be accessed without notifier.
1739 @return KErrNone if successful otherwise one of the other system-wide error codes.
1741 TInt TFSStartup::InitializeLocalPwStore()
1743 // Attempt to initilise the local media password store
1744 // Allows locked device to be accessed without notifier
1746 DEBUGPRINT("InitializeLocalPwStore");
1749 TBuf<sizeof(KMediaPWrdFile)> mediaPWrdFile(KMediaPWrdFile);
1750 mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar();
1751 TInt r=f.Open(iFs,mediaPWrdFile,EFileShareExclusive | EFileStream | EFileRead);
1754 r=WriteLocalPwStore(f);
1755 __ASSERT_DEBUG(r == KErrNone || r == KErrCorrupt || r == KErrNotReady, Panic(ELitInitLocalPwStoreFail,r));
1762 #ifdef LOAD_PATCH_LDD
1764 Find any patch LDDs and load them.
1766 @panic ESTART_8 0; if creation of trap handler failed.
1767 @panic ESTART_9 Error_Code; if loading of LDD failed.
1768 Error_Code is the error code returned by User::LoadLogicalDevice().
1770 void TFSStartup::LoadPatchLDDs()
1772 #if defined(__EPOC32__)
1773 // Load an LDD to patch any bugs in the ROM
1774 // This will always return an error - ignore it
1775 _LIT(KLitPatchBootLdd,"Z:\\Sys\\Bin\\BOOT.LDD");
1777 User::LoadLogicalDevice(KLitPatchBootLdd);
1779 // Install a trap handler - fs.GetDir calls functions which might leave
1780 CTrapCleanup* trapHandler=CTrapCleanup::New();
1781 __ASSERT_ALWAYS(trapHandler!=NULL,Panic(ELitCreateTrapHandlerFail,0));
1783 // Find any patch ldds and load them - files with the .SYS extension and second uid KLogicalDeviceDriverUid
1784 // and third uid KPatchLddUid (0x100000CC, BOOT.LDD should probably be checked for this too)
1785 CDir* patchList=NULL;
1786 _LIT(KLitPatchSysLdd,"?:\\Sys\\Bin\\*.SYS");
1787 TBuf<sizeof(KLitPatchSysLdd)> litPatchSysLdd(KLitPatchSysLdd);
1788 litPatchSysLdd[0] = (TUint8) RFs::GetSystemDriveChar();
1789 if (iFs.GetDir(litPatchSysLdd,(KEntryAttSystem|KEntryAttAllowUid),ESortByName,patchList)==KErrNone)
1791 patchList->Sort(ESortByName);
1793 for (i=0;i<patchList->Count();i++)
1795 TEntry& entry=(*patchList)[i];
1796 if (entry[1]==KLogicalDeviceDriverUid && entry[2].iUid==KPatchLddUidValue)
1798 r=User::LoadLogicalDevice(entry.iName);
1799 __ASSERT_DEBUG(r==KErrNone,Panic(ELitLoadSysLddsFail,r));
1809 Try to add both the ROFS and Composite file systems.
1811 @return KErrNone if successful, KErrNotFound if either fail to be added.
1813 TInt TFSStartup::InitCompositeFileSystem()
1815 DEBUGPRINT("InitCompositeFileSystem");
1816 TInt r=iFs.AddFileSystem(KRofs);
1817 if (r==KErrNone || r==KErrAlreadyExists)
1819 DEBUGPRINT("ROFS is present");
1820 r=iFs.AddFileSystem(KCompfs);
1821 if (r==KErrNone || r==KErrAlreadyExists)
1823 gMountComposite=ETrue;
1824 gMountRofsAlone=EFalse;
1825 DEBUGPRINT("Comp FS is present");
1830 gMountRofsAlone=EFalse;
1832 return(KErrNotFound);
1836 Mount the composite file system on the specified drive.
1838 @param The number of the drive on which the composite FSY is to be loaded on.
1840 @panic ESTART_16 Error_Code; If unable to get file system name on the drive.
1841 Error_Code is the error code returned by RFs::FileSystemName().
1842 @panic ESTART_15 Error_Code; If unable to mount composite file system.
1843 Error_Code is the error code returned by RFs::SwapFileSystem().
1845 _LIT(KCompositeName,"Composite");
1846 void TFSStartup::LoadCompositeFileSystem(TInt aDrive)
1849 if (gMountComposite)
1851 DEBUGPRINT1("LoadCompositeFileSystem on %c:",(aDrive+'A'));
1853 TInt r=iFs.FileSystemName(buf,aDrive);
1854 DEBUGPRINT1("Read current FSY returns %d",r);
1855 __ASSERT_ALWAYS(r==KErrNone, Panic(EFsNameFail,r));
1856 __ASSERT_ALWAYS(buf!=KCompositeName, Panic(EFsNameFail,r));
1858 DEBUGPRINT1("Swap composite for %S",&buf);
1859 r=iFs.SwapFileSystem(buf,_L("Composite"),aDrive);
1860 DEBUGPRINT1("Swap file system returned %d", r);
1861 __ASSERT_ALWAYS(r==KErrNone, Panic(ECompMountFsFail,r));
1862 gCompositeMountState=ESwapped;
1866 Adds a local drive to the composite filesystem.
1868 @param anInfo A stucture holding mounting flags, drive number info.
1870 @panic ESTART_15 -11; If composite mount file already exist.
1872 void TFSStartup::LoadCompositeFileSystem(SLocalDriveMappingInfo& anInfo)
1875 if (gMountComposite)
1877 __ASSERT_ALWAYS(gCompositeMountState<2, Panic(ECompMountFsFail,KErrAlreadyExists));
1880 TBool sync = (anInfo.iFsInfo.iFlags & FS_SYNC_DRIVE)!=0;
1882 fsyname.Set(anInfo.iFsInfo.iFsyName);
1883 TInt r=iFs.AddFileSystem(fsyname);
1884 DEBUGPRINT2("AddFileSystem(%S) -> %d",&fsyname,r);
1885 __ASSERT_ALWAYS(r==KErrNone || r==KErrAlreadyExists, Panic(ECompMountFsFail,r));
1888 objname.Set((anInfo.iFsInfo.iObjName) ? anInfo.iFsInfo.iObjName : anInfo.iFsInfo.iFsyName);
1889 DEBUGPRINT4("LoadCompositeFileSystem on %c: with drive %i (%S) included. Sync=%d",(anInfo.iDriveNumber+'A'),anInfo.iLocalDriveNumber,&objname, anInfo.iFsInfo.iFlags);
1890 r=iFs.AddCompositeMount(objname,anInfo.iLocalDriveNumber,anInfo.iDriveNumber, sync);
1891 DEBUGPRINT1("AddCompositeMount returned %d", r);
1893 gCompositeMountState=EHasMounts;
1899 Initialize the local drives.It loads the relevant File Systems (FSYs),
1900 File Server extensions (FXTs) and mounts these on the appropriate drives.
1901 This involves mapping local drives to particular drive letters.
1902 First it attempts to open the local drive mapping file ESTART.TXT.If this file is
1903 found then ESTART loads this and attempts to apply the mapping contained within it.
1904 If a mapping file is not found then it attempts to automatically detect the most
1905 appropriate configuration for each local drive registered.
1906 Hence, if it has been necessary to customize ESTART solely to provide a custom set
1907 of local drive mappings then the generic ESTART can now be used - in conjunction
1908 with a platform specific version of the local drive mapping file: ESTART.TXT.
1909 However The entire local drive initialisation sequence provided by the generic version
1910 of ESTART can be overridden (while possibly re-using some of the services provided by
1911 the generic version).
1913 @return KErrNone if successful.
1915 @panic ESTART_11 Error_Code; If drive mapping file was not found and autodetect was not enabled.
1916 Error_Code is the error code returned by ProcessLocalDriveMappingFile().
1918 TInt TFSStartup::LocalDriveInit()
1922 for(i=0;i<KMaxLocalDrives;i++)
1923 iDriveMappingInfo[i].iLocalDriveNumber=KDriveInvalid; // reset all local drives
1925 TInt r=ProcessLocalDriveMappingFile();
1927 #if !defined(AUTODETECT_DISABLE)
1928 DetectAndMountFileSystems();
1930 Panic(ELitDriveMappingFileFail,r);
1935 #if defined(_LOCKABLE_MEDIA)
1936 InitializeLocalPwStore();
1939 #ifdef LOAD_PATCH_LDD
1943 // Notify file server that local fs initialisation complete
1944 TRequestStatus status;
1945 iFs.StartupInitComplete(status);
1946 User::WaitForRequest(status);
1947 DEBUGPRINT1("StatusInitComplete r=%d",status.Int());
1953 Get system startup mode. Licensees should override one of these two GetStartupMode
1954 functions to provide mechanism of getting startup mode. Startup mode then is put in iStartupMode.
1956 @return KErrNone if successful.
1958 @see TFSStartup::GetStartupModeFromFile()
1960 TInt TFSStartup::GetStartupMode()
1966 Get system startup mode from file after file server startup.
1968 @return KErrNone if successful.
1970 @see TFSStartup::GetStartupMode()
1972 TInt TFSStartup::GetStartupModeFromFile()
1974 return KErrNotSupported;
1978 Start the rest of the system. Try to find sysstart.exe and launch it.
1979 If failed to find it launch window server instead. This path is deprecated.
1981 @return KErrNone if successful.
1983 @panic ESTART_18 Error_Code; If getting startup mode fails.
1984 Error_Code is the error returned by GetStartupModeFromFile().
1985 @panic ESTART_14 Error_Code; If set for startup Mode fails.
1986 Error_Code is the error returned by RProperty::Set()
1987 @panic ESTART_19 Error_Code; If fails to lunch system agent.
1988 Error_Code is the error returned by StartSysAgt2()
1989 @panic ESTART_17 -1; If unable to start windows server.
1991 TInt TFSStartup::StartSystem()
1993 // Get startup mode when need to access file server
1994 TInt r = GetStartupModeFromFile();
1995 if (r != KErrNotSupported)
1997 __ASSERT_ALWAYS(r==KErrNone, Panic(EStartupModeFail,r));
1998 // Update startup mode property value
1999 r = RProperty::Set(KUidSystemCategory, KSystemStartupModeKey, iStartupMode);
2000 __ASSERT_ALWAYS(r==KErrNone, Panic(EPropertyError,r));
2003 // Launch system starter in system path
2005 r=ws.Create(KSystemStateManager, KNullDesC);
2008 r=ws.Create(KSystemStarterName, KNullDesC);
2012 if (r != KErrNone && r != KErrNotFound)
2013 Panic(ESysAgentFail,r);
2015 // Start the window server if failed starting up system starter
2017 iFs.DriveList(list);
2018 if (!CreateServer(list,KWindowServerRootName1))
2019 Panic(ELitNoWS,KErrNotFound);
2023 #ifdef SYMBIAN_ESTART_OUTPUT_BOOT_TIME
2024 TRequestStatus status;
2027 //-- wait for SystemStarter to finish and then output the number of ticks since boot
2028 //-- !! N.B on some systems SystemStarter process never finish, so the "status" never gets completed.
2029 //-- !! In this case it is worth trying Rendezvous(); because it usually call it.
2031 User::WaitForRequest(status);
2032 TUint tickCount = User::TickCount();
2033 RDebug::Printf("Boot time ticks %d (%d ms)\n", tickCount, tickCount*1000/64);
2037 #endif // SYMBIAN_ESTART_OUTPUT_BOOT_TIME
2043 TRequestStatus status;
2044 ws.Rendezvous(status);
2046 User::WaitForRequest(status);
2047 #ifdef SYMBIAN_ESTART_OUTPUT_BOOT_TIME
2048 // wait for SystemStateManager to finish and then output the number of ticks since boot
2049 TUint tickCount = User::TickCount();
2050 RDebug::Printf("Boot time ticks %d (%d ms)\n", tickCount, tickCount*1000/64);
2052 // System state manager may not exit on completion.
2053 if (ws.ExitType() != EExitKill && ws.ExitType() != EExitPending)
2054 User::Panic(_L("SysState died"),status.Int());
2055 #endif // SYMBIAN_ESTART_OUTPUT_BOOT_TIME
2063 File system startup class constructor
2065 TFSStartup::TFSStartup()
2069 iTotalSupportedDrives=0;
2070 iRuggedFileSystem=0;
2071 iRegisteredDriveBitmask=0;
2074 iUnmountedDriveBitmask=0;
2079 Initilize the file system startup class. Checks for the Capability of the process.
2080 Sets the termination effect of current and subsequently created thread on the
2081 owning process. Publishes startup mode property. Ensures HAL memory allocation is
2082 done and connects to the file server.
2084 @panic ESTART_14 Error_Code; If either the capability is not present or unable to define or set the property.
2085 Error_Code is the error code returned by RProcess().HasCapability() or
2086 RProperty::Define() or RProperty::Set().
2087 @panic ESTART_18 Error_Code; If unable to get startup mode.
2088 Error_Code is the error code returned by GetStartupMode().
2089 @panic ESTART_3 Error_Code; If HAL initialization fails.
2090 Error_Code is the error code returned by HAL::Get().
2091 @panic ESTART_4 Error_Code; If unable to connect to file server.
2092 Error_Code is the error code returned by RFs::Connect().
2093 @panic ESTART_7 Error_Code; If unable to fetch drive information.
2094 Error_Code is the error code returned by UserHal::DriveInfo().
2096 void TFSStartup::Init()
2098 #ifndef SYMBIAN_EXCLUDE_ESTART_DOMAIN_MANAGER
2099 #ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
2100 const char myDiagMsg[] = __PLATSEC_DIAGNOSTIC_STRING("Capability Check Failure");
2101 #endif //!__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
2102 TBool cap=RProcess().HasCapability(ECapabilityPowerMgmt, __PLATSEC_DIAGNOSTIC_STRING(myDiagMsg));
2103 __ASSERT_ALWAYS(cap, Panic(EPropertyError, cap));
2106 User::SetProcessCritical(User::ESystemCritical);
2107 User::SetCritical(User::ESystemCritical);
2109 // Get boot mode without need to access file server
2110 TInt r = GetStartupMode();
2111 __ASSERT_ALWAYS(r==KErrNone, Panic(EStartupModeFail,r));
2113 // Publish startup mode property
2114 _LIT_SECURITY_POLICY_PASS(readPolicy);
2115 _LIT_SECURITY_POLICY_C1(writePolicy, ECapabilityWriteDeviceData);
2116 r = RProperty::Define(KUidSystemCategory, KSystemStartupModeKey, RProperty::EInt, readPolicy, writePolicy);
2117 __ASSERT_ALWAYS(r==KErrNone, Panic(EPropertyError, r));
2118 r = RProperty::Set(KUidSystemCategory, KSystemStartupModeKey, iStartupMode);
2119 __ASSERT_ALWAYS(r==KErrNone, Panic(EPropertyError, r));
2121 r=HAL::Get(HAL::EMachineUid,iMuid); // make sure HAL memory allocation is done
2122 __ASSERT_ALWAYS(r==KErrNone, Panic(ELitHALFail, r));
2125 __ASSERT_ALWAYS(r==KErrNone, Panic(ELitConnectFsFail1, r));
2127 TDriveInfoV1Buf driveInfo;
2128 r=UserHal::DriveInfo(driveInfo);
2129 __ASSERT_ALWAYS(r==KErrNone,Panic(ELitFSInitDriveInfoFail,r));
2130 iTotalSupportedDrives=driveInfo().iTotalSupportedDrives;
2131 iRuggedFileSystem=driveInfo().iRuggedFileSystem;
2132 iRegisteredDriveBitmask=driveInfo().iRegisteredDriveBitmask;
2134 TUint registeredDriveBitmask=iRegisteredDriveBitmask;
2135 for (TInt i=0;i<KMaxLocalDrives;i++)
2137 if (registeredDriveBitmask & 0x01)
2138 iLocalDriveList[i]=DefaultLocalDrive(i);
2140 iLocalDriveList[i]=KDriveInvalid;
2141 registeredDriveBitmask >>= 1;
2143 iUnmountedDriveBitmask=iRegisteredDriveBitmask;
2145 TMachineStartupType reason;
2146 UserHal::StartupReason(reason);
2147 if (reason==EStartupCold || reason==EStartupColdReset)
2152 Mount all removable drives.
2154 @return KErrNone if successful.
2156 TInt TFSStartup::MountRemovableDrives()
2158 DEBUGPRINT("TFSStartup::MountRemovableDrives");
2160 for (TInt i=0;i<iMapCount;i++)
2162 SLocalDriveMappingInfo* infoPtr = &iDriveMappingInfo[i];
2163 if (!infoPtr->iRemovable)
2165 TInt r = MountFileSystem(iDriveMappingInfo[i]);
2166 DEBUGPRINT2("Mount drive (%c) -> %d",'A'+iDriveMappingInfo[i].iDriveNumber,r);
2167 if (r==KErrDisMounted)
2169 // We have encountered a corrupt internal drive which should be swapped with another internal drive
2170 SwapDriveMappings(i,iMapCount);
2171 i--; // Re-attempt to mount the same drive now that the mappings are swapped
2178 This is the main execution function which is responsible to start the File system.
2179 It sets the default Locale properties. Initializes all the local drives, HAL and
2180 creates the domain manager process. It also loads the locale and mounts all the
2183 @return KErrNone if successful.
2185 @panic ESTART_6 Error_Code; If initialization of local properties to default fails.
2186 Error_Code is the error code returned by UserSvr::LocalePropertiesSetDefaults().
2187 @panic ESTART_1 -1; If unable to create domain manager.
2188 @panic ESTART_2 Error_Code; If initialization of domain manager fails.
2189 Error_Code is the error code returned by RDmDomainManager::WaitForInitialization().
2191 TInt TFSStartup::Run()
2194 TInt r = UserSvr::LocalePropertiesSetDefaults();
2195 __ASSERT_ALWAYS(r==KErrNone,Panic(ELitLocaleInitialisationFail,r));
2205 r=LoadCodePageDll();
2208 DEBUGPRINT1("\nLoadCodePageDll() FAILED !!! : returned : %d", r);
2211 // Seperate ScanDrive from MountDrive; this allows drives to be mounted
2212 // followed by locale loading. Scanning drives after locale is set thus can
2213 // recognise non-english filename.
2214 MountRemovableDrives();
2217 // display the setting for all drives
2218 DEBUGPRINT(" L FSY OBJ EXT Flags FileCacheFlags");
2219 for(TInt i=0;i<KMaxLocalDrives;i++)
2221 if (iDriveMappingInfo[i].iLocalDriveNumber != KDriveInvalid)
2224 fsyName.Set(iDriveMappingInfo[i].iFsInfo.iFsyName?iDriveMappingInfo[i].iFsInfo.iFsyName:_L(""));
2226 objName.Set(iDriveMappingInfo[i].iFsInfo.iObjName?iDriveMappingInfo[i].iFsInfo.iObjName:_L(""));
2228 extName.Set(iDriveMappingInfo[i].iFsInfo.iExtName?iDriveMappingInfo[i].iFsInfo.iExtName:_L(""));
2230 // Get the TFileCacheFlags for this drive
2231 TVolumeInfo volInfo;
2232 volInfo.iFileCacheFlags = TFileCacheFlags(0xFFFFFFFF);
2233 r = iFs.Volume(volInfo, iDriveMappingInfo[i].iDriveNumber);
2234 DEBUGPRINT7("%c: %-2d %-8S %-8S %-8S %08X %08X",
2235 (TInt) TChar(iDriveMappingInfo[i].iDriveNumber) + TChar('A'),
2236 iDriveMappingInfo[i].iLocalDriveNumber,
2240 iDriveMappingInfo[i].iFsInfo.iFlags,
2241 volInfo.iFileCacheFlags);
2246 #ifndef SYMBIAN_EXCLUDE_ESTART_DOMAIN_MANAGER
2248 r=iFs.DriveList(list);
2250 // Create Domain Manager Process
2251 if (!CreateServer(list,KDmManagerFileNameLit))
2252 Panic(ELitNoDM, KErrNotFound);
2254 // Wait until Domain Manager completes its intialization
2255 r=RDmDomainManager::WaitForInitialization();
2256 __ASSERT_ALWAYS(r==KErrNone,Panic(ELitDMInitFail,r));
2257 // Now File Server can connect to Domain Manager
2264 Close the file system startup class.
2266 void TFSStartup::Close()
2269 // Ensure that the file servers local drive mapping is set.
2270 if (iDriveSwapCount)
2271 SwapFServLocalDriveMapping(KDriveInvalid,KDriveInvalid);
2279 const TUid KSystemAgentExeUid = {0x10204FC5};
2280 const TUidType serverUid(KNullUid, KNullUid, KSystemAgentExeUid);
2283 TInt err = server.Create(KSystemAgentName, KNullDesC, serverUid);
2287 TRequestStatus stat;
2288 server.Rendezvous(stat);
2289 if(stat != KRequestPending)
2290 server.Kill(0); // abort startup
2292 server.Resume(); // logon OK - start the server
2293 User::WaitForRequest(stat); // wait for start or death
2295 // we can't use the 'exit reason' if the server panicked as this
2296 // is the panic 'reason' and may be '0' which cannot be distinguished
2298 err = server.ExitType() == EExitPanic ? KErrGeneral : stat.Int();
2304 This function is intended to be derived by licensee to show format progress
2307 @param aPercent Percentage of format process
2308 @param aDrive Drive number
2310 void TFSStartup::ShowFormatProgress(TInt /*aPercent*/, TInt /*aDrive*/)
2317 This function loads the codepage dll based on the language index.
2319 @return KErrNotFound if No codepage dll is found to be loaded
2320 KErrNone if codepage dll is successfully loaded
2323 _LIT(KNonStandardCodePageName, "X-FAT%u");
2324 _LIT(KMicrosoftStandardCodePageName, "CP%u");
2326 TInt LoadCodePageDll()
2328 // Always MS codepage type. Currently only supports the Microsoft Standard codepage names
2329 // cp932.dll, cp 950.dll etc
2330 const TFatFilenameConversionType fatConvType = EFatConversionMicrosoftCodePage;
2331 TInt fatConvNumber = 0;
2333 TInt err = KErrNone;
2334 TBuf<KMaxCodepageDllName> codepageDllName;
2335 TBool CodepageFound = EFalse;
2337 /* Default LanguageID --> LocaleDll --> CodepageDll Mapping. Must be maintained.
2338 |---------------|---------------------------|-------------------------|---------------------------|
2339 | Language ID | Language Name | Locale dll (eloc.xxx) | FATCharsetConv (cpnnn.dll)|
2340 |---------------|---------------------------|-------------------------|---------------------------|
2341 | 29 | TaiwanChinese | elocl.29 | cp950.dll |
2342 | 30 | HongKongChinese | elocl.30 | cp950.dll |
2343 | 31 | PrcChinese | elocl.31 | cp936.dll |
2344 | 32 | Japanese | elocl.32 | cp932.dll |
2345 | 157 | English taiwan | elocl.157 | cp950.dll |
2346 | 158 | English HK | elocl.158 | cp950.dll |
2347 | 159 | English prc | elocl.159 | cp936.dll |
2348 | 160 | English japan | elocl.160 | cp932.dll |
2349 | 326 | Bahas Malay | elocl.326 | cp936.dll |
2350 | 327 | Indonesian(APAC)(Bahasa)| elocl.327 | cp936.dll |
2351 |---------------|---------------------------|-------------------------|---------------------------|
2353 Language ID is read from the HAL data file as Language Index. Based on the read Language Index,
2354 corresponding Codepage Dll name is created.
2358 TInt error=HAL::Get(HALData::ELanguageIndex,languageIndex);
2359 if (error==KErrNone)
2361 switch(languageIndex)
2365 fatConvNumber = 950;
2366 CodepageFound=ETrue;
2371 fatConvNumber = 950;
2372 CodepageFound=ETrue;
2377 fatConvNumber = 936;
2378 CodepageFound=ETrue;
2383 fatConvNumber = 936;
2384 CodepageFound=ETrue;
2389 fatConvNumber = 950;
2390 CodepageFound=ETrue;
2395 fatConvNumber = 950;
2396 CodepageFound=ETrue;
2401 fatConvNumber = 936;
2402 CodepageFound=ETrue;
2407 fatConvNumber = 932;
2408 CodepageFound=ETrue;
2413 fatConvNumber = 936;
2414 CodepageFound=ETrue;
2419 fatConvNumber = 936;
2420 CodepageFound=ETrue;
2425 CodepageFound=EFalse;
2431 // Do not use any codepage dll if the language index uses default FATCharsetconv conversions.
2433 return KErrNotFound;
2435 // Create the codepage dll name to be loaded.
2438 // coverity[dead_error_condition]
2439 // Always MS codepage type. Currently only supports the Microsoft Standard codepage names.
2440 case EFatConversionDefault:
2441 // Undefined conversion scheme; conversion obtained is whatever the
2442 // default policy is for this version of the OS.
2443 DEBUGPRINT("...EFatConversionDefault");
2445 case EFatConversionNonStandard:
2446 // x-fat<nnn>.dll is loaded, where <nnn> is the FAT filename conversion number.
2447 DEBUGPRINT("...EFatConversionNonStandard");
2448 codepageDllName.Format(KNonStandardCodePageName, fatConvNumber);
2450 case EFatConversionMicrosoftCodePage:
2451 // cp<nnn>.dll is loaded, where <nnn> is the FAT filename conversion number.
2452 DEBUGPRINT("...EFatConversionMicrosoftCodePage");
2453 codepageDllName.Format(KMicrosoftStandardCodePageName, fatConvNumber);
2456 DEBUGPRINT("...FAT Conversion Type Unknown");
2460 // Load the codepage dll.
2461 if(codepageDllName.Length())
2463 // No need for an F32 API to do this - ESTART is then only intended client for now.
2464 // - Note that we load the code page via the loader, as doing so in the file server
2465 // will cause deadlock (as RLibrary::Load depends on the file server).
2467 err = loader.Connect();
2470 err = loader.SendReceive(ELoadCodePage, TIpcArgs(0, &codepageDllName, 0));
2473 DEBUGPRINT2("...Loaded codepage DLL : %S [err: %d]", &codepageDllName, err);